Update of /cvsroot/netrek/client/netrekxp/src
In directory sc8-pr-cvs16:/tmp/cvs-serv1445/src

Modified Files:
	cowmain.c data.c death.c input.c socket.c 
Log Message:
Terminate() calls within the network thread were causing errors due to
longjump() into the input thread.  A new function, terminate2() deals with
such cases.  Instead of calling longjump() directly, the main thread is
exited via W_TerminateWait() and ExitThread() calls, and a global error
variable is used to pass the exit code to setjmp in cowmain.c
This bit of code was previously used in death.c to handle jumping out
of the network thread to the main thread upon being sent to the team
select entry window.  All terminate() calls in socket.c have been modified
to use the appropriate version (terminate/terminate2) depending on
if THREADED is defined.

Index: input.c
===================================================================
RCS file: /cvsroot/netrek/client/netrekxp/src/input.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- input.c	23 Apr 2007 07:19:30 -0000	1.37
+++ input.c	28 Apr 2007 12:09:51 -0000	1.38
@@ -719,7 +719,7 @@
         W_NextEvent (&event);
     
     ingame = 0;
-    longjmp (env, 0);
+    longjmp (env, globalerr);
 }
 
 /******************************************************************************/

Index: death.c
===================================================================
RCS file: /cvsroot/netrek/client/netrekxp/src/death.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- death.c	6 Apr 2007 06:46:31 -0000	1.18
+++ death.c	28 Apr 2007 12:09:51 -0000	1.19
@@ -246,15 +246,8 @@
 
     longjmp (env, 0);
 #else
-    /* Threaded: when using threads, this thread has been spawned to handle network
-       I/O and so we cannot longjmp here, into another thread! Instead we call
-       W_TerminateWait which makes the main thead's W_WaitForEvent() return 0 
-       and exitthread */
-    if (!playback)
-    {                           /* If we are not playing back a recorded game, do this */
-        W_TerminateWait ();
-        ExitThread (0);
-    }
+    if (!playback) /* If we are not playing back a recorded game, do this */
+        terminate2 (0);
     else
     {                           /* Otherwise we aren't within a thread, so... */
         while (W_EventsPending ())

Index: data.c
===================================================================
RCS file: /cvsroot/netrek/client/netrekxp/src/data.c,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -d -r1.89 -r1.90
--- data.c	27 Apr 2007 07:15:28 -0000	1.89
+++ data.c	28 Apr 2007 12:09:51 -0000	1.90
@@ -35,6 +35,7 @@
 
 int TWINSIDE = 500;             /* Size of tactical window */
 int GWINSIDE = 500;             /* Size of galactic window */
+int globalerr = 0;              /* For sending error # between threads */
 int ingame = 0;                 /* If player is in game - to distinguish between whether
                                    to use double buffering on the local and map window */
 int ghoststart = 0;             /* is this a ghostbust

Index: cowmain.c
===================================================================
RCS file: /cvsroot/netrek/client/netrekxp/src/cowmain.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- cowmain.c	19 Apr 2007 08:22:58 -0000	1.33
+++ cowmain.c	28 Apr 2007 12:09:51 -0000	1.34
@@ -42,7 +42,6 @@
 int isFirstEntry;
 char defaulttmp[100];
 
-#define RETURNBASE 10
 #ifdef PACKET_LOG
 extern int log_packets;
 #endif
@@ -1101,3 +1100,21 @@
 {
     longjmp (env, RETURNBASE + error);
 }
+
+#ifdef THREADED
+/******************************************************************************/
+/***  terminate2() - for terminating inside the network thread              ***/
+/******************************************************************************/
+void
+terminate2 (int error)
+{
+    /* When using threads, a thread has been spawned to handle network
+       I/O and so we cannot longjmp into another thread! Instead we call
+       W_TerminateWait which makes the main thread's W_WaitForEvent()
+       return 0 and exitthread.  We pass the desired error value
+       to longjmp in input() via globalerr. */
+    globalerr = error;
+    W_TerminateWait ();
+    ExitThread (0);
+}
+#endif
\ No newline at end of file

Index: socket.c
===================================================================
RCS file: /cvsroot/netrek/client/netrekxp/src/socket.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- socket.c	25 Apr 2007 06:50:43 -0000	1.30
+++ socket.c	28 Apr 2007 12:09:51 -0000	1.31
@@ -560,7 +560,11 @@
     if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0)
     {
         LineToConsole ("I can't create a socket\n");
+#ifdef THREADED
+        terminate2 (RETURNBASE + 2);
+#else
         terminate (2);
+#endif
     }
 
     /* allow local address resuse */
@@ -577,9 +581,12 @@
 
     if (bind (s, (struct sockaddr *) &addr, sizeof (addr)) < 0)
     {
-
         perror ("bind");        /* NEW */
+#ifdef THREADED
+        terminate2 (RETURNBASE + 1);
+#else
         terminate (1);
+#endif
     }
     if (listen (s, 1) < 0)
         perror ("listen");
@@ -598,7 +605,11 @@
     if (select (max_fd, &readfds, NULL, NULL, &timeout) == 0)
     {
         LineToConsole ("Well, I think the server died!\n");
+#ifdef THREADED
+        terminate2 (RETURNBASE);
+#else
         terminate (0);
+#endif
     }
 
     sock = accept (s, (struct sockaddr *) &naddr, &len);
@@ -664,7 +675,11 @@
     if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0)
     {
         LineToConsole ("I can't create a socket\n");
+#ifdef THREADED
+        terminate2 (RETURNBASE);
+#else
         terminate (0);
+#endif
     }
     addr.sin_family = AF_INET;
     addr.sin_port = htons ((u_short) port);
@@ -674,7 +689,11 @@
         if ((hp = gethostbyname (server)) == NULL)
         {
             LineToConsole ("Who is %s?\n", server);
+#ifdef THREADED
+            terminate2 (RETURNBASE);
+#else
             terminate (0);
+#endif
         }
         else
         {
@@ -686,7 +705,11 @@
     if (connect (s, (struct sockaddr *) &addr, sizeof (addr)) < 0)
     {
         LineToConsole ("Server not listening!\n");
+#ifdef THREADED
+        terminate2 (RETURNBASE);
+#else
         terminate (0);
+#endif
     }
     LineToConsole ("Got connection.\n");
 
@@ -721,7 +744,11 @@
             if (gwrite (s, &msg, sizeof (struct mesg_cpacket)) < 0)
             {
                 LineToConsole ("trekhopd init failure\n");
+#ifdef THREADED
+                terminate2 (RETURNBASE + 1);
+#else
                 terminate (1);
+#endif
             }
             LineToConsole ("--- trekhopd request sent, awaiting reply\n");
             /* now block waiting for reply */
@@ -732,7 +759,11 @@
                 if ((n = recv (s, buf, count, 0)) <= 0)
                 {
                     perror ("trekhopd read");
+#ifdef THREADED
+                    terminate2 (RETURNBASE + 1);
+#else
                     terminate (1);
+#endif
                 }
             }
 
@@ -740,7 +771,11 @@
             {
                 LineToConsole ("Got bogus reply from trekhopd (%d)\n",
                          reply.type);
+#ifdef THREADED
+                terminate2 (RETURNBASE + 1);
+#else
                 terminate (1);
+#endif
             }
             ip = (int *) reply.mesg;
             gw_serv_port = ntohl (*ip++);
@@ -2177,7 +2212,11 @@
         LineToConsole ("Unknown message from handleBadVersion.\n");
         return;
     }
+#ifdef THREADED
+    terminate2 (RETURNBASE + 1);
+#else
     terminate (1);
+#endif
 }
 
 long
@@ -2563,7 +2602,11 @@
         if (getpeername (sock, (struct sockaddr *) &saddr, &len) < 0)
         {
             perror ("getpeername(sock)");
+#ifdef THREADED
+            terminate2 (RETURNBASE + 1);
+#else
             terminate (1);
+#endif
         }
     }
     else
@@ -2577,7 +2620,11 @@
     if (getpeername (sock, (struct sockaddr *) &saddr, &len) < 0)
     {
         perror ("getpeername(sock)");
+#ifdef THREADED
+        terminate2 (RETURNBASE + 1);
+#else
         terminate (1);
+#endif
     }
 #endif
 
@@ -2945,7 +2992,11 @@
             if ((hp = gethostbyname (serverName)) == NULL)
             {
                 LineToConsole ("Who is %s?\n", serverName);
+#ifdef THREADED
+                terminate2 (RETURNBASE);
+#else
                 terminate (0);
+#endif
             }
             else
             {