source: sources/src/pcNotificationThread.cc @ 1479:d92a97f2db7c

Revision 1479:d92a97f2db7c, 4.0 KB checked in by niam, 21 months ago (diff)

{issue #14[resolved]} event-notification interface

Line 
1/***************************************************************************
2 *            pcNotificationThread.cc
3 *
4 *  Sun Aug 29 2010
5 *  Copyright  2010  Dmytro Milinevskyy
6 *  milinevskyy@gmail.com
7 ****************************************************************************/
8
9/*
10 *  This program is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU Lesser General Public License version 2.1 as published by
12 *  the Free Software Foundation;
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU Library General Public License for more details.
18 *
19 *  You should have received a copy of the GNU Lesser General Public License
20 *  along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24/**
25 * vim indentation settings
26 * set tabstop=4
27 * set shiftwidth=4
28 */
29
30#include <libdodo/directives.h>
31
32#ifdef PTHREAD_EXT
33#include <pthread.h>
34#endif
35
36#include <time.h>
37#include <errno.h>
38#include <string.h>
39#include <unistd.h>
40
41#include <libdodo/pcSyncThread.h>
42#include <libdodo/pcNotificationThreadEx.h>
43#include <libdodo/pcNotificationThread.h>
44#include <libdodo/types.h>
45
46#include "pcSyncThread.inline"
47
48namespace dodo {
49    namespace pc {
50        namespace notification {
51            /**
52             * @struct thread::__wake__
53             * @brief defines conditional locking
54             */
55            struct thread::__wake__ {
56#ifdef PTHREAD_EXT
57                pthread_cond_t cond;  ///< lock
58#endif
59            };
60        };
61    };
62};
63
64using namespace dodo::pc::notification;
65
66thread::thread(thread &) : lock(* new sync::thread)
67{
68}
69
70//-------------------------------------------------------------------
71
72thread::thread(sync::thread &lock) : lock(lock),
73                                     wake(new __wake__)
74{
75#ifdef PTHREAD_EXT
76    errno = pthread_cond_init(&wake->cond, NULL);
77    if (errno != 0) {
78        delete wake;
79
80        dodo_throw exception::basic(exception::MODULE_PCNOTIFICATIONTHREAD, THREADEX_CONSTRUCTOR, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
81    }
82#endif
83}
84
85//-------------------------------------------------------------------
86
87thread::~thread()
88{
89#ifdef PTHREAD_EXT
90    pthread_cond_destroy(&wake->cond);
91#endif
92
93    delete wake;
94}
95
96//-------------------------------------------------------------------
97
98bool
99thread::wait(unsigned long microseconds)
100{
101#ifdef PTHREAD_EXT
102    if (microseconds == 0) {
103        errno = pthread_cond_wait(&wake->cond, &lock.lock->keeper);
104        if (errno != 0)
105            dodo_throw exception::basic(exception::MODULE_PCNOTIFICATIONTHREAD, THREADEX_WAIT, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
106    } else {
107        timespec ts = {microseconds/1000000, (microseconds%1000000)*1000};
108        timespec now;
109
110        clock_gettime(CLOCK_REALTIME, &now);
111        ts.tv_sec += now.tv_sec;
112        ts.tv_nsec += now.tv_nsec;
113        if (ts.tv_nsec > 999999999) {
114            ts.tv_sec += 1;
115            ts.tv_nsec -= 999999999;
116        }
117
118        errno = pthread_cond_timedwait(&wake->cond, &lock.lock->keeper, &ts);
119        if (errno != 0) {
120            if (errno == ETIMEDOUT)
121                return false;
122            else
123                dodo_throw exception::basic(exception::MODULE_PCNOTIFICATIONTHREAD, THREADEX_WAIT, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
124        }
125    }
126#endif
127
128    return true;
129}
130
131//-------------------------------------------------------------------
132
133void
134thread::notify(bool all)
135{
136#ifdef PTHREAD_EXT
137    if (all)
138        errno = pthread_cond_broadcast(&wake->cond);
139    else
140        errno = pthread_cond_signal(&wake->cond);
141    if (errno != 0)
142        dodo_throw exception::basic(exception::MODULE_PCNOTIFICATIONTHREAD, THREADEX_NOTIFY, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
143#endif
144}
145
146//-------------------------------------------------------------------
147
Note: See TracBrowser for help on using the repository browser.