[109453] trunk/base/src/pextlib1.0/tracelib.c

cal at macports.org cal at macports.org
Thu Aug 15 12:39:30 PDT 2013


Revision: 109453
          https://trac.macports.org/changeset/109453
Author:   cal at macports.org
Date:     2013-08-15 12:39:30 -0700 (Thu, 15 Aug 2013)
Log Message:
-----------
tracelib: drop usage of EVFILT_USER, fix error conditions leaving mutex locked, add unique identifiers to error messages

 - drop usage of EVFILT_USER: triggering of the EVFILT_USER event would
   sometimes fail with "no such file or directory" in TracelibCloseSocketCmd.
   Since I couldn't figure out why this happens, use the selfpipe only (we
   needed it anyway on systems that don't support EVFILT_USER).
 - fix some errors aborting execution without unlocking a mutex
 - add unique identifiers to perror(3) messages to be able to identify the
   location where a problem occured

Modified Paths:
--------------
    trunk/base/src/pextlib1.0/tracelib.c

Modified: trunk/base/src/pextlib1.0/tracelib.c
===================================================================
--- trunk/base/src/pextlib1.0/tracelib.c	2013-08-15 19:34:55 UTC (rev 109452)
+++ trunk/base/src/pextlib1.0/tracelib.c	2013-08-15 19:39:30 UTC (rev 109453)
@@ -87,11 +87,9 @@
 static char *depends;
 static int sock = -1;
 static int kq = -1;
-#ifndef EVFILT_USER
-/* if EVFILT_USER isn't available (< 10.6), use the self-pipe trick to return
- * from the blocking kqueue(2) call by writing a byte to the pipe */
+/* EVFILT_USER isn't available (< 10.6), use the self-pipe trick to return from
+ * the blocking kqueue(2) call by writing a byte to the pipe */
 static int selfpipe[2];
-#endif
 static int enable_fence = 0;
 static Tcl_Interp *interp;
 static pthread_mutex_t sock_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -553,6 +551,7 @@
     int oldsock;
     int opensockcount = 0;
 
+    pthread_mutex_lock(&sock_mutex);
     if (-1 == (kq = kqueue())) {
         Tcl_SetErrno(errno);
         Tcl_ResetResult(in);
@@ -560,7 +559,6 @@
         return TCL_ERROR;
     }
 
-    pthread_mutex_lock(&sock_mutex);
     if (sock != -1) {
         oldsock = sock;
 
@@ -573,6 +571,7 @@
             Tcl_SetErrno(errno);
             Tcl_ResetResult(in);
             Tcl_AppendResult(in, "fcntl(F_SETFL, += O_NONBLOCK): ", (char *) Tcl_PosixError(in), NULL);
+            pthread_mutex_unlock(&sock_mutex);
             return TCL_ERROR;
         }
 
@@ -581,8 +580,9 @@
         if (1 != kevent(kq, &kev, 1, &kev, 1, NULL)) {
             Tcl_SetErrno(errno);
             Tcl_ResetResult(in);
-            Tcl_AppendResult(in, "kevent: ", (char *) Tcl_PosixError(in), NULL);
+            Tcl_AppendResult(in, "kevent (listen socket): ", (char *) Tcl_PosixError(in), NULL);
             close(kq);
+            pthread_mutex_unlock(&sock_mutex);
             return TCL_ERROR;
         }
         /* kevent(2) on EV_RECEIPT: When passed as input, it forces EV_ERROR to
@@ -591,20 +591,20 @@
         if ((kev.flags & EV_ERROR) == 0 || ((kev.flags & EV_ERROR) > 0 && kev.data != 0)) {
             Tcl_SetErrno(kev.data);
             Tcl_ResetResult(in);
-            Tcl_AppendResult(in, "kevent: ", (char *) Tcl_PosixError(in), NULL);
+            Tcl_AppendResult(in, "kevent (listen socket receipt): ", (char *) Tcl_PosixError(in), NULL);
             close(kq);
+            pthread_mutex_unlock(&sock_mutex);
             return TCL_ERROR;
         }
 
 
-#       ifndef EVFILT_USER
-        /* on systems that don't have EVFILT_USER, use the self-pipe trick to
-         * trigger returning from kevent(2) when tracelib closesocket is
-         * called. */
+        /* use the self-pipe trick to trigger returning from kevent(2) when
+         * tracelib closesocket is called. */
         if (-1 == pipe(selfpipe)) {
             Tcl_SetErrno(errno);
             Tcl_ResetResult(in);
             Tcl_AppendResult(in, "pipe: ", (char *) Tcl_PosixError(in), NULL);
+            pthread_mutex_unlock(&sock_mutex);
             return TCL_ERROR;
         }
 
@@ -614,6 +614,7 @@
             Tcl_SetErrno(errno);
             Tcl_ResetResult(in);
             Tcl_AppendResult(in, "fcntl(F_SETFL, += O_NONBLOCK): ", (char *) Tcl_PosixError(in), NULL);
+            pthread_mutex_unlock(&sock_mutex);
             return TCL_ERROR;
         }
 
@@ -623,8 +624,9 @@
         if (1 != kevent(kq, &kev, 1, &kev, 1, NULL)) {
             Tcl_SetErrno(errno);
             Tcl_ResetResult(in);
-            Tcl_AppendResult(in, "kevent: ", (char *) Tcl_PosixError(in), NULL);
+            Tcl_AppendResult(in, "kevent (selfpipe): ", (char *) Tcl_PosixError(in), NULL);
             close(kq);
+            pthread_mutex_unlock(&sock_mutex);
             return TCL_ERROR;
         }
         /* kevent(2) on EV_RECEIPT: When passed as input, it forces EV_ERROR to
@@ -633,32 +635,11 @@
         if ((kev.flags & EV_ERROR) == 0 || ((kev.flags & EV_ERROR) > 0 && kev.data != 0)) {
             Tcl_SetErrno(kev.data);
             Tcl_ResetResult(in);
-            Tcl_AppendResult(in, "kevent: ", (char *) Tcl_PosixError(in), NULL);
+            Tcl_AppendResult(in, "kevent (selfpipe receipt): ", (char *) Tcl_PosixError(in), NULL);
             close(kq);
+            pthread_mutex_unlock(&sock_mutex);
             return TCL_ERROR;
         }
-#       else /* ifndef EVFILT_USER */
-        /* wait for the user event on the listen socket, as sent by CloseCmd as
-         * deathpill */
-        EV_SET(&kev, oldsock, EVFILT_USER, EV_ADD | EV_RECEIPT, 0, 0, NULL);
-        if (1 != kevent(kq, &kev, 1, &kev, 1, NULL)) {
-            Tcl_SetErrno(errno);
-            Tcl_ResetResult(in);
-            Tcl_AppendResult(in, "kevent: ", (char *) Tcl_PosixError(in), NULL);
-            close(kq);
-            return TCL_ERROR;
-        }
-        /* kevent(2) on EV_RECEIPT: When passed as input, it forces EV_ERROR to
-         * always be returned. When a filter is successfully added, the data field
-         * will be zero. */
-        if ((kev.flags & EV_ERROR) == 0 || ((kev.flags & EV_ERROR) > 0 && kev.data != 0)) {
-            Tcl_SetErrno(kev.data);
-            Tcl_ResetResult(in);
-            Tcl_AppendResult(in, "kevent: ", (char *) Tcl_PosixError(in), NULL);
-            close(kq);
-            return TCL_ERROR;
-        }
-#       endif /* ifndef EVFILT_USER */
     }
     pthread_mutex_unlock(&sock_mutex);
 
@@ -671,14 +652,13 @@
             if (-1 == (keventstatus = kevent(kq, NULL, 0, res_kevents, MAX_SOCKETS, NULL))) {
                 Tcl_SetErrno(errno);
                 Tcl_ResetResult(in);
-                Tcl_AppendResult(in, "kevent: ", (char *) Tcl_PosixError(in), NULL);
+                Tcl_AppendResult(in, "kevent (main loop): ", (char *) Tcl_PosixError(in), NULL);
                 close(kq);
                 return TCL_ERROR;
             }
         } while (keventstatus == 0);
 
         for (i = 0; i < keventstatus; ++i) {
-#           ifndef EVFILT_USER
             /* handle traffic on the selfpipe */
             if ((int) res_kevents[i].ident == selfpipe[0]) {
                 pthread_mutex_lock(&sock_mutex);
@@ -689,7 +669,7 @@
                 pthread_mutex_unlock(&sock_mutex);
                 break;
             }
-#           endif
+
             /* the control socket has activity – we might have a new
              * connection. We use a copy of sock here, because sock might have
              * been set to -1 by the close command */
@@ -811,7 +791,6 @@
 }
 
 static int TracelibCloseSocketCmd(Tcl_Interp *interp UNUSED) {
-    /* interp might be UNUSED on systems without EVFILT_USER */
     cleanuping = 1;
     pthread_mutex_lock(&sock_mutex);
     if (sock != -1) {
@@ -821,24 +800,11 @@
         sock = -1;
 
         if (kq != -1) {
-#           ifdef EVFILT_USER
-            int ret;
-            struct kevent kev;
-            EV_SET(&kev, oldsock, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL);
-            if (-1 == (ret = kevent(kq, &kev, 1, NULL, 0, NULL))) {
-                Tcl_SetErrno(errno);
-                Tcl_ResetResult(interp);
-                Tcl_AppendResult(interp, "kevent: ", (char *) Tcl_PosixError(interp), NULL);
-                pthread_mutex_unlock(&sock_mutex);
-                return TCL_ERROR;
-            }
-#           else /* ifdef EVFILT_USER */
             /* We know the pipes have been created because kq != -1 and we have
              * the lock. We don't have to check for errors, because none should
              * occur but when the pipe is full, which we wouldn't care about.
              * */
             write(selfpipe[1], "!", 1);
-#           endif /* ifdef EVFILT_USER */
         }
     }
     pthread_mutex_unlock(&sock_mutex);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20130815/a80e6bf7/attachment.html>


More information about the macports-changes mailing list