thread safety for core Max (e.g. attributes, outlets, etc.)


    Aug 18 2017 | 3:47 pm
    What core Max components are thread safe with the main and timer thread?
    Max provides thread protection between the timer thread and the main thread for many of its common operations, such as sending messages and using outlets. ... Max provides a default global critical section for your use. This same critical section is used to protect the timer thread from the main thread (and vice versa) for many common Max data structures such as outlets.
    It is unclear what parts of Max are protected except for outlets. To start the conversation... What about attributes with default get/setters? What about attributes with custom getters and/or setters? Does Max core call critical_enter(0) before calling the default and/or custom get/setter.
    Scenario
    1. Max is in overdrive, therefore main and timer thread are both active in a patch.
    2. A custom object "foobar" is written using the Max SDK and instantiated in the patch. This object has an attribute called attr1. This attribute is an array of 5 longs, i.e. CLASS_ATTR_LONG_ARRAY. This attribute uses the default get/setters.
    3. Various objects and patchcords are sending attribute update messages to foobar for attr1 similar to the complex two thread scenario as described in SDK section 16.2.1
    4. Simultaneously, the patch inspector is open on foobar and the value of attr1 is being viewed and changed manually using the inspector UI.
    Inquiring minds want to know if the Max core codebase is providing thread safety protection for this attr1 attribute. And by extending that question, does Max provide thread safety for all four possibilities on attributes (default, only custom get, only custom set, custom get and set)? And what other components provide native thread safety?

    • Aug 29 2017 | 3:57 pm
      Hi Dale,
      This is a difficult question to answer, in part because what happens internally to Max (especially with regards to use of the global critical region) has changed several times over the years. In general we try to avoid using the global critical region in favor of more local and targeted mutex usage and developers of externals are encouraged to do the same.
      As you have asked, many of Max's components have some threadsafety mechanisms the work internally to those components. As an example, the t_linklist, t_hashtab, and t_dictionary structures have such a mechanism. However this does *not* mean that the code calling them is threadsafe! For example, if you look up an index in the linklist and then do something with that you still need to make that entire "transaction" of calls threadsafe yourself.
      In other words: if you need threadsafety for the operation of your external object then you should assume that you need to code defensively and take responsibility for it yourself.
      For the precise scenario you lay out ( attr is being hit in the scheduler thread in the patcher while simultaneously edited at low priority in the inspector ) I just took a quick look at the implementation of object_attr_setvalueof(). My quick reading confirms both my intuition and my statement above. While I could have missed something, I don't see any thread-safety mechanisms built into attribute setting.
      Hope this helps!