This is a recipe for bad bugs. Use defensive programming - grab the lock in the 
top-level functions, have private functions like ‘doXXXXWithLock()’ as a signal 
to the developer that they must be holding the lock.

Allowing callbacks to call back into a concurrent safe structure is very 
difficult - because the callbacks can easily be made async as well. 

I would just re-entrant locks. And ensure that no locks are held when the 
callback is made - or if it is - it needs to be heavily documented on what the 
callee can do.

Still, in your case without detailing api design available I am guessing you 
are going to run in deadlocks very quickly.



> On Jul 5, 2022, at 9:31 AM, Marvin Renich <m...@renich.org> wrote:
> 
> * atd...@gmail.com <atd...@gmail.com> [220705 10:03]:
>> :) That's what the asterisked note was for in the original question. I 
>> don't think I can do that in the real code because the real code is much 
>> more complex. Each node actually triggers a callback that may modify 
>> another node. That callback is user-created, not framework created so I 
>> have no way of knowing if the lock has already been taken.
>> 
>> And I wouldn't want for library users to have to make that distinction 
>> themselves.
> 
> Have the Set method always take some type of context, which is a pointer
> type.  If the context is nil, assume a top-level call to Set, otherwise
> use the context to decide what to do.  All the callbacks will be
> required to accept a context and pass it to the Set method.
> 
> If you have multiple goroutines that can be making top-level Set calls,
> I see no way around using something to distinguish top-level calls from
> Set within callbacks.
> 
> ...Marvin
> 
>> On Tuesday, July 5, 2022 at 3:48:16 PM UTC+2 Brian Candler wrote:
>> 
>>> Have a public Set() that does the lock and then calls a private internal 
>>> function, which assumes it's already running under the lock.
>>> https://go.dev/play/p/M1XuC8bxCxL
>>> 
>>> On Tuesday, 5 July 2022 at 13:32:26 UTC+1 atd...@gmail.com wrote:
>>> 
>>>> Hi,
>>>> 
>>>> I have a tree datastructure where mutating some nodes *may *trigger a 
>>>> mutation on some other tree nodes.
>>>> 
>>>> This tree should be accessible by multiple goroutines but mutated by only 
>>>> one at a time.
>>>> 
>>>> As such, I wanted to have a global lock on the tree such that mutatiing 
>>>> node methods should acquire this lock beforehand.
>>>> 
>>>> But it seems to require for the mutex to be reentrant? 
>>>> 
>>>> I have tried to create a very simplified*** model to illustrate 
>>>> https://go.dev/play/p/v37cbYQ1jSY
>>>> 
>>>> (***) I know people might want to suggest for the Set method to use a 
>>>> lockless variant when iterating over the linked nodes but in the real 
>>>> code, 
>>>> it iterates over user created callbacks instead and I don't think I can 
>>>> expect callbacks writers to juggle between the two kind of methods to 
>>>> avoid 
>>>> deadlocks.
>>>> 
>>>> Any suggestion?
>>>> 
>>>> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/YsRLSsBPXIbN0Nob%40basil.wdw.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/D5D0492E-F34E-4A71-8ACB-157A8DA7F688%40ix.netcom.com.

Reply via email to