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 //---------------------------------------------------------------------------
89 tEplTimerArg TimerArgument;
91 unsigned long ulTimeout;
96 LPCRITICAL_SECTION m_pCriticalSection;
97 CRITICAL_SECTION m_CriticalSection;
99 //---------------------------------------------------------------------------
100 // modul globale vars
101 //---------------------------------------------------------------------------
102 static tEplTimeruInstance EplTimeruInstance_g;
103 static tEplTimeruThread ThreadData_l;
104 //---------------------------------------------------------------------------
105 // local function prototypes
106 //---------------------------------------------------------------------------
107 DWORD PUBLIC EplSdoTimeruThreadms(LPVOID lpParameter);
109 /***************************************************************************/
112 /* C L A S S <Epl Userspace-Timermodule for Win32> */
115 /***************************************************************************/
117 // Description: Epl Userspace-Timermodule for Win32
120 /***************************************************************************/
122 //=========================================================================//
124 // P U B L I C F U N C T I O N S //
126 //=========================================================================//
128 //---------------------------------------------------------------------------
130 // Function: EplTimeruInit
132 // Description: function init first instance
139 // Returns: tEplKernel = errorcode
144 //---------------------------------------------------------------------------
145 tEplKernel PUBLIC EplTimeruInit()
149 Ret = EplTimeruAddInstance();
154 //---------------------------------------------------------------------------
156 // Function: EplTimeruAddInstance
158 // Description: function init additional instance
165 // Returns: tEplKernel = errorcode
170 //---------------------------------------------------------------------------
171 tEplKernel PUBLIC EplTimeruAddInstance()
175 Ret = kEplSuccessful;
177 // create critical section
178 EplTimeruInstance_g.m_pCriticalSection =
179 &EplTimeruInstance_g.m_CriticalSection;
180 InitializeCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
185 //---------------------------------------------------------------------------
187 // Function: EplTimeruDelInstance
189 // Description: function delte instance
190 // -> under Win32 nothing to do
191 // -> no instnace table needed
198 // Returns: tEplKernel = errorcode
203 //---------------------------------------------------------------------------
204 tEplKernel PUBLIC EplTimeruDelInstance()
208 Ret = kEplSuccessful;
213 //---------------------------------------------------------------------------
215 // Function: EplTimeruSetTimerMs
217 // Description: function create a timer and return a handle to the pointer
221 // Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
222 // ulTime_p = time for timer in ms
223 // Argument_p = argument for timer
226 // Returns: tEplKernel = errorcode
231 //---------------------------------------------------------------------------
232 tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p,
233 unsigned long ulTime_p,
234 tEplTimerArg Argument_p)
241 Ret = kEplSuccessful;
244 if (pTimerHdl_p == NULL) {
245 Ret = kEplTimerInvalidHandle;
248 // enter critical section
249 EnterCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
251 // first create event to delete timer
252 DeleteHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
253 if (DeleteHandle == NULL) {
254 Ret = kEplTimerNoTimerCreated;
257 // set handle for caller
258 *pTimerHdl_p = (tEplTimerHdl) DeleteHandle;
260 // fill data for thread
261 ThreadData_l.DelteHandle = DeleteHandle;
262 EPL_MEMCPY(&ThreadData_l.TimerArgument, &Argument_p,
263 sizeof(tEplTimerArg));
264 ThreadData_l.ulTimeout = ulTime_p;
266 // create thread to create waitable timer and wait for timer
267 ThreadHandle = CreateThread(NULL,
269 EplSdoTimeruThreadms,
270 &ThreadData_l, 0, &ThreadId);
271 if (ThreadHandle == NULL) {
272 // leave critical section
273 LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
276 CloseHandle(DeleteHandle);
278 Ret = kEplTimerNoTimerCreated;
286 //---------------------------------------------------------------------------
288 // Function: EplTimeruModifyTimerMs
290 // Description: function change a timer and return a handle to the pointer
294 // Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
295 // ulTime_p = time for timer in ms
296 // Argument_p = argument for timer
299 // Returns: tEplKernel = errorcode
304 //---------------------------------------------------------------------------
305 tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
306 unsigned long ulTime_p,
307 tEplTimerArg Argument_p)
314 Ret = kEplSuccessful;
317 if (pTimerHdl_p == NULL) {
318 Ret = kEplTimerInvalidHandle;
322 DeleteHandle = (HANDLE) (*pTimerHdl_p);
324 // set event to end timer task for this timer
325 SetEvent(DeleteHandle);
328 // first create event to delete timer
329 DeleteHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
330 if (DeleteHandle == NULL) {
331 Ret = kEplTimerNoTimerCreated;
334 // set handle for caller
335 *pTimerHdl_p = (tEplTimerHdl) DeleteHandle;
337 // enter critical section
338 EnterCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
340 // fill data for thread
341 ThreadData_l.DelteHandle = DeleteHandle;
342 EPL_MEMCPY(&ThreadData_l.TimerArgument, &Argument_p,
343 sizeof(tEplTimerArg));
344 ThreadData_l.ulTimeout = ulTime_p;
346 // create thread to create waitable timer and wait for timer
347 ThreadHandle = CreateThread(NULL,
349 EplSdoTimeruThreadms,
350 &ThreadData_l, 0, &ThreadId);
351 if (ThreadHandle == NULL) {
352 // leave critical section
353 LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
357 Ret = kEplTimerNoTimerCreated;
365 //---------------------------------------------------------------------------
367 // Function: EplTimeruDeleteTimer
369 // Description: function delte a timer
373 // Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
376 // Returns: tEplKernel = errorcode
381 //---------------------------------------------------------------------------
382 tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p)
387 Ret = kEplSuccessful;
390 if (pTimerHdl_p == NULL) {
391 Ret = kEplTimerInvalidHandle;
395 DeleteHandle = (HANDLE) (*pTimerHdl_p);
397 // set event to end timer task for this timer
398 SetEvent(DeleteHandle);
400 // set handle invalide
408 //=========================================================================//
410 // P R I V A T E F U N C T I O N S //
412 //=========================================================================//
414 //---------------------------------------------------------------------------
416 // Function: EplSdoTimeruThreadms
418 // Description: function to process timer as thread
422 // Parameters: lpParameter = pointer to structur of type tEplTimeruThread
425 // Returns: DWORD = Errorcode
430 //---------------------------------------------------------------------------
431 DWORD PUBLIC EplSdoTimeruThreadms(LPVOID lpParameter)
434 tEplTimeruThread *pThreadData;
437 LARGE_INTEGER TimeoutTime;
438 unsigned long ulEvent;
440 tEplTimeruThread ThreadData;
441 tEplTimerEventArg TimerEventArg;
443 Ret = kEplSuccessful;
445 // get pointer to data
446 pThreadData = (tEplTimeruThread *) lpParameter;
448 EPL_MEMCPY(&ThreadData, pThreadData, sizeof(ThreadData));
449 pThreadData = &ThreadData;
451 // leave critical section
452 LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
454 // create waitable timer
455 aHandles[1] = CreateWaitableTimer(NULL, FALSE, NULL);
456 if (aHandles[1] == NULL) {
457 Ret = kEplTimerNoTimerCreated;
461 // set timeout interval -> needed to be negativ
462 // -> because relative timeout
463 // -> multiply by 10000 for 100 ns timebase of function
464 TimeoutTime.QuadPart = (((long long)pThreadData->ulTimeout) * -10000);
465 fReturn = SetWaitableTimer(aHandles[1],
466 &TimeoutTime, 0, NULL, NULL, FALSE);
468 Ret = kEplTimerNoTimerCreated;
471 // save delte event handle in handle array
472 aHandles[0] = pThreadData->DelteHandle;
474 // wait for one of the events
475 ulEvent = WaitForMultipleObjects(2, &aHandles[0], FALSE, INFINITE);
476 if (ulEvent == WAIT_OBJECT_0) { // delte event
479 CloseHandle(aHandles[1]);
482 } else if (ulEvent == (WAIT_OBJECT_0 + 1)) { // timer event
483 // call event function
484 TimerEventArg.m_TimerHdl =
485 (tEplTimerHdl) pThreadData->DelteHandle;
486 TimerEventArg.m_ulArg = pThreadData->TimerArgument.m_ulArg;
488 EplEvent.m_EventSink = pThreadData->TimerArgument.m_EventSink;
489 EplEvent.m_EventType = kEplEventTypeTimer;
490 EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(tEplNetTime));
491 EplEvent.m_pArg = &TimerEventArg;
492 EplEvent.m_uiSize = sizeof(TimerEventArg);
494 Ret = EplEventuPost(&EplEvent);
497 CloseHandle(aHandles[1]);
502 ulEvent = GetLastError();
503 TRACE1("Error in WaitForMultipleObjects Errorcode: 0x%x\n",