# start a thread to handle socket commands that will interact with the ROACH threads Dada.logMsg(2, DL, "main: starting command thread") command_thread = commandThread(quit_event, cond, lock, roach_states, roach_results, roach_responses, cfg) command_thread.start() # start a thread to handle plotting of bram dumps # Dada.logMsg(2, DL, "main: starting plot thread") # plot_thread = plotThread(quit_event, cfg, roach_cfg) # plot_thread.start() # allow some time for commandThread to open listening socket time.sleep(2) # open a socket to the command thread hostname = Dada.getHostMachineName() port = int(cfg["IBOB_MANAGER_PORT"]) # wait for all roaches to be active, then start bramdumping till exit roaches_all_active = False command_sock = 0 # connect to our own command thread Dada.logMsg(3, DL, "main: openSocket(" + hostname + ", " + str(port) + ")") command_sock = Dada.openSocket(DL, hostname, port) Dada.logMsg(3, DL, "main: command_sock=" + repr(command_sock)) response = command_sock.recv(4096) Dada.logMsg( 1, DL, 'Configuring ' + roach_cfg["NUM_ROACH"] +
def run(self): self.quit_event = quit_event cond = self.cond lock = self.lock states = self.states results = self.results cfg = self.cfg try: Dada.logMsg(2, DL, "commandThread: starting") # open a socket to receive commands via socket, allow 1 connection hostname = Dada.getHostMachineName() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) Dada.logMsg( 2, DL, "commandThread: binding to " + hostname + ":" + cfg["IBOB_MANAGER_PORT"]) sock.bind((hostname, int(cfg["IBOB_MANAGER_PORT"]))) # listen for at most 2 connections at a time (TCS and self) Dada.logMsg(2, DL, "commandThread: sock.listen(2)") sock.listen(2) can_read = [sock] can_write = [] can_error = [] timeout = 1 valid_commands = dict({ "QUIT":QUIT, \ "STATE":TASK_STATE, \ "CONFIG":TASK_CONFIG, \ "ARM":TASK_ARM, \ "SET_LEVELS":TASK_SET_LEVELS, \ "BRAMPLOT":TASK_BRAMPLOT}) # keep listening while ((not quit_event.isSet()) or (len(can_read) > 1)): Dada.logMsg( 2, DL, "commandThread: calling select len(can_read)=" + str(len(can_read))) did_read, did_write, did_error = select.select( can_read, can_write, can_error, timeout) Dada.logMsg( 3, DL, "commandThread: read=" + str(len(did_read)) + " write=" + str(len(did_write)) + " error=" + str(len(did_error))) # if we did_read if (len(did_read) > 0): for handle in did_read: if (handle == sock): (new_conn, addr) = sock.accept() Dada.logMsg( 2, DL, "commandThread: accept connection from " + repr(addr)) # add the accepted connection to can_read can_read.append(new_conn) # an accepted connection must have generated some data else: message = handle.recv(4096) message = message.strip() Dada.logMsg( 2, DL, "commandThread: message='" + message + "'") if (len(message) == 0): Dada.logMsg( 2, DL, "commandThread: closing connection") handle.close() for i, x in enumerate(can_read): if (x == handle): del can_read[i] else: message = message.upper() if ((message == "BRAMPLOT") or (message == "STATE")): qdl = 2 else: qdl = 1 Dada.logMsg(qdl, DL, "<- " + message) if (message in valid_commands.keys()): command = valid_commands[message] Dada.logMsg( 2, DL, "commandThread: " + message + " was valid, index=" + str(command)) if (command == QUIT): handle.send("ok\r\n") Dada.logMsg(1, DL, " -> ok") quit_event.set() # remove the server socket from the list of can_reads for i, x in enumerate(can_read): if (x == sock): Dada.logMsg( 2, DL, "commandThread: removed sock from can_read" ) del can_read[i] Dada.logMsg( 2, DL, "commandThread: closing server socket [1]" ) sock.close() sock = [] else: # now process this message Dada.logMsg( 2, DL, "commandThread: lock.acquire()") lock.acquire() Dada.logMsg( 2, DL, "commandThread: lock acquired") for i in range(n_roach): roach_states[i] = command roach_state = command Dada.logMsg( 3, DL, "commandThread: states set to " + message) # all commands should happen as soon as is practical, expect # for the arm, which should ocurr very close to 0.5 seconds # through a second. This command should also return the UTC time # corresponding to the expected start if (command == TASK_ARM): # busy sleep until the next second ticks over curr_time = int(time.time()) next_time = curr_time Dada.logMsg( 2, DL, "commandThread: waiting for 1 second boundary" ) while (curr_time == next_time): next_time = int(time.time()) Dada.logMsg( 2, DL, "commandThread: sleeping 0.5 seconds" ) time.sleep(0.5) utc_start = Dada.getUTCDadaTime(1) Dada.logMsg( 2, DL, "commandThread: UTC_START=" + utc_start) # activate threads Dada.logMsg( 3, DL, "commandThread: cond.notifyAll()") cond.notifyAll() Dada.logMsg( 3, DL, "commandThread: lock.release()") lock.release() # wait for all roaches to finished the command Dada.logMsg( 3, DL, "commandThread: lock.acquire()") lock.acquire() Dada.logMsg( 3, DL, "commandThread: lock acquired") command_result = "" command_response = "" while (roach_state == command): Dada.logMsg( 2, DL, "commandThread: checking all roaches for IDLE" ) n_idle = 0 n_error = 0 n_running = 0 n_ok = 0 n_fail = 0 for i in range(n_roach): Dada.logMsg( 2, DL, "commandThread: testing roach[" + str(i) + "]") # check the states of each roach thread if (roach_states[i] == IDLE): n_idle += 1 # check the return values of this roach Dada.logMsg( 2, DL, "commandThread: roach_results[" + str(i) + "] = " + roach_results[i]) if (roach_results[i] == "ok"): n_ok += 1 else: n_fail += 1 elif (roach_states[i] == ERROR ): Dada.logMsg( -1, DL, "commandThread: roach[" + str(i) + "] thread failed") n_error += 1 else: n_running += 1 # if all roach threads are idle, we are done - extract the results if (n_idle == n_roach): roach_state = IDLE if (n_ok == n_roach): command_result = "ok" else: command_result = "fail" for i in range(n_roach): command_response = command_response + "roach" + str( i) + ":" + str( roach_results[ i]) + " " elif (n_error > 0): Dada.logMsg( 2, DL, "commandThread: roach thread error" ) command_result = "fail" command_response = str( n_error ) + " roach threads failed" roach_state = ERROR else: Dada.logMsg( 2, DL, "commandThread: NOT all IDLE, cond.wait()" ) cond.wait() if (command == TASK_ARM): if (command_response != ""): command_response = command_response + "\r\n" + "UTC_START=" + utc_start else: command_response = "UTC_START=" + utc_start if (command_response != ""): handle.send(command_response + "\r\n") Dada.logMsg( qdl, DL, "-> " + command_response) handle.send(command_result + "\r\n") Dada.logMsg(qdl, DL, "-> " + command_result) Dada.logMsg( 2, DL, "commandThread: lock.release()") lock.release() else: Dada.logMsg( 2, DL, "commandThread: unrecognised command") Dada.logMsg(1, DL, " -> fail") handle.send("fail\r\n") except: Dada.logMsg( -2, DL, "commandThread: exception caught: " + str(sys.exc_info()[0])) print '-' * 60 traceback.print_exc(file=sys.stdout) print '-' * 60 if (not sock == []): Dada.logMsg(2, DL, "commandThread: closing server socket [2]") sock.close() Dada.logMsg(2, DL, "commandThread: exiting")