[spambayes-dev] Prevent multiple servers on Windows

Mark Hammond mhammond at skippinet.com.au
Thu Sep 18 01:02:16 EDT 2003


We have touched a little on this before, and I suspect that at least one of
Richie's problems with the binary could be explained by having the proxy
running multiple times.

I propose that for Windows, we hack in a simple mutex to prevent *any* of
the server based apps from starting if any of them are already running.  We
can fix it later :)

Does anyone object to the following patch?  There will have to be changes to
pop3proxy_tray/service, but they are trivial.

Mark.

Index: sb_server.py
===================================================================
RCS file: /cvsroot/spambayes/spambayes/scripts/sb_server.py,v
retrieving revision 1.4
diff -u -r1.4 sb_server.py
--- sb_server.py	13 Sep 2003 05:10:49 -0000	1.4
+++ sb_server.py	18 Sep 2003 04:55:17 -0000
@@ -118,6 +118,10 @@
         newsoft = min(hard, max(soft, 1024*2048))
         resource.setrlimit(resource.RLIMIT_STACK, (newsoft, hard))

+# exception may be raised if we are already running and check such things.
+class AlreadyRunningException(Exception):
+    pass
+
 # number to add to STAT length for each msg to fudge for spambayes headers
 HEADER_SIZE_FUDGE_FACTOR = 512

@@ -726,6 +730,10 @@
     state.bayes.store()
     state.bayes.close()

+    try:
+        state.windows_mutex.Close()
+    except AttributeError:
+        pass
     state = State()

     prepare(state)
@@ -743,6 +751,29 @@
     Dibbler.run(launchBrowser=launchUI)

 def prepare(state):
+    # If we can, prevent multiple servers from running at the same time.
+    # This can be refactored later if other platforms ever want to do
anything
+    # similar.
+    if sys.platform.startswith("win"):
+        try:
+            import win32event, win32api, winerror
+            # ideally, the mutex name could include either the username, or
+            # the munged path to the INI file - this would mean we would
allow
+            # multiple starts so long as they weren't for the same user.
+            # However, as of now, the service version is likely to start as
+            # a different user, so a single mutex is best for now.
+            mutex_name = "SpamBayesServer"
+            hmutex = win32event.CreateMutex(None, True, mutex_name)
+            if win32api.GetLastError()==winerror.ERROR_ALREADY_EXISTS:
+                win32api.CloseHandle(hmutex)
+                raise AlreadyRunningException
+            # remember the handle, but no real need to explicitly close it
+            # when done, as it will die with the process.
+            state.windows_mutex = hmutex
+        except ImportError:
+            # no win32all - no worries, just start
+            pass
+
     # Do whatever we've been asked to do...
     state.createWorkers()

@@ -808,7 +839,12 @@
     print get_version_string("POP3 Proxy")
     print "and engine %s.\n" % (get_version_string(),)

-    prepare(state=state)
+    try:
+        prepare(state=state)
+    except AlreadyRunningException:
+        print "ERROR: The proxy is already running on this machine."
+        print "Please stop the existing proxy and try again"
+        return

     if 0 <= len(args) <= 2:
         # Normal usage, with optional server name and port number.




More information about the spambayes-dev mailing list