summaryrefslogtreecommitdiff
path: root/source/api_wrappers/linux/CWaitableObjectCollection.cpp
blob: e48fd1c25f91152d9d538816acd2c851f56529c4 (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
/*******************************************************************************
 * Copyright (C) ST-Ericsson SA 2011
 * License terms: 3-clause BSD license
 ******************************************************************************/

#include <time.h>
#include <errno.h>

#include "Types.h"
#include "CWaitableObjectCollection.h"
#include <assert.h>

CWaitableObjectCollection::CWaitableObjectCollection()
{
    m_objs.clear();
}

CWaitableObjectCollection::~CWaitableObjectCollection()
{
    m_objs.clear();
}

void CWaitableObjectCollection::Add(CWaitableObject *obj)
{
    m_objs.push_back(obj);
}

CWaitableObject *CWaitableObjectCollection::Wait(DWORD dwTimeout)
{
    vector<CWaitableObject *>::iterator it;
    DWORD dwTimePassed = 0;
    struct timespec ts;
    struct timespec curr_time, start_time;

    if (-1 == clock_gettime(CLOCK_REALTIME, &start_time)) {
        return NULL;
    }

    do {
        for (it = m_objs.begin(); it != m_objs.end(); ++it) {
            assert(*it);

            if (WAIT_OBJECT_0 == (*it)->Wait(0)) {
                return (*it);
            }
        }

        ts.tv_sec = 0;
        ts.tv_nsec = 10000000L;  // 10 milliseconds

        // There isn't any possiblity of errno returning NULL, mean is not defined. Even if
        // errno is not defined this is the least thing that we should care for.

        // coverity[returned_null]
        while (-1 == nanosleep(&ts, &ts) && EINTR == errno);

        if (-1 == clock_gettime(CLOCK_REALTIME, &curr_time)) {
            return NULL;
        }

        dwTimePassed = 1000 * (curr_time.tv_sec - start_time.tv_sec) + \
                       (curr_time.tv_nsec - start_time.tv_nsec) / 1000000;

    } while (dwTimePassed < dwTimeout);

    return NULL;
}