Commit 5c564bc8 authored by Leigh B. Stoller's avatar Leigh B. Stoller

Changes to allow waiting for a specific completion event, which is needed

to make stoprun waiting work correctly.

When tevc is invoked with the -w (wait for completion) option, tevc
generates a token to put into the notification. The event scheduler will
not generate a new token if there is already on in the notification, but
instead pass it on.

For the specific case of stoprun, the simulator agent has to pass that
token along to boss and template_exprun, which generates the completion
event (for reasons discussed in prior commit message).
parent a9e89bd0
......@@ -695,6 +695,7 @@ enqueue(event_handle_t handle, event_notification_t notification, void *data)
char eventtype[TBDB_FLEN_EVEVENTTYPE];
struct agent *agentp;
timeline_agent_t ta = NULL;
int token;
if (! event_notification_get_timeline(handle, notification,
timeline,
......@@ -808,11 +809,20 @@ enqueue(event_handle_t handle, event_notification_t notification, void *data)
event_notification_set_host(handle,
event.notification,
agentp->ipaddr);
event_notification_put_int32(handle,
event.notification,
"TOKEN",
next_token);
next_token += 1;
/*
* Do not override token.
*/
if (! event_notification_get_int32(handle,
event.notification,
"TOKEN",
(int32_t *)&token)) {
event_notification_put_int32(handle,
event.notification,
"TOKEN",
next_token);
next_token += 1;
}
if (recordevents) {
char argsbuf[BUFSIZ] = "";
......
......@@ -401,14 +401,18 @@ static int do_snapshot(simulator_agent_t sa, char *args)
return retval;
}
static int do_stoprun(simulator_agent_t sa, char *args)
static int do_stoprun(simulator_agent_t sa, int token, char *args)
{
int retval = 0;
assert(sa != NULL);
assert(args != NULL);
if (systemf("template_stoprun -p %s -e %s", pid, eid) != 0) {
/*
* Not allowed to use waitmode; will deadlock the event system!
*/
if (systemf("template_stoprun -t %d -p %s -e %s",
token, pid, eid) != 0) {
error("failed to stop current run\n");
retval = -1;
}
......@@ -542,7 +546,7 @@ static void *simulator_agent_looper(void *arg)
do_snapshot(sa, argsbuf);
}
else if (strcmp(evtype, TBDB_EVENTTYPE_STOPRUN) == 0){
do_stoprun(sa, argsbuf);
do_stoprun(sa, token, argsbuf);
}
else {
error("cannot handle SIMULATOR event %s.",
......
......@@ -35,6 +35,8 @@
static int debug;
static int exit_value = 0;
static int completion_token;
static int wait_for_complete;
static event_handle_t handle;
......@@ -77,7 +79,6 @@ main(int argc, char **argv)
char *server = NULL;
char *port = NULL;
int control = 0;
int wait_for_complete = 0;
int timeout = 0;
char *myeid = NULL;
char *keyfile = NULL;
......@@ -365,11 +366,22 @@ main(int argc, char **argv)
when.tv_usec = 0;
}
if (debug) {
if (wait_for_complete) {
struct timeval now;
/*
* If waiting for a complete event, lets stick our
* own token in so we can wait for the proper
* completion event.
*/
gettimeofday(&now, NULL);
completion_token = now.tv_sec;
event_notification_put_int32(handle,
notification,
"TOKEN",
completion_token);
}
if (event_schedule(handle, notification, &when) == 0) {
......@@ -400,9 +412,21 @@ void comp_callback(event_handle_t handle,
void *data)
{
char *value, argsbuf[BUFSIZ] = "";
int ctoken;
event_notification_get_arguments(handle, notification,
argsbuf, sizeof(argsbuf));
if (event_arg_get(argsbuf, "CTOKEN", &value) > 0) {
if (sscanf(value, "%d", &ctoken) != 1) {
error("bad ctoken value for complete: %s\n", argsbuf);
}
if (ctoken != completion_token)
return;
}
else {
return;
}
if (event_arg_get(argsbuf, "ERROR", &value) > 0) {
if (sscanf(value, "%d", &exit_value) != 1) {
......
......@@ -43,7 +43,7 @@ sub usage()
"<guid/vers> - GUID and version to swapin\n");
exit(-1);
}
my $optlist = "qwx:p:E:a:r:e:dscf";
my $optlist = "qwx:p:E:a:r:e:dscft:";
my %options = ();
my $quiet = 0;
my $waitmode = 0;
......@@ -61,6 +61,7 @@ my $guid;
my $version;
my $inputfile;
my $handle;
my $ctoken;
#
# Configure variables
......@@ -90,6 +91,7 @@ my $justexit = 1;
my $checkquota = "$TB/sbin/checkquota";
my $archcontrol = "$TB/bin/archive_control";
my $eventcontrol= "$TB/bin/eventsys_control";
my $tevc = "$TB/bin/tevc";
# Protos
sub ParseArgs();
......@@ -577,6 +579,16 @@ sub ParseArgs()
if (defined($options{"c"})) {
$clean = 1;
}
if (defined($options{"t"})) {
$ctoken = $options{"t"};
if ($ctoken =~ /^([-\w]+)$/) {
$ctoken = $1;
}
else {
tbdie("Bad data in argument: $ctoken.");
}
}
if (defined($options{"E"})) {
if (! TBcheck_dbslot($options{"E"},
"experiment_templates", "description",
......@@ -723,25 +735,14 @@ sub SignalProgAgents($)
sub SendCompletionEvent()
{
fatal(-1, "Could not connect to event system!")
if (!$handle);
my $tuple = address_tuple_alloc();
fatal(-1, "Could not allocate an address tuple\n")
if (!$tuple);
%$tuple = (objtype => "SIMULATOR",
objname => "ns",
eventtype => "COMPLETE",
expt => "$pid/$eid");
my $notification = event_notification_alloc($handle, $tuple);
fatal(-1, "Could not allocate a notification\n")
if (!$notification);
my $arguments = " CTOKEN=$ctoken ERROR=0 ";
if (!event_notify($handle, $notification)) {
fatal(-1, "could not send environment event notification!");
}
#
# Easier to use tevc, and besides the perl swig wrappers are broken
# in some way cause event_notificaton_set_arguments does not work.
#
system("$tevc -e $pid/$eid now ns COMPLETE $arguments") == 0
or fatal(-1, "Could not send completion event notification!");
}
END {
......
......@@ -4825,7 +4825,11 @@ class template:
argstr += " -w "
pass
pass
if opt == "quiet":
elif opt == "token":
argstr += " -t "
argstr += escapeshellarg(val)
pass
elif opt == "quiet":
if xbool(val):
argstr += " -q "
pass
......
......@@ -2179,7 +2179,7 @@ class template_stoprun:
def apply(self):
try:
opts, req_args = getopt.getopt(self.argv, "we:qp:", [ "help" ]);
opts, req_args = getopt.getopt(self.argv, "we:qp:t:", [ "help" ]);
pass
except getopt.error, e:
print e.args[0]
......@@ -2203,8 +2203,11 @@ class template_stoprun:
elif opt == "-p":
pid = val
pass
elif opt == "-t":
params["token"] = val;
pass
elif opt == "-e":
params["exp"] = val;
params["exp"] = val;
pass
pass
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment