Code: Select all
EnableExplicit
Procedure DoSomething()
;Delay(20)
EndProcedure
Global NewList TestList(), TestListMutex = CreateMutex()
Global DoTaskSemaphore = CreateSemaphore(), _TaskBusy, _DoTaskThread, Quit
Procedure DoTask(i)
;Protected NewList _TestList()
Repeat
WaitSemaphore(DoTaskSemaphore)
;LockMutex(TestListMutex)
;CopyList(TestList(), _TestList())
;ClearList(TestList())
;UnlockMutex(TestListMutex)
DoSomething()
; ForEach _TestList()
; Select _TestList()
; Case 1
; DoSomething()
; EndSelect
; Next
Until Quit
_DoTaskThread = 0
EndProcedure
Procedure AddTask()
;LockMutex(TestListMutex)
If AddElement(TestList())
TestList() = 1
EndIf
;UnlockMutex(TestListMutex)
EndProcedure
Procedure Test()
Protected i
For i = 1 To 500000
;LockMutex(TestListMutex)
;AddElement(TestList())
;TestList() = 1
AddTask() ;crashes
; LockMutex(TestListMutex)
; If AddElement(TestList()) ;works
; TestList() = 1 ;works
; EndIf ;works
; UnlockMutex(TestListMutex)
;UnlockMutex(TestListMutex)
SignalSemaphore(DoTaskSemaphore)
Next
MessageRequester("", "Done")
EndProcedure
Global WMain, b1, e
WMain = OpenWindow(#PB_Any, 0, 0, 300, 200, "Test", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
b1 = ButtonGadget(#PB_Any, 10, 10, 100, 30, "A")
_DoTaskThread = CreateThread(@DoTask(), 0)
Repeat
e = WaitWindowEvent()
Select e
Case #PB_Event_Gadget
Select EventGadget()
Case b1
Debug "b1"
Test()
EndSelect
EndSelect
Until e = #PB_Event_CloseWindow
Quit = #True
SignalSemaphore(DoTaskSemaphore)
Hope this helps... in full application it kept on crashing randomly while debugging. I suspected a lot of things, but slowly came to this end result

Seems like a bug in procedure calling debugging. When both sides call into a procedure before/after signalsemaphore/waitsemaphore (or lockmutex/unlockmutex) (test or dotask) it will crash. Doesn't matter how the rest is implemented.
Another version using lockmutex/unlockmutex that shows same crash behavior:
Code: Select all
EnableExplicit
Procedure DoSomething()
;Delay(20)
EndProcedure
Global NewList TestList(), TestListMutex = CreateMutex()
Global DoTaskSemaphore = CreateSemaphore(), _TaskBusy, _DoTaskThread, Quit
Procedure DoTask(i)
;Protected NewList _TestList()
Repeat
LockMutex(TestListMutex)
If ListSize(TestList()) > 0
UnlockMutex(TestListMutex)
DoSomething()
Else
UnlockMutex(TestListMutex)
Delay(20)
EndIf
;WaitSemaphore(DoTaskSemaphore)
;LockMutex(TestListMutex)
;CopyList(TestList(), _TestList())
;ClearList(TestList())
;UnlockMutex(TestListMutex)
;Delay(20)
;DoSomething()
; ForEach _TestList()
; Select _TestList()
; Case 1
; DoSomething()
; EndSelect
; Next
Until Quit
_DoTaskThread = 0
EndProcedure
Procedure AddTask(List lst())
LockMutex(TestListMutex)
If AddElement(lst())
lst() = 1
EndIf
UnlockMutex(TestListMutex)
EndProcedure
Procedure Test()
Protected i
For i = 1 To 500000
;LockMutex(TestListMutex)
;AddElement(TestList())
;TestList() = 1
AddTask(TestList()) ;crashes
; LockMutex(TestListMutex)
; If AddElement(TestList()) ;works
; TestList() = 1 ;works
; EndIf ;works
; UnlockMutex(TestListMutex)
;UnlockMutex(TestListMutex)
;SignalSemaphore(DoTaskSemaphore)
Next
MessageRequester("", "Done")
EndProcedure
Global WMain, b1, e
WMain = OpenWindow(#PB_Any, 0, 0, 300, 200, "Test", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
b1 = ButtonGadget(#PB_Any, 10, 10, 100, 30, "A")
_DoTaskThread = CreateThread(@DoTask(), 0)
Repeat
e = WaitWindowEvent()
Select e
Case #PB_Event_Gadget
Select EventGadget()
Case b1
Debug "b1"
Test()
EndSelect
EndSelect
Until e = #PB_Event_CloseWindow
Quit = #True
SignalSemaphore(DoTaskSemaphore)