Source code for rwlock.service
"""
Module **rwlock.service** has class ``Service``, which is the concrete
version of the read-write-lock service program.
"""
from sesf.rwlock.serviceparts import ServiceParts
from threading import Thread, Lock, Condition, get_ident
from time import sleep
from random import random
import argparse, Pyro4
from sesf.util.pyro import (start_pyrodaemon)
[docs]@Pyro4.expose
class Service():
"""
Read-write lock service (concrete version).
Should be accessed via RPC (Pyro4) for testing a rwlock user program.
Maintains the following variables:
- ``serviceparts`` (obj): read-write-lock serviceparts
- ``lck``, ``cond``: lock and condition variable for atomicity of
call and return parts.
- ``pyrodaemon``: Pyro4 daemon object for handling RPC calls
Functions (all have random delays):
- ``acqr()``: acquire a read lock; blocking.
- ``relr()``: release a read lock; nonblocking.
- ``acqw()``: acquire a write lock; blocking.
- ``relw()``: release a write lock; nonblocking.
"""
def __init__(self):
self.serviceparts = ServiceParts()
self.lck = Lock()
self.cond = Condition(self.lck)
# start pyrodaemon object and store reference in self.pyrodaemon
Thread(name='pyrodaemon', target=start_pyrodaemon,
args=(self, 'sesf.rwlock.service')).start()
def acqr(self):
print('acqr thread', get_ident())
x = self.serviceparts
## validate input
with self.cond:
if not x.acqr_CIC():
raise Exception('acqr CIC violated')
x.acqr_CU()
self.cond.notify_all()
sleep(random()*1)
## do output
with self.cond:
while not x.acqr_ROC():
self.cond.wait()
x.acqr_RU()
self.cond.notify_all()
def relr(self):
print('relr thread', get_ident())
x = self.serviceparts
## validate input
with self.cond:
if not x.relr_CIC():
raise Exception('relr CIC violated')
x.relr_CU()
self.cond.notify_all()
sleep(random()*1)
## do output
with self.cond:
while not x.relr_ROC():
self.cond.wait()
x.relr_RU()
self.cond.notify_all()
def acqw(self):
print('acqw thread', get_ident())
x = self.serviceparts
## validate input
with self.cond:
if not x.acqw_CIC():
raise Exception('acqw CIC violated')
x.acqw_CU()
self.cond.notify_all()
sleep(random()*1)
## do output
with self.cond:
while not x.acqw_ROC():
self.cond.wait()
x.acqw_RU()
self.cond.notify_all()
def relw(self):
print('relw thread', get_ident())
x = self.serviceparts
## validate input
with self.cond:
if not x.relw_CIC():
raise Exception('relw CIC violated')
x.relw_CU()
self.cond.notify_all()
sleep(random()*1)
## do output
with self.cond:
while not x.relw_ROC():
self.cond.wait()
x.relw_RU()
self.cond.notify_all()
def __end__(self):
self.pyrodaemon.shutdown()
### end class Service #################################
if __name__ == '__main__':
print("starting sesf.rwlock.service", flush=True)
service = Service()