Whitespace normalization.

This commit is contained in:
Tim Peters 2001-01-21 07:07:30 +00:00
parent dfc538acae
commit 172c40b20a
3 changed files with 180 additions and 180 deletions

View file

@ -1,12 +1,12 @@
# The following self-contained little program usually freezes with most # The following self-contained little program usually freezes with most
# threads reporting # threads reporting
# #
# Unhandled exception in thread: # Unhandled exception in thread:
# Traceback (innermost last): # Traceback (innermost last):
# File "importbug.py", line 6 # File "importbug.py", line 6
# x = whrandom.randint(1,3) # x = whrandom.randint(1,3)
# AttributeError: randint # AttributeError: randint
# #
# Here's the program; it doesn't use anything from the attached module: # Here's the program; it doesn't use anything from the attached module:
import thread import thread
@ -33,37 +33,37 @@ print 'done'
# Sticking an acquire/release pair around the 'import' statement makes the # Sticking an acquire/release pair around the 'import' statement makes the
# problem go away. # problem go away.
# #
# I believe that what happens is: # I believe that what happens is:
# #
# 1) The first thread to hit the import atomically reaches, and executes # 1) The first thread to hit the import atomically reaches, and executes
# most of, get_module. In particular, it finds Lib/whrandom.pyc, # most of, get_module. In particular, it finds Lib/whrandom.pyc,
# installs its name in sys.modules, and executes # installs its name in sys.modules, and executes
# #
# v = eval_code(co, d, d, d, (object *)NULL); # v = eval_code(co, d, d, d, (object *)NULL);
# #
# to initialize the module. # to initialize the module.
# #
# 2) eval_code "ticker"-slices the 1st thread out, and gives another thread # 2) eval_code "ticker"-slices the 1st thread out, and gives another thread
# a chance. When this 2nd thread hits the same 'import', import_module # a chance. When this 2nd thread hits the same 'import', import_module
# finds 'whrandom' in sys.modules, so just proceeds. # finds 'whrandom' in sys.modules, so just proceeds.
# #
# 3) But the 1st thread is still "in the middle" of executing whrandom.pyc. # 3) But the 1st thread is still "in the middle" of executing whrandom.pyc.
# So the 2nd thread has a good chance of trying to look up 'randint' # So the 2nd thread has a good chance of trying to look up 'randint'
# before the 1st thread has placed it in whrandom's dict. # before the 1st thread has placed it in whrandom's dict.
# #
# 4) The more threads there are, the more likely that at least one of them # 4) The more threads there are, the more likely that at least one of them
# will do this before the 1st thread finishes the import work. # will do this before the 1st thread finishes the import work.
# #
# If that's right, a perhaps not-too-bad workaround would be to introduce a # If that's right, a perhaps not-too-bad workaround would be to introduce a
# static "you can't interrupt this thread" flag in ceval.c, check it before # static "you can't interrupt this thread" flag in ceval.c, check it before
# giving up interpreter_lock, and have IMPORT_NAME set it & restore (plain # giving up interpreter_lock, and have IMPORT_NAME set it & restore (plain
# clearing would not work) it around its call to import_module. To its # clearing would not work) it around its call to import_module. To its
# credit, there's something wonderfully perverse about fixing a race via an # credit, there's something wonderfully perverse about fixing a race via an
# unprotected static <grin>. # unprotected static <grin>.
# #
# as-with-most-other-things-(pseudo-)parallel-programming's-more-fun- # as-with-most-other-things-(pseudo-)parallel-programming's-more-fun-
# in-python-too!-ly y'rs - tim # in-python-too!-ly y'rs - tim
# #
# Tim Peters tim@ksr.com # Tim Peters tim@ksr.com
# not speaking for Kendall Square Research Corp # not speaking for Kendall Square Research Corp

View file

@ -32,121 +32,121 @@ import thread
class WorkQ: class WorkQ:
# Invariants: # Invariants:
# - busy and work are only modified when mutex is locked # - busy and work are only modified when mutex is locked
# - len(work) is the number of jobs ready to be taken # - len(work) is the number of jobs ready to be taken
# - busy is the number of jobs being done # - busy is the number of jobs being done
# - todo is locked iff there is no work and somebody is busy # - todo is locked iff there is no work and somebody is busy
def __init__(self): def __init__(self):
self.mutex = thread.allocate() self.mutex = thread.allocate()
self.todo = thread.allocate() self.todo = thread.allocate()
self.todo.acquire() self.todo.acquire()
self.work = [] self.work = []
self.busy = 0 self.busy = 0
def addwork(self, func, args): def addwork(self, func, args):
job = (func, args) job = (func, args)
self.mutex.acquire() self.mutex.acquire()
self.work.append(job) self.work.append(job)
self.mutex.release() self.mutex.release()
if len(self.work) == 1: if len(self.work) == 1:
self.todo.release() self.todo.release()
def _getwork(self): def _getwork(self):
self.todo.acquire() self.todo.acquire()
self.mutex.acquire() self.mutex.acquire()
if self.busy == 0 and len(self.work) == 0: if self.busy == 0 and len(self.work) == 0:
self.mutex.release() self.mutex.release()
self.todo.release() self.todo.release()
return None return None
job = self.work[0] job = self.work[0]
del self.work[0] del self.work[0]
self.busy = self.busy + 1 self.busy = self.busy + 1
self.mutex.release() self.mutex.release()
if len(self.work) > 0: if len(self.work) > 0:
self.todo.release() self.todo.release()
return job return job
def _donework(self): def _donework(self):
self.mutex.acquire() self.mutex.acquire()
self.busy = self.busy - 1 self.busy = self.busy - 1
if self.busy == 0 and len(self.work) == 0: if self.busy == 0 and len(self.work) == 0:
self.todo.release() self.todo.release()
self.mutex.release() self.mutex.release()
def _worker(self): def _worker(self):
time.sleep(0.00001) # Let other threads run time.sleep(0.00001) # Let other threads run
while 1: while 1:
job = self._getwork() job = self._getwork()
if not job: if not job:
break break
func, args = job func, args = job
apply(func, args) apply(func, args)
self._donework() self._donework()
def run(self, nworkers): def run(self, nworkers):
if not self.work: if not self.work:
return # Nothing to do return # Nothing to do
for i in range(nworkers-1): for i in range(nworkers-1):
thread.start_new(self._worker, ()) thread.start_new(self._worker, ())
self._worker() self._worker()
self.todo.acquire() self.todo.acquire()
# Main program # Main program
def main(): def main():
sys.argv.append("/tmp") sys.argv.append("/tmp")
nworkers = 4 nworkers = 4
opts, args = getopt.getopt(sys.argv[1:], '-w:') opts, args = getopt.getopt(sys.argv[1:], '-w:')
for opt, arg in opts: for opt, arg in opts:
if opt == '-w': if opt == '-w':
nworkers = string.atoi(arg) nworkers = string.atoi(arg)
if not args: if not args:
args = [os.curdir] args = [os.curdir]
wq = WorkQ() wq = WorkQ()
for dir in args: for dir in args:
wq.addwork(find, (dir, selector, wq)) wq.addwork(find, (dir, selector, wq))
t1 = time.time() t1 = time.time()
wq.run(nworkers) wq.run(nworkers)
t2 = time.time() t2 = time.time()
sys.stderr.write('Total time ' + `t2-t1` + ' sec.\n') sys.stderr.write('Total time ' + `t2-t1` + ' sec.\n')
# The predicate -- defines what files we look for. # The predicate -- defines what files we look for.
# Feel free to change this to suit your purpose # Feel free to change this to suit your purpose
def selector(dir, name, fullname, stat): def selector(dir, name, fullname, stat):
# Look for group or world writable files # Look for group or world writable files
return (stat[ST_MODE] & 0022) != 0 return (stat[ST_MODE] & 0022) != 0
# The find procedure -- calls wq.addwork() for subdirectories # The find procedure -- calls wq.addwork() for subdirectories
def find(dir, pred, wq): def find(dir, pred, wq):
try: try:
names = os.listdir(dir) names = os.listdir(dir)
except os.error, msg: except os.error, msg:
print `dir`, ':', msg print `dir`, ':', msg
return return
for name in names: for name in names:
if name not in (os.curdir, os.pardir): if name not in (os.curdir, os.pardir):
fullname = os.path.join(dir, name) fullname = os.path.join(dir, name)
try: try:
stat = os.lstat(fullname) stat = os.lstat(fullname)
except os.error, msg: except os.error, msg:
print `fullname`, ':', msg print `fullname`, ':', msg
continue continue
if pred(dir, name, fullname, stat): if pred(dir, name, fullname, stat):
print fullname print fullname
if S_ISDIR(stat[ST_MODE]): if S_ISDIR(stat[ST_MODE]):
if not os.path.ismount(fullname): if not os.path.ismount(fullname):
wq.addwork(find, (fullname, pred, wq)) wq.addwork(find, (fullname, pred, wq))
# Call the main program # Call the main program

View file

@ -21,94 +21,94 @@ BUFSIZE = 8*1024
# Telnet protocol characters # Telnet protocol characters
IAC = chr(255) # Interpret as command IAC = chr(255) # Interpret as command
DONT = chr(254) DONT = chr(254)
DO = chr(253) DO = chr(253)
WONT = chr(252) WONT = chr(252)
WILL = chr(251) WILL = chr(251)
def main(): def main():
if len(sys.argv) < 2: if len(sys.argv) < 2:
sys.stderr.write('usage: telnet hostname [port]\n') sys.stderr.write('usage: telnet hostname [port]\n')
sys.exit(2) sys.exit(2)
host = sys.argv[1] host = sys.argv[1]
try: try:
hostaddr = gethostbyname(host) hostaddr = gethostbyname(host)
except error: except error:
sys.stderr.write(sys.argv[1] + ': bad host name\n') sys.stderr.write(sys.argv[1] + ': bad host name\n')
sys.exit(2) sys.exit(2)
# #
if len(sys.argv) > 2: if len(sys.argv) > 2:
servname = sys.argv[2] servname = sys.argv[2]
else: else:
servname = 'telnet' servname = 'telnet'
# #
if '0' <= servname[:1] <= '9': if '0' <= servname[:1] <= '9':
port = eval(servname) port = eval(servname)
else: else:
try: try:
port = getservbyname(servname, 'tcp') port = getservbyname(servname, 'tcp')
except error: except error:
sys.stderr.write(servname + ': bad tcp service name\n') sys.stderr.write(servname + ': bad tcp service name\n')
sys.exit(2) sys.exit(2)
# #
s = socket(AF_INET, SOCK_STREAM) s = socket(AF_INET, SOCK_STREAM)
# #
try: try:
s.connect((host, port)) s.connect((host, port))
except error, msg: except error, msg:
sys.stderr.write('connect failed: ' + `msg` + '\n') sys.stderr.write('connect failed: ' + `msg` + '\n')
sys.exit(1) sys.exit(1)
# #
thread.start_new(child, (s,)) thread.start_new(child, (s,))
parent(s) parent(s)
def parent(s): def parent(s):
# read socket, write stdout # read socket, write stdout
iac = 0 # Interpret next char as command iac = 0 # Interpret next char as command
opt = '' # Interpret next char as option opt = '' # Interpret next char as option
while 1: while 1:
data, dummy = s.recvfrom(BUFSIZE) data, dummy = s.recvfrom(BUFSIZE)
if not data: if not data:
# EOF -- exit # EOF -- exit
sys.stderr.write( '(Closed by remote host)\n') sys.stderr.write( '(Closed by remote host)\n')
sys.exit(1) sys.exit(1)
cleandata = '' cleandata = ''
for c in data: for c in data:
if opt: if opt:
print ord(c) print ord(c)
## print '(replying: ' + `opt+c` + ')' ## print '(replying: ' + `opt+c` + ')'
s.send(opt + c) s.send(opt + c)
opt = '' opt = ''
elif iac: elif iac:
iac = 0 iac = 0
if c == IAC: if c == IAC:
cleandata = cleandata + c cleandata = cleandata + c
elif c in (DO, DONT): elif c in (DO, DONT):
if c == DO: print '(DO)', if c == DO: print '(DO)',
else: print '(DONT)', else: print '(DONT)',
opt = IAC + WONT opt = IAC + WONT
elif c in (WILL, WONT): elif c in (WILL, WONT):
if c == WILL: print '(WILL)', if c == WILL: print '(WILL)',
else: print '(WONT)', else: print '(WONT)',
opt = IAC + DONT opt = IAC + DONT
else: else:
print '(command)', ord(c) print '(command)', ord(c)
elif c == IAC: elif c == IAC:
iac = 1 iac = 1
print '(IAC)', print '(IAC)',
else: else:
cleandata = cleandata + c cleandata = cleandata + c
sys.stdout.write(cleandata) sys.stdout.write(cleandata)
sys.stdout.flush() sys.stdout.flush()
## print 'Out:', `cleandata` ## print 'Out:', `cleandata`
def child(s): def child(s):
# read stdin, write socket # read stdin, write socket
while 1: while 1:
line = sys.stdin.readline() line = sys.stdin.readline()
## print 'Got:', `line` ## print 'Got:', `line`
if not line: break if not line: break
s.send(line) s.send(line)
main() main()