662
|
1 #include <string.h>
|
|
2 #include <stdio.h>
|
|
3 #include "lock.h"
|
|
4
|
|
5 /* ************ Locking functions ***************** */
|
|
6 #ifndef FSP_NOLOCKING
|
|
7
|
|
8 static char code_str[] =
|
|
9 "0123456789:_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
10
|
|
11 static void make_key_string( FSP_LOCK *lock,
|
|
12 unsigned long server_addr,
|
|
13 unsigned long server_port)
|
|
14 {
|
|
15 unsigned long v1, v2;
|
|
16 char *p;
|
|
17
|
|
18 strcpy(lock->key_string,FSP_KEY_PREFIX);
|
|
19 for(p = lock->key_string; *p; p++);
|
|
20 v1 = server_addr;
|
|
21 v2 = server_port;
|
|
22
|
|
23 *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
|
24 *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
|
25 *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
|
26 v1 = v1 | (v2 << (32-3*6));
|
|
27 *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
|
28 *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
|
29 *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
|
30 *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
|
31 *p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
|
32 *p = 0;
|
|
33 }
|
|
34 #endif
|
|
35
|
|
36 /********************************************************************/
|
|
37 /******* For those systems that has SysV shared memory + semop ******/
|
|
38 /********************************************************************/
|
|
39 #ifdef FSP_USE_SHAREMEM_AND_SEMOP
|
|
40
|
|
41 #include <sys/types.h>
|
|
42 #include <sys/ipc.h>
|
|
43 #include <sys/shm.h>
|
|
44 #include <sys/sem.h>
|
|
45 #include <fcntl.h>
|
|
46 #include <sys/stat.h>
|
|
47 #include <unistd.h>
|
|
48
|
|
49 #ifdef _SEM_SEMUN_UNDEFINED
|
|
50 union semun
|
|
51 {
|
|
52 int val;
|
|
53 struct semid_ds *buf;
|
|
54 unsigned short int *array;
|
|
55 struct seminfo *__buf;
|
|
56 };
|
|
57 #endif
|
|
58
|
|
59 unsigned short client_get_key (FSP_LOCK *lock)
|
|
60 {
|
|
61 struct sembuf sem;
|
|
62 sem.sem_num = 0;
|
|
63 sem.sem_op = -1;
|
|
64 sem.sem_flg = SEM_UNDO;
|
|
65
|
|
66 if(semop(lock->lock_sem,&sem,1) == -1 )
|
|
67 {
|
|
68 perror("semop lock");
|
|
69 }
|
|
70 return(*lock->share_key);
|
|
71 }
|
|
72
|
|
73 void client_set_key (FSP_LOCK *lock,unsigned short key)
|
|
74 {
|
|
75 struct sembuf sem;
|
|
76
|
|
77 sem.sem_num = 0;
|
|
78 sem.sem_op = 1;
|
|
79 sem.sem_flg = SEM_UNDO;
|
|
80
|
|
81 *lock->share_key = key;
|
|
82 if(semop(lock->lock_sem,&sem,1) == -1) {
|
|
83 perror("semop unlock");
|
|
84 }
|
|
85 }
|
|
86
|
|
87 int client_init_key (FSP_LOCK *lock,
|
|
88 unsigned long server_addr,
|
|
89 unsigned short server_port)
|
|
90 {
|
|
91 mode_t omask;
|
|
92 key_t lock_key;
|
|
93 int fd;
|
|
94 union semun sun;
|
|
95 struct sembuf sem;
|
|
96
|
|
97 make_key_string(lock,server_addr,server_port);
|
|
98
|
|
99 omask = umask(0);
|
|
100 fd = open(lock->key_string,O_RDWR|O_CREAT,0666);
|
|
101 umask(omask);
|
|
102 close(fd);
|
|
103
|
|
104 if((lock_key = ftok(lock->key_string,238)) == -1) {
|
|
105 perror("ftok");
|
|
106 return -1;
|
|
107 }
|
|
108
|
|
109 if((lock->lock_shm = shmget(lock_key,2*sizeof(unsigned int),IPC_CREAT|0666)) == -1) {
|
|
110 perror("shmget");
|
|
111 return -1;
|
|
112 }
|
|
113
|
|
114 if(!(lock->share_key = (unsigned int *) shmat(lock->lock_shm,NULL,0))) {
|
|
115 perror("shmat");
|
|
116 return -1;
|
|
117 }
|
|
118
|
|
119 if((lock->lock_sem = semget(lock_key,0,0)) == -1) {
|
|
120 /* create a new semaphore and init it */
|
|
121 if((lock->lock_sem = semget(lock_key,2,IPC_CREAT|0666)) == -1) {
|
|
122 perror("semget");
|
|
123 return -1;
|
|
124 }
|
|
125 /* we need to init this semaphore */
|
|
126 sun.val=1;
|
|
127 if(semctl(lock->lock_sem,0,SETVAL,sun) == -1)
|
|
128 {
|
|
129 perror("semctl setval");
|
|
130 return -1;
|
|
131 }
|
|
132 }
|
|
133
|
|
134 /* increase in use counter */
|
|
135 sem.sem_num = 1;
|
|
136 sem.sem_op = 1;
|
|
137 sem.sem_flg = SEM_UNDO;
|
|
138
|
|
139 if(semop(lock->lock_sem,&sem,1) == -1) {
|
|
140 perror("semop incuse");
|
|
141 }
|
|
142
|
|
143 return 0;
|
|
144 }
|
|
145
|
|
146 void client_destroy_key(FSP_LOCK *lock)
|
|
147 {
|
|
148 int rc;
|
|
149 struct sembuf sem;
|
|
150
|
|
151 if (shmdt(lock->share_key) < 0)
|
|
152 {
|
|
153 perror("shmdt");
|
|
154 return;
|
|
155 }
|
|
156 /* check if we are only one process holding lock */
|
|
157 rc = semctl(lock->lock_sem,1,GETVAL);
|
|
158 if (rc == 1)
|
|
159 {
|
|
160 /* safe to destroy */
|
|
161 if (
|
|
162 (semctl(lock->lock_sem,0,IPC_RMID) < 0) ||
|
|
163 (shmctl(lock->lock_shm,IPC_RMID,NULL) < 0) ||
|
|
164 (unlink(lock->key_string) < 0) )
|
|
165 rc=0;/* ignore cleanup errors */
|
|
166 }
|
|
167 else
|
|
168 if(rc > 1)
|
|
169 {
|
|
170 /* we need to decrease sem. */
|
|
171 sem.sem_num = 1;
|
|
172 sem.sem_op = -1;
|
|
173 sem.sem_flg = SEM_UNDO;
|
|
174
|
|
175 if(semop(lock->lock_sem,&sem,1) == -1) {
|
|
176 perror("semop decuse");
|
|
177 }
|
|
178 }
|
|
179 }
|
|
180 #endif
|
|
181
|
|
182
|
|
183 /********************************************************************/
|
|
184 /******* For those who do not want to use locking *******************/
|
|
185 /********************************************************************/
|
|
186 #ifdef FSP_NOLOCKING
|
|
187
|
|
188 unsigned short client_get_key (FSP_LOCK *lock)
|
|
189 {
|
|
190 return lock->share_key;
|
|
191 }
|
|
192
|
|
193 void client_set_key (FSP_LOCK *lock,unsigned short key)
|
|
194 {
|
|
195 lock->share_key=key;
|
|
196 }
|
|
197
|
|
198 int client_init_key (FSP_LOCK *lock,
|
|
199 unsigned long server_addr,
|
|
200 unsigned short server_port)
|
|
201 {
|
|
202 return 0;
|
|
203 }
|
|
204
|
|
205 void client_destroy_key(FSP_LOCK *lock)
|
|
206 {
|
|
207 return;
|
|
208 }
|
|
209 #endif
|
|
210
|
|
211 /********************************************************************/
|
|
212 /******* For those systems that has lockf function call *************/
|
|
213 /********************************************************************/
|
|
214 #ifdef FSP_USE_LOCKF
|
|
215
|
|
216 #include <sys/stat.h>
|
|
217 #include <fcntl.h>
|
|
218 #include <unistd.h>
|
|
219
|
|
220 unsigned short client_get_key (FSP_LOCK *lock)
|
|
221 {
|
|
222 unsigned int okey;
|
|
223
|
|
224 if (lockf(lock->lock_fd, F_LOCK, sizeof(okey)) < 0)
|
|
225 {
|
|
226 perror("lockf");
|
|
227 }
|
|
228
|
|
229 if (read(lock->lock_fd, &okey, sizeof(okey)) < 0)
|
|
230 {
|
|
231 perror("readlk");
|
|
232 }
|
|
233
|
|
234 if (lseek(lock->lock_fd, 0L, 0) < 0)
|
|
235 {
|
|
236 perror("seek");
|
|
237 }
|
|
238
|
|
239 return(okey);
|
|
240 }
|
|
241
|
|
242 void client_set_key (FSP_LOCK *lock,unsigned short nkey)
|
|
243 {
|
|
244 unsigned int key;
|
|
245
|
|
246 key=nkey;
|
|
247
|
|
248 if (write(lock->lock_fd, &key, sizeof(key)) < 0)
|
|
249 {
|
|
250 perror("write");
|
|
251 }
|
|
252 if (lseek(lock->lock_fd, 0L, 0) < 0)
|
|
253 {
|
|
254 perror("seek");
|
|
255 }
|
|
256 if (lockf(lock->lock_fd, F_ULOCK, sizeof(key)) < 0)
|
|
257 {
|
|
258 perror("unlockf");
|
|
259 }
|
|
260 }
|
|
261
|
|
262 int client_init_key (FSP_LOCK *lock,
|
|
263 unsigned long server_addr,
|
|
264 unsigned short server_port)
|
|
265 {
|
|
266 mode_t omask;
|
|
267
|
|
268 make_key_string(lock,server_addr, server_port);
|
|
269
|
|
270 omask = umask(0);
|
|
271 lock->lock_fd = open(lock->key_string, O_RDWR | O_CREAT, 0666);
|
|
272 (void)umask(omask);
|
|
273
|
|
274 if(lock->lock_fd < 0)
|
|
275 return -1;
|
|
276 else
|
|
277 return 0;
|
|
278 }
|
|
279
|
|
280 void
|
|
281 client_destroy_key(FSP_LOCK *lock)
|
|
282 {
|
|
283 (void)close(lock->lock_fd);
|
|
284 }
|
|
285 #endif
|