title: concurrency issues with event and lock python
body: <p>My critical region is a shelve object and I'm using a combination of event and lock to keep the threads separated. However this isn't working. By that I mean the process hangs, I have an unchecked lock happening somewhere and nothing happens after that.</p>
  
  <p>I actually discovered the problem. The lock is acquired and the shelve object changed. Then when a condition happens that does event.set(), all the threads are already inside of the block of code after event.wait(). In other words, they're running code in conditions that they shouldn't. I'm going to move away from Event and into Condition objects, I was using Event because originally I was using the Queue. Queue doesn't have persistence though, so now I am using this method.</p>
  
  <p>It goes something like this:</p>
  
  <pre><code>import SocketServer
  SocketServer.TCPServer.allow_reuse_address = True 
  from Dropbox import Dropbox
  import threading
  import json
  
  class DropboxServer(SocketServer.StreamRequestHandler):
      def handle(self):
          inp = self.request.recv(8192).strip()
          Dropbox.enqueue(json.loads(inp), "DropboxServer")
          self.request.send(json.dumps({"status":"success"}))
  
  if __name__ == "__main__":
      HOST, PORT = "localhost", 9999
      event = threading.Event()
      event.clear()
      lock = threading.Lock()
      Dropbox.lock = lock
      Dropbox.event = event                                                                                                                                                                                                                   
      for i in range(Dropbox.thread_count):
              thread = Dropbox()
              thread.start()
      server = SocketServer.TCPServer((HOST, PORT), DropboxServer)
      print "serving forever"
      server.serve_forever()
  </code></pre>
  
  <p>and</p>
  
  <pre><code>from dropbox import session, client
  import Queue
  import random
  import string
  from time import time
  import shelve
  
  class Dropbox(threading.Thread):
      thread_count = 20
      APP_KEY = 'key'
      APP_SECRET = 'sec'
      queue = Queue.Queue()
      requests = shelve.open("requests.db")
  
      def __init__(self):
          self.sess = session.DropboxSession(self.APP_KEY, self.APP_SECRET, 'dropbox')
          self.sess.set_token("token", "secret")
          self.dropbox = client.DropboxClient(self.sess)
          super(Dropbox, self).__init__(group=None, target=None, name=None, args=(), kwargs={})
          Dropbox.requests["dropbox"] = []
  
      def run(self):
          while True:
              self.put_file(Dropbox.dequeue(self.name))
  
      def put_file(self, request):
          file = open(request["local_file_path"])
          self.dropbox.put_file(request["destination"], file)
          file.close()
          print(self.name + " ending. " + str(time() - Dropbox.start_time))
  
      """ 
      {
          destination : project_name/AssetFile.png
          local_file_path : /path/to/asset.png
          token: A9s8d*d8
          secret: a9s9*38
      }
      """
      @staticmethod
      def enqueue(request, name):
          if "destination" not in request:
              for single_request in request:
                  size = Dropbox.enqueue(single_request, name)
              return size
          Dropbox.lock.acquire()
          print(name + " acquired lock")
          temp = Dropbox.requests["dropbox"] 
          temp.append(request)
          print(name + " enqueue size: " + str(len(temp)))
          Dropbox.requests["dropbox"] = temp
          Dropbox.lock.release()
          size = len(temp)
          if size == 1:
              Dropbox.start_time = time()
              print(name + " event set")
              Dropbox.event.set()
          print(name + " releasing lock")                                                                                                                                                                                                     
          return size
  
      @staticmethod
      def dequeue(name):
          Dropbox.lock.acquire()
          print(name + " acquired lock")
          temp = Dropbox.requests["dropbox"]
          try:
              result = temp.pop(0)
          except IndexError:
              Dropbox.event.wait()
          print(name + " dequeue size: " + str(len(temp)))
          Dropbox.requests["dropbox"] = temp
          Dropbox.lock.release()
          if len(temp)  == 0:
              print(name + " event cleared")
              Dropbox.event.clear()
          print(name + " releasing lock")
          return result
  </code></pre>