diff options
Diffstat (limited to 'drivers/staging/epl/ShbIpc-Win32.c')
-rw-r--r-- | drivers/staging/epl/ShbIpc-Win32.c | 1202 |
1 files changed, 0 insertions, 1202 deletions
diff --git a/drivers/staging/epl/ShbIpc-Win32.c b/drivers/staging/epl/ShbIpc-Win32.c deleted file mode 100644 index b918147..0000000 --- a/drivers/staging/epl/ShbIpc-Win32.c +++ /dev/null @@ -1,1202 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: Project independend shared buffer (linear + circular) - - Description: Implementation of platform specific part for the - shared buffer - (Implementation for Win32) - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - 2006/06/27 -rs: V 1.00 (initial version) - -****************************************************************************/ - -#define WINVER 0x0400 // #defines necessary for usage of -#define _WIN32_WINNT 0x0400 // function <SignalObjectAndWait> - -#include <windows.h> -#include <stdio.h> -#include "global.h" -#include "sharedbuff.h" -#include "shbipc.h" - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -#if (!defined(SHBIPC_INLINED)) || defined(SHBIPC_INLINE_ENABLED) - -//--------------------------------------------------------------------------- -// Configuration -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// Constant definitions -//--------------------------------------------------------------------------- - -#define MAX_LEN_BUFFER_ID MAX_PATH - -#define IDX_EVENT_NEW_DATA 0 -#define IDX_EVENT_TERM_REQU 1 -#define IDX_EVENT_TERM_RESP 2 - -#define NAME_MUTEX_BUFF_ACCESS "BuffAccess" -#define NAME_EVENT_NEW_DATA "NewData" -#define NAME_EVENT_TERM_REQU "TermRequ" -#define NAME_EVENT_TERM_RESP "TermResp" -#define NAME_EVENT_JOB_READY "JobReady" - -#define TIMEOUT_ENTER_ATOMIC 1000 // for debgging: INFINITE -#define TIMEOUT_TERM_THREAD 2000 - -#define SBI_MAGIC_ID 0x5342492B // magic ID ("SBI+") -#define SBH_MAGIC_ID 0x5342482A // magic ID ("SBH*") - -//--------------------------------------------------------------------------- -// Local types -//--------------------------------------------------------------------------- - -// This structure is the common header for the shared memory region used -// by all processes attached this shared memory. It includes common -// information to administrate/manage the shared buffer from a couple of -// separated processes (e.g. the refernce counter). This structure is -// located at the start of the shared memory region itself and exists -// consequently only one times per shared memory instance. -typedef struct { - unsigned long m_SbhMagicID; // magic ID ("SBH*") - unsigned long m_ulShMemSize; - unsigned long m_ulRefCount; - char m_szBufferID[MAX_LEN_BUFFER_ID]; - -#ifndef NDEBUG - unsigned long m_ulOwnerProcID; -#endif - -} tShbMemHeader; - -// This structure is the "external entry point" from a separate process -// to get access to a shared buffer. This structure includes all platform -// resp. target specific information to administrate/manage the shared -// buffer from a separate process. Every process attached to the shared -// buffer has its own runtime instance of this structure with its individual -// runtime data (e.g. the scope of an event handle is limitted to the -// owner process only). The structure member <m_pShbMemHeader> points -// to the (process specific) start address of the shared memory region -// itself. -typedef struct { - unsigned long m_SbiMagicID; // magic ID ("SBI+") - HANDLE m_hSharedMem; - HANDLE m_hMutexBuffAccess; - HANDLE m_hThreadNewData; // thraed to signal that new data are available - HANDLE m_ahEventNewData[3]; // IDX_EVENT_NEW_DATA + IDX_EVENT_TERM_REQU + ID_EVENT_TERM_RESP - tSigHndlrNewData m_pfnSigHndlrNewData; - HANDLE m_hThreadJobReady; // thread to signal that a job/operation is ready now (e.g. reset buffer) - HANDLE m_hEventJobReady; - unsigned long m_ulTimeOutJobReady; - tSigHndlrJobReady m_pfnSigHndlrJobReady; - tShbMemHeader *m_pShbMemHeader; - -#ifndef NDEBUG - unsigned long m_ulThreadIDNewData; - unsigned long m_ulThreadIDJobReady; -#endif - -} tShbMemInst; - -//--------------------------------------------------------------------------- -// Global variables -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// Local variables -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// Prototypes of internal functions -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// Get pointer to process local information structure -//--------------------------------------------------------------------------- - -INLINE_FUNCTION tShbMemInst *ShbIpcGetShbMemInst(tShbInstance pShbInstance_p) -{ - - tShbMemInst *pShbMemInst; - - pShbMemInst = (tShbMemInst *) pShbInstance_p; - ASSERT(pShbMemInst->m_SbiMagicID == SBI_MAGIC_ID); - - return (pShbMemInst); - -} - -//--------------------------------------------------------------------------- -// Get pointer to shared memory header -//--------------------------------------------------------------------------- - -INLINE_FUNCTION tShbMemHeader *ShbIpcGetShbMemHeader(tShbInstance - pShbInstance_p) -{ - - tShbMemInst *pShbMemInst; - tShbMemHeader *pShbMemHeader; - - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p); - pShbMemHeader = pShbMemInst->m_pShbMemHeader; - ASSERT(pShbMemHeader->m_SbhMagicID == SBH_MAGIC_ID); - - return (pShbMemHeader); - -} - -// not inlined internal functions -DWORD WINAPI ShbIpcThreadSignalNewData(LPVOID pvThreadParam_p); -DWORD WINAPI ShbIpcThreadSignalJobReady(LPVOID pvThreadParam_p); -const char *ShbIpcGetUniformObjectName(const char *pszEventJobName_p, - const char *pszBufferID_p, - BOOL fGlobalObject_p); - -#endif - -#if !defined(SHBIPC_INLINE_ENABLED) -// true internal functions (not inlined) -static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p); -static void ShbIpcReleasePrivateMem(void *pMem_p); -#endif - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -#if !defined(SHBIPC_INLINE_ENABLED) -// not inlined external functions - -//--------------------------------------------------------------------------- -// Initialize IPC for Shared Buffer Module -//--------------------------------------------------------------------------- - -tShbError ShbIpcInit(void) -{ - - return (kShbOk); - -} - -//--------------------------------------------------------------------------- -// Deinitialize IPC for Shared Buffer Module -//--------------------------------------------------------------------------- - -tShbError ShbIpcExit(void) -{ - - return (kShbOk); - -} - -//--------------------------------------------------------------------------- -// Allocate Shared Buffer -//--------------------------------------------------------------------------- - -tShbError ShbIpcAllocBuffer(unsigned long ulBufferSize_p, - const char *pszBufferID_p, - tShbInstance * ppShbInstance_p, - unsigned int *pfShbNewCreated_p) -{ - - HANDLE hSharedMem; - LPVOID pSharedMem; - unsigned long ulShMemSize; - tShbMemInst *pShbMemInst; - tShbMemHeader *pShbMemHeader; - tShbInstance pShbInstance; - unsigned int fShMemNewCreated; - const char *pszObjectName; - HANDLE hMutexBuffAccess; - HANDLE hEventNewData; - HANDLE hEventJobReady; - tShbError ShbError; - - ulShMemSize = ulBufferSize_p + sizeof(tShbMemHeader); - pSharedMem = NULL; - pShbInstance = NULL; - fShMemNewCreated = FALSE; - ShbError = kShbOk; - - //--------------------------------------------------------------- - // (1) open an existing or create a new shared memory - //--------------------------------------------------------------- - // try to open an already existing shared memory - // (created by an another process) - hSharedMem = OpenFileMapping(FILE_MAP_ALL_ACCESS, // DWORD dwDesiredAccess - FALSE, // BOOL bInheritHandle - pszBufferID_p); // LPCTSTR lpName - if (hSharedMem != NULL) { - // a shared memory already exists - fShMemNewCreated = FALSE; - } else { - // it seams that this process is the first who wants to use the - // shared memory, so it has to create a new shared memory - hSharedMem = CreateFileMapping(INVALID_HANDLE_VALUE, // HANDLE hFile - NULL, // LPSECURITY_ATTRIBUTES lpAttributes - PAGE_READWRITE, // DWORD flProtect - 0, // DWORD dwMaximumSizeHigh - ulShMemSize, // DWORD dwMaximumSizeLow - pszBufferID_p); // LPCTSTR lpName - - fShMemNewCreated = TRUE; - } - - if (hSharedMem == NULL) { - ShbError = kShbOutOfMem; - goto Exit; - } - - //--------------------------------------------------------------- - // (2) get the pointer to the shared memory - //--------------------------------------------------------------- - pSharedMem = MapViewOfFile(hSharedMem, // HANDLE hFileMappingObject - FILE_MAP_ALL_ACCESS, // DWORD dwDesiredAccess, - 0, // DWORD dwFileOffsetHigh, - 0, // DWORD dwFileOffsetLow, - ulShMemSize); // SIZE_T dwNumberOfBytesToMap - - if (pSharedMem == NULL) { - ShbError = kShbOutOfMem; - goto Exit; - } - - //--------------------------------------------------------------- - // (3) setup or update header and management information - //--------------------------------------------------------------- - pShbMemHeader = (tShbMemHeader *) pSharedMem; - - // allocate a memory block from process specific mempool to save - // process local information to administrate/manage the shared buffer - pShbMemInst = - (tShbMemInst *) ShbIpcAllocPrivateMem(sizeof(tShbMemInst)); - if (pShbMemInst == NULL) { - ShbError = kShbOutOfMem; - goto Exit; - } - // reset complete header to default values - pShbMemInst->m_SbiMagicID = SBI_MAGIC_ID; - pShbMemInst->m_hSharedMem = hSharedMem; - pShbMemInst->m_hMutexBuffAccess = INVALID_HANDLE_VALUE; - pShbMemInst->m_hThreadNewData = INVALID_HANDLE_VALUE; - pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] = - INVALID_HANDLE_VALUE; - pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] = - INVALID_HANDLE_VALUE; - pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] = - INVALID_HANDLE_VALUE; - pShbMemInst->m_pfnSigHndlrNewData = NULL; - pShbMemInst->m_hThreadJobReady = INVALID_HANDLE_VALUE; - pShbMemInst->m_hEventJobReady = INVALID_HANDLE_VALUE; - pShbMemInst->m_ulTimeOutJobReady = 0; - pShbMemInst->m_pfnSigHndlrJobReady = NULL; - pShbMemInst->m_pShbMemHeader = pShbMemHeader; - -#ifndef NDEBUG - { - pShbMemInst->m_ulThreadIDNewData = 0; - pShbMemInst->m_ulThreadIDJobReady = 0; - } -#endif - - // create mutex for buffer access - pszObjectName = - ShbIpcGetUniformObjectName(NAME_MUTEX_BUFF_ACCESS, pszBufferID_p, - TRUE); - hMutexBuffAccess = CreateMutex(NULL, // LPSECURITY_ATTRIBUTES lpMutexAttributes - FALSE, // BOOL bInitialOwner - pszObjectName); // LPCTSTR lpName - pShbMemInst->m_hMutexBuffAccess = hMutexBuffAccess; - ASSERT(pShbMemInst->m_hMutexBuffAccess != NULL); - - // The EventNewData is used for signaling of new data after a write - // operation (SetEvent) as well as for waiting for new data on the - // reader side (WaitForMultipleObjects). Because it's not known if - // this process will be read or write data, the event will be - // always created here. - pszObjectName = - ShbIpcGetUniformObjectName(NAME_EVENT_NEW_DATA, pszBufferID_p, - TRUE); - hEventNewData = CreateEvent(NULL, // LPSECURITY_ATTRIBUTES lpEventAttributes - FALSE, // BOOL bManualReset - FALSE, // BOOL bInitialState - pszObjectName); // LPCTSTR lpName - pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] = hEventNewData; - ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] != NULL); - - // The EventJobReady is used for signaling that a job is done (SetEvent) - // as well as for waiting for finishing of a job (WaitForMultipleObjects). - // Because it's not known if this process will signal or wait, the event - // will be always created here. - pszObjectName = - ShbIpcGetUniformObjectName(NAME_EVENT_JOB_READY, pszBufferID_p, - TRUE); - hEventJobReady = CreateEvent(NULL, // LPSECURITY_ATTRIBUTES lpEventAttributes - FALSE, // BOOL bManualReset - FALSE, // BOOL bInitialState - pszObjectName); // LPCTSTR lpName - pShbMemInst->m_hEventJobReady = hEventJobReady; - ASSERT(pShbMemInst->m_hEventJobReady != NULL); - - if (fShMemNewCreated) { - // this process was the first who wanted to use the shared memory, - // so a new shared memory was created - // -> setup new header information inside the shared memory region - // itself - pShbMemHeader->m_SbhMagicID = SBH_MAGIC_ID; - pShbMemHeader->m_ulShMemSize = ulShMemSize; - pShbMemHeader->m_ulRefCount = 1; - strncpy(pShbMemHeader->m_szBufferID, pszBufferID_p, - sizeof(pShbMemHeader->m_szBufferID) - 1); - -#ifndef NDEBUG - { - pShbMemHeader->m_ulOwnerProcID = GetCurrentProcessId(); - } -#endif - } else { - // any other process has created the shared memory and this - // process has only attached to it - // -> check and update existing header information inside the - // shared memory region itself - if (pShbMemHeader->m_ulShMemSize != ulShMemSize) { - ShbError = kShbOpenMismatch; - goto Exit; - } -#ifndef NDEBUG - { - if (strncmp - (pShbMemHeader->m_szBufferID, pszBufferID_p, - sizeof(pShbMemHeader->m_szBufferID) - 1)) { - ShbError = kShbOpenMismatch; - goto Exit; - } - } -#endif - - pShbMemHeader->m_ulRefCount++; - } - - // set abstarct "handle" for returning to application - pShbInstance = (tShbInstance *) pShbMemInst; - - Exit: - - if (ShbError != kShbOk) { - if (pShbMemInst != NULL) { - ShbIpcReleasePrivateMem(pShbMemInst); - } - if (pSharedMem != NULL) { - UnmapViewOfFile(pSharedMem); - } - if (hSharedMem != NULL) { - CloseHandle(hSharedMem); - } - } - - *pfShbNewCreated_p = fShMemNewCreated; - *ppShbInstance_p = pShbInstance; - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Release Shared Buffer -//--------------------------------------------------------------------------- - -tShbError ShbIpcReleaseBuffer(tShbInstance pShbInstance_p) -{ - - tShbMemInst *pShbMemInst; - tShbMemHeader *pShbMemHeader; - HANDLE hEventNewData; - HANDLE hMutexBuffAccess; - tShbError ShbError; - tShbError ShbError2; - - if (pShbInstance_p == NULL) { - return (kShbOk); - } - - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p); - pShbMemHeader = ShbIpcGetShbMemHeader(pShbInstance_p); - - if (!--pShbMemHeader->m_ulRefCount) { - ShbError = kShbOk; - } else { - ShbError = kShbMemUsedByOtherProcs; - } - - ShbError2 = ShbIpcStopSignalingNewData(pShbInstance_p); - hEventNewData = pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA]; - if (hEventNewData != INVALID_HANDLE_VALUE) { - CloseHandle(hEventNewData); - pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] = - INVALID_HANDLE_VALUE; - } - - hMutexBuffAccess = pShbMemInst->m_hMutexBuffAccess; - if (hMutexBuffAccess != INVALID_HANDLE_VALUE) { - CloseHandle(hMutexBuffAccess); - pShbMemInst->m_hMutexBuffAccess = INVALID_HANDLE_VALUE; - } - - UnmapViewOfFile(pShbMemHeader); - if (pShbMemInst->m_hSharedMem != INVALID_HANDLE_VALUE) { - CloseHandle(pShbMemInst->m_hSharedMem); - pShbMemInst->m_hSharedMem = INVALID_HANDLE_VALUE; - } - - ShbIpcReleasePrivateMem(pShbMemInst); - - if (ShbError == kShbOk) { - ShbError = ShbError2; - } - - return (ShbError); - -} - -#endif // !defined(SHBIPC_INLINE_ENABLED) - -#if (!defined(SHBIPC_INLINED)) || defined(SHBIPC_INLINE_ENABLED) - -//--------------------------------------------------------------------------- -// Enter atomic section for Shared Buffer access -//--------------------------------------------------------------------------- - -INLINE_FUNCTION tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p) -{ - - tShbMemInst *pShbMemInst; - HANDLE hMutexBuffAccess; - DWORD dwWaitResult; - tShbError ShbError; - - if (pShbInstance_p == NULL) { - return (kShbInvalidArg); - } - - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p); - ShbError = kShbOk; - - hMutexBuffAccess = pShbMemInst->m_hMutexBuffAccess; - if (hMutexBuffAccess != INVALID_HANDLE_VALUE) { - dwWaitResult = - WaitForSingleObject(hMutexBuffAccess, TIMEOUT_ENTER_ATOMIC); - switch (dwWaitResult) { - case WAIT_OBJECT_0 + 0: - { - break; - } - - case WAIT_TIMEOUT: - { - TRACE0 - ("\nShbIpcEnterAtomicSection(): WAIT_TIMEOUT"); - ASSERT(0); - ShbError = kShbBufferInvalid; - break; - } - - case WAIT_ABANDONED: - { - TRACE0 - ("\nShbIpcEnterAtomicSection(): WAIT_ABANDONED"); - ASSERT(0); - ShbError = kShbBufferInvalid; - break; - } - - case WAIT_FAILED: - { - TRACE1 - ("\nShbIpcEnterAtomicSection(): WAIT_FAILED -> LastError=%ld", - GetLastError()); - ASSERT(0); - ShbError = kShbBufferInvalid; - break; - } - - default: - { - TRACE1 - ("\nShbIpcEnterAtomicSection(): unknown error -> LastError=%ld", - GetLastError()); - ASSERT(0); - ShbError = kShbBufferInvalid; - break; - } - } - } else { - ShbError = kShbBufferInvalid; - } - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Leave atomic section for Shared Buffer access -//--------------------------------------------------------------------------- - -INLINE_FUNCTION tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p) -{ - - tShbMemInst *pShbMemInst; - HANDLE hMutexBuffAccess; - BOOL fRes; - tShbError ShbError; - - if (pShbInstance_p == NULL) { - return (kShbInvalidArg); - } - - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p); - ShbError = kShbOk; - - hMutexBuffAccess = pShbMemInst->m_hMutexBuffAccess; - if (hMutexBuffAccess != INVALID_HANDLE_VALUE) { - fRes = ReleaseMutex(hMutexBuffAccess); - ASSERT(fRes); - } else { - ShbError = kShbBufferInvalid; - } - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Start signaling of new data (called from reading process) -//--------------------------------------------------------------------------- - -INLINE_FUNCTION tShbError ShbIpcStartSignalingNewData(tShbInstance - pShbInstance_p, - tSigHndlrNewData - pfnSignalHandlerNewData_p, - tShbPriority - ShbPriority_p) -{ - - tShbMemInst *pShbMemInst; - tShbMemHeader *pShbMemHeader; - const char *pszObjectName; - HANDLE hEventTermRequ; - HANDLE hEventTermResp; - HANDLE hThreadNewData; - unsigned long ulThreadIDNewData; - tShbError ShbError; - int iPriority; - - if ((pShbInstance_p == NULL) || (pfnSignalHandlerNewData_p == NULL)) { - return (kShbInvalidArg); - } - - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p); - pShbMemHeader = ShbIpcGetShbMemHeader(pShbInstance_p); - ShbError = kShbOk; - - if ((pShbMemInst->m_hThreadNewData != INVALID_HANDLE_VALUE) || - (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] != - INVALID_HANDLE_VALUE) - || (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] != - INVALID_HANDLE_VALUE) - || (pShbMemInst->m_pfnSigHndlrNewData != NULL)) { - ShbError = kShbAlreadySignaling; - goto Exit; - } - - pShbMemInst->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p; - - // Because the event <pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA]> - // is used for signaling of new data after a write operation too (using - // SetEvent), it is always created here (see <ShbIpcAllocBuffer>). - - pszObjectName = - ShbIpcGetUniformObjectName(NAME_EVENT_TERM_REQU, - pShbMemHeader->m_szBufferID, FALSE); - hEventTermRequ = CreateEvent(NULL, // LPSECURITY_ATTRIBUTES lpEventAttributes - FALSE, // BOOL bManualReset - FALSE, // BOOL bInitialState - pszObjectName); // LPCTSTR lpName - pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] = hEventTermRequ; - ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] != NULL); - - pszObjectName = - ShbIpcGetUniformObjectName(NAME_EVENT_TERM_RESP, - pShbMemHeader->m_szBufferID, FALSE); - hEventTermResp = CreateEvent(NULL, // LPSECURITY_ATTRIBUTES lpEventAttributes - FALSE, // BOOL bManualReset - FALSE, // BOOL bInitialState - pszObjectName); // LPCTSTR lpName - pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] = hEventTermResp; - ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] != NULL); - - hThreadNewData = CreateThread(NULL, // LPSECURITY_ATTRIBUTES lpThreadAttributes - 0, // SIZE_T dwStackSize - ShbIpcThreadSignalNewData, // LPTHREAD_START_ROUTINE lpStartAddress - pShbInstance_p, // LPVOID lpParameter - 0, // DWORD dwCreationFlags - &ulThreadIDNewData); // LPDWORD lpThreadId - - switch (ShbPriority_p) { - case kShbPriorityLow: - iPriority = THREAD_PRIORITY_BELOW_NORMAL; - break; - - case kShbPriorityNormal: - iPriority = THREAD_PRIORITY_NORMAL; - break; - - case kshbPriorityHigh: - iPriority = THREAD_PRIORITY_ABOVE_NORMAL; - break; - - } - - ASSERT(pShbMemInst->m_hThreadNewData != NULL); - - SetThreadPriority(hThreadNewData, iPriority); - - pShbMemInst->m_hThreadNewData = hThreadNewData; - -#ifndef NDEBUG - { - pShbMemInst->m_ulThreadIDNewData = ulThreadIDNewData; - } -#endif - - Exit: - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Stop signaling of new data (called from reading process) -//--------------------------------------------------------------------------- - -INLINE_FUNCTION tShbError ShbIpcStopSignalingNewData(tShbInstance - pShbInstance_p) -{ - - tShbMemInst *pShbMemInst; - HANDLE hEventTermRequ; - HANDLE hEventTermResp; - DWORD dwWaitResult; - - if (pShbInstance_p == NULL) { - return (kShbInvalidArg); - } - - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p); - - // terminate new data signaling thread - // (set event <hEventTermRequ> to wakeup the thread and dispose it - // to exit, then wait for confirmation using event <hEventTermResp>) - hEventTermRequ = pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU]; - hEventTermResp = pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP]; - if ((hEventTermRequ != INVALID_HANDLE_VALUE) && - (hEventTermResp != INVALID_HANDLE_VALUE)) { - TRACE0("\nShbIpcStopSignalingNewData(): enter wait state"); - dwWaitResult = SignalObjectAndWait(hEventTermRequ, // HANDLE hObjectToSignal - hEventTermResp, // HANDLE hObjectToWaitOn - TIMEOUT_TERM_THREAD, // DWORD dwMilliseconds - FALSE); // BOOL bAlertable - TRACE0 - ("\nShbIpcStopSignalingNewData(): wait state leaved: ---> "); - switch (dwWaitResult) { - case WAIT_OBJECT_0 + 0: // event "new data signaling thread terminated" - { - TRACE0("Event = WAIT_OBJECT_0+0"); - break; - } - - default: - { - TRACE0("Unhandled Event"); - ASSERT(0); - break; - } - } - } - - if (pShbMemInst->m_hThreadNewData != INVALID_HANDLE_VALUE) { - CloseHandle(pShbMemInst->m_hThreadNewData); - pShbMemInst->m_hThreadNewData = INVALID_HANDLE_VALUE; - } - - if (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] != - INVALID_HANDLE_VALUE) { - CloseHandle(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU]); - pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] = - INVALID_HANDLE_VALUE; - } - - if (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] != - INVALID_HANDLE_VALUE) { - CloseHandle(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP]); - pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] = - INVALID_HANDLE_VALUE; - } - - pShbMemInst->m_pfnSigHndlrNewData = NULL; - - return (kShbOk); - -} - -//--------------------------------------------------------------------------- -// Signal new data (called from writing process) -//--------------------------------------------------------------------------- - -INLINE_FUNCTION tShbError ShbIpcSignalNewData(tShbInstance pShbInstance_p) -{ - - tShbMemInst *pShbMemInst; - HANDLE hEventNewData; - BOOL fRes; - - // TRACE0("\nShbIpcSignalNewData(): enter\n"); - - if (pShbInstance_p == NULL) { - return (kShbInvalidArg); - } - - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p); - - ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] != - INVALID_HANDLE_VALUE); - hEventNewData = pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA]; - if (hEventNewData != INVALID_HANDLE_VALUE) { - fRes = SetEvent(hEventNewData); - // TRACE1("\nShbIpcSignalNewData(): EventNewData set (Result=%d)\n", (int)fRes); - ASSERT(fRes); - } - // TRACE0("\nShbIpcSignalNewData(): leave\n"); - return (kShbOk); - -} - -//--------------------------------------------------------------------------- -// Start signaling for job ready (called from waiting process) -//--------------------------------------------------------------------------- - -INLINE_FUNCTION tShbError ShbIpcStartSignalingJobReady(tShbInstance - pShbInstance_p, - unsigned long - ulTimeOut_p, - tSigHndlrJobReady - pfnSignalHandlerJobReady_p) -{ - - tShbMemInst *pShbMemInst; - tShbMemHeader *pShbMemHeader; - HANDLE hThreadJobReady; - unsigned long ulThreadIDJobReady; - tShbError ShbError; - - if ((pShbInstance_p == NULL) || (pfnSignalHandlerJobReady_p == NULL)) { - return (kShbInvalidArg); - } - - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p); - pShbMemHeader = ShbIpcGetShbMemHeader(pShbInstance_p); - ShbError = kShbOk; - - if ((pShbMemInst->m_hThreadJobReady != INVALID_HANDLE_VALUE) || - (pShbMemInst->m_pfnSigHndlrJobReady != NULL)) { - ShbError = kShbAlreadySignaling; - goto Exit; - } - - pShbMemInst->m_ulTimeOutJobReady = ulTimeOut_p; - pShbMemInst->m_pfnSigHndlrJobReady = pfnSignalHandlerJobReady_p; - - // Because the event <pShbMemInst->m_ahEventJobReady> is used for - // signaling of a finished job too (using SetEvent), it is always - // created here (see <ShbIpcAllocBuffer>). - - hThreadJobReady = CreateThread(NULL, // LPSECURITY_ATTRIBUTES lpThreadAttributes - 0, // SIZE_T dwStackSize - ShbIpcThreadSignalJobReady, // LPTHREAD_START_ROUTINE lpStartAddress - pShbInstance_p, // LPVOID lpParameter - 0, // DWORD dwCreationFlags - &ulThreadIDJobReady); // LPDWORD lpThreadId - - pShbMemInst->m_hThreadJobReady = hThreadJobReady; - ASSERT(pShbMemInst->m_hThreadJobReady != NULL); - -#ifndef NDEBUG - { - pShbMemInst->m_ulThreadIDJobReady = ulThreadIDJobReady; - } -#endif - - Exit: - - return (ShbError); - -} - -//--------------------------------------------------------------------------- -// Signal job ready (called from executing process) -//--------------------------------------------------------------------------- - -INLINE_FUNCTION tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p) -{ - - tShbMemInst *pShbMemInst; - HANDLE hEventJobReady; - BOOL fRes; - - // TRACE0("\nShbIpcSignalJobReady(): enter\n"); - - if (pShbInstance_p == NULL) { - return (kShbInvalidArg); - } - - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p); - - ASSERT(pShbMemInst->m_hEventJobReady != INVALID_HANDLE_VALUE); - hEventJobReady = pShbMemInst->m_hEventJobReady; - if (hEventJobReady != INVALID_HANDLE_VALUE) { - fRes = SetEvent(hEventJobReady); - // TRACE1("\nShbIpcSignalJobReady(): EventJobReady set (Result=%d)\n", (int)fRes); - ASSERT(fRes); - } - // TRACE0("\nShbIpcSignalJobReady(): leave\n"); - return (kShbOk); - -} - -//--------------------------------------------------------------------------- -// Get pointer to common used share memory area -//--------------------------------------------------------------------------- - -INLINE_FUNCTION void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p) -{ - - tShbMemHeader *pShbMemHeader; - void *pShbShMemPtr; - - pShbMemHeader = ShbIpcGetShbMemHeader(pShbInstance_p); - if (pShbMemHeader != NULL) { - pShbShMemPtr = (BYTE *) pShbMemHeader + sizeof(tShbMemHeader); - } else { - pShbShMemPtr = NULL; - } - - return (pShbShMemPtr); - -} - -#endif - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -#if !defined(SHBIPC_INLINE_ENABLED) - -//--------------------------------------------------------------------------- -// Allocate a memory block from process specific mempool -//--------------------------------------------------------------------------- - -static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p) -{ - - HGLOBAL hMem; - void *pMem; - - hMem = GlobalAlloc(GMEM_FIXED, ulMemSize_p + sizeof(HGLOBAL)); - pMem = GlobalLock(hMem); - if (pMem != NULL) { - *(HGLOBAL *) pMem = hMem; - (BYTE *) pMem += sizeof(HGLOBAL); - } - -#ifndef NDEBUG - { - memset(pMem, 0xaa, ulMemSize_p); - } -#endif - - return (pMem); - -} - -//--------------------------------------------------------------------------- -// Release a memory block from process specific mempool -//--------------------------------------------------------------------------- - -static void ShbIpcReleasePrivateMem(void *pMem_p) -{ - - HGLOBAL hMem; - - if (pMem_p == NULL) { - return; - } - - (BYTE *) pMem_p -= sizeof(HGLOBAL); - hMem = *(HGLOBAL *) pMem_p; - - GlobalUnlock(hMem); - GlobalFree(hMem); - - return; - -} - -//--------------------------------------------------------------------------- -// Create uniform object name (needed for inter-process communication) -//--------------------------------------------------------------------------- - -const char *ShbIpcGetUniformObjectName(const char *pszObjectJobName_p, - const char *pszBufferID_p, - BOOL fGlobalObject_p) -{ - - static char szObjectName[MAX_PATH]; - char szObjectPrefix[MAX_PATH]; - - if (fGlobalObject_p) { - strncpy(szObjectPrefix, "Global\\", sizeof(szObjectPrefix)); - } else { - _snprintf(szObjectPrefix, sizeof(szObjectPrefix), "PID%08lX_", - (unsigned long)GetCurrentProcessId()); - } - - _snprintf(szObjectName, sizeof(szObjectName), "%s%s#%s", - szObjectPrefix, pszBufferID_p, pszObjectJobName_p); - - return (szObjectName); - -} - -//--------------------------------------------------------------------------- -// Thread for new data signaling -//--------------------------------------------------------------------------- - -DWORD WINAPI ShbIpcThreadSignalNewData(LPVOID pvThreadParam_p) -{ - - tShbInstance pShbInstance; - tShbMemInst *pShbMemInst; - DWORD dwWaitResult; - BOOL fTermRequ; - int fCallAgain; - - TRACE1 - ("\nShbIpcThreadSignalNewData(): SignalThread started (pShbInstance=0x%08lX)\n", - (DWORD) pvThreadParam_p); - - pShbInstance = (tShbMemInst *) pvThreadParam_p; - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance); - fTermRequ = FALSE; - - do { - ASSERT((pShbMemInst->m_ahEventNewData[0] != - INVALID_HANDLE_VALUE) - && (pShbMemInst->m_ahEventNewData[0] != NULL)); - ASSERT((pShbMemInst->m_ahEventNewData[1] != - INVALID_HANDLE_VALUE) - && (pShbMemInst->m_ahEventNewData[1] != NULL)); - - TRACE0("\nShbIpcThreadSignalNewData(): enter wait state"); - dwWaitResult = WaitForMultipleObjects(2, // DWORD nCount - pShbMemInst->m_ahEventNewData, // const HANDLE* lpHandles - FALSE, // BOOL bWaitAll - INFINITE); // DWORD dwMilliseconds - TRACE0 - ("\nShbIpcThreadSignalNewData(): wait state leaved: ---> "); - switch (dwWaitResult) { - case WAIT_OBJECT_0 + 0: // event "new data" - { - TRACE0("Event = WAIT_OBJECT_0+0"); - if (pShbMemInst->m_pfnSigHndlrNewData != NULL) { - TRACE0 - ("\nShbIpcThreadSignalNewData(): calling SignalHandlerNewData"); - do { - fCallAgain = - pShbMemInst-> - m_pfnSigHndlrNewData - (pShbInstance); - // d.k.: try to run any shared buffer which has higher priority. - // under Windows this is not really necessary because the Windows scheduler - // already preempts tasks with lower priority. - } while (fCallAgain != FALSE); - } - break; - } - - case WAIT_OBJECT_0 + 1: // event "terminate" - { - TRACE0("Event = WAIT_OBJECT_0+1"); - fTermRequ = TRUE; - break; - } - - default: - { - TRACE0("Unhandled Event"); - ASSERT(0); - fTermRequ = TRUE; - break; - } - } - } - while (!fTermRequ); - - if (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] != - INVALID_HANDLE_VALUE) { - SetEvent(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP]); - } - - TRACE1 - ("\nShbIpcThreadSignalNewData(): SignalThread terminated (pShbInstance=0x%08lX)\n", - (DWORD) pShbInstance); - - ExitThread(0); - -} - -//--------------------------------------------------------------------------- -// Thread for new data signaling -//--------------------------------------------------------------------------- - -DWORD WINAPI ShbIpcThreadSignalJobReady(LPVOID pvThreadParam_p) -{ - - tShbInstance *pShbInstance; - tShbMemInst *pShbMemInst; - DWORD ulTimeOut; - DWORD dwWaitResult; - unsigned int fTimeOut; - - TRACE1 - ("\nShbIpcThreadSignalJobReady(): SignalThread started (pShbInstance=0x%08lX)\n", - (DWORD) pvThreadParam_p); - - pShbInstance = (tShbInstance *) pvThreadParam_p; - pShbMemInst = ShbIpcGetShbMemInst(pShbInstance); - fTimeOut = FALSE; - - if (pShbMemInst->m_ulTimeOutJobReady != 0) { - ulTimeOut = pShbMemInst->m_ulTimeOutJobReady; - } else { - ulTimeOut = INFINITE; - } - - ASSERT((pShbMemInst->m_hEventJobReady != INVALID_HANDLE_VALUE) - && (pShbMemInst->m_hEventJobReady != NULL)); - - TRACE0("\nShbIpcThreadSignalJobReady(): enter wait state"); - dwWaitResult = WaitForSingleObject(pShbMemInst->m_hEventJobReady, // HANDLE hHandle - ulTimeOut); // DWORD dwMilliseconds - TRACE0("\nShbIpcThreadSignalJobReady(): wait state leaved: ---> "); - switch (dwWaitResult) { - case WAIT_OBJECT_0 + 0: // event "new data" - { - TRACE0("Event = WAIT_OBJECT_0+0"); - fTimeOut = FALSE; - break; - } - - case WAIT_TIMEOUT: - { - TRACE0("\nEvent = WAIT_TIMEOUT"); - fTimeOut = TRUE; - // ASSERT(0); - break; - } - - default: - { - TRACE0("Unhandled Event"); - fTimeOut = TRUE; - ASSERT(0); - break; - } - } - - if (pShbMemInst->m_pfnSigHndlrJobReady != NULL) { - TRACE0 - ("\nShbIpcThreadSignalJobReady(): calling SignalHandlerJobReady"); - pShbMemInst->m_pfnSigHndlrJobReady(pShbInstance, fTimeOut); - } - - pShbMemInst->m_hThreadJobReady = INVALID_HANDLE_VALUE; - pShbMemInst->m_pfnSigHndlrJobReady = NULL; - - TRACE1 - ("\nShbIpcThreadSignalJobReady(): SignalThread terminated (pShbInstance=0x%08lX)\n", - (DWORD) pShbInstance); - - ExitThread(0); - -} - -#endif - -// EOF |