1
0
mirror of https://gitlab.com/fdroid/fdroidserver.git synced 2024-11-09 00:40:11 +01:00

Merge branch 'asynchronous_reader' into 'master'

Add asynchronous filereader, fix python3 lockups

with the current implementation of AsynchronousFileReader with Python 3 FDroidPopen deadlocks with 100% CPU-utilization

The code is from https://github.com/soxofaan/asynchronousfilereader

I hope the MIT-Licence makes no problems




See merge request !80
This commit is contained in:
Daniel Martí 2015-09-21 22:09:23 +00:00
commit 21bdd2941c
3 changed files with 67 additions and 28 deletions

View File

@ -0,0 +1,64 @@
"""
AsynchronousFileReader
======================
Simple thread based asynchronous file reader for Python.
see https://github.com/soxofaan/asynchronousfilereader
MIT License
Copyright (c) 2014 Stefaan Lippens
"""
__version__ = '0.2.1'
import threading
try:
# Python 2
from Queue import Queue
except ImportError:
# Python 3
from queue import Queue
class AsynchronousFileReader(threading.Thread):
"""
Helper class to implement asynchronous reading of a file
in a separate thread. Pushes read lines on a queue to
be consumed in another thread.
"""
def __init__(self, fd, queue=None, autostart=True):
self._fd = fd
if queue is None:
queue = Queue()
self.queue = queue
threading.Thread.__init__(self)
if autostart:
self.start()
def run(self):
"""
The body of the tread: read lines and put them on the queue.
"""
while True:
line = self._fd.readline()
if not line:
break
self.queue.put(line)
def eof(self):
"""
Check whether there is no more content to expect.
"""
return not self.is_alive() and self.queue.empty()
def readlines(self):
"""
Get currently available lines.
"""
while not self.queue.empty():
yield self.queue.get()

View File

@ -30,7 +30,6 @@ import subprocess
import time import time
import operator import operator
import Queue import Queue
import threading
import logging import logging
import hashlib import hashlib
import socket import socket
@ -40,6 +39,8 @@ from distutils.version import LooseVersion
from zipfile import ZipFile from zipfile import ZipFile
import metadata import metadata
from fdroidserver.asynchronousfilereader import AsynchronousFileReader
XMLElementTree.register_namespace('android', 'http://schemas.android.com/apk/res/android') XMLElementTree.register_namespace('android', 'http://schemas.android.com/apk/res/android')
@ -1547,31 +1548,6 @@ def isApkDebuggable(apkfile, config):
return False return False
class AsynchronousFileReader(threading.Thread):
'''
Helper class to implement asynchronous reading of a file
in a separate thread. Pushes read lines on a queue to
be consumed in another thread.
'''
def __init__(self, fd, queue):
assert isinstance(queue, Queue.Queue)
assert callable(fd.readline)
threading.Thread.__init__(self)
self._fd = fd
self._queue = queue
def run(self):
'''The body of the tread: read lines and put them on the queue.'''
for line in iter(self._fd.readline, ''):
self._queue.put(line)
def eof(self):
'''Check whether there is no more content to expect.'''
return not self.is_alive() and self._queue.empty()
class PopenResult: class PopenResult:
returncode = None returncode = None
output = '' output = ''
@ -1612,7 +1588,6 @@ def FDroidPopen(commands, cwd=None, output=True):
stdout_queue = Queue.Queue() stdout_queue = Queue.Queue()
stdout_reader = AsynchronousFileReader(p.stdout, stdout_queue) stdout_reader = AsynchronousFileReader(p.stdout, stdout_queue)
stdout_reader.start()
# Check the queue for output (until there is no more to get) # Check the queue for output (until there is no more to get)
while not stdout_reader.eof(): while not stdout_reader.eof():

View File

@ -16,7 +16,7 @@ setup(name='fdroidserver',
author='The F-Droid Project', author='The F-Droid Project',
author_email='team@f-droid.org', author_email='team@f-droid.org',
url='https://f-droid.org', url='https://f-droid.org',
packages=['fdroidserver'], packages=['fdroidserver', 'fdroidserver.asynchronousfilereader'],
scripts=['fdroid', 'fd-commit'], scripts=['fdroid', 'fd-commit'],
data_files=[ data_files=[
(data_prefix + '/share/doc/fdroidserver/examples', (data_prefix + '/share/doc/fdroidserver/examples',