[FIX] hw_scanner, hw_escpos: prevent driver threads from deadlocking when woken by two simultaneous requests

bzr revid: fva@openerp.com-20140206140524-ur51ghcpdzwxv1yr
This commit is contained in:
Frédéric van der Essen 2014-02-06 15:05:24 +01:00
parent 1e4d99eede
commit a9226e3d5b
2 changed files with 21 additions and 10 deletions

View File

@ -11,7 +11,7 @@ import math
import md5 import md5
import openerp.addons.hw_proxy.controllers.main as hw_proxy import openerp.addons.hw_proxy.controllers.main as hw_proxy
import subprocess import subprocess
from threading import Thread from threading import Thread, Lock
from Queue import Queue, Empty from Queue import Queue, Empty
try: try:
@ -39,6 +39,7 @@ class EscposDriver(Thread):
def __init__(self): def __init__(self):
Thread.__init__(self) Thread.__init__(self)
self.queue = Queue() self.queue = Queue()
self.lock = Lock()
self.status = {'status':'connecting', 'messages':[]} self.status = {'status':'connecting', 'messages':[]}
def connected_usb_devices(self): def connected_usb_devices(self):
@ -47,6 +48,12 @@ class EscposDriver(Thread):
if usb.core.find(idVendor=device['vendor'], idProduct=device['product']) != None: if usb.core.find(idVendor=device['vendor'], idProduct=device['product']) != None:
connected.append(device) connected.append(device)
return connected return connected
def lockedstart(self):
self.lock.acquire()
if not self.isAlive():
self.start()
self.lock.release()
def get_escpos_printer(self): def get_escpos_printer(self):
try: try:
@ -113,8 +120,7 @@ class EscposDriver(Thread):
_logger.error(e); _logger.error(e);
def push_task(self,task, data = None): def push_task(self,task, data = None):
if not self.isAlive(): self.lockedstart()
self.start()
self.queue.put((time.time(),task,data)) self.queue.put((time.time(),task,data))
def print_receipt_body(self,eprint,receipt): def print_receipt_body(self,eprint,receipt):

View File

@ -4,7 +4,7 @@ import os
import time import time
from os import listdir from os import listdir
from os.path import join from os.path import join
from threading import Thread from threading import Thread, Lock
from select import select from select import select
from Queue import Queue, Empty from Queue import Queue, Empty
@ -26,6 +26,7 @@ except ImportError:
class Scanner(Thread): class Scanner(Thread):
def __init__(self): def __init__(self):
Thread.__init__(self) Thread.__init__(self)
self.lock = Lock()
self.status = {'status':'connecting', 'messages':[]} self.status = {'status':'connecting', 'messages':[]}
self.input_dir = '/dev/input/by-id/' self.input_dir = '/dev/input/by-id/'
self.barcodes = Queue() self.barcodes = Queue()
@ -86,6 +87,12 @@ class Scanner(Thread):
57:(" "," "), 57:(" "," "),
} }
def lockedstart(self):
self.lock.acquire()
if not self.isAlive():
self.start()
self.lock.release()
def set_status(self, status, message = None): def set_status(self, status, message = None):
if status == self.status['status']: if status == self.status['status']:
if message != None and message != self.status['messages'][-1]: if message != None and message != self.status['messages'][-1]:
@ -102,8 +109,6 @@ class Scanner(Thread):
elif status == 'disconnected' and message: elif status == 'disconnected' and message:
_logger.warning('Disconnected Barcode Scanner: '+message) _logger.warning('Disconnected Barcode Scanner: '+message)
def get_device(self): def get_device(self):
try: try:
if not evdev: if not evdev:
@ -135,6 +140,8 @@ class Scanner(Thread):
busy reading another barcode busy reading another barcode
""" """
self.lockedstart()
while True: while True:
try: try:
timestamp, barcode = self.barcodes.get(True, 5) timestamp, barcode = self.barcodes.get(True, 5)
@ -144,8 +151,7 @@ class Scanner(Thread):
return '' return ''
def get_status(self): def get_status(self):
if not s.isAlive(): self.lockedstart()
s.start()
return self.status return self.status
def run(self): def run(self):
@ -209,7 +215,6 @@ hw_proxy.drivers['scanner'] = s
class ScannerDriver(hw_proxy.Proxy): class ScannerDriver(hw_proxy.Proxy):
@http.route('/hw_proxy/scanner', type='json', auth='none', cors='*') @http.route('/hw_proxy/scanner', type='json', auth='none', cors='*')
def scanner(self): def scanner(self):
if not s.isAlive():
s.start()
return s.get_barcode() return s.get_barcode()