Author: tack
Date: Mon Jan 7 15:56:24 2008
New Revision: 2946
Log:
New main api, with temporary backward compatibility. (Access of old api logs
warning message.)
Added:
trunk/base/src/notifier/main.py (contents, props changed)
Modified:
trunk/base/src/__init__.py
trunk/base/src/notifier/__init__.py
Modified: trunk/base/src/__init__.py
==============================================================================
--- trunk/base/src/__init__.py (original)
+++ trunk/base/src/__init__.py Mon Jan 7 15:56:24 2008
@@ -30,10 +30,41 @@
# import notifier functions into kaa namespace
from kaa.notifier import *
-from kaa.notifier import loop as main
# strutils
import strutils
# tempfile support. FIXME: remove TEMP when no longer used
from tmpfile import tempfile, TEMP
+
+
+# XXX: when support for deprecated API is removed, everything below can be
deleted
+# and replaced by 'from kaa.notifier import main'
+import kaa.notifier.main
+
+class MainWrapper:
+ signals = kaa.notifier.main.signals
+
+ def __call__(self):
+ import logging
+ log = logging.getLogger('notifier')
+ log.warning('Deprecated call to kaa.main(); use kaa.main.start()
instead')
+ return kaa.notifier.main.start()
+
+ # Wrappers for new API.
+ def start(self):
+ return kaa.notifier.main.start()
+
+ def step(self):
+ return kaa.notifier.main.step()
+
+ def stop(self):
+ return kaa.notifier.main.stop()
+
+ def is_running(self):
+ return kaa.notifier.main.is_running()
+
+ def select_notifier(self, *args, **kwargs):
+ return kaa.notifier.main.select_notifier(*args, **kwargs)
+
+main = MainWrapper()
Modified: trunk/base/src/notifier/__init__.py
==============================================================================
--- trunk/base/src/notifier/__init__.py (original)
+++ trunk/base/src/notifier/__init__.py Mon Jan 7 15:56:24 2008
@@ -39,11 +39,7 @@
import threading
import atexit
-# kaa.notifier imports
-import nf_wrapper as notifier
-
from popen import Process
-from popen import proclist as _proclist
from callback import Callback, WeakCallback, Signal, Signals
from thread import MainThreadCallback, Thread, is_mainthread, wakeup,
set_current_as_mainthread
from timer import Timer, WeakTimer, OneShotTimer, WeakOneShotTimer, AtTimer,
OneShotAtTimer
@@ -51,7 +47,6 @@
from event import Event, EventHandler, WeakEventHandler
from yieldfunc import YieldContinue, YieldCallback, YieldFunction,
yield_execution
from jobserver import ThreadCallback, execute_in_thread
-from jobserver import killall as kill_jobserver
from async import Progress, InProgress
from decorators import execute_in_timer, execute_in_mainloop
@@ -69,152 +64,30 @@
'ThreadCallback', 'execute_in_thread',
'execute_in_timer', 'execute_in_mainloop',
- # From this module
- 'init', 'shutdown', 'step', 'running', 'signals'
- # 'loop' gets imported as 'main'
+ # XXX: DEPRECATED wrappers From this module
+ 'init', 'shutdown', 'step', 'running', 'signals', 'loop'
]
+# XXX: support for deprecated API. Delete everything below when support is
removed.
+import main
+
# get logging object
log = logging.getLogger('notifier')
-# variable to check if the notifier is running
-running = False
-# Set if currently in shutdown() (to prevent reentrancy)
-shutting_down = False
-
-def _step_signal_changed(signal, flag):
- if flag == Signal.SIGNAL_CONNECTED and signal.count() == 1:
- notifier.dispatcher_add(signals["step"].emit)
- elif flag == Signal.SIGNAL_DISCONNECTED and signal.count() == 0:
- notifier.dispatcher_remove(signals["step"].emit)
-
-
-signals = {
- "shutdown": Signal(),
- "step": Signal(changed_cb = _step_signal_changed),
-}
-
-
-def shutdown():
- """
- Shutdown notifier and kill all background processes.
- """
- global shutting_down
-
- # Ensure shutdown() is called from main thread.
- if not is_mainthread():
- return MainThreadCallback(shutdown)()
-
- if running:
- # notifier loop still running, send system exit
- log.info('Stop notifier loop')
- raise SystemExit
-
- if shutting_down:
- return
- shutting_down = True
-
- _proclist.stop_all()
- signals["shutdown"].emit()
- signals["shutdown"].disconnect_all()
- signals["step"].disconnect_all()
-
- # Kill processes _after_ shutdown emits to give callbacks a chance to
- # close them properly.
- _proclist.kill_all()
- while _proclist.check():
- # wait until all processes are stopped
- step()
- kill_jobserver()
- # Collect any zombies
- try:
- os.waitpid(-1, os.WNOHANG)
- except:
- pass
-
-
-def loop():
- """
- Notifier main loop function. It will loop until an exception
- is raised or sys.exit is called.
- """
- global running
- running = True
-
- set_current_as_mainthread()
- try:
- while True:
- notifier.step()
- except (KeyboardInterrupt, SystemExit):
- try:
- # This looks stupid, I know that. The problem is that if we have
- # a KeyboardInterrupt, that flag is still valid somewhere inside
- # python. The next system call will fail because of that. Since we
- # don't want a join of threads or similar fail, we use a very short
- # sleep here. In most cases we won't sleep at all because this
sleep
- # fails. But after that everything is back to normal.
- time.sleep(0.001)
- except:
- pass
- except Exception, e:
- log.exception('loop')
- running = False
- shutdown()
-
-
-def init( module, **options ):
- """
- Init the notifier.
- """
- if module in ('thread', 'twisted'):
- import nf_thread
- return nf_thread.init(module, **options)
- return notifier.init( module, **options )
-
-
-def step(*args, **kwargs):
- """
- Notifier step function with signal support.
- """
- if not is_mainthread():
- # If step is being called from a thread, wake up the mainthread
- # instead of allowing the thread into notifier.step.
- wakeup()
- # Sleep for epsilon to prevent busy loops.
- time.sleep(0.001)
- return
-
- try:
- notifier.step(*args, **kwargs)
- except (KeyboardInterrupt, SystemExit):
- raise SystemExit
-
-
-def _shutdown_check(*args):
- # Helper function to shutdown kaa on system exit
- # The problem is that pytgtk just exits python and
- # does not simply return from the main loop and kaa
- # can't call the shutdown handler. This is not a perfect
- # solution, e.g. with the generic notifier you can do
- # stuff after kaa.main() which is not possible with gtk
- global running
- if running:
- # If the kaa mainthread (i.e. thread the mainloop is running in)
- # is not the program's main thread, then is_mainthread() will be False
- # and we don't need to set running=False since shutdown() will raise a
- # SystemExit and things will exit normally.
- if is_mainthread():
- running = False
- shutdown()
-
-# catch SIGTERM and SIGINT if possible for a clean shutdown
-if threading.enumerate()[0] == threading.currentThread():
- def signal_handler(*args):
- sys.exit(0)
- signal.signal(signal.SIGTERM, signal_handler)
- signal.signal(signal.SIGINT, signal_handler)
-else:
- log.info('kaa imported from thread, disable SIGTERM handler')
-
-# check to make sure we really call our shutdown function
-atexit.register(_shutdown_check)
+def wrap(old_name, new_name, *args, **kwargs):
+ def f(*args, **kwargs):
+ log.warning('Deprecated call to notifier.%s(); use main.%s() instead'
% (old_name, new_name))
+ return getattr(main, new_name)(*args, **kwargs)
+ return f
+
+class RunningWrapper:
+ def __nonzero__(self):
+ log.warning('Deprecated access of notifier.running; use
main.is_running() instead')
+ return main.is_running()
+
+init = wrap('init', 'select_notifier')
+loop = wrap('loop', 'start')
+shutdown = wrap('shutdown', 'stop')
+step = wrap('step', 'step')
+signals = main.signals
+running = RunningWrapper()
Added: trunk/base/src/notifier/main.py
==============================================================================
--- (empty file)
+++ trunk/base/src/notifier/main.py Mon Jan 7 15:56:24 2008
@@ -0,0 +1,198 @@
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------------
+# main.py - Main loop functions
+# -----------------------------------------------------------------------------
+# $Id$
+#
+# -----------------------------------------------------------------------------
+# kaa.notifier - Mainloop and callbacks
+# Copyright (C) 2005, 2006 Dirk Meyer, Jason Tackaberry, et al.
+#
+# First Version: Dirk Meyer <[EMAIL PROTECTED]>
+# Maintainer: Dirk Meyer <[EMAIL PROTECTED]>
+# Jason Tackaberry <[EMAIL PROTECTED]>
+#
+# Please see the file AUTHORS for a complete list of authors.
+#
+# This library is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version
+# 2.1 as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 USA
+#
+# -----------------------------------------------------------------------------
+
+# python imports
+import sys
+import logging
+import os
+import time
+import signal
+import threading
+import atexit
+
+import nf_wrapper as notifier
+from callback import Signal
+from popen import proclist as _proclist
+from thread import MainThreadCallback, is_mainthread, wakeup,
set_current_as_mainthread
+from jobserver import killall as kill_jobserver
+from decorators import execute_in_mainloop
+
+__all__ = [ 'init', 'start', 'stop', 'step', 'is_running' ]
+
+# get logging object
+log = logging.getLogger('notifier')
+
+# variable to check if the notifier is running
+_running = False
+# Set if currently in shutdown() (to prevent reentrancy)
+_shutting_down = False
+
+
+def _step_signal_changed(signal, flag):
+ if flag == Signal.SIGNAL_CONNECTED and signal.count() == 1:
+ notifier.dispatcher_add(signals["step"].emit)
+ elif flag == Signal.SIGNAL_DISCONNECTED and signal.count() == 0:
+ notifier.dispatcher_remove(signals["step"].emit)
+
+signals = {
+ 'shutdown': Signal(),
+ 'step': Signal(changed_cb = _step_signal_changed),
+}
+
+
+# Ensure stop() is called from main thread.
[EMAIL PROTECTED]()
+def stop():
+ """
+ Shutdown notifier and kill all background processes.
+ """
+ global _shutting_down
+
+ if _running:
+ # notifier loop still running, send system exit
+ log.info('Stop notifier loop')
+ raise SystemExit
+
+ if _shutting_down:
+ return
+
+ _shutting_down = True
+
+ _proclist.stop_all()
+ signals["shutdown"].emit()
+ signals["shutdown"].disconnect_all()
+ signals["step"].disconnect_all()
+
+ # Kill processes _after_ shutdown emits to give callbacks a chance to
+ # close them properly.
+ _proclist.kill_all()
+ while _proclist.check():
+ # wait until all processes are stopped
+ step()
+ kill_jobserver()
+ # Collect any zombies
+ try:
+ os.waitpid(-1, os.WNOHANG)
+ except:
+ pass
+
+
+def start():
+ """
+ Notifier main loop function. It will loop until an exception
+ is raised or sys.exit is called.
+ """
+ global _running
+ _running = True
+
+ set_current_as_mainthread()
+ try:
+ while True:
+ notifier.step()
+ except (KeyboardInterrupt, SystemExit):
+ try:
+ # This looks stupid, I know that. The problem is that if we have
+ # a KeyboardInterrupt, that flag is still valid somewhere inside
+ # python. The next system call will fail because of that. Since we
+ # don't want a join of threads or similar fail, we use a very short
+ # sleep here. In most cases we won't sleep at all because this
sleep
+ # fails. But after that everything is back to normal.
+ time.sleep(0.001)
+ except:
+ pass
+ except Exception, e:
+ log.exception('loop')
+ _running = False
+ stop()
+
+
+def is_running():
+ return _running
+
+
+def select_notifier(module, **options):
+ """
+ Initialize the specified notifier.
+ """
+ if module in ('thread', 'twisted'):
+ import nf_thread
+ return nf_thread.init(module, **options)
+ return notifier.init( module, **options )
+
+
+def step(*args, **kwargs):
+ """
+ Notifier step function with signal support.
+ """
+ if not is_mainthread():
+ # If step is being called from a thread, wake up the mainthread
+ # instead of allowing the thread into notifier.step.
+ wakeup()
+ # Sleep for epsilon to prevent busy loops.
+ time.sleep(0.001)
+ return
+
+ try:
+ notifier.step(*args, **kwargs)
+ except (KeyboardInterrupt, SystemExit):
+ raise SystemExit
+
+
+def _shutdown_check(*args):
+ # Helper function to shutdown kaa on system exit
+ # The problem is that pytgtk just exits python and
+ # does not simply return from the main loop and kaa
+ # can't call the shutdown handler. This is not a perfect
+ # solution, e.g. with the generic notifier you can do
+ # stuff after kaa.main() which is not possible with gtk
+ global _running
+ if _running:
+ # If the kaa mainthread (i.e. thread the mainloop is running in)
+ # is not the program's main thread, then is_mainthread() will be False
+ # and we don't need to set running=False since shutdown() will raise a
+ # SystemExit and things will exit normally.
+ if is_mainthread():
+ _running = False
+ shutdown()
+
+
+# catch SIGTERM and SIGINT if possible for a clean shutdown
+if threading.enumerate()[0] == threading.currentThread():
+ def signal_handler(*args):
+ sys.exit(0)
+ signal.signal(signal.SIGTERM, signal_handler)
+ signal.signal(signal.SIGINT, signal_handler)
+else:
+ log.info('kaa imported from thread, disable SIGTERM handler')
+
+# check to make sure we really call our shutdown function
+atexit.register(_shutdown_check)
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog