Applies To:
  • CitectSCADA 5.xx

Summary:
If you call EnterCriticalSection() from a thread and that task is killed or ends without calling LeaveCriticalSection(), all other tasks waiting to enter that section will be granted access at the same time, instead of just one thread at a time. 

Solution:
EnterCriticalSection() is a Cicode function in the Include project. It uses SemWait() to block the thread until it can have access to some resource. The problem is that it does not check if an error has been returned from SemWait().

The following function could be added to your project to use instead of EnterCriticalSection. This is a modified version of EnterCriticalSection() which automatically retries SemWait() if the semaphore owner has died prematurely. If any other errors occur, it returns the error code, otherwise it returns 0.

INT
FUNCTION
AccessCriticalSection(STRING sName)
    INT hSem;
    INT iErr;

    hSem = SemOpen(sName, 2);
    iErr = SemWait(hSem, -1);

    WHILE iErr = 297 DO // Repeat if semaphore owner died
          iErr = SemWait(hSem, -1);
    END

    RETURN iErr;
END

 

Keywords:
 

Attachments