Metered Section
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5

Thread: Metered Section

  1. #1
    Join Date
    Sep 2003
    Posts
    815

    Metered Section

    Hello,

    I have read in the MSDN about metered sections and it seems like the right way to synchronise between a few applications I have.
    I tried using the CreateMeteredSection function but I got the following compilation error: d:\Projects\MyProject\MeterSec.cpp(1174): error C3861: 'CreateMeteredSection': identifier not found, even with argument-dependent lookup

    I have no idea which include to add I also don't find this function in the MSDN indexing, I saw it only in an article from 1998 'A Quick and Versatile Synchronization Object'

    Anyone knows about this Meterd Section, or maybe anyone has anothe way for fast synchronisation between 2 process?

    Thanks
    avi

  2. #2
    Join Date
    Mar 2004
    Location
    (Upper-) Austria
    Posts
    2,899
    the msdn contains the full source of meteredsection.h:

    Code:
    /************************************************************
        Module Name: MeteredSection.h
        Author: Dan Chou
        Description: Defines the metered section synchronization object
    ************************************************************/
    
    #ifndef _METERED_SECTION_H_
    #define _METERED_SECTION_H_
    
    #define MAX_METSECT_NAMELEN 128
    
    #ifdef __cplusplus
    extern "C"
    {
    #endif // __cplusplus
    
    // Shared info needed for metered section
    typedef struct _METSECT_SHARED_INFO {
        BOOL   fInitialized;     // Is the metered section initialized?
        LONG   lSpinLock;        // Used to gain access to this structure
        LONG   lThreadsWaiting;  // Count of threads waiting
        LONG   lAvailableCount;  // Available resource count
        LONG   lMaximumCount;    // Maximum resource count
    } METSECT_SHARED_INFO, *LPMETSECT_SHARED_INFO;
    
    // The opaque Metered Section data structure
    typedef struct _METERED_SECTION {
        HANDLE hEvent;           // Handle to a kernel event object
        HANDLE hFileMap;         // Handle to memory mapped file
        LPMETSECT_SHARED_INFO lpSharedInfo;
    } METERED_SECTION, *LPMETERED_SECTION;
    
    // Interface functions
    LPMETERED_SECTION
    CreateMeteredSection(LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName);
    
    #ifndef _WIN32_WCE
    LPMETERED_SECTION OpenMeteredSection(LPCTSTR lpName);
    #endif
    
    DWORD EnterMeteredSection(LPMETERED_SECTION lpMetSect, 
          DWORD dwMilliseconds);
    BOOL LeaveMeteredSection(LPMETERED_SECTION lpMetSect, 
          LONG lReleaseCount, LPLONG lpPreviousCount);
    void CloseMeteredSection(LPMETERED_SECTION lpMetSect);
    
    #ifdef __cplusplus
    }
    #endif // __cplusplus
    
    #endif // _METERED_SECTION_H_
    I am not offering technical guidiance via email or IM
    Come on share your photo with us! CG members photo album!
    Use the Code Tags!

  3. #3
    Join Date
    Mar 2004
    Location
    (Upper-) Austria
    Posts
    2,899
    and meteredsection.c:

    Code:
    /************************************************************
        Module Name: MeteredSection.c
        Author: Dan Chou
        Description: Implements the metered section synchronization object
    ************************************************************/
    
    #include <windows.h>
    #include <tchar.h>
    #include "MeteredSection.h"
    
    // Internal function declarations
    BOOL InitMeteredSection(LPMETERED_SECTION lpMetSect, LONG lInitialCount, 
          LONG lMaximumCount, LPCTSTR lpName, BOOL bOpenOnly);
    BOOL CreateMetSectEvent(LPMETERED_SECTION lpMetSect, LPCTSTR lpName, BOOL 
          bOpenOnly);
    BOOL CreateMetSectFileView(LPMETERED_SECTION lpMetSect, LONG lInitialCount, 
          LONG lMaximumCount, LPCTSTR lpName, BOOL bOpenOnly);
    void GetMeteredSectionLock(LPMETERED_SECTION lpMetSect);
    void ReleaseMeteredSectionLock(LPMETERED_SECTION lpMetSect);
    
    /*
     * CreateMeteredSection
     */
    LPMETERED_SECTION CreateMeteredSection(LONG lInitialCount, 
          LONG lMaximumCount, LPCTSTR lpName)
    {
        LPMETERED_SECTION lpMetSect;
    
        // Verify the parameters
        if ((lMaximumCount < 1)             ||
            (lInitialCount > lMaximumCount) ||
            (lInitialCount < 0)             ||
            ((lpName) && (_tcslen(lpName) > MAX_METSECT_NAMELEN)))
        {
            SetLastError(ERROR_INVALID_PARAMETER);
            return NULL;
        }
    
        // Allocate memory for the metered section
        lpMetSect = (LPMETERED_SECTION)malloc(sizeof(METERED_SECTION));
    
        // If the memory for the metered section was allocated okay, 
        initialize it
        if (lpMetSect)
        {
            if (!InitMeteredSection(lpMetSect, lInitialCount, 
          lMaximumCount, lpName, FALSE))
            {
                CloseMeteredSection(lpMetSect);
                lpMetSect = NULL;
            }
        }
        return lpMetSect;
    }
    
    /*
     * OpenMeteredSection
     */
    #ifndef _WIN32_WCE
    LPMETERED_SECTION OpenMeteredSection(LPCTSTR lpName)
    {
        LPMETERED_SECTION lpMetSect = NULL;
    
        if (lpName)
        {
            lpMetSect = (LPMETERED_SECTION)malloc(sizeof(METERED_SECTION));
    
            // If the memory for the metered section was allocated okay
            if (lpMetSect)
            {
                if (!InitMeteredSection(lpMetSect, 0, 0, lpName, TRUE))
                {
                    // Metered section failed to initialize
                    CloseMeteredSection(lpMetSect);
                    lpMetSect = NULL;
                }
            }
        }
        return lpMetSect;
    }
    #endif
    
    /*
     * EnterMeteredSection
     */
    DWORD EnterMeteredSection(LPMETERED_SECTION lpMetSect, 
          DWORD dwMilliseconds)
    {
        while (TRUE)
        {
            GetMeteredSectionLock(lpMetSect);
    
            // We have access to the metered section, everything we 
          do now will be atomic
            if (lpMetSect->lpSharedInfo->lAvailableCount >= 1)
            {
                lpMetSect->lpSharedInfo->lAvailableCount--;
                ReleaseMeteredSectionLock(lpMetSect);
                return WAIT_OBJECT_0;
            }
    
            // Couldn't get in. Wait on the event object
            lpMetSect->lpSharedInfo->lThreadsWaiting++;
            ResetEvent(lpMetSect->hEvent);
            ReleaseMeteredSectionLock(lpMetSect);
            if (WaitForSingleObject(lpMetSect->hEvent, 
             dwMilliseconds) == WAIT_TIMEOUT)
            {
                return WAIT_TIMEOUT;
            }
        }
    }
    
    /*
     * LeaveMeteredSection
     */
    BOOL LeaveMeteredSection(LPMETERED_SECTION lpMetSect, LONG lReleaseCount, 
             LPLONG lpPreviousCount)
    {
        int iCount;
        GetMeteredSectionLock(lpMetSect);
    
        // Save the old value if they want it
        if (lpPreviousCount)
        {
            *lpPreviousCount = lpMetSect->lpSharedInfo->lAvailableCount;
        }
    
        // We have access to the metered section, 
        everything we do now will be atomic
        if ((lReleaseCount < 0) ||
            (lpMetSect->lpSharedInfo->lAvailableCount+lReleaseCount >
             lpMetSect->lpSharedInfo->lMaximumCount))
        {
            ReleaseMeteredSectionLock(lpMetSect);
            SetLastError(ERROR_INVALID_PARAMETER);
            return FALSE;
        }
        lpMetSect->lpSharedInfo->lAvailableCount += lReleaseCount;
        
        // Set the event the appropriate number of times
        lReleaseCount = 
          min(lReleaseCount,lpMetSect->lpSharedInfo->lThreadsWaiting);
        if (lpMetSect->lpSharedInfo->lThreadsWaiting)
        {
            for (iCount=0; iCount < lReleaseCount ; iCount++)
            {
                lpMetSect->lpSharedInfo->lThreadsWaiting--;
                SetEvent(lpMetSect->hEvent);
            }
        }
        ReleaseMeteredSectionLock(lpMetSect);
        return TRUE;
    }
    
    /*
     * CloseMeteredSection
     */
    void CloseMeteredSection(LPMETERED_SECTION lpMetSect)
    {
        if (lpMetSect)
        {
            // Clean up
            if (lpMetSect->lpSharedInfo) 
             UnmapViewOfFile(lpMetSect->lpSharedInfo);
            if (lpMetSect->hFileMap) CloseHandle(lpMetSect->hFileMap);
            if (lpMetSect->hEvent) CloseHandle(lpMetSect->hEvent);
            free(lpMetSect);
        }
    }
    
    /*
     * InitMeteredSection
     */
    BOOL InitMeteredSection(LPMETERED_SECTION lpMetSect, 
             LONG lInitialCount, LONG lMaximumCount,
                            LPCTSTR lpName, BOOL bOpenOnly)
    {
        // Try to create the event object
        if (CreateMetSectEvent(lpMetSect, lpName, bOpenOnly))
        {
            // Try to create the memory mapped file
            if (CreateMetSectFileView(lpMetSect, 
             lInitialCount, lMaximumCount, lpName, bOpenOnly))
            {
                return TRUE;
            }
        }
    
        // Error occured, return FALSE so the caller knows to clean up
        return FALSE;
    }
    
    /*
     * CreateMetSectEvent
     */
    BOOL CreateMetSectEvent(LPMETERED_SECTION lpMetSect, 
             LPCTSTR lpName, BOOL bOpenOnly)
    {
        TCHAR sz[MAX_PATH];
        if (lpName)
        {
            wsprintf(sz, _TEXT("DKC_MSECT_EVT_%s"), lpName);
    
    #ifndef _WIN32_WCE
            if (bOpenOnly)
            {
                lpMetSect->hEvent = OpenEvent(0, FALSE, sz);
            }
            else
            {
    #endif
                // Create an auto-reset named event object
                lpMetSect->hEvent = CreateEvent(NULL, FALSE, FALSE, sz);
    #ifndef _WIN32_WCE
            }
    #endif
        }
        else
        {
            // Create an auto-reset unnamed event object
            lpMetSect->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
        }
        return (lpMetSect->hEvent ? TRUE : FALSE);
    }
    
    /*
     * CreateMetSectFileView
     */
    BOOL CreateMetSectFileView(LPMETERED_SECTION lpMetSect, 
             LONG lInitialCount, LONG lMaximumCount,
                               LPCTSTR lpName, BOOL bOpenOnly)
    {
        TCHAR sz[MAX_PATH];
        DWORD dwLastError; 
    
        if (lpName)
        {
            wsprintf(sz, _TEXT("DKC_MSECT_MMF_%s"), lpName);
    
    #ifndef _WIN32_WCE
            if (bOpenOnly)
            {
                lpMetSect->hFileMap = OpenFileMapping(0, FALSE, sz);
            }
            else
            {
    #endif
                // Create a named file mapping
                lpMetSect->hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, 
             NULL, PAGE_READWRITE, 0, sizeof(METSECT_SHARED_INFO), sz);
    #ifndef _WIN32_WCE
            }
    #endif
        }
        else
        {
            // Create an unnamed file mapping
            lpMetSect->hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, 
             NULL, PAGE_READWRITE, 0, sizeof(METSECT_SHARED_INFO), NULL);
        }
     
        // Map a view of the file
        if (lpMetSect->hFileMap)
        {
            dwLastError = GetLastError();
            lpMetSect->lpSharedInfo = (LPMETSECT_SHARED_INFO) 
             MapViewOfFile(lpMetSect->hFileMap, FILE_MAP_WRITE, 0, 0, 0);
            if (lpMetSect->lpSharedInfo)
            {
                if (dwLastError != ERROR_ALREADY_EXISTS)
                {
                    lpMetSect->lpSharedInfo->lSpinLock = 0;
                    lpMetSect->lpSharedInfo->lThreadsWaiting = 0;
                    lpMetSect->lpSharedInfo->lAvailableCount = lInitialCount;
                    lpMetSect->lpSharedInfo->lMaximumCount = lMaximumCount;
                    InterlockedExchange(&(lpMetSect->lpSharedInfo-
                >fInitialized), TRUE);
                }
                else
                {   // Already exists; wait for it to be initialized by the creator
                  while (!lpMetSect->lpSharedInfo->fInitialized) Sleep(0);
                }
                return TRUE;
            }
        }
        return FALSE;
    }
    
    /*
     * GetMeteredSectionLock
     */
    void GetMeteredSectionLock(LPMETERED_SECTION lpMetSect)
    {
        // Spin and get access to the metered section lock
        while (InterlockedExchange(&(lpMetSect->lpSharedInfo->lSpinLock), 1) != 0)
            Sleep(0);
    }
    
    /*
     * ReleaseMeteredSectionLock
     */
    void ReleaseMeteredSectionLock(LPMETERED_SECTION lpMetSect)
    {
        InterlockedExchange(&(lpMetSect->lpSharedInfo->lSpinLock), 0);
    }
    I am not offering technical guidiance via email or IM
    Come on share your photo with us! CG members photo album!
    Use the Code Tags!

  4. #4
    Join Date
    Mar 2004
    Location
    (Upper-) Austria
    Posts
    2,899
    just create those files and add them to your project ...

    taken from: Here
    I am not offering technical guidiance via email or IM
    Come on share your photo with us! CG members photo album!
    Use the Code Tags!

  5. #5
    Andy Tacker is offline More than "Just Another Member"
    Join Date
    Jun 2001
    Location
    5550' N 3739' E
    Posts
    1,503
    this link might be some interest to you....
    CreateMeteredSection in MSDN

    [edit]... nohero posted it already
    If you think you CAN, you can, If you think you CAN'T, you are probably right.

    Have some nice Idea to share? Write an Article Online or Email to us and You may WIN a Technical Book from CG.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This a Codeguru.com survey!


On-Demand Webinars (sponsored)