Untested attempt to get rid of SIGIO pain
authorshort <>
Thu, 14 Mar 2002 19:31:27 +0000 (19:31 +0000)
committershort <>
Thu, 14 Mar 2002 19:31:27 +0000 (19:31 +0000)
common/data/virtmodem.c
common/devices/device.c
common/devices/unixserial.c
include/devices/device.h
include/uccompat.h

index f6f1f3e..169b117 100644 (file)
@@ -136,10 +136,12 @@ bool VM_ThreadLoop(void)
 
                FD_ZERO(&readfds);
                FD_SET(PtyRDFD,&readfds);
 
                FD_ZERO(&readfds);
                FD_SET(PtyRDFD,&readfds);
+               FD_SET(device_portfd,&readfds);
                timeout.tv_sec=2;
                timeout.tv_usec=0;/*500*1000;*/
 
                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 */
 
                switch (res) {
                        case 0: /* Timeout */
@@ -155,9 +157,12 @@ bool VM_ThreadLoop(void)
                                return (false);
 
                        default:
                                return (false);
 
                        default:
-                         if (FD_ISSET(PtyRDFD,&readfds)) {
+                         if (FD_ISSET(PtyRDFD,&readfds))
                            VM_CharHandler();
                            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;
                }
          }
                          break;
                }
          }
index 6a28122..826eee4 100644 (file)
@@ -42,7 +42,7 @@ static bool duringwrite;
   pthread_t selThread;
 #endif
 
   pthread_t selThread;
 #endif
 
-static int device_portfd = -1;
+int device_portfd = -1;
 
 /*
  * Structure to store the filedescriptor we use.
 
 /*
  * 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;
   
   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);
 
   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;
     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;
 }
 
   return mysize;
 }
 
@@ -159,7 +164,7 @@ static void device_dumpserial(void)
 
 static char SigHandler_buffer[255];
 
 
 static char SigHandler_buffer[255];
 
-static void SigHandler(int status)
+void SigHandler(int status)
 {
   int count, res;
 
 {
   int count, res;
 
@@ -174,6 +179,49 @@ static void SigHandler(int status)
   LIVE_ENABLE;
 }
 
   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 */
 
 #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];
 
 
   char text[100];
 
+#ifndef UCLINUX
 #if defined(__svr4__) || defined(__FreeBSD__)
   int rtn;
 #else
   struct sigaction sig_io;
 #endif
 #if defined(__svr4__) || defined(__FreeBSD__)
   int rtn;
 #else
   struct sigaction sig_io;
 #endif
+#endif /* UCLINUX */
 
 #ifndef UCLINUX
 #ifdef DEBUG
 
 #ifndef UCLINUX
 #ifdef DEBUG
@@ -270,6 +320,7 @@ bool StartConnection (char *port_device, bool with_odd_parity, GSM_ConnectionTyp
 //    return false;
 //  }
 
 //    return false;
 //  }
 
+#ifndef UCLINUX
 #if defined(__svr4__) || defined(__FreeBSD__)
 #else
         /* Set up and install handler before enabling async IO on port. */
 #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
         sig_io.sa_flags = 0;
         sigaction (SIGIO, &sig_io, NULL);
 #endif
+#endif /* UCLINUX */
 
     /* Open device. */
     result = device_open(PortDevice, with_odd_parity);
 
     /* 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;
     }
 
       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);
 #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
       return false;
     }
 #endif
+#endif /* UCLINUX */
 
   return true;
 }
 
   return true;
 }
index c98d27f..b2e4f6e 100644 (file)
@@ -116,6 +116,7 @@ int serial_opendevice(__const char *__file, int __with_odd_parity, int __with_as
   if (fd < 0) 
     return fd;
 
   if (fd < 0) 
     return fd;
 
+#ifndef UCLINUX
   /* Allow process/thread to receive SIGIO */
 
 #if !(__unices__)
   /* 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);
     }
   }
       return(-1);
     }
   }
+#endif /* UCLINUX */
   
   /* Initialise the port settings */
 
   
   /* Initialise the port settings */
 
index fabe975..f4b4153 100644 (file)
@@ -33,6 +33,8 @@ typedef enum {
 #endif /* UCLINUX */
 } GSM_ConnectionType;
 
 #endif /* UCLINUX */
 } GSM_ConnectionType;
 
+extern int device_portfd;
+
 #ifndef WIN32
   #include <unistd.h>
   #include "misc.h"
 #ifndef WIN32
   #include <unistd.h>
   #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 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 */
 
 #endif  /* __device_h */
index fa3a2b7..f4f2359 100644 (file)
@@ -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 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 */
 
 
 #endif /* UCCOMPAT */