Set a no-op functor when none is provided

Instead of having later checks to check for
none when calling the thread bundle callback
just initially set it to a no-op functor that
does nothing at binding time instead; this avoids
the need to do repeated checks at start/stop
time.

Change-Id: I5ab4f801bf4767c802ea607fdf864d4852e6c84d
This commit is contained in:
Joshua Harlow
2015-03-07 07:35:19 -08:00
parent 41f31423f0
commit 1f108da515

View File

@@ -82,16 +82,19 @@ _ThreadBuilder = collections.namedtuple('_ThreadBuilder',
['thread_factory', ['thread_factory',
'before_start', 'after_start', 'before_start', 'after_start',
'before_join', 'after_join']) 'before_join', 'after_join'])
_ThreadBuilder.callables = tuple([ _ThreadBuilder.fields = tuple([
# Attribute name -> none allowed as a valid value... 'thread_factory',
('thread_factory', False), 'before_start',
('before_start', True), 'after_start',
('after_start', True), 'before_join',
('before_join', True), 'after_join',
('after_join', True),
]) ])
def no_op(*args, **kwargs):
"""Function that does nothing."""
class ThreadBundle(object): class ThreadBundle(object):
"""A group/bundle of threads that start/stop together.""" """A group/bundle of threads that start/stop together."""
@@ -110,13 +113,19 @@ class ThreadBundle(object):
in dead-lock since the lock on this object is not in dead-lock since the lock on this object is not
meant to be (and is not) reentrant... meant to be (and is not) reentrant...
""" """
if before_start is None:
before_start = no_op
if after_start is None:
after_start = no_op
if before_join is None:
before_join = no_op
if after_join is None:
after_join = no_op
builder = _ThreadBuilder(thread_factory, builder = _ThreadBuilder(thread_factory,
before_start, after_start, before_start, after_start,
before_join, after_join) before_join, after_join)
for attr_name, none_allowed in builder.callables: for attr_name in builder.fields:
cb = getattr(builder, attr_name) cb = getattr(builder, attr_name)
if cb is None and none_allowed:
continue
if not six.callable(cb): if not six.callable(cb):
raise ValueError("Provided callback for argument" raise ValueError("Provided callback for argument"
" '%s' must be callable" % attr_name) " '%s' must be callable" % attr_name)
@@ -130,11 +139,6 @@ class ThreadBundle(object):
False, False,
]) ])
@staticmethod
def _trigger_callback(callback, thread):
if callback is not None:
callback(thread)
def start(self): def start(self):
"""Creates & starts all associated threads (that are not running).""" """Creates & starts all associated threads (that are not running)."""
count = 0 count = 0
@@ -145,11 +149,11 @@ class ThreadBundle(object):
continue continue
if not thread: if not thread:
self._threads[i][1] = thread = builder.thread_factory() self._threads[i][1] = thread = builder.thread_factory()
self._trigger_callback(builder.before_start, thread) builder.before_start(thread)
thread.start() thread.start()
count += 1 count += 1
try: try:
self._trigger_callback(builder.after_start, thread) builder.after_start(thread)
finally: finally:
# Just incase the 'after_start' callback blows up make sure # Just incase the 'after_start' callback blows up make sure
# we always set this... # we always set this...
@@ -164,11 +168,11 @@ class ThreadBundle(object):
for i, (builder, thread, started) in it: for i, (builder, thread, started) in it:
if not thread or not started: if not thread or not started:
continue continue
self._trigger_callback(builder.before_join, thread) builder.before_join(thread)
thread.join() thread.join()
count += 1 count += 1
try: try:
self._trigger_callback(builder.after_join, thread) builder.after_join(thread)
finally: finally:
# Just incase the 'after_join' callback blows up make sure # Just incase the 'after_join' callback blows up make sure
# we always set/reset these... # we always set/reset these...