diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/staging/epl/EplTimeruNull.c | 312 | ||||
-rw-r--r-- | drivers/staging/epl/EplTimeruWin32.c | 513 | ||||
-rw-r--r-- | drivers/staging/epl/ShbIpc-Win32.c | 1202 |
3 files changed, 0 insertions, 2027 deletions
diff --git a/drivers/staging/epl/EplTimeruNull.c b/drivers/staging/epl/EplTimeruNull.c deleted file mode 100644 index 40ce403cbd03..000000000000 --- a/drivers/staging/epl/EplTimeruNull.c +++ /dev/null @@ -1,312 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for Epl Userspace-Timermodule NULL-Implementation - - 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. - - ------------------------------------------------------------------------- - - $RCSfile: EplTimeruNull.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.3 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - KEIL uVision 2 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/07/06 k.t.: start of the implementation - -****************************************************************************/ - -#include "user/EplTimeru.h" - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S <Epl Userspace-Timermodule NULL-Implementation> */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: Epl Userspace-Timermodule NULL-Implementation -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplTimeruInit -// -// Description: function init first instance -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel PUBLIC EplTimeruInit() -{ - tEplKernel Ret; - - Ret = EplTimeruAddInstance(); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplTimeruAddInstance -// -// Description: function init additional instance -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel PUBLIC EplTimeruAddInstance() -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplTimeruDelInstance -// -// Description: function delte instance -// -> under Win32 nothing to do -// -> no instnace table needed -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel PUBLIC EplTimeruDelInstance() -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplTimeruSetTimerMs -// -// Description: function create a timer and return a handle to the pointer -// -// -// -// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle -// ulTime_p = time for timer in ms -// Argument_p = argument for timer -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p, - unsigned long ulTime_p, - tEplTimerArg Argument_p) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // check handle - if (pTimerHdl_p == NULL) { - Ret = kEplTimerInvalidHandle; - goto Exit; - } - - Exit: - return Ret; -} - - //--------------------------------------------------------------------------- -// -// Function: EplTimeruModifyTimerMs -// -// Description: function change a timer and return a handle to the pointer -// -// -// -// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle -// ulTime_p = time for timer in ms -// Argument_p = argument for timer -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p, - unsigned long ulTime_p, - tEplTimerArg Argument_p) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // check parameter - if (pTimerHdl_p == NULL) { - Ret = kEplTimerInvalidHandle; - goto Exit; - } - - Exit: - return Ret; -} - - //--------------------------------------------------------------------------- -// -// Function: EplTimeruDeleteTimer -// -// Description: function delte a timer -// -// -// -// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p) -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // check parameter - if (pTimerHdl_p == NULL) { - Ret = kEplTimerInvalidHandle; - goto Exit; - } - // set handle invalide - *pTimerHdl_p = 0; - - Exit: - return Ret; - -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -// EOF diff --git a/drivers/staging/epl/EplTimeruWin32.c b/drivers/staging/epl/EplTimeruWin32.c deleted file mode 100644 index a967b4e59d4b..000000000000 --- a/drivers/staging/epl/EplTimeruWin32.c +++ /dev/null @@ -1,513 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: source file for Epl Userspace-Timermodule 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. - - ------------------------------------------------------------------------- - - $RCSfile: EplTimeruWin32.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $ - - $State: Exp $ - - Build Environment: - GCC V3.4 - - ------------------------------------------------------------------------- - - Revision History: - - 2006/07/06 k.t.: start of the implementation - -****************************************************************************/ - -#include "user/EplTimeru.h" - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- -typedef struct { - tEplTimerArg TimerArgument; - HANDLE DelteHandle; - unsigned long ulTimeout; - -} tEplTimeruThread; - -typedef struct { - LPCRITICAL_SECTION m_pCriticalSection; - CRITICAL_SECTION m_CriticalSection; -} tEplTimeruInstance; -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- -static tEplTimeruInstance EplTimeruInstance_g; -static tEplTimeruThread ThreadData_l; -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- -DWORD PUBLIC EplSdoTimeruThreadms(LPVOID lpParameter); - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S <Epl Userspace-Timermodule for Win32> */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: Epl Userspace-Timermodule for Win32 -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P U B L I C F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplTimeruInit -// -// Description: function init first instance -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel PUBLIC EplTimeruInit() -{ - tEplKernel Ret; - - Ret = EplTimeruAddInstance(); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplTimeruAddInstance -// -// Description: function init additional instance -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel PUBLIC EplTimeruAddInstance() -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - // create critical section - EplTimeruInstance_g.m_pCriticalSection = - &EplTimeruInstance_g.m_CriticalSection; - InitializeCriticalSection(EplTimeruInstance_g.m_pCriticalSection); - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplTimeruDelInstance -// -// Description: function delte instance -// -> under Win32 nothing to do -// -> no instnace table needed -// -// -// -// Parameters: -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel PUBLIC EplTimeruDelInstance() -{ - tEplKernel Ret; - - Ret = kEplSuccessful; - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EplTimeruSetTimerMs -// -// Description: function create a timer and return a handle to the pointer -// -// -// -// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle -// ulTime_p = time for timer in ms -// Argument_p = argument for timer -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p, - unsigned long ulTime_p, - tEplTimerArg Argument_p) -{ - tEplKernel Ret; - HANDLE DeleteHandle; - HANDLE ThreadHandle; - DWORD ThreadId; - - Ret = kEplSuccessful; - - // check handle - if (pTimerHdl_p == NULL) { - Ret = kEplTimerInvalidHandle; - goto Exit; - } - // enter critical section - EnterCriticalSection(EplTimeruInstance_g.m_pCriticalSection); - - // first create event to delete timer - DeleteHandle = CreateEvent(NULL, FALSE, FALSE, NULL); - if (DeleteHandle == NULL) { - Ret = kEplTimerNoTimerCreated; - goto Exit; - } - // set handle for caller - *pTimerHdl_p = (tEplTimerHdl) DeleteHandle; - - // fill data for thread - ThreadData_l.DelteHandle = DeleteHandle; - EPL_MEMCPY(&ThreadData_l.TimerArgument, &Argument_p, - sizeof(tEplTimerArg)); - ThreadData_l.ulTimeout = ulTime_p; - - // create thread to create waitable timer and wait for timer - ThreadHandle = CreateThread(NULL, - 0, - EplSdoTimeruThreadms, - &ThreadData_l, 0, &ThreadId); - if (ThreadHandle == NULL) { - // leave critical section - LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection); - - // delte handle - CloseHandle(DeleteHandle); - - Ret = kEplTimerNoTimerCreated; - goto Exit; - } - - Exit: - return Ret; -} - - //--------------------------------------------------------------------------- -// -// Function: EplTimeruModifyTimerMs -// -// Description: function change a timer and return a handle to the pointer -// -// -// -// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle -// ulTime_p = time for timer in ms -// Argument_p = argument for timer -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p, - unsigned long ulTime_p, - tEplTimerArg Argument_p) -{ - tEplKernel Ret; - HANDLE DeleteHandle; - HANDLE ThreadHandle; - DWORD ThreadId; - - Ret = kEplSuccessful; - - // check parameter - if (pTimerHdl_p == NULL) { - Ret = kEplTimerInvalidHandle; - goto Exit; - } - - DeleteHandle = (HANDLE) (*pTimerHdl_p); - - // set event to end timer task for this timer - SetEvent(DeleteHandle); - - // create new timer - // first create event to delete timer - DeleteHandle = CreateEvent(NULL, FALSE, FALSE, NULL); - if (DeleteHandle == NULL) { - Ret = kEplTimerNoTimerCreated; - goto Exit; - } - // set handle for caller - *pTimerHdl_p = (tEplTimerHdl) DeleteHandle; - - // enter critical section - EnterCriticalSection(EplTimeruInstance_g.m_pCriticalSection); - - // fill data for thread - ThreadData_l.DelteHandle = DeleteHandle; - EPL_MEMCPY(&ThreadData_l.TimerArgument, &Argument_p, - sizeof(tEplTimerArg)); - ThreadData_l.ulTimeout = ulTime_p; - - // create thread to create waitable timer and wait for timer - ThreadHandle = CreateThread(NULL, - 0, - EplSdoTimeruThreadms, - &ThreadData_l, 0, &ThreadId); - if (ThreadHandle == NULL) { - // leave critical section - LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection); - - // delte handle - - Ret = kEplTimerNoTimerCreated; - goto Exit; - } - - Exit: - return Ret; -} - - //--------------------------------------------------------------------------- -// -// Function: EplTimeruDeleteTimer -// -// Description: function delte a timer -// -// -// -// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle -// -// -// Returns: tEplKernel = errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p) -{ - tEplKernel Ret; - HANDLE DeleteHandle; - - Ret = kEplSuccessful; - - // check parameter - if (pTimerHdl_p == NULL) { - Ret = kEplTimerInvalidHandle; - goto Exit; - } - - DeleteHandle = (HANDLE) (*pTimerHdl_p); - - // set event to end timer task for this timer - SetEvent(DeleteHandle); - - // set handle invalide - *pTimerHdl_p = 0; - - Exit: - return Ret; - -} - -//=========================================================================// -// // -// P R I V A T E F U N C T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// -// Function: EplSdoTimeruThreadms -// -// Description: function to process timer as thread -// -// -// -// Parameters: lpParameter = pointer to structur of type tEplTimeruThread -// -// -// Returns: DWORD = Errorcode -// -// -// State: -// -//--------------------------------------------------------------------------- -DWORD PUBLIC EplSdoTimeruThreadms(LPVOID lpParameter) -{ - tEplKernel Ret; - tEplTimeruThread *pThreadData; - HANDLE aHandles[2]; - BOOL fReturn; - LARGE_INTEGER TimeoutTime; - unsigned long ulEvent; - tEplEvent EplEvent; - tEplTimeruThread ThreadData; - tEplTimerEventArg TimerEventArg; - - Ret = kEplSuccessful; - - // get pointer to data - pThreadData = (tEplTimeruThread *) lpParameter; - // copy thread data - EPL_MEMCPY(&ThreadData, pThreadData, sizeof(ThreadData)); - pThreadData = &ThreadData; - - // leave critical section - LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection); - - // create waitable timer - aHandles[1] = CreateWaitableTimer(NULL, FALSE, NULL); - if (aHandles[1] == NULL) { - Ret = kEplTimerNoTimerCreated; - goto Exit; - } - // set timer - // set timeout interval -> needed to be negativ - // -> because relative timeout - // -> multiply by 10000 for 100 ns timebase of function - TimeoutTime.QuadPart = (((long long)pThreadData->ulTimeout) * -10000); - fReturn = SetWaitableTimer(aHandles[1], - &TimeoutTime, 0, NULL, NULL, FALSE); - if (fReturn == 0) { - Ret = kEplTimerNoTimerCreated; - goto Exit; - } - // save delte event handle in handle array - aHandles[0] = pThreadData->DelteHandle; - - // wait for one of the events - ulEvent = WaitForMultipleObjects(2, &aHandles[0], FALSE, INFINITE); - if (ulEvent == WAIT_OBJECT_0) { // delte event - - // close handels - CloseHandle(aHandles[1]); - // terminate thread - goto Exit; - } else if (ulEvent == (WAIT_OBJECT_0 + 1)) { // timer event - // call event function - TimerEventArg.m_TimerHdl = - (tEplTimerHdl) pThreadData->DelteHandle; - TimerEventArg.m_ulArg = pThreadData->TimerArgument.m_ulArg; - - EplEvent.m_EventSink = pThreadData->TimerArgument.m_EventSink; - EplEvent.m_EventType = kEplEventTypeTimer; - EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(tEplNetTime)); - EplEvent.m_pArg = &TimerEventArg; - EplEvent.m_uiSize = sizeof(TimerEventArg); - - Ret = EplEventuPost(&EplEvent); - - // close handels - CloseHandle(aHandles[1]); - // terminate thread - goto Exit; - - } else { // error - ulEvent = GetLastError(); - TRACE1("Error in WaitForMultipleObjects Errorcode: 0x%x\n", - ulEvent); - // terminate thread - goto Exit; - } - - Exit: - return Ret; -} - -// EOF diff --git a/drivers/staging/epl/ShbIpc-Win32.c b/drivers/staging/epl/ShbIpc-Win32.c deleted file mode 100644 index b9181471ae0b..000000000000 --- 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 |