00001
00002 #ifndef NO_STDIO
00003 #include <stdio.h>
00004 #endif
00005
00006 #include <stdlib.h>
00007 #include <errno.h>
00008 #include <string.h>
00009 #ifdef __CENTERLINE__
00010 #ifndef USING_VARARGS
00011 #define USING_VARARGS
00012 #endif
00013 #include <varargs.h>
00014 #else
00015 #include <stdarg.h>
00016 #endif
00017 #include <sys/types.h>
00018 #include <sys/ipc.h>
00019 #if defined(darwin) || defined(qnx)
00020 #include <semaphore.h>
00021 #define POSIX_SEMAPHORES
00022 #else
00023 #include <sys/sem.h>
00024 #endif
00025
00026 #ifdef qnx
00027 #include <fcntl.h>
00028 #endif
00029
00030 #ifdef LYNX
00031 #include <file.h>
00032 #include <sys/types.h>
00033 #include <fcntl.h>
00034 #include <time.h>
00035 #endif
00036
00037 #ifndef irix6
00038 #include <math.h>
00039 #else
00040
00041
00042
00043
00044 extern double fmod (double, double);
00045 #endif
00046
00047 #include "_timer.h"
00048 #include "dbg_mem.h"
00049 #if defined(os5) && defined(sparc)
00050 union semun
00051 {
00052 int val;
00053 struct semid_ds *buf;
00054 ushort *array;
00055 };
00056 #endif
00057
00058
00059 #if defined(sunos5) || defined(linux) || defined(LYNX) || defined(POSIX_SEMAPHORES)
00060 #define USE_ITIMER_SIGNALS
00061 #endif
00062
00063 #ifdef USE_ITIMER_SIGNALS
00064 #include <signal.h>
00065 #include <sys/time.h>
00066 #endif
00067
00068 int sem_force_fifo = 0;
00069
00070 #define SEM_TAKE (-1)
00071 #define SEM_GIVE (1)
00072
00073
00074 #if defined(LINUX_KERNEL_2_2) || \
00075 defined(LINUX_KERNEL_2_3) || \
00076 defined(LINUX_KERNEL_2_4) || \
00077 defined(linux_2_2) || \
00078 defined(linux_2_3) || \
00079 defined(linux_2_4)
00080 #if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
00081
00082 #else
00083
00084 union semun
00085 {
00086 int val;
00087 struct semid_ds *buf;
00088 unsigned short int *array;
00089 struct seminfo *__buf;
00090 };
00091 #endif
00092 #endif
00093
00094 int
00095 rcs_sem_init (rcs_sem_t * sem, int pshared, unsigned int value)
00096 {
00097 #ifdef POSIX_SEMAPHORES
00098 int retval;
00099 if (sem == NULL)
00100 {
00101 return -1;
00102 }
00103 retval = sem_init (sem->sem, pshared, value);
00104 if (retval == -1)
00105 {
00106 rcs_print_error ("sem_init(%p{key=%d,sem=%d},%d,%d): ERROR - %s %d\n",
00107 sem, sem->key, sem->sem, pshared, value,
00108 strerror (errno), errno);
00109 }
00110 return retval;
00111 #else
00112 #ifdef LYNX
00113 if (value == 1)
00114 {
00115 return 0;
00116 }
00117 else
00118 {
00119 return -1;
00120 }
00121 #else
00122 struct sembuf sops;
00123 union semun sem_arg;
00124
00125
00126
00127 sops.sem_num = 0;
00128 sops.sem_flg = 0;
00129 sops.sem_op = (value == 0 ? 0 : 1);
00130
00131 if (NULL == sem)
00132 {
00133 rcs_print_error ("sem_init: Pointer to semaphore object is NULL.\n");
00134 return -1;
00135 }
00136
00137 if (value == 1)
00138 {
00139 if (semop (*sem, &sops, 1) == -1)
00140 {
00141 rcs_print_error
00142 ("semop(semid=%d, {sem_num=%d,sem_op=%d,sem_flg=%d},nsops=1): can't initialize semaphore .",
00143 *sem, sops.sem_num, sops.sem_op, sops.sem_flg);
00144 #ifndef __CENTERLINE__
00145 rcs_puts ((char *) strerror (errno));
00146 #endif
00147 return -1;
00148 }
00149 }
00150 else
00151 {
00152 sem_arg.val = value;
00153 semctl (*sem, 0, SETVAL, sem_arg);
00154 }
00155
00156 return 0;
00157 #endif
00158 #endif
00159 }
00160
00161
00162
00163 int
00164 rcs_sem_destroy (rcs_sem_t * sem)
00165 {
00166 #ifdef POSIX_SEMAPHORES
00167 return 0;
00168 #else
00169
00170 #ifndef sunos5
00171 union semun sem_arg;
00172 sem_arg.val = 0;
00173 #else
00174 int sem_arg = 0;
00175 #endif
00176 if (semctl (*sem, 0, IPC_RMID, sem_arg) == -1)
00177 {
00178 rcs_print_error ("semctl(%d,0,%d,%d) failed: (errno = %d) %s\n",
00179 *sem, IPC_RMID, sem_arg, errno, strerror (errno));
00180 return -1;
00181 }
00182 return 0;
00183 #endif
00184 }
00185
00186 int sem_clear_bus_errors = 0;
00187 void
00188 sem_clear_bus_error_handler (int sig)
00189 {
00190 sem_clear_bus_errors++;
00191 }
00192
00193
00194 int
00195 rcs_sem_clear (rcs_sem_t * sem)
00196 {
00197 #ifdef POSIX_SEMAPHORES
00198
00199 return (-1);
00200 #else
00201 union semun sem_arg;
00202 sem_arg.val = 1;
00203 semctl (*sem, 1, SETVAL, sem_arg);
00204 #endif
00205 return (0);
00206 }
00207
00208 static int rcs_sem_open_val = 0;
00209
00210
00211 rcs_sem_t *
00212 rcs_sem_open (const char *name, int oflag, ...)
00213 {
00214 #ifdef POSIX_SEMAPHORES
00215 va_list ap;
00216 rcs_sem_t *retval;
00217 int mode;
00218 char true_name[32];
00219 retval = DEBUG_MALLOC (sizeof (rcs_sem_t));
00220 if (NULL == retval)
00221 {
00222 return NULL;
00223 }
00224 sprintf (retval->name, "%d", ((int) name));
00225 retval->key = (int) name;
00226 if (oflag)
00227 {
00228 #ifdef USING_VARARGS
00229 va_start (ap);
00230 #else
00231 va_start (ap, oflag);
00232 #endif
00233 mode = va_arg (ap, int);
00234 va_end (ap);
00235 #ifdef darwin
00236 retval->sem = sem_open (retval->name, oflag, mode, rcs_sem_open_val);
00237 #else
00238 retval->sem = sem_open (retval->name, oflag, mode);
00239 #endif
00240 }
00241 else
00242 {
00243 retval->sem = sem_open (retval->name, oflag);
00244 }
00245 if (retval->sem == SEM_FAILED)
00246 {
00247 rcs_print_error ("sem_open(%s,%d(0x%X),%d(0x%X),%d): ERROR - %s %d\n",
00248 retval->name, oflag, oflag, mode, mode,
00249 rcs_sem_open_val, strerror (errno), errno);
00250 DEBUG_FREE (retval);
00251 return NULL;
00252 }
00253 return retval;
00254 #else
00255
00256 va_list ap;
00257 int mode;
00258 key_t key;
00259 rcs_sem_t semid, *retval;
00260 int semflg = 0;
00261 #ifdef LYNX
00262 int stat_ret;
00263 struct stat status;
00264 char true_name[32];
00265 #endif
00266
00267
00268
00269 if (oflag & IPC_CREAT)
00270 {
00271 #ifdef USING_VARARGS
00272 va_start (ap);
00273 #else
00274 va_start (ap, oflag);
00275 #endif
00276 mode = va_arg (ap, int);
00277 va_end (ap);
00278 semflg |= mode;
00279 semflg |= IPC_CREAT;
00280 }
00281 else
00282 {
00283 semflg &= ~IPC_CREAT;
00284 }
00285
00286 #ifdef LYNX
00287 #define PERMISSION 0666
00288
00289
00290
00291 key = (key_t) name;
00292 sprintf (true_name, "/tmp/sem%d", (int) key);
00293 if (oflag & IPC_CREAT)
00294 {
00295 stat_ret = stat (true_name, &status);
00296 if (stat_ret != -1 || errno != ENOENT)
00297 {
00298 unlink (true_name);
00299 }
00300 if (mksem (true_name, PERMISSION, SEM_PRIO_INH) < 0)
00301 {
00302 rcs_print_error ("mksem: ERROR -- %s %d\n", strerror (errno),
00303 errno);
00304 return NULL;
00305 }
00306 if ((semid = open (true_name, O_RDWR, mode)) < 0)
00307 {
00308 rcs_print_error ("rcs_sem_open: open(%s,%d,%d): ERROR -- %s %d\n",
00309 true_name, oflag, mode, strerror (errno), errno);
00310 return NULL;
00311 }
00312 }
00313 else
00314 {
00315 if ((semid = open (true_name, O_RDWR)) < 0)
00316 {
00317 rcs_print_error ("rcs_sem_open: open(%s,%d): ERROR -- %s %d\n",
00318 true_name, oflag, strerror (errno), errno);
00319 return NULL;
00320 }
00321 }
00322
00323 #else
00324
00325
00326 key = (key_t) name;
00327 if (key < 1)
00328 {
00329 rcs_print_error ("rcs_sem_open: invalid key %d\n", key);
00330 return NULL;
00331 }
00332
00333
00334 if ((semid = (rcs_sem_t) semget ((key_t) key, 1, semflg)) == -1)
00335 {
00336 rcs_print_error ("semget");
00337 #ifndef __CENTERLINE__
00338 rcs_puts ((char *) strerror (errno));
00339 #endif
00340 return NULL;
00341 }
00342
00343 #endif
00344
00345
00346
00347
00348 retval = (rcs_sem_t *) DEBUG_MALLOC (sizeof (rcs_sem_t));
00349 *retval = semid;
00350 return retval;
00351
00352 #endif
00353 }
00354
00355 int
00356 rcs_sem_close (rcs_sem_t * sem)
00357 {
00358 #ifdef POSIX_SEMAPHORES
00359 return sem_close (sem->sem);
00360 #endif
00361 if (sem != 0)
00362 {
00363 #ifdef sparcworks_sun4
00364
00365 DEBUG_FREE ((char *) sem);
00366 #else
00367 DEBUG_FREE (sem);
00368 #endif
00369 }
00370 return 0;
00371 }
00372
00373 int
00374 rcs_sem_unlink (const char *name)
00375 {
00376 #ifdef POSIX_SEMAPHORES
00377 return sem_unlink (name);
00378 #else
00379 return 0;
00380 #endif
00381 }
00382
00383 #ifdef USE_ITIMER_SIGNALS
00384 static int semwait_alarm_count = 0;
00385 #ifdef LYNX
00386 static void
00387 semwait_alarm_handler (int signumber, int code, struct sigcontext context,
00388 struct fp_context *fpcontext)
00389 #else
00390 static void
00391 semwait_alarm_handler (int sig)
00392 #endif
00393 {
00394 rcs_print_debug (PRINT_SEMAPHORE_ACTIVITY,
00395 "semwait_alarm_handler:: alarm_count=%d\n",
00396 semwait_alarm_count);
00397 semwait_alarm_count++;
00398
00399
00400 signal (SIGALRM, semwait_alarm_handler);
00401 }
00402 #endif
00403
00404
00405 int
00406 rcs_sem_wait_notimeout (rcs_sem_t * sem)
00407 {
00408 int retval = -1;
00409 #if defined(POSIX_SEMAPHORES)
00410 retval = sem_wait (sem->sem);
00411
00412 if (errno == EINTR)
00413 {
00414 return retval;
00415 }
00416 if (retval == -1)
00417 {
00418 rcs_print_error ("sem_wait(%p{key=%d,sem=%d}): ERROR: %s %d\n",
00419 sem->key, sem->sem, strerror (errno), errno);
00420 }
00421 return retval;
00422 #else
00423 #ifdef LYNX
00424 retval = semwait (*sem);
00425 if (errno == EINTR)
00426 {
00427 return retval;
00428 }
00429 if (retval == -1)
00430 {
00431 rcs_print_error ("semwait: ERROR: %s %d\n", strerror (errno), errno);
00432 }
00433 return retval;
00434 #else
00435 struct sembuf sops;
00436 union semun sem_arg;
00437 sem_arg.val = 0;
00438 sops.sem_num = 0;
00439 sops.sem_op = SEM_TAKE;
00440 sops.sem_flg = 0;
00441 retval = semop (*sem, &sops, 1);
00442 if (errno == EINTR)
00443 {
00444 rcs_print_debug (PRINT_SEMAPHORE_ACTIVITY, "semop interrupted! %d\n",
00445 semwait_alarm_count);
00446 return retval;
00447 }
00448 if (retval == -1)
00449 {
00450 rcs_print_error
00451 ("semop(semid=%d, {sem_num=%d,sem_op=%d,sem_flg=%d},nsops=1): ERROR: %s %d\n",
00452 *sem, sops.sem_num, sops.sem_op, sops.sem_flg, strerror (errno),
00453 errno);
00454 }
00455 #if 0
00456 if (sem_force_fifo)
00457 {
00458 semval = semctl (*sem, 0, GETVAL, sem_arg);
00459 if (semval == 1)
00460 {
00461 sops.sem_num = 0;
00462 sops.sem_op = -1;
00463 sops.sem_flg = IPC_NOWAIT;
00464 semop (*sem, &sops, 1);
00465 }
00466 }
00467 #endif
00468
00469 return retval;
00470 #endif
00471 #endif
00472 }
00473
00474 int
00475 rcs_sem_trywait (rcs_sem_t * sem)
00476 {
00477 #ifdef POSIX_SEMAPHORES
00478 int retval;
00479 retval = sem_trywait (sem->sem);
00480 if (retval == -1)
00481 {
00482 rcs_print_error ("sem_trywait: ERROR -- %s %d\n", strerror (errno),
00483 errno);
00484 }
00485 #else
00486 #ifdef LYNX
00487 return semifwait (*sem);
00488 #else
00489 struct sembuf sops;
00490 sops.sem_num = 0;
00491 sops.sem_op = SEM_TAKE;
00492 sops.sem_flg = IPC_NOWAIT;
00493 return semop (*sem, &sops, 1);
00494 #endif
00495 #endif
00496
00497 }
00498
00499 int
00500 rcs_sem_wait (rcs_sem_t * sem, double timeout)
00501 {
00502 #ifdef USE_ITIMER_SIGNALS
00503 int last_semwait_alarm_count = semwait_alarm_count;
00504 int retval = -1;
00505 double start_time = 0.0;
00506 double elapsed_time = 0.0;
00507 double time_left = 0.0;
00508 double current_time = 0.0;
00509 struct itimerval sem_itimer;
00510 struct itimerval sem_itimer_backup;
00511 void (*old_sigalarm_handler) (int);
00512 old_sigalarm_handler = SIG_ERR;
00513 time_left = timeout;
00514 #ifdef POSIX_SEMAPHORES
00515 if (SEM_FAILED == sem)
00516 {
00517 return -1;
00518 }
00519 #endif
00520 if (0 == sem)
00521 {
00522 return -1;
00523 }
00524
00525 #ifdef darwin
00526 rcs_print_debug (PRINT_SEMAPHORE_ACTIVITY, "rcs_sem_wait(%d,%f) called.\n",
00527 sem, timeout);
00528 #else
00529 rcs_print_debug (PRINT_SEMAPHORE_ACTIVITY, "rcs_sem_wait(%d,%f) called.\n",
00530 *sem, timeout);
00531 #endif
00532
00533 if (timeout < 0)
00534 {
00535 retval = rcs_sem_wait_notimeout (sem);
00536 if (retval == -1)
00537 {
00538 rcs_print_error ("semwait: ERROR -- %s %d\n", strerror (errno),
00539 errno);
00540 }
00541 return retval;
00542 }
00543 if (timeout < clk_tck () / 2)
00544 {
00545 retval = rcs_sem_trywait (sem);
00546 if (retval == -1)
00547 {
00548 rcs_print_error ("semifwait: ERROR -- %s %d\n", strerror (errno),
00549 errno);
00550 }
00551 return retval;
00552 }
00553 start_time = etime ();
00554 old_sigalarm_handler = signal (SIGALRM, semwait_alarm_handler);
00555
00556 if (old_sigalarm_handler == SIG_ERR)
00557 {
00558 rcs_print_error ("Can't setup SIGALRM. errno = %d, %s\n",
00559 errno, strerror (errno));
00560 return -1;
00561 }
00562 sem_itimer.it_interval.tv_sec = 0;
00563 sem_itimer.it_interval.tv_usec = 0;
00564 sem_itimer.it_value.tv_sec = 0;
00565 sem_itimer.it_value.tv_usec = 0;
00566 getitimer (ITIMER_REAL, &sem_itimer_backup);
00567 sem_itimer_backup.it_value.tv_sec = 0;
00568 sem_itimer_backup.it_value.tv_usec = 0;
00569 do
00570 {
00571 sem_itimer.it_interval.tv_sec = time_left;
00572 sem_itimer.it_interval.tv_usec = (fmod (time_left + 1.0, 1.0) * 1E6);
00573 sem_itimer.it_value.tv_sec = sem_itimer.it_interval.tv_sec;
00574 sem_itimer.it_value.tv_usec = sem_itimer.it_interval.tv_usec;
00575 setitimer (ITIMER_REAL, &sem_itimer, &sem_itimer_backup);
00576 rcs_print_debug (PRINT_SEMAPHORE_ACTIVITY,
00577 "Semaphore itimer setup: \n\tit_interval {%d secs and %d usecs}\n\tit_value {%d secs and %d usecs}\n",
00578 sem_itimer.it_interval.tv_sec,
00579 sem_itimer.it_interval.tv_usec,
00580 sem_itimer.it_value.tv_sec,
00581 sem_itimer.it_value.tv_usec);
00582 retval = rcs_sem_wait_notimeout (sem);
00583 setitimer (ITIMER_REAL, &sem_itimer_backup, &sem_itimer);
00584 rcs_print_debug (PRINT_SEMAPHORE_ACTIVITY,
00585 "Semaphore itimer removed.\n");
00586 current_time = etime ();
00587 elapsed_time = current_time - start_time;
00588 time_left = timeout - elapsed_time;
00589 if (retval == -1)
00590 {
00591 if (EINTR == errno
00592 && last_semwait_alarm_count < semwait_alarm_count)
00593 {
00594 retval = -2;
00595 last_semwait_alarm_count = semwait_alarm_count;
00596 continue;
00597 }
00598 rcs_print_error ("sem_wait: ERROR: %s %d\n", strerror (errno),
00599 errno);
00600 return -1;
00601 }
00602 }
00603 while (time_left > 5e-3 && retval < 0);
00604 setitimer (ITIMER_REAL, &sem_itimer_backup, NULL);
00605 if (old_sigalarm_handler == SIG_ERR || old_sigalarm_handler == SIG_DFL)
00606 {
00607 old_sigalarm_handler = SIG_IGN;
00608 }
00609 signal (SIGALRM, old_sigalarm_handler);
00610 return (retval);
00611
00612 #else
00613
00614 struct sembuf sops;
00615 double elapsed_time, current_time, start_time;
00616 start_time = current_time = 0.0;
00617 if (timeout >= 0.0)
00618 {
00619 start_time = etime ();
00620 }
00621
00622 sops.sem_num = 0;
00623 sops.sem_op = SEM_TAKE;
00624 if (timeout < 0.0)
00625 {
00626 sops.sem_flg = 0;
00627 }
00628 else
00629 {
00630 sops.sem_flg = IPC_NOWAIT;
00631 }
00632 if (timeout >= 0.0)
00633 {
00634 current_time = etime ();
00635 }
00636 elapsed_time = current_time - start_time;
00637 while (elapsed_time < timeout || timeout < 0.0)
00638 {
00639 if (semop (*sem, &sops, 1) == -1)
00640 {
00641 if (errno == EINTR)
00642 {
00643
00644 #if 0
00645
00646 #ifndef __CENTERLINE__
00647
00648 #endif
00649 #endif
00650 if (timeout != 0.0)
00651 {
00652 #if 0
00653
00654 #endif
00655 continue;
00656 }
00657 else
00658 {
00659 return -1;
00660 }
00661 }
00662 else if (errno == EAGAIN)
00663 {
00664 if (timeout >= 0.0)
00665 {
00666 current_time = etime ();
00667 elapsed_time = current_time - start_time;
00668 }
00669 continue;
00670 }
00671 else
00672 {
00673 rcs_print_error
00674 ("semop(semid=%d, {sem_num=%d,sem_op=%d,sem_flg=%d},nsops=1)",
00675 *sem, sops.sem_num, sops.sem_op, sops.sem_flg);
00676 #ifndef __CENTERLINE__
00677 rcs_print_error ("errno=%d : %s\n", errno, strerror (errno));
00678 #endif
00679 return -1;
00680 }
00681 }
00682 else
00683 {
00684 return -2;
00685 }
00686 }
00687 return (0);
00688 #endif
00689 }
00690
00691 int
00692 rcs_sem_post (rcs_sem_t * sem)
00693 {
00694 #if defined(POSIX_SEMAPHORES)
00695 int retval;
00696 retval = sem_post (sem->sem);
00697 if (retval == -1)
00698 {
00699 rcs_print_error ("sem_post: ERROR -- %s %d\n", strerror (errno), errno);
00700 }
00701 return retval;
00702 #else
00703 #ifdef LYNX
00704 int retval;
00705 retval = sempost (*sem);
00706 if (retval == -1)
00707 {
00708 rcs_print_error ("sem_post: ERROR -- %s %d\n", strerror (errno), errno);
00709 }
00710 return retval;
00711 #else
00712 struct sembuf sops;
00713
00714 #ifndef sunos5
00715 union semun sem_arg;
00716 sem_arg.val = 0;
00717 #else
00718 int sem_arg = 0;
00719 #endif
00720
00721 #if 0
00722 sem_arg.val = 1;
00723 semctl (*sem, 0, SETVAL, sem_arg);
00724 return (0);
00725 #else
00726
00727 rcs_print_debug (PRINT_SEMAPHORE_ACTIVITY, "rcs_sem_post(%d) called.\n",
00728 *sem);
00729
00730 sops.sem_num = 0;
00731 sops.sem_flg = 0;
00732 sops.sem_op = SEM_GIVE;
00733
00734 if (semctl (*sem, 0, GETVAL, sem_arg) == 1)
00735 {
00736
00737 return 0;
00738 }
00739
00740
00741
00742
00743 while (1)
00744 {
00745 if (semop (*sem, &sops, 1) == -1)
00746 {
00747 if (errno == EINTR)
00748 {
00749
00750 rcs_print_error ("semop:");
00751 #ifndef __CENTERLINE__
00752 rcs_print_error ("errno=%d : %s\n", errno, strerror (errno));
00753 #endif
00754 rcs_puts ("restarting");
00755 continue;
00756 }
00757 else
00758 {
00759 rcs_print_error ("semop");
00760 #ifndef __CENTERLINE__
00761 rcs_print_error ("errno=%d : %s\n", errno, strerror (errno));
00762 #endif
00763 return -1;
00764 }
00765 }
00766 else
00767 {
00768 return 0;
00769 }
00770 }
00771 return (0);
00772 #endif
00773 #endif
00774 #endif
00775 }
00776
00777 int
00778 rcs_sem_flush (rcs_sem_t * sem)
00779 {
00780 int semval;
00781 int sems_to_give;
00782 int ncount = -1;
00783 #if defined(POSIX_SEMAPHORES)
00784 int retval;
00785 retval = sem_post (sem->sem);
00786 if (retval == -1)
00787 {
00788 rcs_print_error ("sem_post: ERROR -- %s %d\n", strerror (errno), errno);
00789 }
00790 #ifndef darwin
00791 retval = sem_getvalue (sem->sem, &semval);
00792 if (retval == -1)
00793 {
00794 rcs_print_error ("sem_getvalue: ERROR -- %s %d\n", strerror (errno),
00795 errno);
00796 }
00797 while (semval == 0)
00798 {
00799 retval = sem_post (sem->sem);
00800 if (retval == -1)
00801 {
00802 rcs_print_error ("sem_post: ERROR -- %s %d\n", strerror (errno),
00803 errno);
00804 break;
00805 }
00806 retval = sem_getvalue (sem->sem, &semval);
00807 if (retval == -1)
00808 {
00809 rcs_print_error ("sem_getvalue: ERROR -- %s %d\n", strerror (errno),
00810 errno);
00811 break;
00812 }
00813 }
00814 #endif
00815 return retval;
00816 #else
00817 #ifdef LYNX
00818 int retval;
00819 retval = sempost (*sem);
00820 if (retval == -1)
00821 {
00822 rcs_print_error ("sem_post: ERROR -- %s %d\n", strerror (errno), errno);
00823 }
00824 return retval;
00825 #else
00826
00827 struct sembuf sops;
00828 union semun sem_arg;
00829 sem_arg.val = 0;
00830
00831 #if 0
00832 sem_arg.val = 1;
00833 semctl (*sem, 0, SETVAL, sem_arg);
00834 return (0);
00835 #else
00836
00837
00838 sops.sem_num = 0;
00839 sops.sem_flg = IPC_NOWAIT;
00840 sops.sem_op = SEM_GIVE;
00841 semval = semctl (*sem, 0, GETVAL, sem_arg);
00842 ncount = semctl (*sem, 0, GETNCNT, sem_arg);
00843
00844
00845 if (semval < 0)
00846 {
00847 semval = 0;
00848 }
00849 if (ncount < 0)
00850 {
00851 ncount = 0;
00852 }
00853 if (semval > ncount)
00854 {
00855 return 0;
00856 }
00857
00858 sems_to_give = ncount - semval + 1;
00859
00860
00861
00862
00863
00864 sops.sem_op = sems_to_give;
00865 while (sems_to_give > 0)
00866 {
00867 if (semop (*sem, &sops, 1) == -1)
00868 {
00869 if (errno == EINTR)
00870 {
00871
00872 rcs_print_error ("semop:");
00873 #ifndef __CENTERLINE__
00874 rcs_print_error ("errno=%d : %s\n", errno, strerror (errno));
00875 #endif
00876 rcs_puts ("restarting");
00877 continue;
00878 }
00879 else
00880 {
00881 rcs_print_error ("semop");
00882 #ifndef __CENTERLINE__
00883 rcs_print_error ("errno=%d : %s\n", errno, strerror (errno));
00884 #endif
00885 return -1;
00886 }
00887 }
00888 sems_to_give -= sops.sem_op;
00889 }
00890 return (0);
00891 #endif
00892 #endif
00893 #endif
00894 }
00895
00896
00897 int
00898 rcs_sem_getvalue (rcs_sem_t * sem, unsigned int *sval)
00899 {
00900 #ifdef POSIX_SEMAPHORES
00901 return sem_getvalue (sem->sem, sval);
00902 #else
00903
00904 #ifndef sunos5
00905 union semun sem_arg;
00906 sem_arg.val = 0;
00907 #else
00908 int sem_arg = 0;
00909 #endif
00910
00911 return (*sval = (unsigned int) semctl (*sem, 0, GETVAL, sem_arg));
00912 #endif
00913 }
00914
00915 rcs_sem_t *
00916 rcs_sem_create (unsigned long int id, int mode, int state)
00917 {
00918 rcs_sem_t *sem;
00919
00920 if (id < 1)
00921 {
00922 rcs_print_error ("rcs_sem_create: invalid id %d\n", id);
00923 }
00924
00925 rcs_sem_open_val = state;
00926
00927 #ifdef POSIX_SEMAPHORES
00928 sem = rcs_sem_open ((char *) id, O_CREAT, mode);
00929 #else
00930 sem = rcs_sem_open ((char *) id, IPC_CREAT, mode);
00931 #endif
00932
00933
00934 sem = rcs_sem_open ((char *) id, IPC_CREAT, mode);
00935
00936 #ifndef darwin
00937
00938 if (0 != ((int) sem) && -1 != ((int) sem))
00939 {
00940 rcs_sem_init (sem, 1, state);
00941 }
00942 #endif
00943
00944 return sem;
00945 }