Skip to content

Signal Event

A pair of C programs demonstrating cross-process synchronization with a named event — one waits on it, the other finds and signals it.

Published Jul 13, 1997

The simplest cross-process handshake there is. The waiter creates a named manual-reset-style event (auto-reset here, FALSE) with an explicit security descriptor so any process can open it, then blocks in WaitForSingleObject. The signaler probes for the name with OpenEvent, and if found opens it via CreateEvent (which returns the existing handle when the name already exists) and calls SetEvent to release the waiter. Run the waiter first, then the signaler from another console, and watch the blocked program continue. A good reference for the create/open/signal/wait dance whenever you need one-shot coordination between two of your own programs.

// Waiter
//////////////////////////////////////////////////////////////////////////////////////////////

#include <Windows.H>
#include <WindowsX.H>
#include <Stdio.H>
#include <Stdlib.H>

#define EventName "EventName"

struct _GlobalSecurity{
	SECURITY_DESCRIPTOR SD;
	SECURITY_ATTRIBUTES SA;
}; struct _GlobalSecurity GS;

void InitializeSecurity(void);

//////////////////////////////////////////////////////////////////////////////////////////////

int main(int argc, char *argv[])
{

	HANDLE EventHandle = NULL;

	EventHandle = CreateEvent( &GS.SA, FALSE, FALSE, EventName );

	printf("Waiting...\n");

	WaitForSingleObject( EventHandle, INFINITE );

	printf("Signaled...\n");
	system("Pause");

	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////

void InitializeSecurity(void)
{
	InitializeSecurityDescriptor(&GS.SD, SECURITY_DESCRIPTOR_REVISION);

	SetSecurityDescriptorDacl(&GS.SD, TRUE, 0, FALSE);

	GS.SA.nLength			   = sizeof(GS.SA);
	GS.SA.lpSecurityDescriptor = &GS.SD;
	GS.SA.bInheritHandle	   = FALSE;
}
// Signaler
#include <Windows.H>
#include <WindowsX.H>
#include <Stdio.H>
#include <Stdlib.H>

#define EventName "EventName"


int main(int argc, char *argv[])
{
    HANDLE EventHandle = NULL;

	EventHandle = OpenEvent( SYNCHRONIZE, FALSE, EventName );
	if(!EventHandle)
	{
		printf("Event Does Not Exist!\n");
		CloseHandle( EventHandle );
        return 0;
	}

    CloseHandle( EventHandle );

    printf("Event Exist! Signaling...\n");

	EventHandle = CreateEvent( NULL, FALSE, FALSE, EventName );

    SetEvent(EventHandle);

    printf("Signaled...\n");
    system("Pause");

    CloseHandle( EventHandle );
	return 0;
}

Two quirks worth knowing: the signaler's OpenEvent probe leaks nothing but does close and re-open the handle just to get a handle with write access (a single OpenEvent with EVENT_MODIFY_STATE would do), and the waiter never calls InitializeSecurity before using GS.SA in this listing - call it first in real code so the DACL is actually set up.

An unhandled error has occurred. Reload 🗙