forked from SeattleTestbed/repy_v2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
emultimer.py
executable file
·134 lines (98 loc) · 3.01 KB
/
emultimer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
"""
Author: Justin Cappos
Start Date: 29 June 2008
Description:
Timer functions for the sandbox. This does sleep as well as setting and
cancelling timers.
"""
import threading
import thread # Armon: this is to catch thread.error
import nanny
import idhelper
# for printing exceptions
import tracebackrepy
# for harshexit
import harshexit
# For getruntime()
import nonportable
# For sleep
import time
# Import the exception hierarchy
from exception_hierarchy import *
##### Constants
# Armon: Prefix for use with event handles
EVENT_PREFIX = "_EVENT:"
# Store callable
safe_callable = callable
##### Public Functions
def sleep(seconds):
"""
<Purpose>
Allow the current event to pause execution (similar to time.sleep()).
This function will not return early for any reason
<Arguments>
seconds:
The number of seconds to sleep. This can be a floating point value
<Exceptions>
RepyArgumentException if seconds is not an int/long/float.
<Side Effects>
None.
<Returns>
None.
"""
# Check seconds to ensure it is a valid type.
if type(seconds) not in [long, float, int]:
raise RepyArgumentError("Invalid type " + str(type(seconds)))
# Using getruntime() in lieu of time.time() because we want elapsed time
# regardless of the oddities of NTP
start = nonportable.getruntime()
sleeptime = seconds
# Return no earlier than the finish time
finish = start + seconds
while sleeptime > 0.0:
time.sleep(sleeptime)
# If sleeptime > 0.0 then I woke up early...
sleeptime = finish - nonportable.getruntime()
def createthread(function):
"""
<Purpose>
Creates a new thread of execution.
<Arguments>
function:
The function to invoke on entering the new thread.
<Exceptions>
RepyArgumentError is raised if the function is not callable.
ResourceExhaustedError is raised if there are no available events.
<Side Effects>
Launches a new thread.
<Resource Consumption>
Consumes an event.
<Returns>
None
"""
# Check if the function is callable
if not safe_callable(function):
raise RepyArgumentError("Provided function is not callable!")
# Generate a unique handle and see if there are resources available
eventhandle = EVENT_PREFIX + idhelper.getuniqueid()
nanny.tattle_add_item('events', eventhandle)
# Wrap the provided function
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)
# Create a thread object
tobj = threading.Thread(target=wrapped_func, name=idhelper.get_new_thread_name(EVENT_PREFIX))
# Check if we get an exception trying to create a new thread
try:
tobj.start()
except thread.error:
# Set exit code 56, which stands for a Threading Error
# The Node manager will detect this and handle it
harshexit.harshexit(56)