UnlockMutex w/o Lock locks

Just starting out? Need help? Post your questions and find answers here.
Polly
User
User
Posts: 29
Joined: Sat Jan 19, 2008 10:31 pm

UnlockMutex w/o Lock locks

Post by Polly »

UnlockMutex w/o previous Lock locks the mutex. Even a following Unlock can't unlock it again.

I know that this is not the normal process, but I think this behaviour is rather unexpected and causes unneccessary difficulties - you must make sure that in any case a lock has been set previously or your pgm is hanging.

Code: Select all

mut=CreateMutex()
Debug UnlockMutex(mut)
Debug LockMutex(mut)
Debug UnlockMutex(mut)
Tested on XP, 4.30
Fred
Administrator
Administrator
Posts: 18263
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

You can't use it like that without border effects. It's a raw API call, so it's the 'normal' behavior on Windows. The doc will be updated to reflect this.
Polly
User
User
Posts: 29
Joined: Sat Jan 19, 2008 10:31 pm

Post by Polly »

And you can't bypass this "normal Windows behaviour" by maintaining an index whether this mutex is in a lock or not? Of course I can do this in my application, but I would rather see this as a service from PB. One unlock too much and the pgm is hanging - that's a very nasty behaviour.
freak
PureBasic Team
PureBasic Team
Posts: 5944
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

> One unlock too much and the pgm is hanging - that's a very nasty behaviour.

If this happens then you have a serious bug in your program logic. Its not PB's job to correct that.
quidquid Latine dictum sit altum videtur
Polly
User
User
Posts: 29
Joined: Sat Jan 19, 2008 10:31 pm

Post by Polly »

Yes, I have a bug - and you a bug-prone interface design ...

I think, this could easily be avoided.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

There should be a debugger check for this, else it would be hard to know where the bug is, since when the program hangs in LockMutex() the debugger's "stop" command doesn't work.
freak
PureBasic Team
PureBasic Team
Posts: 5944
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

Polly wrote:Yes, I have a bug - and you a bug-prone interface design ...

I think, this could easily be avoided.
Mutexes are there to protect critical resources from being accessed by two threads. What good is that if you don't even know wether your resource is currently locked or not ?

If PB "fixed" this error you would gain nothing. Your program wouldn't hang, but still whatever the mutex was protecting is now in an inconsistent state. If you are unlucky you end up corrupting your program data. I'd prefere a hanging program in that case. There is no sense in "fixing" problems for the programmer when all it does is lead to potentially more dangerous problems.

Besides that, "easily avoided" is not quite right. Things are no as easy as some people might think, especially when it comes to threads.

@Trond:
I'll try to add a check for that.
quidquid Latine dictum sit altum videtur
Polly
User
User
Posts: 29
Joined: Sat Jan 19, 2008 10:31 pm

Post by Polly »

I used this Unlock to make sure that at a given point the resource was unlocked, regardless what happened before. I find this a quite reasonable approch and cannot see where the problem should be when Unlock always would do what it says.

I found a workaround now - just put a TryLock before - but I think there will be others that will fall into this trap. However it should be easy for you to fix the problem based on that.

BTW: The command TryLock is only senseful "if you don't even know wether your resource is currently locked or not"
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

You are in danger of making mutex useless by the way you are thinking/coding.

Code: Select all

mut=CreateMutex()

;The next code is someplace else in the program.
This is the proper way to check for a lock, while not blocking the thread.

If TryLockMutex(mut)
 Debug "Was not locked"
 ;Do some stuff here if needed.
 Debug UnlockMutex(mut)
Else
 Debug "Was locked"
 ;Nothing we can do, attempting to unlock here would be pointless
 ;as in a multi-threaded app it is possible that it's been unlocked already
 ;by the time this Else block is executed.

 ;However if this in the cleanup routine of your program,
 ;AND it is the very last time the mutex is referenced,
 ;AND all other threads using the mutex has finished,
 ;THEN you could do a unlock, but only then.
 ;PS! "A mutex can only be unlocked by the thread that also locked it. " so you need to trigger the cleanup in the thread that made the lock.
EndIf
Polly wrote:BTW: The command TryLock is only senseful "if you don't even know wether your resource is currently locked or not"
Actually no, it's purpose is to allow doing stuff if nothing else is doing stuff.
If Try fails it means something else is busy doing stuff.

LockMutex() is a blocking wait.
TryLockMutex() let you do "other" stuff, or implement you own wait loop.
TryLock is used a lot in parallel processing for example.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

Polly wrote:I found a workaround now - just put a TryLock before - but I think there will be others that will fall into this trap. However it should be easy for you to fix the problem based on that.

BTW: The command TryLock is only senseful "if you don't even know wether your resource is currently locked or not"
You forgot to take into consideration that UnlockMutex() is only useful if the current thread holds the lock (which you should know), while TryLockMutex() is for the cases where you don't know if other threads are holding the lock. TryLockMutex() is not meant to help you know whether the current thread holds the lock.
Polly
User
User
Posts: 29
Joined: Sat Jan 19, 2008 10:31 pm

Post by Polly »

So much arguments, only to justify that an Unlock must do the opposite of what it says in certain cases? Very strange....
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

Polly wrote:So much arguments, only to justify that an Unlock must do the opposite of what it says in certain cases? Very strange....
The help says that UnlockMutex() unlocks a mutex previously locked in the same thread by LockMutex(). If it doesn't work like that it's a bug (but it does work like that).

Calling UnlockMutex() without LockMutex() is like calling CloseWindow() without OpenWindow() or FreeMemory() without AllocateMemory() or PlaySound() without LoadSound(). It's obvious that it won't work.
Post Reply