Skip to content

Commit

Permalink
Merge del-threadsafelist-5473: Removed t.p.threadpool.ThreadSafeList …
Browse files Browse the repository at this point in the history
…(deprecated in 10.1), an internal implementation detail of support for Jython 2.1, which is now obsolete.

Author: thijs
Reviewer: jesstess
Fixes: twisted#5473


git-svn-id: svn://svn.twistedmatrix.com/svn/Twisted/trunk@33537 bbbe8e31-12d6-0310-92fd-ac37d47ddeeb
  • Loading branch information
thijstriemstra committed Feb 11, 2012
1 parent 43752eb commit 4c076c2
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 84 deletions.
91 changes: 29 additions & 62 deletions twisted/python/threadpool.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,11 @@
instead of creating a thread pool directly.
"""

# System Imports
import Queue
import threading
import copy

# Twisted Imports
from twisted.python import log, context, failure
from twisted.python.deprecate import deprecatedModuleAttribute
from twisted.python.versions import Version


WorkerStop = object()
Expand All @@ -28,9 +24,9 @@ class ThreadPool:
This class (hopefully) generalizes the functionality of a pool of
threads to which work can be dispatched.
callInThread() and stop() should only be called from
a single thread, unless you make a subclass where stop() and
_startSomeWorkers() are synchronized.
L{callInThread} and L{stop} should only be called from
a single thread, unless you make a subclass where L{stop} and
L{_startSomeWorkers} are synchronized.
"""
min = 5
max = 20
Expand All @@ -47,7 +43,6 @@ def __init__(self, minthreads=5, maxthreads=20, name=None):
Create a new threadpool.
@param minthreads: minimum number of threads in the pool
@param maxthreads: maximum number of threads in the pool
"""
assert minthreads >= 0, 'minimum is negative'
Expand All @@ -60,6 +55,7 @@ def __init__(self, minthreads=5, maxthreads=20, name=None):
self.threads = []
self.working = []


def start(self):
"""
Start the threadpool.
Expand All @@ -69,27 +65,32 @@ def start(self):
# Start some threads.
self.adjustPoolsize()


def startAWorker(self):
self.workers += 1
name = "PoolThread-%s-%s" % (self.name or id(self), self.workers)
newThread = self.threadFactory(target=self._worker, name=name)
self.threads.append(newThread)
newThread.start()


def stopAWorker(self):
self.q.put(WorkerStop)
self.workers -= 1


def __setstate__(self, state):
self.__dict__ = state
ThreadPool.__init__(self, self.min, self.max)


def __getstate__(self):
state = {}
state['min'] = self.min
state['max'] = self.max
return state


def _startSomeWorkers(self):
neededSize = self.q.qsize() + len(self.working)
# Create enough, but not too many
Expand All @@ -103,42 +104,42 @@ def callInThread(self, func, *args, **kw):
@param func: callable object to be called in separate thread
@param *args: positional arguments to be passed to func
@param *args: positional arguments to be passed to C{func}
@param **kw: keyword args to be passed to func
@param **kw: keyword args to be passed to C{func}
"""
self.callInThreadWithCallback(None, func, *args, **kw)


def callInThreadWithCallback(self, onResult, func, *args, **kw):
"""
Call a callable object in a separate thread and call onResult
Call a callable object in a separate thread and call C{onResult}
with the return value, or a L{twisted.python.failure.Failure}
if the callable raises an exception.
The callable is allowed to block, but the onResult function
The callable is allowed to block, but the C{onResult} function
must not block and should perform as little work as possible.
A typical action for onResult for a threadpool used with a
Twisted reactor would be to schedule a Deferred to fire in the
main reactor thread using C{.callFromThread}. Note that
onResult is called inside the separate thread, not inside the
reactor thread.
A typical action for C{onResult} for a threadpool used with a
Twisted reactor would be to schedule a
L{twisted.internet.defer.Deferred} to fire in the main
reactor thread using C{.callFromThread}. Note that C{onResult}
is called inside the separate thread, not inside the reactor thread.
@param onResult: a callable with the signature (success, result).
If the callable returns normally, onResult is called with
(True, result) where result is the return value of the callable.
If the callable throws an exception, onResult is called with
(False, failure).
@param onResult: a callable with the signature C{(success, result)}.
If the callable returns normally, C{onResult} is called with
C{(True, result)} where C{result} is the return value of the
callable. If the callable throws an exception, C{onResult} is
called with C{(False, failure)}.
Optionally, onResult may be None, in which case it is not
Optionally, C{onResult} may be C{None}, in which case it is not
called at all.
@param func: callable object to be called in separate thread
@param *args: positional arguments to be passed to func
@param *args: positional arguments to be passed to C{func}
@param **kwargs: keyword arguments to be passed to func
@param **kwargs: keyword arguments to be passed to C{func}
"""
if self.joined:
return
Expand All @@ -151,7 +152,7 @@ def callInThreadWithCallback(self, onResult, func, *args, **kw):

def _worker(self):
"""
Method used as target of the created threads: retrieve task to run
Method used as target of the created threads: retrieve a task to run
from the threadpool, run it, and proceed to the next task until
threadpool is stopped.
"""
Expand Down Expand Up @@ -207,6 +208,7 @@ def stop(self):
for thread in threads:
thread.join()


def adjustPoolsize(self, minthreads=None, maxthreads=None):
if minthreads is None:
minthreads = self.min
Expand All @@ -230,44 +232,9 @@ def adjustPoolsize(self, minthreads=None, maxthreads=None):
# Start some threads if there is a need.
self._startSomeWorkers()


def dumpStats(self):
log.msg('queue: %s' % self.q.queue)
log.msg('waiters: %s' % self.waiters)
log.msg('workers: %s' % self.working)
log.msg('total: %s' % self.threads)



class ThreadSafeList:
"""
In Jython 2.1 lists aren't thread-safe, so this wraps it. Newer versions
of Jython are completely different than 2.1, so this class is deprecated
to make way for future versions of Jython.
"""

deprecatedModuleAttribute(
Version("Twisted", 10, 1, 0),
"This was an internal implementation detail of support for Jython 2.1,"
" which is now obsolete.",
__name__, "ThreadSafeList")

def __init__(self):
self.lock = threading.Lock()
self.l = []

def append(self, i):
self.lock.acquire()
try:
self.l.append(i)
finally:
self.lock.release()

def remove(self, i):
self.lock.acquire()
try:
self.l.remove(i)
finally:
self.lock.release()

def __len__(self):
return len(self.l)
22 changes: 0 additions & 22 deletions twisted/test/test_threadpool.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,25 +524,3 @@ def cbLoop(ignored):
loopDeferred.addCallback(cbLoop)
submit(10)
return loopDeferred



class ThreadSafeListDeprecationTestCase(unittest.TestCase):
"""
Test deprecation of threadpool.ThreadSafeList in twisted.python.threadpool
"""

def test_threadSafeList(self):
"""
Test deprecation of L{threadpool.ThreadSafeList}.
"""
threadpool.ThreadSafeList()

warningsShown = self.flushWarnings([self.test_threadSafeList])
self.assertEqual(len(warningsShown), 1)
self.assertIdentical(warningsShown[0]['category'], DeprecationWarning)
self.assertEqual(
warningsShown[0]['message'],
"twisted.python.threadpool.ThreadSafeList was deprecated in "
"Twisted 10.1.0: This was an internal implementation detail of "
"support for Jython 2.1, which is now obsolete.")
1 change: 1 addition & 0 deletions twisted/topfiles/5473.removal
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
twisted.python.threadpool.ThreadSafeList (deprecated in 10.1) is removed.

0 comments on commit 4c076c2

Please sign in to comment.