+++ /dev/null
-/****************************************************************************
-
- (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
+++ /dev/null
-/****************************************************************************
-
- (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
+++ /dev/null
-/****************************************************************************
-
- (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