Windows CE Networking Team WebLog

Windows CE Networking - from NDIS to TCP to SOAP to VOIP and everything in between.

How do clients know a service is ready?

Often clients start before servers, and need to be signaled when the service
is ready. In this post we'll  find a good solution to this problem.

Approach #1: Server signals a named event, clients waits for the event.

    Server:
        //Create manual reset event for service started
        hEvent = CreateEvent(NULL,TRUE,FALSE, SRV_STARTED_EVENT);
        SetEvent(hEvent)

    Clients:
       // Create manual reset event for service started
        hServiceReadyEvent = CreateEvent(NULL,TRUE,FALSE, SRV_STARTED_EVENT);

        WaitForSingleObject(hServiceReadyEvent)

Problems with #1:


What if the clients accidentally create the named event as an auto reset event. E.g. 

    Broken Client:

        // Accidently create an auto  reset event
        hServiceReadyEvent = CreateEvent(NULL,FALSE,FALSE, SRV_STARTED_EVENT);
        WaitForSingleObject(hServiceReadyEvent)


If the client code runs after the server code runs everything works as expected.    However, if the client code runs before the server code, the event is created  as an auto reset, and the next client that goes to check the event will block forever.   This bug can be very hard to find if you have a broken client that only  runs before  the server a few times.

Enough people have had this problem, that the OS provides a solution.  If  you create a registry key under HKLM/System/Events, filesys will open the named event as manual reset unsignaled and keep them open for the lifetime  of  filesys.exe

Approach #2: Have filesys create your named manual-reset at startup, then have client and server use OpenEvent.

    Registry Changes:

    ; @CESYSGEN IF CE_MODULES_IGOR_SERVICE
    ; HIVE BOOT SECTION
    [HKEY_LOCAL_MACHINE\SYSTEM\Events]
    "IgorsServiceReadyEventName"="Event triggered after IgorsService can be used"
    ; END HIVE BOOT SECTION
    ; @CESYSGEN ENDIF

    common code:

        #define SRV_STARTED_EVENT L"IgorsServiceReadyEventName"

    Server:

        //Open service ready event
        hServiceReadyEvent = OpenEvent(EVENT_ALL_ACCESS,FALSE,SRV_STARTED_EVENT);
      
SetEvent(hEvent)

   Clients:

        hServiceReadyEvent = OpenEvent(EVENT_ALL_ACCESS,FALSE,SRV_STARTED_EVENT);
        WaitForSingleObject(hServiceReadyEvent)

An interesting side effect of this solution is if OpenEvent fails, the client will know the service is not in the image, thus client code can be: 

   Clients that run on multiple CE configurations:
        hServiceReadyEvent = OpenEvent(EVENT_ALL_ACCESS,FALSE,SRV_STARTED_EVENT);
        if (hServiceReadyEvent == NULL)
        {
            // fatal service is not present in this configuration.
        }
        WaitForSingleObject(hServiceReadyEvent)

[Author: Igor Dvorkin]

Published Monday, October 10, 2005 4:18 PM by cenet

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

ce_base said:

Reference: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcecoreos5/html/wce50conEventRegistration.asp

The other detail here is that many of the "ready" events have the "SYSTEM/" prefix on them, which prevents untrusted callers from creating or modifying the events, but also prevents untrusted callers from opening or waiting for them. So we created the IsNamedEventSignaled API to allow an untrusted caller to test whether an event is signaled. Alas, this gets rid of the benefit of being able to open and see if the event will NEVER get signaled -- or to block and wait for it.
October 11, 2005 10:00 AM

Leave a Comment

(required) 
(optional)
(required) 
Submit

© 2008 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker