[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