From 35acc80f23f9f81f3145a686a9c7df4b622b25fe Mon Sep 17 00:00:00 2001 From: short <> Date: Thu, 14 Mar 2002 19:31:27 +0000 Subject: [PATCH] Untested attempt to get rid of SIGIO pain --- common/data/virtmodem.c | 11 ++++++--- common/devices/device.c | 60 ++++++++++++++++++++++++++++++++++++++++++--- common/devices/unixserial.c | 2 ++ include/devices/device.h | 3 +++ include/uccompat.h | 5 ++++ 5 files changed, 75 insertions(+), 6 deletions(-) diff --git a/common/data/virtmodem.c b/common/data/virtmodem.c index f6f1f3e..169b117 100644 --- a/common/data/virtmodem.c +++ b/common/data/virtmodem.c @@ -136,10 +136,12 @@ bool VM_ThreadLoop(void) FD_ZERO(&readfds); FD_SET(PtyRDFD,&readfds); + FD_SET(device_portfd,&readfds); timeout.tv_sec=2; timeout.tv_usec=0;/*500*1000;*/ - res = select(PtyRDFD+1,&readfds,NULL/*writefds*/,NULL/*exceptfds*/,&timeout); + res = select((device_portfd > PtyRDFD ? device_portfd : PtyRDFD)+1, + &readfds,NULL/*writefds*/,NULL/*exceptfds*/,&timeout); switch (res) { case 0: /* Timeout */ @@ -155,9 +157,12 @@ bool VM_ThreadLoop(void) return (false); default: - if (FD_ISSET(PtyRDFD,&readfds)) { + if (FD_ISSET(PtyRDFD,&readfds)) VM_CharHandler(); - } else usleep(500); /* Probably the file has been closed */ + if (FD_ISSET(device_portfd,&readfds)) + SigHandler(0); + if (!FD_ISSET(PtyRDFD,&readfds) && !FD_ISSET(device_portfd,&readfds)) + usleep(500); /* Probably the file has been closed */ break; } } diff --git a/common/devices/device.c b/common/devices/device.c index 6a28122..826eee4 100644 --- a/common/devices/device.c +++ b/common/devices/device.c @@ -42,7 +42,7 @@ static bool duringwrite; pthread_t selThread; #endif -static int device_portfd = -1; +int device_portfd = -1; /* * Structure to store the filedescriptor we use. @@ -126,7 +126,10 @@ size_t device_write(__const __ptr_t __buf, size_t __n) { u8 buffer[300]; size_t mysize; - while (duringwrite) {} + while (duringwrite) { + fprintf(stderr,"device_write: reentrance violation!\n"); + _exit(1); + } memcpy(buffer,__buf,__n); AppendLog(buffer,__n,true); @@ -136,6 +139,8 @@ size_t device_write(__const __ptr_t __buf, size_t __n) { default : mysize = serial_write(device_portfd, __buf, __n); break; } duringwrite=false; + if (mysize!=__n) + fprintf(stderr,"WARNING: device_write(__n=%ld)=%ld\n",(long)__n,(long)mysize); return mysize; } @@ -159,7 +164,7 @@ static void device_dumpserial(void) static char SigHandler_buffer[255]; -static void SigHandler(int status) +void SigHandler(int status) { int count, res; @@ -174,6 +179,49 @@ static void SigHandler(int status) LIVE_ENABLE; } +#ifdef UCLINUX +void usleep_watchdevice(unsigned long usecs) +{ +int err; +fd_set readfds; +struct timeval target,timeout; + + if (gettimeofday(&target/*tv*/,NULL/*tz*/)) + perror("usleep_watchdevice()/gettimeofday(2) init"); + target.tv_usec+=usecs%1000000; + target.tv_sec +=usecs/1000000 + (target.tv_usec/1000000); + target.tv_usec%=1000000; + + for (;;) + FD_ZERO(&readfds); + if (device_portfd>=0) + FD_SET(device_portfd,&readfds); + + if (gettimeofday(&timeout/*tv*/,NULL/*tz*/)) + perror("usleep_watchdevice()/gettimeofday(2) loop"); + if (target.tv_sec < timeout.tv_sec) + return; + timeout.tv_sec =target.tv_sec - timeout.tv_sec; + if (target.tv_usec < timeout.tv_usec) { + target.tv_usec+=1000000; + if (target.tv_sec <= 0) + return; + target.tv_sec--; + } + timeout.tv_usec=target.tv_usec - timeout.tv_usec; + + err=select((device_portfd<0 ? 0 : device_portfd+1),&readfds,NULL,NULL,&timeout); + if ( err > 0 ) { + if (device_portfd>=0 && FD_ISSET(device_portfd,&readfds)) { + /* call singal handler to process incoming data */ + SigHandler(0); + } + } else { + if (err == -1) + perror("Error in SelectLoop"); + } +} +#endif #if defined(__svr4__) || defined(__FreeBSD__) /* thread for handling incoming data */ @@ -209,11 +257,13 @@ bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionTyp char text[100]; +#ifndef UCLINUX #if defined(__svr4__) || defined(__FreeBSD__) int rtn; #else struct sigaction sig_io; #endif +#endif /* UCLINUX */ #ifndef UCLINUX #ifdef DEBUG @@ -270,6 +320,7 @@ bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionTyp // return false; // } +#ifndef UCLINUX #if defined(__svr4__) || defined(__FreeBSD__) #else /* Set up and install handler before enabling async IO on port. */ @@ -277,6 +328,7 @@ bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionTyp sig_io.sa_flags = 0; sigaction (SIGIO, &sig_io, NULL); #endif +#endif /* UCLINUX */ /* Open device. */ result = device_open(PortDevice, with_odd_parity); @@ -286,6 +338,7 @@ bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionTyp return false; } +#ifndef UCLINUX #if defined(__svr4__) || defined(__FreeBSD__) /* create a thread to handle incoming data from mobile phone */ rtn=pthread_create(&selThread,NULL,(void*)SelectLoop,(void*)NULL); @@ -294,6 +347,7 @@ bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionTyp return false; } #endif +#endif /* UCLINUX */ return true; } diff --git a/common/devices/unixserial.c b/common/devices/unixserial.c index c98d27f..b2e4f6e 100644 --- a/common/devices/unixserial.c +++ b/common/devices/unixserial.c @@ -116,6 +116,7 @@ int serial_opendevice(__const char *__file, int __with_odd_parity, int __with_as if (fd < 0) return fd; +#ifndef UCLINUX /* Allow process/thread to receive SIGIO */ #if !(__unices__) @@ -137,6 +138,7 @@ int serial_opendevice(__const char *__file, int __with_odd_parity, int __with_as return(-1); } } +#endif /* UCLINUX */ /* Initialise the port settings */ diff --git a/include/devices/device.h b/include/devices/device.h index fabe975..f4b4153 100644 --- a/include/devices/device.h +++ b/include/devices/device.h @@ -33,6 +33,8 @@ typedef enum { #endif /* UCLINUX */ } GSM_ConnectionType; +extern int device_portfd; + #ifndef WIN32 #include #include "misc.h" @@ -51,5 +53,6 @@ typedef enum { extern char PortDevice[GSM_MAX_DEVICE_NAME_LENGTH]; bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionType con); +extern void SigHandler(int status); #endif /* __device_h */ diff --git a/include/uccompat.h b/include/uccompat.h index fa3a2b7..f4f2359 100644 --- a/include/uccompat.h +++ b/include/uccompat.h @@ -36,6 +36,11 @@ extern char * strrchr __P ((const char *, int)); extern pid_t getpid(void); extern int execv(const char *path, char *const argv[]); +extern void usleep_watchdevice(unsigned long usecs); +#define usleep(usecs) usleep_watchdevice((usecs)) +#define sleep(secs) usleep((secs)*1000000) + + #endif /* UCCOMPAT */ -- 1.8.3.1