pthread_mutex_t mutex; /**< the pthread robust mutex */
26
pcilib_lock_flags_t flags; /**< flags to define the type of the mutex */
25
27
#ifdef HAVE_STDATOMIC_H
26
volatile atomic_uint refs;
28
volatile atomic_uint refs; /**< approximate number of processes that hold the lock initialized, may desynchronize on crashes */
27
29
#else /* HAVE_STDATOMIC_H */
28
volatile uint32_t refs;
30
volatile uint32_t refs; /**< approximate number of processes that hold the lock initialized, may desynchronize on crashes */
29
31
#endif /* HAVE_STDATOMIC_H */
30
char name[];
32
char name[]; /**< lock identifier */
31
33
};
32
34
33
35
34
/**
35
* this function initialize a new semaphore in the kernel if it's not already initialized given the key that permits to differentiate semaphores, and then return the integer that points to the semaphore that have been initialized or to a previously already initialized semaphore
36
*/
37
36
int pcilib_init_lock(pcilib_lock_t *lock, pcilib_lock_flags_t flags, const char *lock_id) {
38
37
int err;
39
38
pthread_mutexattr_t attr;
53
52
return PCILIB_ERROR_FAILED;
54
53
}
55
54
55
/* we declare the mutex as possibly shared amongst different processes*/
56
56
if ((err = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED))!=0) {
57
57
pcilib_error("Can't configure a shared mutex attribute, errno %i", errno);
58
58
return PCILIB_ERROR_FAILED;
59
59
}
60
60
61
/* we set the mutex as robust, so it would be automatically unlocked if the application crash*/
61
62
if ((flags&PCILIB_LOCK_FLAG_PERSISTENT)==0) {
62
63
if ((err = pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST))!=0) {
63
64
pcilib_error("Can't configure a robust mutex attribute, errno: %i", errno);
78
79
}
79
80
80
81
81
/*
82
* we uninitialize a mutex and set its name to 0 pointed by lock_ctx with this function. setting name to is the real destroying operation, but we need to unitialize the lock to initialize it again after
83
*/
84
82
void pcilib_free_lock(pcilib_lock_t *lock) {
85
83
int err;
86
84
134
132
return NULL;
135
133
}
136
134
137
/*
138
* this function will take the lock for the semaphore pointed by semId
139
*/
140
135
int pcilib_lock_custom(pcilib_lock_t *lock, pcilib_lock_flags_t flags, pcilib_timeout_t timeout) {
141
136
int err;
142
137
149
144
150
145
switch (timeout) {
151
146
case PCILIB_TIMEOUT_INFINITE:
147
/* the process will be hold till it can gain acquire the lock*/
152
148
err = pthread_mutex_lock(&lock->mutex);
153
149
break;
154
150
case PCILIB_TIMEOUT_IMMEDIATE:
151
/* the function returns immediatly if it can't acquire the lock*/
155
152
err = pthread_mutex_trylock(&lock->mutex);
156
153
break;
157
154
default:
155
/* the process will be hold till it can acquire the lock and timeout is not reached*/
158
156
clock_gettime(CLOCK_REALTIME, &tm);
159
157
tm.tv_nsec += 1000 * (timeout%1000000);
160
158
if (tm.tv_nsec < 1000000000)
171
169
172
170
switch (err) {
173
171
case EOWNERDEAD:
172
/*in the case an application with a lock acquired crashes, this lock becomes inconsistent. we have so to make it consistent again to use it again.*/
174
173
err = pthread_mutex_consistent(&lock->mutex);
175
174
if (err) {
176
175
pcilib_error("Failed to mark mutex as consistent, errno %i", err);