Ian Branch 127 Posted January 23 Hi Team, Delphi 12. I am trying my hand at Semaphores. Never touched them before this. ATT I have the following code: // // Create the named semaphore (if it doesn't already exist) GlobalSemaphore := TSemaphore.Create(nil, 1, 1, 'DBiAdminSemaphore'); // try // if GlobalSemaphore.Acquire then begin I understand that if the Semaphore 'DBiAdminSemaphore' already exists, it won't be created again. If it already exists, I want to test for its existance, hence the thought of Acquire, but it seems Acquire doesn't return a Boolean. How do I test if the Semaphore already exists? The objective here is to prevent the following code exceuting if the Semaphore exists. Regards & TIA, Ian Share this post Link to post
JonRobertson 72 Posted January 23 42 minutes ago, Ian Branch said: The objective here is to prevent the following code exceuting if the Semaphore exists Using AInitialCount and AMaximumCount values of 1, the semaphore may only be acquired "one time" and other calls to Acquire will block until the semaphore has been released by calling Release. You could call GlobalSemaphore.WaitFor(1) and check the result for wrTimeout. But that only tells you that the semaphore was already acquired when the call as made. The semaphore could be released, and possibly acquired by a different thread, before you called Acquire again. I hope that makes sense. Share this post Link to post
Ian Branch 127 Posted January 23 Hi Jon, Tks. The code is in the MainForm.FormShow Event. The App is accessed by multiple Users via ThinFinity (WEB), RDP & LAN. If one of the App has the GlobalSemaphore created, I don't want any of the other Apps running this piece of code. I don't know that I need to use Acquire at all? If WaitFor(1) works as suggested, I will be fine. Regards, Ian Share this post Link to post
DelphiUdIT 176 Posted January 24 (edited) May be you can use the Mutex (refer to https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createmutexw ) : Uses WinApi.Windows; var hMutex: THandle //Create a global mutex (valid for all system) hMutex:=CreateMutex(Nil,False,'Global\DBiAdminSemaphore'); //If the Mutex is already owned then exit (this means that another application take it) if (WaitForSingleObject(hMutex,0) = wait_TimeOut) then exitprocess(255); //The Mutex will close automatically when the program close Bye Edited January 24 by DelphiUdIT Share this post Link to post
PeterBelow 238 Posted January 24 12 hours ago, Ian Branch said: Hi Team, Delphi 12. I am trying my hand at Semaphores. Never touched them before this. ATT I have the following code: // // Create the named semaphore (if it doesn't already exist) GlobalSemaphore := TSemaphore.Create(nil, 1, 1, 'DBiAdminSemaphore'); // try // if GlobalSemaphore.Acquire then begin I understand that if the Semaphore 'DBiAdminSemaphore' already exists, it won't be created again. If it already exists, I want to test for its existance, hence the thought of Acquire, but it seems Acquire doesn't return a Boolean. How do I test if the Semaphore already exists? You call GetLastError after the Create call. It will return ERROR_ALREADY_EXISTS if the named semaphore already exists. That also applies to other named synchronization objects, like mutexes. See the API function CreateSemaphoreW. TSemaphore inherits a property LastError from THandleObject, it may serve as well. 1 Share this post Link to post
Remy Lebeau 1398 Posted January 24 (edited) 10 hours ago, PeterBelow said: TSemaphore inherits a property LastError from THandleObject, it may serve as well. Unfortunately, that does not work. The LastError property is set only if THandleObject.Wait() fails with an OS error. If a creation or acquisition/release fails, an exception is raised instead. If a creation succeeds with a non-zero error code, the LastError property is not set to reflect that. I have now opened a ticket for that feature: RSP-44312: THandleObject.LastError should be set during object creation Edited January 24 by Remy Lebeau 1 Share this post Link to post