[Live-devel] Total Event Trigger Number and Thread Safety

单铭铭 shanmingming at itssky.com
Sat Dec 19 18:14:35 PST 2020


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.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.live555.com/pipermail/live-devel/attachments/20201220/119a6773/attachment.htm>


More information about the live-devel mailing list