def execute_namespace_until_completion(thisnamespace, thiscontext): # I'll use this to detect when the program is idle so I know when to quit... idlethreadcount = threading.activeCount() # add my thread to the set of threads that are used... event_id = idhelper.getuniqueid() try: nanny.tattle_add_item('events', event_id) except Exception as e: tracebackrepy.handle_internalerror("Failed to acquire event for '" + \ "initialize' event.\n(Exception was: %s)" % e.message, 140) try: thisnamespace.evaluate(thiscontext) except SystemExit: raise except: # I think it makes sense to exit if their code throws an exception... tracebackrepy.handle_exception() harshexit.harshexit(6) finally: nanny.tattle_remove_item('events', event_id) # I've changed to the threading library, so this should increase if there are # pending events while threading.activeCount() > idlethreadcount: # do accounting here? time.sleep(0.25) # Once there are no more events, return... return
def wrapped_func(): try: function() except: # Exit if they throw an uncaught exception tracebackrepy.handle_exception() harshexit.harshexit(30) finally: # Remove the event before I exit nanny.tattle_remove_item('events',eventhandle)
def wrapped_func(): try: function() except: # Exit if they throw an uncaught exception tracebackrepy.handle_exception() harshexit.harshexit(30) finally: # Remove the event before I exit nanny.tattle_remove_item('events', eventhandle)
def finalize(): global idlethreadcount, event_id nanny.tattle_remove_item('events', event_id) # I've changed to the threading library, so this should increase if there are # pending events while threading.activeCount() > idlethreadcount: # do accounting here? time.sleep(0.25) # Once there are no more pending events for the user thread, we exit harshexit.harshexit(0)
def __init__(self, filename, create): """ This is an internal initializer. See emulated_open for details. """ # Initialize the fields, otherwise __del__ gets confused # when we throw an exception. This was not a problem when the # logic was in emulated_open, since we would never throw an # exception self.filename = filename self.fobj = None self.seek_lock = threading.Lock() self.filesize = 0 # raise an RepyArgumentError if the filename isn't valid _assert_is_allowed_filename(filename) # Check the type of create if type(create) is not bool: raise RepyArgumentError( "Create argument type is invalid! Must be a Boolean!") OPEN_FILES_LOCK.acquire() try: # I am not checking whether this file is already opened, I will allow two fd's # on the same file. This behaviour is normal with python in windows and linux. # Here is where we try to allocate a "file" resource from the # nanny system. We will restore this below if there is an exception # This may raise a ResourceExhautedError nanny.tattle_add_item('filesopened', self.filename) # When a file is opened in "r+", it will only succeed if the file already exists # this will work when create is set to False, I catch the exception and raise RepyError # this avoids the need to explicitly check with the create flag. # Store a file handle. try: self.fobj = safe_open(self.filename, "w+b" if create else "r+b") except IOError: raise FileNotFoundError('Cannot openfile non-existent file "' + filename + '" without creating it!') # I am not sure what will cause this exception, I will leave it for now, this won't have # any performance impact. except RepyException: # Restore the file handle we tattled nanny.tattle_remove_item('filesopened', self.filename) raise finally: OPEN_FILES_LOCK.release()
def __init__(self, filename, create): """ This is an internal initializer. See emulated_open for details. """ # Initialize the fields, otherwise __del__ gets confused # when we throw an exception. This was not a problem when the # logic was in emulated_open, since we would never throw an # exception self.filename = filename self.fobj = None self.seek_lock = threading.Lock() self.filesize = 0 # raise an RepyArgumentError if the filename isn't valid _assert_is_allowed_filename(filename) # Check the type of create if type(create) is not bool: raise RepyArgumentError("Create argument type is invalid! Must be a Boolean!") OPEN_FILES_LOCK.acquire() try: # I am not checking whether this file is already opened, I will allow two fd's # on the same file. This behaviour is normal with python in windows and linux. # Here is where we try to allocate a "file" resource from the # nanny system. We will restore this below if there is an exception # This may raise a ResourceExhautedError nanny.tattle_add_item('filesopened', self.filename) # When a file is opened in "r+", it will only succeed if the file already exists # this will work when create is set to False, I catch the exception and raise RepyError # this avoids the need to explicitly check with the create flag. # Store a file handle. try: self.fobj = safe_open(self.filename, "w+b" if create else "r+b") except IOError: raise FileNotFoundError('Cannot openfile non-existent file "'+filename+'" without creating it!') # I am not sure what will cause this exception, I will leave it for now, this won't have # any performance impact. except RepyException: # Restore the file handle we tattled nanny.tattle_remove_item('filesopened', self.filename) raise finally: OPEN_FILES_LOCK.release()
def __del__(self): myfilehandle = self.filehandle # Tell nanny we're gone. nanny.tattle_remove_item('filesopened', myfilehandle) # Take the fileinfo dict lock, delete ourselves, and unlock. fileinfolock.acquire() try: del fileinfo[myfilehandle]['fobj'] del fileinfo[myfilehandle] except KeyError: pass finally: fileinfolock.release()
def __del__(self): myfilehandle = self.filehandle # Tell nanny we're gone. nanny.tattle_remove_item("filesopened", myfilehandle) # Take the fileinfo dict lock, delete ourselves, and unlock. fileinfolock.acquire() try: del fileinfo[myfilehandle]["fobj"] del fileinfo[myfilehandle] except KeyError: pass finally: fileinfolock.release()
def close(self): """ <Purpose> Allows the user program to close the handle to the file. <Arguments> None. <Exceptions> FileClosedError is raised if the file is already closed. <Resource Consumption> Releases a file handle. <Returns> None. """ # Acquire the lock to the set OPEN_FILES_LOCK.acquire() # Tell nanny we're gone. nanny.tattle_remove_item('filesopened', self.abs_filename) # Acquire the seek lock self.seek_lock.acquire() try: # Release the file object fobj = self.fobj if fobj is not None: fobj.close() self.fobj = None else: raise FileClosedError("File '" + str(self.filename) + "' is already closed!") # Remove this file from the list of open files OPEN_FILES.remove(self.filename) finally: # Release the two locks we hold self.seek_lock.release() OPEN_FILES_LOCK.release()
def canceltimer(timerhandle): """ <Purpose> Cancels a timer. <Arguments> timerhandle: The handle of the timer that should be stopped. Handles are returned by settimer <Exceptions> None. <Side Effects> None. <Returns> If False is returned, the timer already fired or was cancelled previously. If True is returned, the timer was cancelled """ restrictions.assertisallowed('canceltimer') # Armon: Check that the given handle is valid if not is_valid_eventhandle(timerhandle): raise Exception("Invalid timer handle specified!") try: timerinfo[timerhandle]['timer'].cancel() except KeyError: # The timer already fired (or was cancelled) return False try: del timerinfo[timerhandle] except KeyError: # The timer just fired (or was cancelled) return False else: # I was able to delete the entry, the function will abort. I can remove # the event nanny.tattle_remove_item('events', timerhandle) return True
def close(self): """ <Purpose> Allows the user program to close the handle to the file. <Arguments> None. <Exceptions> FileClosedError is raised if the file is already closed. <Resource Consumption> Releases a file handle. <Returns> None. """ # Acquire the lock to the set OPEN_FILES_LOCK.acquire() # Tell nanny we're gone. nanny.tattle_remove_item('filesopened', self.abs_filename) # Acquire the seek lock self.seek_lock.acquire() try: # Release the file object fobj = self.fobj if fobj is not None: fobj.close() self.fobj = None else: raise FileClosedError("File '"+str(self.filename)+"' is already closed!") # Remove this file from the list of open files OPEN_FILES.remove(self.filename) finally: # Release the two locks we hold self.seek_lock.release() OPEN_FILES_LOCK.release()
def canceltimer(timerhandle): """ <Purpose> Cancels a timer. <Arguments> timerhandle: The handle of the timer that should be stopped. Handles are returned by settimer <Exceptions> None. <Side Effects> None. <Returns> If False is returned, the timer already fired or was cancelled previously. If True is returned, the timer was cancelled """ restrictions.assertisallowed('canceltimer') # Armon: Check that the given handle is valid if not is_valid_eventhandle(timerhandle): raise Exception("Invalid timer handle specified!") try: timerinfo[timerhandle]['timer'].cancel() except KeyError: # The timer already fired (or was cancelled) return False try: del timerinfo[timerhandle] except KeyError: # The timer just fired (or was cancelled) return False else: # I was able to delete the entry, the function will abort. I can remove # the event nanny.tattle_remove_item('events',timerhandle) return True
def functionwrapper(func, timerhandle, args): #restrictions ? # call the function with the arguments try: if timerhandle in timerinfo: del timerinfo[timerhandle] else: # I've been "stopped" by canceltimer return except KeyError: # I've been "stopped" by canceltimer return try: func(*args) except: # Exit if they throw an uncaught exception tracebackrepy.handle_exception() harshexit.harshexit(30) # remove the event before I exit nanny.tattle_remove_item('events',timerhandle)
def functionwrapper(func, timerhandle, args): #restrictions ? # call the function with the arguments try: if timerhandle in timerinfo: del timerinfo[timerhandle] else: # I've been "stopped" by canceltimer return except KeyError: # I've been "stopped" by canceltimer return try: func(*args) except: # Exit if they throw an uncaught exception tracebackrepy.handle_exception() harshexit.harshexit(30) # remove the event before I exit nanny.tattle_remove_item('events', timerhandle)
def close(self): # prevent TOCTOU race with client changing my filehandle myfilehandle = self.filehandle restrictions.assertisallowed('file.close') # Ignore multiple closes (as file does) if myfilehandle not in fileinfo: return nanny.tattle_remove_item('filesopened',myfilehandle) fileinfolock.acquire() try: returnvalue = fileinfo[myfilehandle]['fobj'].close() # delete the filehandle del fileinfo[myfilehandle] finally: fileinfolock.release() return returnvalue
def close(self): """ <Purpose> Allows the user program to close the handle to the file. <Arguments> None. <Exceptions> FileClosedError is raised if the file is already closed. <Resource Consumption> Releases a file handle. <Returns> None. """ # Acquire the lock to the set OPEN_FILES_LOCK.acquire() # Tell nanny we're gone. nanny.tattle_remove_item('filesopened', self.filename) try: # Once again, don't explicitly check if the file handle is valid or not # allow python to generate an exception and we will catch it. # Also, close can be called multiple times on the same file handle. This # behaviour is normal with python in linux and windows. # Release the file object self.fobj.close() except AttributeError: raise FileClosedError("File '" + str(self.filename) + "' is already closed!") finally: # Release the two locks we hold OPEN_FILES_LOCK.release()
def close(self): # prevent TOCTOU race with client changing my filehandle myfilehandle = self.filehandle restrictions.assertisallowed("file.close") # Ignore multiple closes (as file does) if myfilehandle not in fileinfo: return nanny.tattle_remove_item("filesopened", myfilehandle) fileinfolock.acquire() try: returnvalue = fileinfo[myfilehandle]["fobj"].close() # delete the filehandle del fileinfo[myfilehandle] finally: fileinfolock.release() return returnvalue
def close(self): """ <Purpose> Allows the user program to close the handle to the file. <Arguments> None. <Exceptions> FileClosedError is raised if the file is already closed. <Resource Consumption> Releases a file handle. <Returns> None. """ # Acquire the lock to the set OPEN_FILES_LOCK.acquire() # Tell nanny we're gone. nanny.tattle_remove_item('filesopened', self.filename) try: # Once again, don't explicitly check if the file handle is valid or not # allow python to generate an exception and we will catch it. # Also, close can be called multiple times on the same file handle. This # behaviour is normal with python in linux and windows. # Release the file object self.fobj.close() except AttributeError: raise FileClosedError("File '"+str(self.filename)+"' is already closed!") finally: # Release the two locks we hold OPEN_FILES_LOCK.release()
if profile: p = cProfile.Profile() p.runctx('main_namespace.evaluate(usercontext)', globals(), locals(),) p = pstats.Stats(p) # p.sort_stats('cumulative') p.print_stats() else: main_namespace.evaluate(usercontext) except SystemExit: raise except: # I think it makes sense to exit if their code throws an exception... tracebackrepy.handle_exception() harshexit.harshexit(6) finally: nanny.tattle_remove_item('events', event_id) # I've changed to the threading library, so this should increase if there are # pending events while threading.activeCount() > idlethreadcount: # do accounting here? time.sleep(0.25) # Once there are no more pending events for the user thread, we exit harshexit.harshexit(0) def usage(str_err=""): # Ivan 12/24/2008 """
try: nanny.tattle_add_item('events', initialize_id) except Exception, e: tracebackrepy.handle_internalerror("Failed to aquire event for '" + \ "initialize' event.\n(Exception was: %s)" % e.message, 140) try: main_namespace.evaluate(usercontext) except SystemExit: raise except: # I think it makes sense to exit if their code throws an exception... tracebackrepy.handle_exception() harshexit.harshexit(6) finally: nanny.tattle_remove_item('events', initialize_id) # I've changed to the threading library, so this should increase if there are # pending events while threading.activeCount() > idlethreadcount: # do accounting here? time.sleep(0.25) # Once there are no more pending events for the user thread, we give them # an "exit" event. This allows them to clean up, etc. if needed. # call the user program to notify them that we are exiting... usercontext['callfunc'] = 'exit'
nanny.tattle_add_item("events", event_id) except Exception, e: tracebackrepy.handle_internalerror( "Failed to acquire event for '" + "initialize' event.\n(Exception was: %s)" % e.message, 140 ) try: thisnamespace.evaluate(thiscontext) except SystemExit: raise except: # I think it makes sense to exit if their code throws an exception... tracebackrepy.handle_exception() harshexit.harshexit(6) finally: nanny.tattle_remove_item("events", event_id) # I've changed to the threading library, so this should increase if there are # pending events while threading.activeCount() > idlethreadcount: # do accounting here? time.sleep(0.25) # Once there are no more events, return... return def init_repy_location(repy_directory): # Translate into an absolute path if os.path.isabs(repy_directory):
def __init__(self, filename, create): """ This is an internal initializer. See emulated_open for details. """ # Initialize the fields, otherwise __del__ gets confused # when we throw an exception. This was not a problem when the # logic was in emulated_open, since we would never throw an # exception self.filename = filename self.abs_filename = None self.fobj = None self.seek_lock = threading.Lock() self.filesize = 0 # raise an RepyArgumentError if the filename isn't valid _assert_is_allowed_filename(filename) # Check the type of create if type(create) is not bool: raise RepyArgumentError("Create argument type is invalid! Must be a Boolean!") OPEN_FILES_LOCK.acquire() try: # Check if the file is in use if filename in OPEN_FILES: raise FileInUseError('Cannot open file "'+filename+'" because it is already open!') # Get the absolute file name self.abs_filename = os.path.abspath(os.path.join(repy_constants.REPY_CURRENT_DIR, filename)) # Here is where we try to allocate a "file" resource from the # nanny system. We will restore this below if there is an exception # This may raise a ResourceExhautedError nanny.tattle_add_item('filesopened', self.abs_filename) # charge for checking if the file exists. nanny.tattle_quantity('fileread', 4096) exists = os.path.isfile(self.abs_filename) # if there isn't a file already... if not exists: # if we shouldn't create it, it's an error if not create: raise FileNotFoundError('Cannot openfile non-existent file "'+filename+'" without creating it!') # okay, we should create it... nanny.tattle_quantity('filewrite', 4096) safe_open(self.abs_filename, "w").close() # Forces file creation # Store a file handle # Always open in mode r+b, this avoids Windows text-mode # quirks, and allows reading and writing self.fobj = safe_open(self.abs_filename, "r+b") # Add the filename to the open files OPEN_FILES.add(filename) # Get the file's size self.filesize = os.path.getsize(self.abs_filename) except RepyException: # Restore the file handle we tattled nanny.tattle_remove_item('filesopened', self.abs_filename) raise finally: OPEN_FILES_LOCK.release()
try: nanny.tattle_add_item('events', event_id) except Exception, e: tracebackrepy.handle_internalerror("Failed to acquire event for '" + \ "initialize' event.\n(Exception was: %s)" % e.message, 140) try: thisnamespace.evaluate(thiscontext) except SystemExit: raise except: # I think it makes sense to exit if their code throws an exception... tracebackrepy.handle_exception() harshexit.harshexit(6) finally: nanny.tattle_remove_item('events', event_id) # I've changed to the threading library, so this should increase if there are # pending events while threading.activeCount() > idlethreadcount: # do accounting here? time.sleep(0.25) # Once there are no more events, return... return def init_repy_location(repy_directory): # Translate into an absolute path if os.path.isabs(repy_directory):
def __init__(self, filename, create): """ This is an internal initializer. See emulated_open for details. """ # Initialize the fields, otherwise __del__ gets confused # when we throw an exception. This was not a problem when the # logic was in emulated_open, since we would never throw an # exception self.filename = filename self.abs_filename = None self.fobj = None self.seek_lock = threading.Lock() self.filesize = 0 # raise an RepyArgumentError if the filename isn't valid _assert_is_allowed_filename(filename) # Check the type of create if type(create) is not bool: raise RepyArgumentError( "Create argument type is invalid! Must be a Boolean!") OPEN_FILES_LOCK.acquire() try: # Check if the file is in use if filename in OPEN_FILES: raise FileInUseError('Cannot open file "' + filename + '" because it is already open!') # Get the absolute file name self.abs_filename = os.path.abspath( os.path.join(repy_constants.REPY_CURRENT_DIR, filename)) # Here is where we try to allocate a "file" resource from the # nanny system. We will restore this below if there is an exception # This may raise a ResourceExhautedError nanny.tattle_add_item('filesopened', self.abs_filename) # charge for checking if the file exists. nanny.tattle_quantity('fileread', 4096) exists = os.path.isfile(self.abs_filename) # if there isn't a file already... if not exists: # if we shouldn't create it, it's an error if not create: raise FileNotFoundError( 'Cannot openfile non-existent file "' + filename + '" without creating it!') # okay, we should create it... nanny.tattle_quantity('filewrite', 4096) safe_open(self.abs_filename, "w").close() # Forces file creation # Store a file handle # Always open in mode r+b, this avoids Windows text-mode # quirks, and allows reading and writing self.fobj = safe_open(self.abs_filename, "r+b") # Add the filename to the open files OPEN_FILES.add(filename) # Get the file's size self.filesize = os.path.getsize(self.abs_filename) except RepyException: # Restore the file handle we tattled nanny.tattle_remove_item('filesopened', self.abs_filename) raise finally: OPEN_FILES_LOCK.release()
def __init__(self, filename, mode="r", create=False): """ <Purpose> Allows the user program to open a file safely. This function is not meant to resemble the builtin "open". <Arguments> filename: The file that should be operated on mode: The mode: "r": Open the file for reading. "rw": Open the file for reading and writing. These are the only valid modes accepted by this version of open(). Note: files are always opened in "binary" mode. create: If True, create the file if it doesn't exist already. <Exceptions> As with open, this may raise a number of errors. Additionally: ValueError is raised if this is passed an invalid mode. <Side Effects> Opens a file on disk, using a file descriptor. <Returns> A file-like object """ # Only allow 'r' and 'rw'. actual_mode = None if mode == "r": actual_mode = "rb" elif mode == "rw": actual_mode = "r+b" if actual_mode is None: raise ValueError("Valid modes for opening a file in repy are 'r' and 'rw'.") restrictions.assertisallowed("file.__init__", filename, actual_mode) # Here we are checking that we only open a given file once in 'write' mode # so that file access is more uniform across platforms. (On Microsoft # Windows, for example, writing to the same file from two different file- # handles throws an error because of the way Windows (by default) locks # files opened for writing.) fileinfolock.acquire() try: # Check the entire fileinfo dictionary for the same file already being # open. for fileinfokey in fileinfo.keys(): # If the filename matches this one, raise an exception. if os.path.abspath(fileinfo[fileinfokey]["filename"]) == os.path.abspath(filename): raise ValueError("A file is only allowed to have one open filehandle.") _assert_is_allowed_filename(filename) # If the file doesn't exist and the create flag was passed, create the # file first. if create and not os.path.exists(filename): # Create a file by opening it in write mode and then closing it. restrictions.assertisallowed("file.__init__", filename, "wb") # Allocate a resource. try: nanny.tattle_add_item("filesopened", self.filehandle) except Exception: # Ok, maybe we can free up a file by garbage collecting. gc.collect() nanny.tattle_add_item("filesopened", self.filehandle) # Create the file, and then free up the resource. created_file = myfile(filename, "wb") created_file.close() nanny.tattle_remove_item("filesopened", self.filehandle) self.filehandle = idhelper.getuniqueid() # Here is where we try to allocate a "file" resource from the # nanny system. If that fails, we garbage collect and try again # (this forces __del__() methods to be called on objects with # no references, which is how we automatically free up # file resources). try: nanny.tattle_add_item("filesopened", self.filehandle) except Exception: # Ok, maybe we can free up a file by garbage collecting. gc.collect() nanny.tattle_add_item("filesopened", self.filehandle) fileinfo[self.filehandle] = { "filename": filename, "mode": actual_mode, "fobj": myfile(filename, actual_mode), } self.name = filename self.mode = mode finally: fileinfolock.release()
def __init__(self, filename, mode="r", create=False): """ <Purpose> Allows the user program to open a file safely. This function is not meant to resemble the builtin "open". <Arguments> filename: The file that should be operated on mode: The mode: "r": Open the file for reading. "rw": Open the file for reading and writing. These are the only valid modes accepted by this version of open(). Note: files are always opened in "binary" mode. create: If True, create the file if it doesn't exist already. <Exceptions> As with open, this may raise a number of errors. Additionally: ValueError is raised if this is passed an invalid mode. <Side Effects> Opens a file on disk, using a file descriptor. <Returns> A file-like object """ # Only allow 'r' and 'rw'. actual_mode = None if mode == "r": actual_mode = "rb" elif mode == "rw": actual_mode = "r+b" if actual_mode is None: raise ValueError("Valid modes for opening a file in repy are 'r' and 'rw'.") restrictions.assertisallowed('file.__init__', filename, actual_mode) # Here we are checking that we only open a given file once in 'write' mode # so that file access is more uniform across platforms. (On Microsoft # Windows, for example, writing to the same file from two different file- # handles throws an error because of the way Windows (by default) locks # files opened for writing.) fileinfolock.acquire() try: # Check the entire fileinfo dictionary for the same file already being # open. for fileinfokey in fileinfo.keys(): # If the filename matches this one, raise an exception. if os.path.abspath(fileinfo[fileinfokey]['filename']) == \ os.path.abspath(filename): raise ValueError(\ "A file is only allowed to have one open filehandle.") _assert_is_allowed_filename(filename) # If the file doesn't exist and the create flag was passed, create the # file first. if create and not os.path.exists(filename): # Create a file by opening it in write mode and then closing it. restrictions.assertisallowed('file.__init__', filename, 'wb') # Allocate a resource. try: nanny.tattle_add_item('filesopened', self.filehandle) except Exception: # Ok, maybe we can free up a file by garbage collecting. gc.collect() nanny.tattle_add_item('filesopened', self.filehandle) # Create the file, and then free up the resource. created_file = myfile(filename, 'wb') created_file.close() nanny.tattle_remove_item('filesopened', self.filehandle) self.filehandle = idhelper.getuniqueid() # Here is where we try to allocate a "file" resource from the # nanny system. If that fails, we garbage collect and try again # (this forces __del__() methods to be called on objects with # no references, which is how we automatically free up # file resources). try: nanny.tattle_add_item('filesopened', self.filehandle) except Exception: # Ok, maybe we can free up a file by garbage collecting. gc.collect() nanny.tattle_add_item('filesopened', self.filehandle) fileinfo[self.filehandle] = {'filename':filename, \ 'mode':actual_mode, 'fobj':myfile(filename, actual_mode)} self.name = filename self.mode = mode finally: fileinfolock.release()