For your explanation to Question (1),

   Because the definition of “EventTriggerId” (in
   “UsageEnvironment/include/UsageEnvironment.hh”) is “u_int32_t”,
   *all* implementations (not just the default implementation) support
   no more than 32 different event triggers.

I don't think so. Total event trigger number can be incremented by changing the implementation, by not assuming that "EventTriggerId"(u_int32_t) has only one bit set on and others off. What I mean is, "EventTriggerId" can range in { 1, 2, 3, 4, 5, ..., 2^32 - 1 }, not just { 1, 2, 4, 8, 16, ..., 2^31 }. Take system socket file descriptor as an example. Socket descriptor is usually implemented by int(or other int-releated). We can assume that system limit one process to 1024 simultanously openned file descriptor, then socket descriptor can range from 1 to 1023 (not very precise), and this is supported by implementation similar to your implementation of event trigger, but with a bit recording system of "fd_set, which may be 1024 bits size. I believe live555's event trigger upper limit can be pushed by changing the implementation of the generation and recording system of "EventTriggerId", just like system socket's implementation. But if "BasicUsageEnvironment0.hh"is also the not-to-modify public interface, then the limit can't be changed since "EventTriggerId BasicTaskScheduler0::fTriggersAwaitingHandling" already has type "EventTriggerId", which only has 32-bit to set to distinguish different events.

And

   do {fTriggersAwaitingHandling |= eventTriggerId} while
   ((fTriggersAwaitingHandling&eventTriggerId) == 0); // (a)

There may still be some risk that "fTriggersAwaitingHandling" will be corrupted. The code above can only ensure that the bit is really set by "TriggerEvent" function, but it may corrupt other operation on it inside event loop in "BasicTaskScheduler::SingleStep":

   fTriggersAwaitingHandling &=~ fLastUsedTriggerMask;  // (b)

If the order of (a) and (b) is following:

   1. (b) Read.

   2. (b) Modify.

   3. (a) Read, Modify.

   4. (b) Write back to fTriggersAwaitingHandling .

   5. (a) Write back to fTriggersAwaitingHandling .

And (a) operation is completed, but (b) is not, since (b)'s write operation is overwrited by (a)'s write. I believe some protection to fTriggersAwaitingHandling's Read-Write is needed. And if you decide to change the implementation of event trigger(use other data structrue to recording event as I describe above), the exclusive Read-Write mechanism is still needed.

For solution, I didn't come up some ideas. Maybe spinlock is possible, but I'm not sure it can be implemented purely by normal C++(without other library support).


By mitshan.

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

Reply via email to