Jamoma API  0.6.0.a19
Max/library/includes/JamomaThreading.h
1 /*
2  Issues surrounding threading with Jamoma in general,
3  and with objects subscribed to the hub in particular.
4 
5  PROJECT CODE NAME: "Be less critical"
6 
7  At a minimum we need to define our own mutex for the hub and not use Max's global
8  critical region.
9 
10  At the moment there are serious concerns about deadock because so much subscriber-related code
11  is calling outlet functions from within critical regions. For example, j.init, etc.
12  Also, critical regions is slow. So the question is: can we reduce or eliminate them?
13 
14  What we know:
15  * Subscribers are created and deleted only in the main thread.
16  * j.init (need to check this) should always be deferred and thus called in the main thread.
17  * j.message and j.parameter can be called from other threads (and thus need some protection)
18  * not sure about j.remote
19 
20  What we need to protect against, some scenarios:
21  * deadlock: j.init sends a message to j.parameter
22  * deadlock: j.message sends a message out of a module into another module and it bangs a j.init
23  * corruption: j.hub is in the middle of traversing the list of parameters to dispatch a message in the scheduler thread
24  in the middle of doing this a parameter is deleted or added in the main thread
25 
26  Big question: does this whole problem just go away if we switch to using Max's hashtab to manage parameters?
27  But wait, we need to keep an alphabetized list too. So in this case it makes sense (and we discussed briefly in Brussels)
28  that we should keep everything stored in parallel in a linklist and in a hashtab. Hmmm....
29 
30  In Max 5 there is a new dictionary object that does this, but maybe we want something lighter-weight and not as tied
31  to the Max API (e.g. for a future Pd port)? So then make our dictionary...
32 
33  So here is one suggestion:
34  1. we switch to dictionaries to manage parameters
35  2. we are basically in the same position we are already in
36  3. oops
37 
38 
39  Here is another suggestion:
40  The real concern is whether or not subscribers are being deleted or created. So we add a flag member
41  to the hub's struct.
42  * we set the flag anytime we are adding or removing a subscriber from the list
43  * immediately before dispatching a message we check the flag and abort the dispatch is needed
44 
45  This isn't quite as 'perfectly' safe, but actually this the same way it works with Max linklist implementation
46  where the critical region is buried inside of the linklist access itself, and if the object is deleted after
47  that access then it's just a message to a bad object (and not the end of the world). So in fact, it is safe
48  enough. Yes?
49 
50  This should allow us to avoid the potential deadlock situation. We should devise an intentional deadlock test first
51  and then compare before and after to be sure.
52 
53  In terms of the speed of the operation for checking the flag instead of entering and exiting the critical region,
54  my intuition tells me that it will be faster, but I would like to profile it first so we can compare before and
55  after. Probably the best test is some stuff with uzi objects driving parameters.
56 
57  */