forked from twisted/twisted
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge desynchronize-2673-4: Brief description
Author: glyph Reviewer: exarkun, hawkowl Fixes: twisted#2673 Fix an intermittent test failure, rewriting nearly everything about multithreading in Twisted in the process. git-svn-id: svn://svn.twistedmatrix.com/svn/Twisted/trunk@45376 bbbe8e31-12d6-0310-92fd-ac37d47ddeeb
- Loading branch information
Showing
19 changed files
with
1,680 additions
and
243 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# -*- test-case-name: twisted.test.test_paths -*- | ||
# Copyright (c) Twisted Matrix Laboratories. | ||
# See LICENSE for details. | ||
|
||
""" | ||
Twisted integration with operating system threads. | ||
""" | ||
|
||
from __future__ import absolute_import, division, print_function | ||
|
||
from ._threadworker import ThreadWorker, LockWorker | ||
from ._ithreads import IWorker, AlreadyQuit | ||
from ._team import Team | ||
from ._memory import createMemoryWorker | ||
from ._pool import pool | ||
|
||
__all__ = [ | ||
"ThreadWorker", | ||
"LockWorker", | ||
"IWorker", | ||
"AlreadyQuit", | ||
"Team", | ||
"createMemoryWorker", | ||
"pool", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# -*- test-case-name: twisted._threads.test.test_convenience -*- | ||
# Copyright (c) Twisted Matrix Laboratories. | ||
# See LICENSE for details. | ||
|
||
""" | ||
Common functionality used within the implementation of various workers. | ||
""" | ||
|
||
from __future__ import absolute_import, division, print_function | ||
|
||
from ._ithreads import AlreadyQuit | ||
|
||
|
||
class Quit(object): | ||
""" | ||
A flag representing whether a worker has been quit. | ||
@ivar isSet: Whether this flag is set. | ||
@type isSet: L{bool} | ||
""" | ||
|
||
def __init__(self): | ||
""" | ||
Create a L{Quit} un-set. | ||
""" | ||
self.isSet = False | ||
|
||
|
||
def set(self): | ||
""" | ||
Set the flag if it has not been set. | ||
@raise AlreadyQuit: If it has been set. | ||
""" | ||
self.check() | ||
self.isSet = True | ||
|
||
|
||
def check(self): | ||
""" | ||
Check if the flag has been set. | ||
@raise AlreadyQuit: If it has been set. | ||
""" | ||
if self.isSet: | ||
raise AlreadyQuit() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# -*- test-case-name: twisted._threads.test -*- | ||
# Copyright (c) Twisted Matrix Laboratories. | ||
# See LICENSE for details. | ||
|
||
""" | ||
Interfaces related to threads. | ||
""" | ||
|
||
from __future__ import absolute_import, division, print_function | ||
|
||
from zope.interface import Interface | ||
|
||
|
||
class AlreadyQuit(Exception): | ||
""" | ||
This worker worker is dead and cannot execute more instructions. | ||
""" | ||
|
||
|
||
|
||
class IWorker(Interface): | ||
""" | ||
A worker that can perform some work concurrently. | ||
All methods on this interface must be thread-safe. | ||
""" | ||
|
||
def do(task): | ||
""" | ||
Perform the given task. | ||
As an interface, this method makes no specific claims about concurrent | ||
execution. An L{IWorker}'s C{do} implementation may defer execution | ||
for later on the same thread, immediately on a different thread, or | ||
some combination of the two. It is valid for a C{do} method to | ||
schedule C{task} in such a way that it may never be executed. | ||
It is important for some implementations to provide specific properties | ||
with respect to where C{task} is executed, of course, and client code | ||
may rely on a more specific implementation of C{do} than L{IWorker}. | ||
@param task: a task to call in a thread or other concurrent context. | ||
@type task: 0-argument callable | ||
@raise AlreadyQuit: if C{quit} has been called. | ||
""" | ||
|
||
def quit(): | ||
""" | ||
Free any resources associated with this L{IWorker} and cause it to | ||
reject all future work. | ||
@raise: L{AlreadyQuit} if this method has already been called. | ||
""" | ||
|
||
|
||
class IExclusiveWorker(IWorker): | ||
""" | ||
Like L{IWorker}, but with the additional guarantee that the callables | ||
passed to C{do} will not be called exclusively with each other. | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
# -*- test-case-name: twisted._threads.test.test_memory -*- | ||
# Copyright (c) Twisted Matrix Laboratories. | ||
# See LICENSE for details. | ||
|
||
""" | ||
Implementation of an in-memory worker that defers execution. | ||
""" | ||
|
||
from __future__ import absolute_import, division, print_function | ||
|
||
from zope.interface import implementer | ||
|
||
from . import IWorker | ||
from ._convenience import Quit | ||
|
||
NoMoreWork = object() | ||
|
||
@implementer(IWorker) | ||
class MemoryWorker(object): | ||
""" | ||
An L{IWorker} that queues work for later performance. | ||
@ivar _quit: a flag indicating | ||
@type _quit: L{Quit} | ||
""" | ||
|
||
def __init__(self, pending=list): | ||
""" | ||
Create a L{MemoryWorker}. | ||
""" | ||
self._quit = Quit() | ||
self._pending = pending() | ||
|
||
|
||
def do(self, work): | ||
""" | ||
Queue some work for to perform later; see L{createMemoryWorker}. | ||
@param work: The work to perform. | ||
""" | ||
self._quit.check() | ||
self._pending.append(work) | ||
|
||
|
||
def quit(self): | ||
""" | ||
Quit this worker. | ||
""" | ||
self._quit.set() | ||
self._pending.append(NoMoreWork) | ||
|
||
|
||
|
||
def createMemoryWorker(): | ||
""" | ||
Create an L{IWorker} that does nothing but defer work, to be performed | ||
later. | ||
@return: a worker that will enqueue work to perform later, and a callable | ||
that will perform one element of that work. | ||
@rtype: 2-L{tuple} of (L{IWorker}, L{callable}) | ||
""" | ||
def perform(): | ||
if not worker._pending: | ||
return False | ||
if worker._pending[0] is NoMoreWork: | ||
return False | ||
worker._pending.pop(0)() | ||
return True | ||
worker = MemoryWorker() | ||
return (worker, perform) |
Oops, something went wrong.