I'm reading live555's UsageEnvironment related source codes. And I note that the implementation of EventTriggerId is u_int32_t, and every ID only has one bit set on and others off. Now I have some questions (to the default provided implementation of these classes):

(1). Does the default implementation can only handle different event triggers no more than 32 at the same time?

(2). Since the implementation is u_int32_t, and TaskScheduler::TriggerEvent function may be called outside the event loop, is there any thread-safety problem?

For question (2), I note that member variable BasicTaskScheduler0::fTriggersAwaitingHandling can be modified both in and outside of the event loop. For example, in the event loop BasicTaskScheduler::SingleStep may execute fTriggersAwaitingHandling &=~ fLastUsedTriggerMask; And in the BasicTaskScheduler0::triggerEvent (out side the event loop) may execute fTriggersAwaitingHandling |= eventTriggerId; And from the view of assembly code, |= or &= operator consists of three steps:

1. Read the variable from memory into register; 2. Operate on the register(| or &); 3. Write register back to variable memory.

BTW, the volatile specifier hasn't been ignored by me, but I don't think it can ensure the atomic operation on variableBasicTaskScheduler0::fTriggersAwaitingHandling.

And also by the comment inside BasicTaskScheduler0::triggerEvent:

      // Then, note this event as being ready to be handled.
      // (Note that because this function (unlike others in the
   library) can be called from an external thread, we do this last, to
      //  reduce the risk of a race condition.)
      fTriggersAwaitingHandling |= eventTriggerId;

Can I understand it as: The risk of a race condition is reduced, but it may ocurr under some circumstances.

I'll appreciate any explanation.

_______________________________________________
live-devel mailing list
live-devel@lists.live555.com
http://lists.live555.com/mailman/listinfo/live-devel

Reply via email to