https://bugs.kde.org/show_bug.cgi?id=407952

            Bug ID: 407952
           Summary: Race condition when capturing guide frames, with
                    possible fix
           Product: kstars
           Version: git
          Platform: MS Windows
                OS: MS Windows
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: general
          Assignee: mutla...@ikarustech.com
          Reporter: ke...@familyross.net
  Target Milestone: ---

When capturing guide frames, I would occasionally get the error in the INDI
panel that the requested value (0) was out of range. Also occasionally, I would
get a really, really short exposure, which would result in a guide frame with
just noise.

Digging in, and putting a lot of debug logging in place, I think the problem
comes from when the INDI server sends back status messages about the current
exposure remaining. The problem seems to be made worse because the server and
client are communicating over WiFi, which slows down the responses from the
server to the client.

So, I believe what is happening:

    Guide module requests the CCD to capture a new frame.
    CCDChip::capture gets the exposure INumberVectorProperty from the device,
and updates the value to the new exposure value.
    (I think this is where things go wrong) The client receives a notification
from the server that the exposure value has changed, overwriting the
INumberVectorProperty above
    CCDChip::capture sends the wrong value to sendNewNumber()

I verified that # 3 is happening, by modifying CCDCHip::capture so that it
prints the value of the INumberVectorProperty right after it is set, and loops
a few times with a small delay, and prints the values again. During this time,
the value will sometimes change all on its own to 0, leading me to believe that
# 3 above is the culprit.

My fix is to modify CCDChip::capture to clone the INumberVectorProperty into a
local variable and make changes there. Since I don't know the proper way to
clone an INumberVectorProperty, my method is probably not ideal.

But here's my version of CCDChip::capture:

bool CCDChip::capture(double exposure)
{
    INumberVectorProperty *expProp = nullptr;

    switch (type)
    {
        case PRIMARY_CCD:
            expProp = baseDevice->getNumber("CCD_EXPOSURE");
            break;

        case GUIDE_CCD:
            expProp = baseDevice->getNumber("GUIDER_EXPOSURE");
            break;
    }

    if (expProp == nullptr)
        return false;

    // clone the INumberVectorProperty, to avoid modifications to the same
    // property from two threads
    INumber n;
    strcpy(n.name, expProp->np[0].name);
    n.value = exposure;

    auto newExpProp = std::make_unique<INumberVectorProperty>();
    strcpy(newExpProp->device, expProp->device);
    strcpy(newExpProp->name, expProp->name);
    newExpProp->np = &n;
    newExpProp->nnp = 1;

    clientManager->sendNewNumber(newExpProp.get());

    return true;
}

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to