]> granicus.if.org Git - python/commitdiff
choose_boundary(): Incorporated a threadsafe incrementing counter, so that
authorTim Peters <tim.peters@gmail.com>
Sun, 15 Jun 2003 22:05:58 +0000 (22:05 +0000)
committerTim Peters <tim.peters@gmail.com>
Sun, 15 Jun 2003 22:05:58 +0000 (22:05 +0000)
unique boundary strings within a program run are guaranteed.  On Windows,
duplicates were pretty likely, due to the coarse granularity of time.time.
Toned down the absurdly optimistic claims in the docstring.

Bugfix candidate.

Lib/mimetools.py

index f1e20d444f41868deb9fb059ced0273e8e3ce7f5..67623ec72081251e0cd9bcd00ea42beb688ed1a0 100644 (file)
@@ -95,15 +95,31 @@ class Message(rfc822.Message):
 # Utility functions
 # -----------------
 
+try:
+    import thread
+except ImportError:
+    import dummy_thread as thread
+_counter_lock = thread.allocate_lock()
+del thread
+
+_counter = 0
+def _get_next_counter():
+    global _counter
+    _counter_lock.acquire()
+    _counter += 1
+    result = _counter
+    _counter_lock.release()
+    return result
 
 _prefix = None
 
 def choose_boundary():
-    """Return a random string usable as a multipart boundary.
-    The method used is so that it is *very* unlikely that the same
-    string of characters will every occur again in the Universe,
-    so the caller needn't check the data it is packing for the
-    occurrence of the boundary.
+    """Return a string usable as a multipart boundary.
+
+    The string chosen is unique within a single program run, and
+    incorporates the user id (if available), process id (if available),
+    and current time.  So it's very unlikely the returned string appears
+    in message text, but there's no guarantee.
 
     The boundary contains dots so you have to quote it in the header."""
 
@@ -122,9 +138,7 @@ def choose_boundary():
         except AttributeError:
             pid = '1'
         _prefix = hostid + '.' + uid + '.' + pid
-    timestamp = '%.3f' % time.time()
-    seed = `random.randint(0, 32767)`
-    return _prefix + '.' + timestamp + '.' + seed
+    return "%s.%.3f.%d" % (_prefix, time.time(), _get_next_counter())
 
 
 # Subroutines for decoding some common content-transfer-types