Killing a thread

catlee at my-deja.com catlee at my-deja.com
Mon Jul 19 17:13:39 EDT 1999


In article <ePJk3.4$Z11.6082 at news-dal.corridex.com>,
  "Evan Simpson" <evan at tokenexchange.com> wrote:
> This makes me wonder; Zope has a similar problem, which it mostly
handles
> with severe restrictions on what's available to the user (no 'while',
only
> 'for', and no '[x]range' to generate arbitrarily large tuples).
> Nevertheless, a creative malcontent could consume a lot of resources
with
> nested loops.
>
> Bytecodehacks to the rescue?  <waves hands furiously> Wrap the user
code in
> a function (if it isn't already), find all jump-back codes, and
insert a bit
> of test code in front of them which bails out if ?a global variable
is set?
> (not sure what's best, here).  You'll take a slight performance hit,
but
> that probably won't matter in this context.  Perhaps you could inline
a call
> to time.clock and use it to limit the running time of the function.

It looks like it is bytecodebacks to the rescue!  I've never used the
bytecodehacks module before, but WOW!  This has so many uses!  Here's
some code I whipped up in 15 minutes that handles the "while 1: 1+1"
problem:
from bytecodehacks.ops import *
from bytecodehacks.code_editor import *
from threading import Thread
from rexec import RExec
import time,thread

class thing(Thread):
	def __init__(self):
		Thread.__init__(self)
		self.done_flag=0

	def run(self):
		self.renv=RExec()
		self.source="while 1: 1+1"
		self.code=compile(self.source,'<string>','exec')
		self.fix_code()
		self.renv.r_exec(self.code)

	def fix_code(self):
		co=EditableCode(self.code)
		pos=0
		while pos < len(co.co_code):
			if co.co_code[pos].is_jump():
				op=LOAD_NAME("quit_if_done")
				co.co_code.insert(pos,op)
				op=CALL_FUNCTION(0)
				pos=pos+1
				co.co_code.insert(pos,op)
				pos=pos+1
			pos=pos+1
		self.code=co.make_code()
		self.renv.modules['__main__'].__dict__['quit_if_done']
=self.quit_if_done

	def stop(self):
		self.done_flag=1

	def quit_if_done(self):
		if self.done_flag==1:
			thread.exit()

t=thing()
t.start()
time.sleep(1)
t.stop()
t.join()

Now, some things I'm not sure about:
- Everything SHOULD be cleaned up correctly since the thread exited
itself, it wasn't killed forcibly
- Is it conceivable that a user could make write some resource
intensive code without using any kind of jump operations?  I don't
think so, unless s/he writes out a 200 megabytes file, but that's easy
enough to limit.
- Can the user somehow overwrite the quit_if_done function?

Cheers,
Chris


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




More information about the Python-list mailing list