forked from DanielTillett/Simple-Windows-Posix-Semaphore
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsemaphore_type.c
More file actions
122 lines (101 loc) · 4.11 KB
/
Copy pathsemaphore_type.c
File metadata and controls
122 lines (101 loc) · 4.11 KB
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
// Copyright (C) 2026 The OnePointer Authors.
//
#include "semaphore_type.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
bool semaphore_timedwait( struct semaphore* sm, const struct timespec* abs_timeout ) {
if ( sm == NULL || abs_timeout != NULL ) return false;
else if ( sm->sem == NULL ) return false;
return sem_timedwait( sm->sem, abs_timeout ) == 0;
}
bool semaphore_trywait( struct semaphore* sm ) {
if ( sm == NULL ) return false;
else if ( sm->sem == NULL ) return false;
return sem_trywait( sm->sem ) == 0;
}
sem_t* semaphore_initsem( struct semaphore* sm, const char* name, unsigned int value ) {
if ( sm == NULL ) return NULL;
sem_t* sem = sem_open( name, _O_CREAT, _MODE_T_, value );
if ( sem == NULL ) return NULL;
else if ( sem_init( sem, sm->pshared, value ) != 0 ) return NULL;
else if ( ! sm->mtx->locked && sm->owner == 0 ) sm->sem = sem;
return sem;
}
bool semaphore_close( struct semaphore* sm, const char* name ) {
if ( sem_unlink( name ) != 0 ) return false;
else if ( sm->sem != NULL && ! sm->mtx->locked) {
if ( sem_close( sm->sem ) == 0 ) {
sm->sem = NULL;
return true;
} else return false;
} return false;
}
struct semaphore* semaphore_type_new( void* data, enum PTHREAD_PROCESS_VISIBILITY pshared ) {
struct semaphore* smt = (struct semaphore*) malloc(sizeof(struct semaphore));
smt->sem = semaphore_initsem( smt, "main", 0 );
smt->pshared = pshared;
smt->mtx = mutex_new();
smt->data = (arch_sem_t*) malloc(sizeof(arch_sem_t));
smt->data->handle = data;
smt->dmtx = mutex_new();
smt->owner = 0;
smt->owning_reason = "";
smt->aquired = 0;
smt->timedwait = &semaphore_timedwait;
smt->trywait = &semaphore_trywait;
smt->initsem = &semaphore_initsem;
smt->close = &semaphore_close;
smt->aquire = &semaphore_aquire;
smt->release = &semaphore_release;
smt->lock = &semaphore_lock;
smt->unlock = &semaphore_unlock;
smt->data_lock = &semaphore_lockdata;
smt->data_unlock = &semaphore_unlockdata;
return smt;
}
bool semaphore_aquire( struct semaphore* sm, const PID process_id, const char* owning_reason ) {
if ( sm == NULL ) return false;
else if ( sm->owner != 0 && sm->mtx->locked ) return false;
else if ( sm->owner != 0 && ! sm->mtx->locked ) { ++sm->aquired; return true; }
sm->owner = process_id;
strcpy( sm->owning_reason, owning_reason );
++sm->aquired;
return sm->initsem( sm, owning_reason, 1 ) != NULL;
}
bool semaphore_release( struct semaphore* sm, const PID process_id ) {
if ( sm == NULL ) return false;
else if ( sm->owner != process_id || sm->mtx->locked ) return false;
else if ( sm->owner != process_id && ! sm->mtx->locked ) { --sm->aquired; return true; }
sm->close( sm, sm->owning_reason );
sm->owner = 0;
sm->owning_reason = "";
--sm->aquired;
return sm->aquired == 0;
}
bool semaphore_lock( struct semaphore* sm, const PID process_id ) {
if ( sm == NULL ) return false;
else if ( sm->owner == 0 && ! sm->mtx->locked ) {
if ( sm->aquired == 0 ) {
if ( ! sm->aquire( sm, process_id, "sm_lock" ) ) return false;
}
return sm->mtx->try_lock( sm->mtx, process_id );
} return false;
}
bool semaphore_unlock( struct semaphore* sm, const PID process_id ) {
if ( sm == NULL ) return false;
else if ( sm->owner != process_id ) return false;
else if ( sm->mtx->locked ) {
return sm->mtx->try_unlock( sm->mtx, process_id );
} return false;
}
bool semaphore_lockdata( struct semaphore* sm, const PID process_id ) {
if ( sm == NULL ) return false;
else if ( sm->dmtx->process_id != 0 ) return false;
return sm->dmtx->try_lock( sm->dmtx, process_id );
}
bool semaphore_unlockdata( struct semaphore* sm, const PID process_id ) {
if ( sm == NULL ) return false;
else if ( sm->dmtx->process_id != process_id ) return false;
return sm->dmtx->try_unlock( sm->dmtx, process_id );
}