1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-12-19 03:52:17 +00:00
freebsd-ports/net/dctc/files/patch-src::sema.c
Mario Sergio Fujikawa Ferreira fd3eb836b9 o Update to 0.83.2
o Fix long standing issue with upload feature: client would freeze
  in semwait state. It was a pthread vs semaphore issue and a
  database lookup issue. Check PR for complete report
o All patches are related to upload feature fix

PR:		41323
2002-08-04 18:03:54 +00:00

159 lines
4.1 KiB
C

--- src/sema.c.orig Sun Jul 21 21:13:59 2002
+++ src/sema.c Mon Jul 22 19:30:15 2002
@@ -22,6 +22,10 @@
# include <config.h>
#endif
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -57,6 +61,11 @@
#include "uaddr.h"
#include "status.h"
+/* interval between busy wait tries measured in microseconds */
+#define MUTEX_BUSY_WAIT_TIME 5000
+
+pthread_mutex_t *semaphore_mutex = PTHREAD_MUTEX_INITIALIZER;
+
/***********************************************************************/
/* the following functions manage the bandwidth upload limit */
/* The system is build on 2 semaphores and 1 file */
@@ -100,6 +109,8 @@
int semid;
+ lp_mutex_init_(&semaphore_mutex, NULL);
+
fd=open(keyfile,O_CREAT|O_WRONLY|O_EXCL,0600); /* create the file if not exists */
if(fd==-1)
{
@@ -131,7 +142,11 @@
{
close(fd);
/* a key exist */
+#if !(defined(BSD) && (BSD >= 199103))
semid=semget(key,0,IPC_ALLOC);
+#else
+ semid=semget(key,0,IPC_STAT);
+#endif
if(semid==-1)
goto create_new_sema;
printf("current sema found.\n");
@@ -293,8 +308,13 @@
void check_sema_master(int semid)
{
struct sembuf sb={0,-1,IPC_NOWAIT|SEM_UNDO}; /* master sema */
+ int result;
+
+ (void) lp_mutex_lock_(semaphore_mutex);
+ result = semop(semid,&sb,1);
+ (void) lp_mutex_unlock_(semaphore_mutex);
- if(semop(semid,&sb,1)==0)
+ if (result==0)
{
/* to get slice, the function checks if the clock thread still runs */
create_sema_master(semid);
@@ -308,15 +328,29 @@
/*******************************************/
void get_slice(int semid, SPD_SEMA semnum)
{
+#if !(defined(BSD) && (BSD >= 199103))
+ struct sembuf local={0,-1,0}; /* slave sema */
+#else
+ struct sembuf local={0,-1,0|IPC_NOWAIT}; /* slave sema */
+#endif
+ local.sem_num=semnum;
+
+ (void) lp_mutex_lock_(semaphore_mutex);
while(1)
{
- struct sembuf local={0,-1,0}; /* slave sema */
-
- local.sem_num=semnum;
- if(semop(semid,&local,1)==0)
- {
- /* we have what we want */
- return;
+ switch (semop(semid,&local,1)) {
+ case 0: (void) lp_mutex_unlock_(semaphore_mutex);
+ /* we have what we want */
+ return;
+ break;
+ case -1: switch(errno) {
+ case EAGAIN: /* triggers busy wait */
+ case EINTR: /* interrupted by system call, try again */
+ pthread_yield();
+ usleep(MUTEX_BUSY_WAIT_TIME); /* busy wait with a small time out */
+ continue;
+ break;
+ }
}
}
}
@@ -368,9 +402,26 @@
/******************************/
void lock_ul_slot_controler(int semid)
{
+#if !(defined(BSD) && (BSD >= 199103))
struct sembuf get_ul_ctrl={UL_SLOT_SEMA,-1,SEM_UNDO};
+#else
+ struct sembuf get_ul_ctrl={UL_SLOT_SEMA,-1,SEM_UNDO|IPC_NOWAIT};
+#endif
+
+ (void) lp_mutex_lock_(semaphore_mutex);
+repeat:
/* lock the UL slot controler */
- semop(semid,&get_ul_ctrl,1);
+ if (semop(semid,&get_ul_ctrl,1)==-1)
+ switch(errno)
+ {
+ case EAGAIN: /* triggers busy wait */
+ case EINTR: /* interrupted by system call, try again */
+ pthread_yield();
+ usleep(MUTEX_BUSY_WAIT_TIME); /* busy wait with a small time out */
+ goto repeat;
+ break;
+ }
+ (void) lp_mutex_unlock_(semaphore_mutex);
}
/*********************************/
@@ -526,11 +577,28 @@
perror("free_one_ul_slot");
}
#else
+# if !(defined(BSD) && (BSD >= 199103))
struct sembuf free_one_ul_slot_op={UL_SLOT_BUSY_SEMA,-1,SEM_UNDO};
- if(semop(semid,&free_one_ul_slot_op,1)==-1)
- {
- perror("free_one_ul_slot");
+# else
+ struct sembuf free_one_ul_slot_op={UL_SLOT_BUSY_SEMA,-1,SEM_UNDO|IPC_NOWAIT};
+# endif
+
+ (void) lp_mutex_lock_(semaphore_mutex);
+repeat:
+ if(semop(semid,&free_one_ul_slot_op,1)==-1) {
+ switch(errno) {
+ case EAGAIN: /* triggers busy wait */
+ case EINTR: /* interrupted by system call, try again */
+ pthread_yield();
+ usleep(MUTEX_BUSY_WAIT_TIME); /* busy wait with a small time out */
+ goto repeat;
+ break;
+ default:
+ perror("free_one_ul_slot");
+ break;
+ }
}
+ (void) lp_mutex_unlock_(semaphore_mutex);
#endif
nb_local_ul--;
}