/* * Copyright (c) 1995, 1996 Gunther Schadow. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Triptrap test with semaphores. *Much* cleaner! Just one problem is * left: how can I model priorities in case of contention? */ #include "pg_config.h" #include "semaphor.h" #include "trap.h" #include #include #include #ifdef WITH_DELAY # define slp usleep(rand() % 100000 + 10000); #else # define slp #endif # define LOGFILE "./semtt.log"; void trip(semaphor mutex); void trap(semaphor mutex); void reaper(int sig); int main() { pid_t trip_pid; pid_t trap_pid; semaphor mutex; logfile = LOGFILE; if((mutex = SEM_ALLOC(0 /* or IPC_NOWAIT */)) == NULL) { perror("semtt: can not allocate semaphore"); exit(1); } fprintf(stderr, "mutex->buf.sem_num = %hd, mutex->id = %hd", mutex->buf.sem_num, mutex->id); ssignal(SIGCHLD,reaper,0); trap_pid = getpid(); trip_pid = fork(); if(trip_pid < 0) { perror("fork for trip:"); exit(1); } else if(trip_pid == 0) trip(mutex); /* child */ else trap(mutex); return 0; } void trip(semaphor mutex) { openlog("trip", LOG_NDELAY | LOG_PID, LOG_LPR); DBG(syslog(LOG_DEBUG,"I am trip and mutex is %d", mutex)); while(TRUE) { DBG(syslog(LOG_DEBUG,"waiting ...")); slp; DBG(syslog(LOG_DEBUG,"claim the line")); if(PROBEREN(mutex) == FAIL) { syslog(LOG_ERR, "failed to claim the line: %m"); continue; } syslog(LOG_DEBUG, "have the line"); fprintf(stderr, "*** TRIP ***\n"); DBG(syslog(LOG_DEBUG,"working ...")); slp; DBG(syslog(LOG_DEBUG,"release the line")); VERHOGEN(mutex); SEM_MODE(mutex, IPC_NOWAIT); } } void trap(semaphor mutex) { openlog("trap", LOG_NDELAY | LOG_PID, LOG_LPR); DBG(syslog(LOG_DEBUG,"I am trap and mutex is %d", mutex)); while(TRUE) { DBG(syslog(LOG_DEBUG,"waiting ...")); slp; DBG(syslog(LOG_DEBUG,"claim the line")); if(PROBEREN(mutex) == FAIL) { syslog(LOG_ERR, "failed to claim the line: %m"); continue; } syslog(LOG_DEBUG, "have the line"); fprintf(stderr, "*** TRAP ***\n"); DBG(syslog(LOG_DEBUG,"working ...")); slp; DBG(syslog(LOG_DEBUG,"release the line")); VERHOGEN(mutex); } } void reaper(int sig) { int status; pid_t pid; DBG(syslog(LOG_DEBUG, "reaper called by signal %d `%s'", sig, sys_siglist[sig])); while((pid = wait3(&status, WNOHANG, 0)) > 0) { if(WIFEXITED(status)) { DBG(syslog(LOG_DEBUG, "process %d exited with %d", pid, WEXITSTATUS(status))); } else if(WIFSIGNALED(status)) { int tsig = WTERMSIG(status); DBG(syslog(LOG_DEBUG, "process %d received signal %d `%s'", pid, tsig, sys_siglist[tsig])); } else if(WIFSTOPPED(status)) { int ssig = WSTOPSIG(status); DBG(syslog(LOG_DEBUG, "process %d stopped by signal %d `s'", pid, ssig, sys_siglist[ssig])); kill(pid, SIGCONT); } } exit(2); }