summaryrefslogtreecommitdiff
path: root/source/api_wrappers/linux/CEventObject.cpp
blob: eecbe6d528307505b6eb7fc799b40b70c9a3bf8c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*******************************************************************************
 * Copyright (C) ST-Ericsson SA 2011
 * License terms: 3-clause BSD license
 ******************************************************************************/

#include <errno.h>
#include <sys/time.h>
#include <fcntl.h>
#include <time.h>
#include "Types.h"
#include "CEventObject.h"
#include "OS.h"

// ******************************************************************************
// Name:  CEventObject()
// Desc:  CEventObject constructor which initializes the m_sem member
// Ret:
// ******************************************************************************
CEventObject::CEventObject()
{
#if defined(__APPLE__)
    char sem_name[SEM_NAME_MAX_LENGTH];
    int sem_nr = 1;

    while (sem_nr <= SEM_MAX_NR) {
        snprintf(sem_name, SEM_NAME_MAX_LENGTH, "lcdriversem_%d", sem_nr);

        /* open semaphore with "rw" permissions for everyone - 0666 */
        m_sem = sem_open(sem_name, O_CREAT | O_EXCL, 0666 , 0);

        if (m_sem != SEM_FAILED) {
            break;
        }

        sem_nr++;
    }
#elif defined(__linux__)
    sem_init(&m_sem, 0, 0);
#endif
}

// ******************************************************************************
// Name:  ~CEventObject()
// Desc:  CEventObject destructor
// Ret:
// ******************************************************************************
CEventObject::~CEventObject()
{
#if defined(__APPLE__)
    sem_close(m_sem);
#elif defined(__linux__)
    sem_destroy(&m_sem);
#endif
}

// ******************************************************************************
// Name:  SetEvent()
// Desc:  Sets an event by post-ing the member semaphore m_sem
// Ret:
// ******************************************************************************
void CEventObject::SetEvent()
{
#if defined(__APPLE__)
    sem_post(m_sem);
#elif defined(__linux__)
    sem_post(&m_sem);
#endif
}

// ******************************************************************************
// Name:  Wait()
// Desc:  implementation of the pure virtual base class member Wait()
// Ret:   WAIT_OBJECT_0 when event occurs, or WAIT_TIMEOUT on timeout
// ******************************************************************************
DWORD CEventObject::Wait(DWORD dwTimeout)
{
#if defined(__APPLE__)
    if (INFINITE == dwTimeout) {
        sem_wait(m_sem);
    } else {
        struct timeval curr_time, start_time;
        DWORD dwTimePassed = 0;
        int ret;

        gettimeofday(&start_time, NULL);

        /* Try to lock the semaphore */
        ret = sem_trywait(m_sem);

        if (ret != 0) {
            while (dwTimePassed < dwTimeout) {
                /* Sleep 1ms */
                OS::Sleep(1);

                /* Try to lock the semaphore again*/
                ret = sem_trywait(m_sem);

                if (ret == 0) {
                    return WAIT_OBJECT_0;
                }

                gettimeofday(&curr_time, NULL);

                dwTimePassed = 1000 * (curr_time.tv_sec - start_time.tv_sec) + \
                               (curr_time.tv_usec - start_time.tv_usec) / 1000;
            }

            return WAIT_TIMEOUT;
        }
    }

    return WAIT_OBJECT_0;

#elif defined(__linux__)
    if (INFINITE == dwTimeout) {
        sem_wait(&m_sem);
        return WAIT_OBJECT_0;
    } else {
        timespec absolute_time = OS::GetAbsoluteTime(dwTimeout);
        int ret;

        /* coverity[returned_null] */
        while (-1 == (ret = sem_timedwait(&m_sem, &absolute_time)) && errno == EINTR);

        if (0 == ret) {
            return WAIT_OBJECT_0;
        } else {
            return WAIT_TIMEOUT;
        }
    }
#endif
}