WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   General Authoring Discussion (https://www.wowinterface.com/forums/forumdisplay.php?f=20)
-   -   Threads: where is the mutex/lock api? (https://www.wowinterface.com/forums/showthread.php?t=58225)

Stea 09-26-20 04:11 AM

Threads: where is the mutex/lock api?
 
I have just noticed some problems that have the hallmark race conditions. I have two functions, both called via an event. One of them I just added and it is essentially called every 3 seconds. The other is called based on an in game event, GROUP_ROSTER_UPDATE. Both of these functions call another which iterates over the group. I had noticed various errors around the return from GetRaidRosterInfo() being nil, which while its annoying that there is no interface to get a static representation of the group, can be explained by those group events like join/leave happening asynchronously and I just having the ability to iterate over an ever changing group. Bad, but explainable.

Now, when I really started to think I might be getting called by more than one thread, is when I got an index nil error for something that had just been returned by pair(). e.g.

Code:

  findWaitingPlayerIdx = function(self, player)
    for i, wait in pairs(self.waiting) do
      if wait[1] == player then
        return i
      end
    end
    return nil
  end,

self.waiting is core, so anything that has accessed it or changed it up to now has been hit pretty hard. What has changed was the function that enumerates groups started calling in to functions like the above, one of which removes an item from the list, and also started being called by two different event paths.

So, after that not so brief introduction, can anyone tell me categorically that wow either does or does not call events on multiple threads, and if it doesn't then I will go scratch my head some more and be glad I don't have the problem I think I might.

But if it it does, how am I to deal with that when the mutexess etc. are not included in the wow version of Lua. I've stumbled upon something that implements a mutex like thing, but without atomic operations that need support and guarantees from the silicon it can only help to reduce the window of a race condition, not eliminate it.

Thanks

Nevcairiel 09-26-20 04:55 AM

The entire WoW Lua API is single-threaded, there is no asynchronous calls for anything. While your code is running, no other Lua code is going to run, and your code is not getting interrupted for something else to run (sort of, if you call something that triggers an event, the event handler might run as part of that function call, and only return control to you once its done - all on the same thread)

In fact the UI even runs on the main game thread, to ensure relative integrity of game data while its running - of course that also means that slow addons tank performance, which they certainly can.

You didn't really explain your problem very much but directly jumped onto threading - which is just not the case. So maybe with some explanation, we can shed some light whats going on.

Stea 09-26-20 01:07 PM

Thanks, that is good news. I suspect then that the problem is just something to do with the changing group membership list while iterating the group - that at least is asynchronous, correct? Or should I be able to rely upon the membership list remaining static while I am enumerating it within one function?

Nevcairiel 09-27-20 04:11 AM

I don't think it should change during the execution of a Lua script

Vrul 09-27-20 06:16 AM

Quote:

Originally Posted by Stea (Post 336897)
I suspect then that the problem is just something to do with the changing group membership list while iterating the group

It depends on how you implemented it. Post your code.

d87 09-27-20 07:19 AM

This may be related to the issue that when joining group finder or lfd groups GetRaidRosterInfo() doesn't immediately has all the data about the members. And it returns nil for name, class etc

Stea 09-28-20 09:04 AM

Quote:

Originally Posted by d87 (Post 336910)
This may be related to the issue that when joining group finder or lfd groups GetRaidRosterInfo() doesn't immediately has all the data about the members. And it returns nil for name, class etc

Hmm that might explain the instance of nil for name that I got (I have catches and debug output for that now, along with a check around membership size changing during the loop). Though this add-on is classic only and that is where I saw the issue.

Stea 09-28-20 09:16 AM

Quote:

Originally Posted by Vrul (Post 336909)
It depends on how you implemented it. Post your code.

It's nothing fancy. Essentially:

getgroupmembership() do

-- add stuff to various lists within the same module
-- a few function calls base on trigger conditions (where the function updates updates lists in its own module modules)

end

If you are super interested in the current code it is here: https://github.com/prowley/SteaSummo...aster/raid.lua

You'll notice that I commented out the path from the roster update event callback, since I had decided not to deal with the issue for now since the group enumerated every 3 seconds on the other path anyway (because roster update doesn't appear to fire for every change of state in the roster).


All times are GMT -6. The time now is 02:30 AM.

vBulletin © 2020, Jelsoft Enterprises Ltd
© 2004 - 2020 MMOUI