Author: duncan
Date: Sun Feb 18 14:24:56 2007
New Revision: 9242
Modified:
branches/rel-1/freevo/src/childapp.py
branches/rel-1/freevo/src/helpers/recordserver.py
branches/rel-1/freevo/src/osd.py
branches/rel-1/freevo/src/plugins/rom_drives.py
branches/rel-1/freevo/src/rc.py
branches/rel-1/freevo/src/tv/channels.py
branches/rel-1/freevo/src/util/Rendezvous.py
branches/rel-1/freevo/src/util/popen3.py
Log:
Added a try finally block around all lock acquire lock release blocks.
This is a safety measure to ensure that there a no deadlocks caused by a
missing release
Modified: branches/rel-1/freevo/src/childapp.py
==============================================================================
--- branches/rel-1/freevo/src/childapp.py (original)
+++ branches/rel-1/freevo/src/childapp.py Sun Feb 18 14:24:56 2007
@@ -181,75 +181,76 @@
return
self.lock.acquire()
- # maybe child is dead and only waiting?
- if self.wait():
- _debug_('done the easy way', 2)
- self.child = None
- if not self.infile.closed:
- self.infile.close()
- self.lock.release()
- return
+ try:
+ # maybe child is dead and only waiting?
+ if self.wait():
+ _debug_('done the easy way', 2)
+ self.child = None
+ if not self.infile.closed:
+ self.infile.close()
+ return
- if signal:
- _debug_('childapp: killing pid %s signal %s' % (self.child.pid,
signal))
- try:
- os.kill(self.child.pid, signal)
- except OSError:
- pass
+ if signal:
+ _debug_('childapp: killing pid %s signal %s' %
(self.child.pid, signal))
+ try:
+ os.kill(self.child.pid, signal)
+ except OSError:
+ pass
- _debug_('childapp: Before wait(%s)' % self.child.pid)
- for i in range(60):
- if self.wait():
- break
- time.sleep(0.1)
- else:
- print 'force killing with signal 9'
- try:
- os.kill(self.child.pid, 9)
- except OSError:
- pass
- for i in range(20):
+ _debug_('childapp: Before wait(%s)' % self.child.pid)
+ for i in range(60):
if self.wait():
break
time.sleep(0.1)
- _debug_('childapp: After wait()')
+ else:
+ print 'force killing with signal 9'
+ try:
+ os.kill(self.child.pid, 9)
+ except OSError:
+ pass
+ for i in range(20):
+ if self.wait():
+ break
+ time.sleep(0.1)
+ _debug_('childapp: After wait()')
- # now check if the app is really dead. If it is, outfile
- # should be closed by the reading thread
- for i in range(5):
- if self.outfile.closed:
- break
- time.sleep(0.1)
- else:
- # Problem: the program had more than one thread, each thread has a
- # pid. We killed only a part of the program. The filehandles are
- # still open, the program still lives. If we try to close the
infile
- # now, Freevo will be dead.
- # Solution: there is no good one, let's try killall on the binary.
It's
- # ugly but it's the _only_ way to stop this nasty app
- print 'Oops, command refuses to die, try bad hack....'
- util.killall(self.binary, sig=15)
- for i in range(20):
+ # now check if the app is really dead. If it is, outfile
+ # should be closed by the reading thread
+ for i in range(5):
if self.outfile.closed:
break
time.sleep(0.1)
else:
- # still not dead. Puh, something is realy broekn here.
- # Try killall -9 as last chance
- print 'Try harder to kill the app....'
- util.killall(self.binary, sig=9)
+ # Problem: the program had more than one thread, each thread
has a
+ # pid. We killed only a part of the program. The filehandles
are
+ # still open, the program still lives. If we try to close the
infile
+ # now, Freevo will be dead.
+ # Solution: there is no good one, let's try killall on the
binary. It's
+ # ugly but it's the _only_ way to stop this nasty app
+ print 'Oops, command refuses to die, try bad hack....'
+ util.killall(self.binary, sig=15)
for i in range(20):
if self.outfile.closed:
break
time.sleep(0.1)
else:
- # Oops...
- print 'PANIC'
- if not self.infile.closed:
- self.infile.close()
- self.child = None
- self.lock.release()
+ # still not dead. Puh, something is realy broekn here.
+ # Try killall -9 as last chance
+ print 'Try harder to kill the app....'
+ util.killall(self.binary, sig=9)
+ for i in range(20):
+ if self.outfile.closed:
+ break
+ time.sleep(0.1)
+ else:
+ # Oops...
+ print 'PANIC'
+ if not self.infile.closed:
+ self.infile.close()
+ self.child = None
+ finally:
+ self.lock.release()
Modified: branches/rel-1/freevo/src/helpers/recordserver.py
==============================================================================
--- branches/rel-1/freevo/src/helpers/recordserver.py (original)
+++ branches/rel-1/freevo/src/helpers/recordserver.py Sun Feb 18 14:24:56 2007
@@ -1203,8 +1203,8 @@
def xmlrpc_isPlayerRunning(self):
(status, message) = (FALSE, 'RecordServer::isPlayerRunning: cannot
acquire lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
status = self.isPlayerRunning()
message = status and 'player is running' or 'player is not running'
finally:
@@ -1213,6 +1213,7 @@
def xmlrpc_isRecording(self):
(status, message) = (FALSE, 'RecordServer::isRecording: cannot acquire
lock')
+ self.lock.acquire()
try:
status = self.isRecording()
message = status and 'is recording' or 'is not recording'
@@ -1222,8 +1223,8 @@
def xmlrpc_findNextProgram(self):
(status, message) = (FALSE, 'RecordServer::findNextProgram: cannot
acquire lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
response = self.findNextProgram()
status = response != None
return (status, jellyToXML(response))
@@ -1233,8 +1234,8 @@
def xmlrpc_getScheduledRecordings(self):
(status, message) = (FALSE, 'RecordServer::getScheduledRecordings:
cannot acquire lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
return (TRUE, jellyToXML(self.getScheduledRecordings()))
finally:
self.lock.release()
@@ -1243,8 +1244,8 @@
def xmlrpc_saveScheduledRecordings(self, scheduledRecordings=None):
(status, message) = (FALSE, 'RecordServer::saveScheduledRecordings:
cannot acquire lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
status = self.saveScheduledRecordings(scheduledRecordings)
message = status and 'saveScheduledRecordings::success' or
'saveScheduledRecordings::failure'
finally:
@@ -1257,8 +1258,8 @@
return (FALSE, 'RecordServer::scheduleRecording: no prog')
(status, message) = (FALSE, 'RecordServer::scheduleRecording: cannot
acquire lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
prog = unjellyFromXML(prog)
(status, response) = self.scheduleRecording(prog)
message = 'RecordServer::scheduleRecording: %s' % response
@@ -1272,8 +1273,8 @@
return (FALSE, 'RecordServer::removeScheduledRecording: no prog')
(status, message) = (FALSE, 'RecordServer::removeScheduledRecording:
cannot acquire lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
prog = unjellyFromXML(prog)
(status, response) = self.removeScheduledRecording(prog)
message = 'RecordServer::removeScheduledRecording: %s' % response
@@ -1287,8 +1288,8 @@
return (FALSE, 'removeScheduledRecording::failure: no prog')
(status, message) = (FALSE, 'RecordServer::removeScheduledRecording:
cannot acquire lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
prog = unjellyFromXML(prog)
if schedule:
schedule = unjellyFromXML(schedule)
@@ -1301,8 +1302,8 @@
def xmlrpc_findProg(self, chan, start):
(status, message) = (FALSE, 'RecordServer::findProg: cannot acquire
lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
(status, response) = self.findProg(chan, start)
message = status and jellyToXML(response) or
('RecordServer::findProg: %s' % response)
finally:
@@ -1312,8 +1313,8 @@
def xmlrpc_findMatches(self, find, movies_only):
(status, message) = (FALSE, 'RecordServer::findMatches: cannot acquire
lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
(status, response) = self.findMatches(find, movies_only)
message = status and jellyToXML(response) or
('RecordServer::findMatches: %s' % response)
finally:
@@ -1323,8 +1324,8 @@
def xmlrpc_echotest(self, blah):
(status, message) = (FALSE, 'RecordServer::echotest: cannot acquire
lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
(status, message) = (TRUE, 'RecordServer::echotest: %s' % blah)
finally:
self.lock.release()
@@ -1333,8 +1334,8 @@
def xmlrpc_addFavorite(self, name, prog, exactchan=FALSE, exactdow=FALSE,
exacttod=FALSE):
(status, message) = (FALSE, 'RecordServer::addFavorite: cannot acquire
lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
prog = unjellyFromXML(prog)
(status, response) = self.addFavorite(name, prog, exactchan,
exactdow, exacttod)
message = 'RecordServer::addFavorite: %s' % response
@@ -1345,8 +1346,8 @@
def xmlrpc_addEditedFavorite(self, name, title, chan, dow, mod, priority,
allowDuplicates, onlyNew):
(status, message) = (FALSE, 'RecordServer::addEditedFavorite: cannot
acquire lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
(status, response) = self.addEditedFavorite(unjellyFromXML(name), \
unjellyFromXML(title), chan, dow, mod, priority, allowDuplicates,
onlyNew)
message = 'RecordServer::addEditedFavorite: %s' % response
@@ -1357,8 +1358,8 @@
def xmlrpc_removeFavorite(self, name=None):
(status, message) = (FALSE, 'RecordServer::removeFavorite: cannot
acquire lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
(status, response) = self.removeFavorite(name)
message = 'RecordServer::removeFavorite: %s' % response
finally:
@@ -1368,8 +1369,8 @@
def xmlrpc_clearFavorites(self):
(status, message) = (FALSE, 'RecordServer::clearFavorites: cannot
acquire lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
(status, response) = self.clearFavorites()
message = 'RecordServer::clearFavorites: %s' % response
finally:
@@ -1379,8 +1380,8 @@
def xmlrpc_getFavorites(self):
(status, message) = (FALSE, 'RecordServer::getFavorites: cannot
acquire lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
(status, message) = (TRUE,
jellyToXML(self.getScheduledRecordings().getFavorites()))
finally:
self.lock.release()
@@ -1389,8 +1390,8 @@
def xmlrpc_getFavorite(self, name):
(status, message) = (FALSE, 'RecordServer::getFavorite: cannot acquire
lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
(status, response) = self.getFavorite(name)
message = status and jellyToXML(response) or
'RecordServer::getFavorite: %s' % response
finally:
@@ -1400,8 +1401,8 @@
def xmlrpc_adjustPriority(self, favname, mod=0):
(status, message) = (FALSE, 'RecordServer::adjustPriority: cannot
acquire lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
(status, response) = self.adjustPriority(favname, mod)
message = 'RecordServer::adjustPriority: %s' % response
finally:
@@ -1411,8 +1412,8 @@
def xmlrpc_isProgAFavorite(self, prog, favs=None):
(status, message) = (FALSE, 'RecordServer::adjustPriority: cannot
acquire lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
prog = unjellyFromXML(prog)
if favs:
favs = unjellyFromXML(favs)
@@ -1425,8 +1426,8 @@
def xmlrpc_removeFavoriteFromSchedule(self, fav):
(status, message) = (FALSE, 'RecordServer::removeFavoriteFromSchedule:
cannot acquire lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
(status, response) = self.removeFavoriteFromSchedule(fav)
message = 'RecordServer::removeFavoriteFromSchedule: %s' % response
finally:
@@ -1436,8 +1437,8 @@
def xmlrpc_addFavoriteToSchedule(self, fav):
(status, message) = (FALSE, 'RecordServer::addFavoriteToSchedule:
cannot acquire lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
(status, response) = self.addFavoriteToSchedule(fav)
message = 'RecordServer::addFavoriteToSchedule: %s' % response
finally:
@@ -1447,8 +1448,8 @@
def xmlrpc_updateFavoritesSchedule(self):
(status, message) = (FALSE, 'updateFavoritesSchedule: cannot acquire
lock')
+ self.lock.acquire()
try:
- self.lock.acquire()
(status, response) = self.updateFavoritesSchedule()
message = 'RecordServer::updateFavoritesSchedule: %s' % response
finally:
Modified: branches/rel-1/freevo/src/osd.py
==============================================================================
--- branches/rel-1/freevo/src/osd.py (original)
+++ branches/rel-1/freevo/src/osd.py Sun Feb 18 14:24:56 2007
@@ -248,10 +248,12 @@
def wait(self, timer):
self.lock.acquire()
- self.active = True
- self.timer = timer
- self.mode_flag.set()
- self.lock.release()
+ try:
+ self.active = True
+ self.timer = timer
+ self.mode_flag.set()
+ finally:
+ self.lock.release()
def stop(self):
self.lock.acquire()
@@ -268,26 +270,28 @@
if self.active:
import skin
self.lock.acquire()
- osd = get_singleton()
- icon = skin.get_icon('misc/osd_busy')
- if icon:
- image = osd.loadbitmap(icon)
- width = image.get_width()
- height = image.get_height()
- x = osd.width - config.OSD_OVERSCAN_X - 20 - width
- y = osd.height - config.OSD_OVERSCAN_Y - 20 - height
-
- self.rect = (x,y,width,height)
- # backup the screen
- screen = pygame.Surface((width,height))
- screen.blit(osd.screen, (0,0), self.rect)
- # draw the icon
- osd.drawbitmap(image, x, y)
- osd.update(rect=self.rect, stop_busyicon=False)
-
- # restore the screen
- osd.screen.blit(screen, (x,y))
- self.lock.release()
+ try:
+ osd = get_singleton()
+ icon = skin.get_icon('misc/osd_busy')
+ if icon:
+ image = osd.loadbitmap(icon)
+ width = image.get_width()
+ height = image.get_height()
+ x = osd.width - config.OSD_OVERSCAN_X - 20 - width
+ y = osd.height - config.OSD_OVERSCAN_Y - 20 - height
+
+ self.rect = (x,y,width,height)
+ # backup the screen
+ screen = pygame.Surface((width,height))
+ screen.blit(osd.screen, (0,0), self.rect)
+ # draw the icon
+ osd.drawbitmap(image, x, y)
+ osd.update(rect=self.rect, stop_busyicon=False)
+
+ # restore the screen
+ osd.screen.blit(screen, (x,y))
+ finally:
+ self.lock.release()
while self.active:
time.sleep(0.01)
Modified: branches/rel-1/freevo/src/plugins/rom_drives.py
==============================================================================
--- branches/rel-1/freevo/src/plugins/rom_drives.py (original)
+++ branches/rel-1/freevo/src/plugins/rom_drives.py Sun Feb 18 14:24:56 2007
@@ -691,18 +691,20 @@
return
self.lock.acquire()
- for media in config.REMOVABLE_MEDIA:
- last_status = media.drive_status
- self.identify(media)
-
- if last_status != media.drive_status:
- _debug_('MEDIA: Status=%s' % media.drive_status,2)
- _debug_('Posting IDENTIFY_MEDIA event',2)
- if last_status == None:
- rc.post_event(plugin.event('IDENTIFY_MEDIA', arg=(media,
True)))
- else:
- rc.post_event(plugin.event('IDENTIFY_MEDIA', arg=(media,
False)))
- self.lock.release()
+ try:
+ for media in config.REMOVABLE_MEDIA:
+ last_status = media.drive_status
+ self.identify(media)
+
+ if last_status != media.drive_status:
+ _debug_('MEDIA: Status=%s' % media.drive_status,2)
+ _debug_('Posting IDENTIFY_MEDIA event',2)
+ if last_status == None:
+ rc.post_event(plugin.event('IDENTIFY_MEDIA',
arg=(media, True)))
+ else:
+ rc.post_event(plugin.event('IDENTIFY_MEDIA',
arg=(media, False)))
+ finally:
+ self.lock.release()
def __init__(self):
Modified: branches/rel-1/freevo/src/rc.py
==============================================================================
--- branches/rel-1/freevo/src/rc.py (original)
+++ branches/rel-1/freevo/src/rc.py Sun Feb 18 14:24:56 2007
@@ -511,11 +511,13 @@
add event to the queue
"""
self.lock.acquire()
- if not isinstance(e, Event):
- self.queue += [ Event(e, context=self.context) ]
- else:
- self.queue += [ e ]
- self.lock.release()
+ try:
+ if not isinstance(e, Event):
+ self.queue += [ Event(e, context=self.context) ]
+ else:
+ self.queue += [ e ]
+ finally:
+ self.lock.release()
if self.event_callback:
self.event_callback()
@@ -549,14 +551,16 @@
timer: timer * 0.01 seconds when to call the function
"""
self.lock.acquire()
- if timer == SHUTDOWN:
- _debug_('register shutdown callback: %s' % function, 2)
- self.shutdown_callbacks.append([ function, arg ])
- else:
- if repeat:
- _debug_('register callback: %s' % function, 2)
- self.callbacks.append([ function, repeat, timer, 0, arg ])
- self.lock.release()
+ try:
+ if timer == SHUTDOWN:
+ _debug_('register shutdown callback: %s' % function, 2)
+ self.shutdown_callbacks.append([ function, arg ])
+ else:
+ if repeat:
+ _debug_('register callback: %s' % function, 2)
+ self.callbacks.append([ function, repeat, timer, 0, arg ])
+ finally:
+ self.lock.release()
def unregister(self, function):
@@ -564,15 +568,17 @@
unregister an object from the main loop
"""
self.lock.acquire()
- for c in copy.copy(self.callbacks):
- if c[0] == function:
- _debug_('unregister callback: %s' % function, 2)
- self.callbacks.remove(c)
- for c in copy.copy(self.shutdown_callbacks):
- if c[0] == function:
- _debug_('unregister shutdown callback: %s' % function, 2)
- self.shutdown_callbacks.remove(c)
- self.lock.release()
+ try:
+ for c in copy.copy(self.callbacks):
+ if c[0] == function:
+ _debug_('unregister callback: %s' % function, 2)
+ self.callbacks.remove(c)
+ for c in copy.copy(self.shutdown_callbacks):
+ if c[0] == function:
+ _debug_('unregister shutdown callback: %s' % function, 2)
+ self.shutdown_callbacks.remove(c)
+ finally:
+ self.lock.release()
def suspend(self):
@@ -607,9 +613,11 @@
if not c[1]:
# remove if it is no repeat callback:
self.lock.acquire()
- if c in self.callbacks:
- self.callbacks.remove(c)
- self.lock.release()
+ try:
+ if c in self.callbacks:
+ self.callbacks.remove(c)
+ finally:
+ self.lock.release()
else:
# reset counter for next run
c[3] = 0
Modified: branches/rel-1/freevo/src/tv/channels.py
==============================================================================
--- branches/rel-1/freevo/src/tv/channels.py (original)
+++ branches/rel-1/freevo/src/tv/channels.py Sun Feb 18 14:24:56 2007
@@ -80,8 +80,8 @@
"""
Gets the VideoGroup object used by this Freevo channel.
"""
+ self.lock.acquire()
try:
- self.lock.acquire()
group = 0
for i in range(len(config.TV_CHANNELS)):
Modified: branches/rel-1/freevo/src/util/Rendezvous.py
==============================================================================
--- branches/rel-1/freevo/src/util/Rendezvous.py (original)
+++ branches/rel-1/freevo/src/util/Rendezvous.py Sun Feb 18 14:24:56 2007
@@ -796,8 +796,10 @@
# or addition of a socket
#
self.condition.acquire()
- self.condition.wait(self.timeout)
- self.condition.release()
+ try:
+ self.condition.wait(self.timeout)
+ finally:
+ self.condition.release()
else:
rr, wr, er = select.select(rs, [], [], self.timeout)
for socket in rr:
@@ -809,26 +811,34 @@
def getReaders(self):
result = []
self.condition.acquire()
- result = self.readers.keys()
- self.condition.release()
+ try:
+ result = self.readers.keys()
+ finally:
+ self.condition.release()
return result
def addReader(self, reader, socket):
self.condition.acquire()
- self.readers[socket] = reader
- self.condition.notify()
- self.condition.release()
+ try:
+ self.readers[socket] = reader
+ self.condition.notify()
+ finally:
+ self.condition.release()
def delReader(self, socket):
self.condition.acquire()
- del self.readers[socket]
- self.condition.notify()
- self.condition.release()
+ try:
+ del self.readers[socket]
+ self.condition.notify()
+ finally:
+ self.condition.release()
def notify(self):
self.condition.acquire()
- self.condition.notify()
- self.condition.release()
+ try:
+ self.condition.notify()
+ finally:
+ self.condition.release()
class Listener(object):
"""A Listener is used by this module to listen on the multicast
@@ -1205,14 +1215,18 @@
"""Calling thread waits for a given number of milliseconds or
until notified."""
self.condition.acquire()
- self.condition.wait(timeout/1000)
- self.condition.release()
+ try:
+ self.condition.wait(timeout/1000)
+ finally:
+ self.condition.release()
def notifyAll(self):
"""Notifies all waiting threads"""
self.condition.acquire()
- self.condition.notifyAll()
- self.condition.release()
+ try:
+ self.condition.notifyAll()
+ finally:
+ self.condition.release()
def getServiceInfo(self, type, name, timeout=3000):
"""Returns network's service information for a particular
Modified: branches/rel-1/freevo/src/util/popen3.py
==============================================================================
--- branches/rel-1/freevo/src/util/popen3.py (original)
+++ branches/rel-1/freevo/src/util/popen3.py Sun Feb 18 14:24:56 2007
@@ -112,8 +112,10 @@
if pid:
wait_lock.acquire()
- dead_childs.append(pid)
- wait_lock.release()
+ try:
+ dead_childs.append(pid)
+ finally:
+ wait_lock.release()
return
if config.IS_RECORDSERVER:
@@ -130,12 +132,14 @@
_debug_('poll', 2)
wait_lock.acquire()
- if pid in dead_childs:
- dead_childs.remove(pid)
+ try:
+ if pid in dead_childs:
+ dead_childs.remove(pid)
+ wait_lock.release()
+ return 1
+ return 0
+ finally:
wait_lock.release()
- return 1
- wait_lock.release()
- return 0
def stdout(app):
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog