source: sources/src/pcSyncThread.cc @ 1485:3a149151a9cd

Revision 1485:3a149151a9cd, 4.4 KB checked in by niam, 21 months ago (diff)

[pc::sync] acquire returns false if the lock was not acquired within given timeout

Line 
1/***************************************************************************
2 *            pcSyncThread.cc
3 *
4 *  Wed Nov 30 2005
5 *  Copyright  2005  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/pcSyncThreadEx.h>
43#include <libdodo/pcSyncProtector.h>
44#include <libdodo/types.h>
45
46#include "pcSyncThread.inline"
47
48using namespace dodo::pc::sync;
49
50thread::thread(thread &)
51{
52}
53
54//-------------------------------------------------------------------
55
56thread::thread() : lock(new thread::__lock__)
57{
58#ifdef PTHREAD_EXT
59    pthread_mutexattr_t attr;
60
61    errno = pthread_mutexattr_init(&attr);
62    if (errno != 0) {
63        delete lock;
64
65        dodo_throw exception::basic(exception::MODULE_PCSYNCTHREAD, THREADEX_CONSTRUCTOR, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
66    }
67
68    errno = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
69    if (errno != 0) {
70        delete lock;
71
72        dodo_throw exception::basic(exception::MODULE_PCSYNCTHREAD, THREADEX_CONSTRUCTOR, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
73    }
74
75    errno = pthread_mutex_init(&lock->keeper, &attr);
76    if (errno != 0) {
77        delete lock;
78
79        dodo_throw exception::basic(exception::MODULE_PCSYNCTHREAD, THREADEX_CONSTRUCTOR, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
80    }
81
82    errno = pthread_mutexattr_destroy(&attr);
83    if (errno != 0) {
84        delete lock;
85
86        dodo_throw exception::basic(exception::MODULE_PCSYNCTHREAD, THREADEX_CONSTRUCTOR, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
87    }
88#endif
89}
90
91//-------------------------------------------------------------------
92
93thread::~thread()
94{
95#ifdef PTHREAD_EXT
96    if (pthread_mutex_trylock(&lock->keeper) == 0)
97        pthread_mutex_unlock(&lock->keeper);
98
99    pthread_mutex_destroy(&lock->keeper);
100#endif
101
102    delete lock;
103}
104
105//-------------------------------------------------------------------
106
107bool
108thread::acquire(unsigned long microseconds)
109{
110#ifdef PTHREAD_EXT
111    if (microseconds == 0) {
112        errno = pthread_mutex_lock(&lock->keeper);
113        if (errno != 0)
114            dodo_throw exception::basic(exception::MODULE_PCSYNCTHREAD, THREADEX_ACQUIRE, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
115    } else {
116        timespec ts = {microseconds/1000000, (microseconds%1000000)*1000};
117        timespec now;
118
119        clock_gettime(CLOCK_REALTIME, &now);
120        ts.tv_sec += now.tv_sec;
121        ts.tv_nsec += now.tv_nsec;
122        if (ts.tv_nsec > 999999999) {
123            ts.tv_sec += 1;
124            ts.tv_nsec -= 999999999;
125        }
126
127        errno = pthread_mutex_timedlock(&lock->keeper, &ts);
128        if (errno != 0) {
129            if (errno == ETIMEDOUT)
130                return false;
131            else
132                dodo_throw exception::basic(exception::MODULE_PCSYNCTHREAD, THREADEX_ACQUIRE, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
133        }
134    }
135#endif
136
137    return true;
138}
139
140//-------------------------------------------------------------------
141
142void
143thread::release()
144{
145#ifdef PTHREAD_EXT
146    errno = pthread_mutex_unlock(&lock->keeper);
147    if (errno != 0)
148        dodo_throw exception::basic(exception::MODULE_PCSYNCTHREAD, THREADEX_RELEASE, exception::ERRNO_ERRNO, errno, strerror(errno), __LINE__, __FILE__);
149#endif
150}
151
152//-------------------------------------------------------------------
153
Note: See TracBrowser for help on using the repository browser.