FYI CreateMutex on Delphi5 is busted

Started by
4 comments, last by Shannon Barber 21 years, 6 months ago
And they fixed it on Delphi7 (don''t know about 6, we skipped that version). When you create a mutex, you can tell it whether or not you want it ''taken'' upon creation. In Delphi5 the mutex is never taken because they defined TRUE as $FFFFFFFF, and in the windows.h the TRUE they corresponds to BOOL is defined as 1. Then, inside of the CreateMutexW call (that CreateMutexA eventually makes), the flag is compared against 1, not against 0. By Delphi7 they added an extra function call that fixes up the flag and makes it 1 if it''s not 0. So if you use CreateMutex(..., TRUE, ...) in a Delphi5 app, you have a Race Condition in your code, because the mutex is not taken. If/when you call ReleaseMutex it will return an error indicating that the mutex is not taken. If only everybody checked all the return codes... brunt many hours on this, thought you guys might benefit from this information.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Advertisement

  procedure TForm1.Button1Click(Sender: TObject);var  x: Integer;  y: Integer;begin  x := Integer(LongBool(True));  y := Integer(True);  ShowMessage(Format('%x', [X]));  ShowMessage(Format('%x', [Y]));end;    


I may be wrong, but you could probably use "LongBool(True)" instead of just "True". Try it and let me know if it works.

Note: CreateMutex expects a LongBool as its second parameter, not a Boolean.

EDIT: Oops, looks like I got it back to front - sorry! Disregard this, I don't think it helps.

[edited by - Alimonster on October 18, 2002 3:09:04 PM]
Weird! CreateMutex works but not CreateMutexW? Hmm, sorry to hear about that bug. Thanks for letting us know!
Small test project using Delphi5 :

  program Project1;{$APPTYPE CONSOLE}uses SysUtils;Procedure _longbool(a : longbool);beginWriteln(Integer(a));end;Procedure _boolean(a : boolean);beginWriteln(Integer(a));end;begin_longbool(true);_boolean(true);readln;end.  

The output is:
-11 

Is it just be or does this NOT make sense?

CreateMutex, CreateMutexA & CreateMutexW all use the type longbool.
It makes sense in a way (but not a sensible one). Some people use -1 for true because it''s the total opposite of 0 (i.e., 0 = $00000000 and -1 = $FFFFFFFF), but some people use 1 instead (because they think in terms of bits, 1 or 0).

quote:A value of type ByteBool, LongBool, or WordBool is considered True when its ordinality is nonzero. If such a value appears in a context where a Boolean is expected, the compiler automatically converts any value of nonzero ordinality to True.


This seems to work:


  program JustOne;{$APPTYPE CONSOLE}uses  Windows,  SysUtils;var  H: THandle;begin  H := CreateMutex(nil, True, ''my_lovely_mutex'');  if GetLastError = ERROR_ALREADY_EXISTS then  begin    MessageBox(0, ''Error - already running'', ''Already exists'',               MB_OK or MB_ICONHAND or MB_DEFBUTTON1);    Halt;  end;  try    WriteLn(''A test of only one instance'');    ReadLn;  finally    Win32Check(ReleaseMutex(h));  end;end.  

However, it doesn''t if you use CreateMutexW. Weird! I repeat what I said before: Weird!

Can anyone get CreateMutexW working?
I have used CreateMutex(.., TRUE, ..) many times in D5E - It always works. Also, a search for this issue in google groups turns up nothing.

There can be ownership problems if ReleaseMutex is never called, if a program crashes in a certain way, for example.

You should try posting this to the borland.public.delphi.nativeapi newsgroup at newsgroups.borland.com

--- "A penny saved never boils."

This topic is closed to new replies.

Advertisement