+ if (session->have_thread)
+ {
+ //
+ // Tell the data connection thread main capture loop to
+ // break out of that loop.
+ //
+ // This may be sufficient to wake up a blocked thread,
+ // but it's not guaranteed to be sufficient.
+ //
+ pcap_breakloop(session->fp);
+
+#ifdef _WIN32
+ //
+ // Set the event on which a read would block, so that,
+ // if it's currently blocked waiting for packets to
+ // arrive, it'll wake up, so it can see the "break
+ // out of the loop" indication. (pcap_breakloop()
+ // might do this, but older versions don't. Setting
+ // it twice should, at worst, cause an extra wakeup,
+ // which shouldn't be a problem.)
+ //
+ // XXX - what about modules other than NPF?
+ //
+ SetEvent(pcap_getevent(session->fp));
+
+ //
+ // Wait for the thread to exit, so we don't close
+ // sockets out from under it.
+ //
+ // XXX - have a timeout, so we don't wait forever?
+ //
+ WaitForSingleObject(session->thread, INFINITE);
+
+ //
+ // Release the thread handle, as we're done with
+ // it.
+ //
+ CloseHandle(session->thread);
+ session->have_thread = 0;
+ session->thread = INVALID_HANDLE_VALUE;
+#else
+ //
+ // Send a SIGUSR1 signal to the thread, so that, if
+ // it's currently blocked waiting for packets to arrive,
+ // it'll wake up (we've turned off SA_RESTART for
+ // SIGUSR1, so that the system call in which it's blocked
+ // should return EINTR rather than restarting).
+ //
+ pthread_kill(session->thread, SIGUSR1);
+
+ //
+ // Wait for the thread to exit, so we don't close
+ // sockets out from under it.
+ //
+ // XXX - have a timeout, so we don't wait forever?
+ //
+ pthread_join(session->thread, NULL);
+ session->have_thread = 0;
+ memset(&session->thread, 0, sizeof(session->thread));
+#endif
+ }
+