1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
8 Description: source file for Epl Userspace-Timermodule for Win32
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
19 2. Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in the
21 documentation and/or other materials provided with the distribution.
23 3. Neither the name of SYSTEC electronic GmbH nor the names of its
24 contributors may be used to endorse or promote products derived
25 from this software without prior written permission. For written
26 permission, please contact info@systec-electronic.com.
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 POSSIBILITY OF SUCH DAMAGE.
43 If a provision of this License is or becomes illegal, invalid or
44 unenforceable in any jurisdiction, that shall not affect:
45 1. the validity or enforceability in that jurisdiction of any other
46 provision of this License; or
47 2. the validity or enforceability in other jurisdictions of that or
48 any other provision of this License.
50 -------------------------------------------------------------------------
52 $RCSfile: EplTimeruWin32.c,v $
56 $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $
63 -------------------------------------------------------------------------
67 2006/07/06 k.t.: start of the implementation
69 ****************************************************************************/
71 #include "user/EplTimeru.h"
73 /***************************************************************************/
76 /* G L O B A L D E F I N I T I O N S */
79 /***************************************************************************/
81 //---------------------------------------------------------------------------
83 //---------------------------------------------------------------------------
85 //---------------------------------------------------------------------------
87 //---------------------------------------------------------------------------
90 tEplTimerArg TimerArgument;
92 unsigned long ulTimeout;
98 LPCRITICAL_SECTION m_pCriticalSection;
99 CRITICAL_SECTION m_CriticalSection;
101 //---------------------------------------------------------------------------
102 // modul globale vars
103 //---------------------------------------------------------------------------
104 static tEplTimeruInstance EplTimeruInstance_g;
105 static tEplTimeruThread ThreadData_l;
106 //---------------------------------------------------------------------------
107 // local function prototypes
108 //---------------------------------------------------------------------------
109 DWORD PUBLIC EplSdoTimeruThreadms(LPVOID lpParameter);
111 /***************************************************************************/
114 /* C L A S S <Epl Userspace-Timermodule for Win32> */
117 /***************************************************************************/
119 // Description: Epl Userspace-Timermodule for Win32
122 /***************************************************************************/
124 //=========================================================================//
126 // P U B L I C F U N C T I O N S //
128 //=========================================================================//
130 //---------------------------------------------------------------------------
132 // Function: EplTimeruInit
134 // Description: function init first instance
141 // Returns: tEplKernel = errorcode
146 //---------------------------------------------------------------------------
147 tEplKernel PUBLIC EplTimeruInit()
151 Ret = EplTimeruAddInstance();
156 //---------------------------------------------------------------------------
158 // Function: EplTimeruAddInstance
160 // Description: function init additional instance
167 // Returns: tEplKernel = errorcode
172 //---------------------------------------------------------------------------
173 tEplKernel PUBLIC EplTimeruAddInstance()
177 Ret = kEplSuccessful;
180 // create critical section
181 EplTimeruInstance_g.m_pCriticalSection = &EplTimeruInstance_g.m_CriticalSection;
182 InitializeCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
189 //---------------------------------------------------------------------------
191 // Function: EplTimeruDelInstance
193 // Description: function delte instance
194 // -> under Win32 nothing to do
195 // -> no instnace table needed
202 // Returns: tEplKernel = errorcode
207 //---------------------------------------------------------------------------
208 tEplKernel PUBLIC EplTimeruDelInstance()
212 Ret = kEplSuccessful;
217 //---------------------------------------------------------------------------
219 // Function: EplTimeruSetTimerMs
221 // Description: function create a timer and return a handle to the pointer
225 // Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
226 // ulTime_p = time for timer in ms
227 // Argument_p = argument for timer
230 // Returns: tEplKernel = errorcode
235 //---------------------------------------------------------------------------
236 tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl* pTimerHdl_p,
237 unsigned long ulTime_p,
238 tEplTimerArg Argument_p)
246 Ret = kEplSuccessful;
249 if(pTimerHdl_p == NULL)
251 Ret = kEplTimerInvalidHandle;
255 // enter critical section
256 EnterCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
258 // first create event to delete timer
259 DeleteHandle = CreateEvent(NULL,FALSE,FALSE, NULL);
260 if(DeleteHandle == NULL)
262 Ret = kEplTimerNoTimerCreated;
266 // set handle for caller
267 *pTimerHdl_p = (tEplTimerHdl)DeleteHandle;
272 // fill data for thread
273 ThreadData_l.DelteHandle = DeleteHandle;
274 EPL_MEMCPY(&ThreadData_l.TimerArgument, &Argument_p, sizeof(tEplTimerArg));
275 ThreadData_l.ulTimeout = ulTime_p;
277 // create thread to create waitable timer and wait for timer
278 ThreadHandle = CreateThread(NULL,
280 EplSdoTimeruThreadms,
284 if(ThreadHandle == NULL)
286 // leave critical section
287 LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
290 CloseHandle(DeleteHandle);
292 Ret = kEplTimerNoTimerCreated;
301 //---------------------------------------------------------------------------
303 // Function: EplTimeruModifyTimerMs
305 // Description: function change a timer and return a handle to the pointer
309 // Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
310 // ulTime_p = time for timer in ms
311 // Argument_p = argument for timer
314 // Returns: tEplKernel = errorcode
319 //---------------------------------------------------------------------------
320 tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl* pTimerHdl_p,
321 unsigned long ulTime_p,
322 tEplTimerArg Argument_p)
329 Ret = kEplSuccessful;
332 if(pTimerHdl_p == NULL)
334 Ret = kEplTimerInvalidHandle;
338 DeleteHandle = (HANDLE)(*pTimerHdl_p);
340 // set event to end timer task for this timer
341 SetEvent(DeleteHandle);
344 // first create event to delete timer
345 DeleteHandle = CreateEvent(NULL,FALSE,FALSE, NULL);
346 if(DeleteHandle == NULL)
348 Ret = kEplTimerNoTimerCreated;
352 // set handle for caller
353 *pTimerHdl_p = (tEplTimerHdl)DeleteHandle;
355 // enter critical section
356 EnterCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
358 // fill data for thread
359 ThreadData_l.DelteHandle = DeleteHandle;
360 EPL_MEMCPY(&ThreadData_l.TimerArgument, &Argument_p, sizeof(tEplTimerArg));
361 ThreadData_l.ulTimeout = ulTime_p;
363 // create thread to create waitable timer and wait for timer
364 ThreadHandle = CreateThread(NULL,
366 EplSdoTimeruThreadms,
370 if(ThreadHandle == NULL)
372 // leave critical section
373 LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
377 Ret = kEplTimerNoTimerCreated;
385 //---------------------------------------------------------------------------
387 // Function: EplTimeruDeleteTimer
389 // Description: function delte a timer
393 // Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
396 // Returns: tEplKernel = errorcode
401 //---------------------------------------------------------------------------
402 tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl* pTimerHdl_p)
407 Ret = kEplSuccessful;
410 if(pTimerHdl_p == NULL)
412 Ret = kEplTimerInvalidHandle;
416 DeleteHandle = (HANDLE)(*pTimerHdl_p);
418 // set event to end timer task for this timer
419 SetEvent(DeleteHandle);
421 // set handle invalide
430 //=========================================================================//
432 // P R I V A T E F U N C T I O N S //
434 //=========================================================================//
436 //---------------------------------------------------------------------------
438 // Function: EplSdoTimeruThreadms
440 // Description: function to process timer as thread
444 // Parameters: lpParameter = pointer to structur of type tEplTimeruThread
447 // Returns: DWORD = Errorcode
452 //---------------------------------------------------------------------------
453 DWORD PUBLIC EplSdoTimeruThreadms(LPVOID lpParameter)
456 tEplTimeruThread* pThreadData;
459 LARGE_INTEGER TimeoutTime;
460 unsigned long ulEvent;
462 tEplTimeruThread ThreadData;
463 tEplTimerEventArg TimerEventArg;
465 Ret = kEplSuccessful;
467 // get pointer to data
468 pThreadData = (tEplTimeruThread*)lpParameter;
470 EPL_MEMCPY(&ThreadData, pThreadData, sizeof(ThreadData));
471 pThreadData = &ThreadData;
473 // leave critical section
474 LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
476 // create waitable timer
477 aHandles[1] = CreateWaitableTimer(NULL,FALSE,NULL);
478 if(aHandles[1] == NULL)
480 Ret = kEplTimerNoTimerCreated;
485 // set timeout interval -> needed to be negativ
486 // -> because relative timeout
487 // -> multiply by 10000 for 100 ns timebase of function
488 TimeoutTime.QuadPart = (((long long)pThreadData->ulTimeout) * -10000);
489 fReturn = SetWaitableTimer(aHandles[1],
497 Ret = kEplTimerNoTimerCreated;
501 // save delte event handle in handle array
502 aHandles[0] = pThreadData->DelteHandle;
504 // wait for one of the events
505 ulEvent = WaitForMultipleObjects( 2,
509 if(ulEvent == WAIT_OBJECT_0)
513 CloseHandle(aHandles[1]);
517 else if(ulEvent == (WAIT_OBJECT_0 + 1))
519 // call event function
520 TimerEventArg.m_TimerHdl = (tEplTimerHdl)pThreadData->DelteHandle;
521 TimerEventArg.m_ulArg = pThreadData->TimerArgument.m_ulArg;
523 EplEvent.m_EventSink = pThreadData->TimerArgument.m_EventSink;
524 EplEvent.m_EventType = kEplEventTypeTimer;
525 EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(tEplNetTime));
526 EplEvent.m_pArg = &TimerEventArg;
527 EplEvent.m_uiSize = sizeof(TimerEventArg);
529 Ret = EplEventuPost(&EplEvent);
532 CloseHandle(aHandles[1]);
539 ulEvent = GetLastError();
540 TRACE1("Error in WaitForMultipleObjects Errorcode: 0x%x\n",ulEvent);