%title 'null symbiont' module symbiont( ident='01', addressing_mode(external=general), main=symbiont ) = begin !++ ! Null symbiont. ! For DECUS use... !-- !+ ! Library calls !- library 'sys$library:lib'; !+ ! External references !- external routine smb$initialize, smb$read_message, smb$read_message_item, smb$send_to_jobctl; !+ ! Forward routine !- forward routine msg_from_jbc : novalue, send_to_jbc : novalue; %sbttl 'main symbiont routine' global routine symbiont : novalue = !++ ! This is the main routine in the null symbiont process. ! It establishes communication with the job controller, and ! thereafter simply processes queue requests at the direction ! of the job controller. ! !-- begin local status; ! ! Initialise symbiont/job-controller interface ! status = smb$initialize( %ref(smbmsg$k_structure_level), msg_from_jbc ); if not .status then $exit(code=.status); !+ ! Mainline just hibernates from now on !- while 1 do $hiber; end; %sbttl 'process message from job controller' routine msg_from_jbc : novalue = !++ ! This routine is executed as an AST whenever the job controller ! has something to say to us. The request is processed entirely ! at AST level. ! !-- begin local status, stream, request; own msg_buffer : block[8,byte] preset( [dsc$b_class]=dsc$k_class_d, [dsc$b_dtype]=dsc$k_dtype_t, [dsc$w_length]=0, [dsc$a_pointer]=0 ); !+ ! Read request. !- status = smb$read_message(stream, msg_buffer, request); if not .status then return; !+ ! Dispatch on request type code !- selectone .request of set [smbmsg$k_start_task]: !+ ! Start task. Acknowledge start, then send immediate ! completion message. !- begin send_to_jbc(.request); send_to_jbc(smbmsg$k_task_complete, .status); end; [smbmsg$k_stop_task]: !+ ! Stop task. We ignore this request. !- ; [smbmsg$k_start_stream]: !+ ! Start stream. This is done when the queue is ! started. Just acknowledge it. !- begin send_to_jbc(.request); end; [smbmsg$k_stop_stream, smbmsg$k_reset_stream]: !+ ! Stop or reset stream. The symbiont is to exit. !- begin send_to_jbc(.request); $exit(code=ss$_normal); end; tes; end; %sbttl 'send response to job controller' routine send_to_jbc (resp, cond) : novalue = !++ ! Sends a reply back to the job controller. ! !-- begin local stream : initial(0), status; !+ ! Start-stream is slightly different; needs the symbiont status ! to say we're a server !- if .resp eql smbmsg$k_start_stream then status = smb$send_to_jobctl(stream, resp, 0, 0, %ref(smbmsg$m_server)) !+ ! Task-complete needs an error code !- else if .resp eql smbmsg$k_task_complete then begin local condvec : vector[2] initial(1,.cond); status = smb$send_to_jobctl(stream, resp, 0, 0, 0, condvec); end !+ ! Everything else just takes the request/reply type !- else status = smb$send_to_jobctl(stream, resp); !+ ! And check for errors !- if not .status then $exit(code=.status); end; end eludom