Mutex Execution Locks

Just starting out? Need help? Post your questions and find answers here.
Learner
User
User
Posts: 15
Joined: Tue Dec 14, 2004 1:32 am
Location: Australia

Mutex Execution Locks

Post by Learner »

Why does this eventually lockup?

Code: Select all

#Red1=$0000FF  ;red
#Gray1=$D4D4D4  ;grey
Global Mutex1=CreateMutex()

MainWindow = OpenWindow(0,0,0,800,600,"",#PB_Window_TitleBar|#PB_Window_SystemMenu) 
PImage = CreateImage(1,700, 500)
If MainWindow=0 Or CreateGadgetList(WindowID(0))=0:MessageRequester("Error","OpenWindow Error",0) :End:  EndIf
PRDrawing = ImageGadget(1, 40, 85,700,500,PImage,#PB_Image_Border)

Procedure DoLoop()
  For a =1 To 100000
    LockMutex(Mutex1)
    ApiDC=StartDrawing(ImageOutput(1)) ;api commands need apiDC
    Box(0,0,40,40,#Red1) ; and draw it
    StopDrawing() 
    Debug "mutex Proc  "+Str(a)
    SetGadgetState(1, ImageID(1))   
    UnlockMutex(Mutex1)
  Next
EndProcedure  

Thread =CreateThread(@DoLoop(),#Null) 
Repeat
  Event=WaitWindowEvent()
  If Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
    KillThread(Thread)
    Break
  EndIf
  LockMutex(Mutex1)
  ApiDC=StartDrawing(ImageOutput(1)) 
  Box(0,0,40,40,#Gray1) ; and draw it
  StopDrawing() 
  Debug "mutex Main"
  SetGadgetState(1, ImageID(1))   
  UnlockMutex(Mutex1)
ForEver
Regards
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

LockMutex() waits. You can't stop a main window proc loop like that, the messages will pile up and lock the program. It's OK for the thread to wait, it's got nothing better to do, but the main window proc must be allowed to continue processing messages if the mutex isn't available. Replace the code in the main loop with If TryLockMutex() .. <drawing stuff> .. Endif and it will work fine. But it will only draw in the main loop if there are window messages the way you've written it. Try with WaitWindowEvent(1) to keep the loop going.
BERESHEIT
Learner
User
User
Posts: 15
Joined: Tue Dec 14, 2004 1:32 am
Location: Australia

Post by Learner »

Thanx for the help netmaestro. Will try your suggestion.
Regards.
Learner
User
User
Posts: 15
Joined: Tue Dec 14, 2004 1:32 am
Location: Australia

Post by Learner »

This seems to work ok,

Code: Select all

#Red1=$0000FF  ;red
#Gray1=$D4D4D4  ;grey
Global Mutex1=CreateMutex()

MainWindow = OpenWindow(0,0,0,800,600,"",#PB_Window_TitleBar|#PB_Window_SystemMenu) 
PImage = CreateImage(1,700, 500)
If MainWindow=0 Or CreateGadgetList(WindowID(0))=0:MessageRequester("Error","OpenWindow Error",0) :End:  EndIf
PRDrawing = ImageGadget(1, 40, 85,700,500,PImage,#PB_Image_Border)

Procedure DoLoop()
  For a =1 To 100000
    LockMutex(Mutex1)
    ApiDC=StartDrawing(ImageOutput(1)) ;api commands need apiDC
    Box(0,0,40,40,#Red1) ; and draw it
    StopDrawing() 
    Debug "mutex Proc  "+Str(a)
    SetGadgetState(1, ImageID(1))   
    UnlockMutex(Mutex1)
    ; Reduce speed so main thread can get a look in
    Delay(50)
  Next
EndProcedure  

Thread =CreateThread(@DoLoop(),#Null) 
Repeat
  Event=WaitWindowEvent()
  If Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
    KillThread(Thread)
    Break
  EndIf
  ;
  ; Other Code
  ;
  ;
  ;
  
  ; This will fix the problem if loosing some messages isnt a problem
  While Not TryLockMutex(Mutex1)
    Event=WaitWindowEvent(1) 
  Wend
  ApiDC=StartDrawing(ImageOutput(1)) 
  Box(0,0,40,40,#Gray1) ; and draw it
  StopDrawing() 
  Debug "mutex Main"
  SetGadgetState(1, ImageID(1))   
  UnlockMutex(Mutex1)
ForEver
Post Reply