/home/dko/projects/mobilec/trunk/src/agent.c

Go to the documentation of this file.
00001 /* SVN FILE INFO
00002  * $Revision: 230 $ : Last Committed Revision
00003  * $Date: 2008年10月24日 15:47:36 -0700 (2008年10月24日) $ : Last Committed Date */
00004 /*[
00005  * Copyright (c) 2007 Integration Engineering Laboratory
00006  University of California, Davis
00007  *
00008  * Permission to use, copy, and distribute this software and its
00009  * documentation for any purpose with or without fee is hereby granted,
00010  * provided that the above copyright notice appear in all copies and
00011  * that both that copyright notice and this permission notice appear
00012  * in supporting documentation.
00013  *
00014  * Permission to modify the software is granted, but not the right to
00015  * distribute the complete modified source code. Modifications are to
00016  * be distributed as patches to the released version. Permission to
00017  * distribute binaries produced by compiling modified sources is granted,
00018  * provided you
00019  * 1. distribute the corresponding source modifications from the
00020  * released version in the form of a patch file along with the binaries,
00021  * 2. add special version identification to distinguish your version
00022  * in addition to the base release version number,
00023  * 3. provide your name and address as the primary contact for the
00024  * support of your modified version, and
00025  * 4. retain our contact information in regard to use of the base
00026  * software.
00027  * Permission to distribute the released version of the source code along
00028  * with corresponding source modifications in the form of a patch file is
00029  * granted with same provisions 2 through 4 for binary distributions.
00030  *
00031  * This software is provided "as is" without express or implied warranty
00032  * to the extent permitted by applicable law.
00033 ]*/
00034 
00035 #ifndef _WIN32
00036 #include <unistd.h>
00037 #endif
00038 
00039 #include <embedch.h>
00040 
00041 #include "include/libmc.h"
00042 #include "include/agent.h"
00043 #include "include/mc_platform.h"
00044 #include "include/message.h"
00045 #include "include/agent_lib.h"
00046 #include "include/interpreter_variable_data.h"
00047 #include "include/xml_parser.h"
00048 
00049 int agent_AddPersistentVariable(agent_p agent, int task_num, const char* var_name)
00050 {
00051 int i;
00052 int size;
00053 int data_type_size;
00054 int progress;
00055 interpreter_variable_data_t *agent_variable_data;
00056 agent_variable_data = (interpreter_variable_data_t*)malloc(sizeof(interpreter_variable_data_t));
00057 agent_variable_data->name = strdup(var_name);
00058 
00059 /* Get the array data type */
00060 agent_variable_data->data_type = Ch_DataType(
00061 agent->agent_interp,
00062 var_name );
00063 /* Make sure the variable exists */
00064 if (agent_variable_data->data_type == CH_UNDEFINETYPE) {
00065 free(agent_variable_data);
00066 fprintf(stderr, "Warning: agent %s attempted saving of invalid variable, %s. %s:%d\n",
00067 agent->name, var_name, __FILE__, __LINE__);
00068 return MC_ERR;
00069 }
00070 /* Get the array dimension */
00071 agent_variable_data->array_dim = Ch_ArrayDim(
00072 agent->agent_interp,
00073 var_name );
00074 /* Get the array extents */
00075 agent_variable_data->array_extent = (int*)malloc(
00076 sizeof(int) * agent_variable_data->array_dim );
00077 for (i=0; i<agent_variable_data->array_dim; i++) {
00078 agent_variable_data->array_extent[i] = 
00079 Ch_ArrayExtent(
00080 agent->agent_interp,
00081 var_name,
00082 i );
00083 }
00084 /* Finally, allocate and point returnData to the right place. */
00085 size = 1;
00086 for (i=0; i < agent_variable_data->array_dim; i++) {
00087 size *= agent_variable_data->array_extent[i];
00088 }
00089 
00090 /* Now get the data type size */
00091 CH_DATATYPE_SIZE(agent_variable_data->data_type, data_type_size);
00092 
00093 agent_variable_data->data = (void*)malloc(size * data_type_size);
00094 CHECK_NULL(agent_variable_data->data, exit(0));
00095 /* Copy the data over from the agent */
00096 /* For now, only support statically allocated global vars. */
00097 progress = agent->datastate->task_progress;
00098 i = 0;
00099 
00100 if (agent_variable_data->array_dim == 0) {
00101 memcpy(
00102 agent_variable_data->data,
00103 (void*)Ch_GlobalSymbolAddrByName(
00104 agent->agent_interp,
00105 var_name),
00106 size*data_type_size
00107 );
00108 
00109 } else {
00110 memcpy(
00111 agent_variable_data->data,
00112 (void*)Ch_GlobalSymbolAddrByName(
00113 agent->agent_interp,
00114 var_name),
00115 size*data_type_size
00116 );
00117 }
00118 agent_variable_data->size = size*data_type_size;
00119 
00120 /* Make sure that the variable is not already in the agent's list already. */
00121 agent_variable_list_Remove(
00122 agent->datastate->tasks[task_num]->agent_variable_list, 
00123 var_name);
00124 agent_variable_list_Add(
00125 agent->datastate->tasks[task_num]->agent_variable_list, 
00126 agent_variable_data);
00127 return 0;
00128 }
00129 
00130 agent_p
00131 agent_Copy(const agent_p agent)
00132 {
00133 agent_p cp_agent;
00134 cp_agent = (agent_p)malloc(sizeof(agent_t));
00135 
00136 MUTEX_LOCK(agent->lock);
00137 /* id */
00138 cp_agent->id = agent->id;
00139 /* name */
00140 cp_agent->name = (char*)malloc
00141 (
00142 sizeof(char) * 
00143 (strlen(agent->name) + 1)
00144 );
00145 strcpy(cp_agent->name, agent->name);
00146 /* connect_id: Not Needed */
00147 /* arrival_time */
00148 cp_agent->arrival_time = agent->arrival_time;
00149 /*owner*/
00150 cp_agent->owner = (char*)malloc
00151 (
00152 sizeof(char) * 
00153 (strlen(agent->owner) + 1)
00154 );
00155 strcpy(cp_agent->owner, agent->owner);
00156 /*home*/
00157 cp_agent->home = (char*)malloc
00158 (
00159 sizeof(char) * 
00160 (strlen(agent->home) + 1)
00161 );
00162 strcpy(cp_agent->home, agent->home);
00163 /*home_port*/
00164 cp_agent->home_port = agent->home_port;
00165 /*datastate*/
00166 cp_agent->datastate = agent_datastate_Copy(agent->datastate);
00167 /* Agent is an orphan */
00168 cp_agent->orphan = 1;
00169 /*agent_type*/
00170 cp_agent->agent_type = agent->agent_type;
00171 /*agent_status*/
00172 cp_agent->agent_status = agent->agent_status;
00173 /*return_data*/
00174 cp_agent->return_data = agent->return_data;
00175 /*agent_interp*/
00176 cp_agent->agent_interp = NULL;
00177 /*agent_thread*/
00178 cp_agent->agent_thread = NULL;
00179 /*run_lock*/
00180 cp_agent->run_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00181 MUTEX_INIT(cp_agent->run_lock);
00182 /*agent_persistent*/
00183 cp_agent->agent_persistent = agent->agent_persistent;
00184 
00185 /*lock*/
00186 cp_agent->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00187 MUTEX_INIT(cp_agent->lock);
00188 
00189 return cp_agent;
00190 }
00191 
00192 agent_p
00193 agent_New(void)
00194 {
00195 agent_p agent;
00196 agent = (agent_p)malloc(sizeof(agent_t));
00197 if(agent==NULL) {
00198 fprintf(stderr, "Memory error at %s:%d\n",
00199 __FILE__, __LINE__);
00200 return NULL;
00201 }
00202 /* Just init everything to zero */
00203 memset(agent, 0, sizeof(agent_t));
00204 
00205 /* Lets go ahead and allocate the threading stuff */
00206 MUTEX_NEW(agent->run_lock);
00207 MUTEX_INIT(agent->run_lock);
00208 
00209 MUTEX_NEW(agent->lock);
00210 MUTEX_INIT(agent->lock);
00211 
00212 return agent;
00213 }
00214 
00215 agent_p 
00216 agent_Initialize(
00217 struct mc_platform_s *mc_platform,
00218 message_p message,
00219 int id)
00220 {
00221 agent_p agent; 
00222 int err_code;
00223 
00224 /* malloc memory for the agent */
00225 agent = (MCAgent_t)malloc(sizeof(agent_t));
00226 memset(agent, 0, sizeof(agent_t));
00227 
00228 /* Set up general agent data access mutex */
00229 agent->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00230 MUTEX_INIT(agent->lock);
00231 
00232 /* Set up run_lock mutex */
00233 agent->run_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00234 MUTEX_INIT(agent->run_lock);
00235 
00236 /* set flags and variables for the agent */
00237 agent->id = id;
00238 #ifndef _WIN32
00239 agent->arrival_time = time(NULL);
00240 #else
00241 GetSystemTime( &(agent->arrival_time) );
00242 #endif
00243 
00244 /* set flags */
00245 agent->orphan = 0;
00246 agent->agent_script_ready = 1;
00247 agent->agent_pipe_ready_to_read = 0;
00248 agent->agent_ready_to_send = 0;
00249 agent->agent_pipe_active = 0;
00250 
00251 /* set the agent thread to null until activated */
00252 agent->agent_thread = NULL;
00253 agent->agent_thread_id = 0;
00254 
00255 /* Set up an empty mailbox */
00256 agent->mailbox = agent_mailbox_New();
00257 
00258 /* parse the xml */
00259 agent->datastate = agent_datastate_New();
00260 agent->datastate->xml_agent_root = message->xml_payload;
00261 agent->datastate->xml_root = message->xml_root;
00262 message->agent_xml_flag = 1;
00263 
00264 if (agent->datastate->xml_agent_root != NULL) {
00265 switch(message->message_type) {
00266 case MOBILE_AGENT:
00267 agent->agent_type = MC_REMOTE_AGENT;
00268 if( (err_code = agent_xml_parse(agent))) {
00269 fprintf(stderr, "error code %d. %s:%d\n",
00270 err_code, __FILE__, __LINE__ );
00271 agent_Destroy(agent);
00272 return NULL;
00273 }
00274 if (mc_platform->default_agentstatus != -1) {
00275 agent->agent_status = mc_platform->default_agentstatus;
00276 }
00277 break;
00278 case RETURN_MSG:
00279 agent->agent_type = MC_RETURN_AGENT;
00280 if( (err_code = agent_xml_parse(agent))) {
00281 fprintf(stderr, "error code %d. %s:%d\n",
00282 err_code, __FILE__, __LINE__ );
00283 agent_Destroy(agent);
00284 return NULL;
00285 }
00286 break;
00287 default:
00288 fprintf(stderr, "Invalid agent type: %d %s:%d\n",
00289 agent->agent_type, __FILE__, __LINE__ );
00290 }
00291 } else {
00292 mc_platform->err = MC_ERR_PARSE;
00293 /* Free up memory. */
00294 MUTEX_DESTROY(agent->lock);
00295 free(agent->lock);
00296 MUTEX_DESTROY(agent->run_lock);
00297 free(agent->run_lock);
00298 
00299 free(agent);
00300 return NULL;
00301 }
00302 
00303 /* In the future we will compare the current tasks server name to 
00304  the one on the server, presently this is not implemented */
00305 
00306 /* set the CH exectution flag */
00307 /* FIXME: This should be in the xml parser */
00308 /*if (agent->datastate->tasks[agent->datastate->task_progress]->init_agent_status != -1) {
00309  agent->agent_status = agent->datastate->tasks[agent->datastate->task_progress]->init_agent_status;
00310  } else {
00311  agent->agent_status = mc_platform->default_agentstatus;
00312  }
00313  */
00314 agent->agent_status = MC_WAIT_CH;
00315 
00316 agent->mc_platform = mc_platform;
00317 
00318 /* return */
00319 return agent;
00320 }
00321 
00322 int
00323 agent_Destroy(agent_p agent)
00324 {
00325 if (agent == NULL) {
00326 return MC_SUCCESS;
00327 }
00328 MUTEX_LOCK(agent->lock);
00329 if (agent->name != NULL) {
00330 free(agent->name);
00331 }
00332 if (agent->owner != NULL) {
00333 free(agent->owner);
00334 }
00335 if (agent->home != NULL) {
00336 free(agent->home);
00337 }
00338 /* Terminate the agent datastate memory */
00339 MUTEX_DESTROY(agent->lock);
00340 if (agent->agent_status == MC_AGENT_NEUTRAL) {
00341 if ((agent->agent_interp) != NULL) {
00342 Ch_End(agent->agent_interp);
00343 }
00344 }
00345 free(agent->lock);
00346 agent_datastate_Destroy(agent->datastate);
00347 free(agent->agent_thread);
00348 free(agent->run_lock);
00349 agent_mailbox_Destroy(agent->mailbox);
00350 /* deallocate the agent */
00351 free(agent);
00352 agent = NULL;
00353 return MC_SUCCESS;
00354 }
00355 
00356 extern void 
00357 agent_RunChScript(agent_p agent, mc_platform_p mc_platform)
00358 {
00359 #ifndef _WIN32
00360 pthread_attr_t attr;
00361 pthread_attr_init(&attr);
00362 if(mc_platform->stack_size[MC_THREAD_AGENT] != -1) {
00363 pthread_attr_setstacksize
00364 (
00365 &attr, 
00366 mc_platform->stack_size[MC_THREAD_AGENT]
00367 );
00368 }
00369 pthread_attr_setdetachstate /* Automatically reclaim thread memory for this thread */
00370 (
00371 &attr,
00372 PTHREAD_CREATE_DETACHED
00373 );
00374 #else
00375 int stack_size;
00376 if (mc_platform->stack_size[MC_THREAD_AGENT] < 1) {
00377 stack_size = mc_platform->stack_size[MC_THREAD_AGENT]+1;
00378 } else {
00379 stack_size = mc_platform->stack_size[MC_THREAD_AGENT];
00380 }
00381 #endif
00382 if(agent->agent_thread == NULL) 
00383 {
00384 agent->agent_thread = (THREAD_T *)malloc(sizeof(THREAD_T));
00385 }
00386 
00387 agent->agent_status = MC_AGENT_ACTIVE;
00388 agent->mc_platform = mc_platform;
00389 
00390 THREAD_CREATE(agent->agent_thread,
00391 agent_RunChScriptThread,
00392 agent );
00393 
00394 return;
00395 }
00396 
00397 #ifndef _WIN32
00398 void* 
00399 agent_RunChScriptThread(void * ChAgent)
00400 #else
00401 DWORD WINAPI 
00402 agent_RunChScriptThread(void* ChAgent)
00403 #endif
00404 {
00405 #ifndef _WIN32
00406 int fd;
00407 #endif
00408 MCAgent_t agent;
00409 mc_platform_p mc_platform;
00410 int i,n;
00411 FILE *TEMP_FILE;
00412 char *temp_store_file;
00413 char *ChShellArg[2];
00414 void *result;
00415 int progress;
00416 char *tmp_buf;
00417 
00418 /* set up the agent object */
00419 agent = (MCAgent_t)ChAgent;
00420 progress = agent->datastate->task_progress;
00421 mc_platform = agent->mc_platform;
00422 
00423 /* check to see if the agent is null */
00424 if(ChAgent == NULL)
00425 {
00426 printf("ERROR, AGENT NULL \n");
00427 #ifndef _WIN32
00428 return NULL;
00429 #else
00430 return 0;
00431 #endif
00432 }
00433 /* We need to check for custom interp_options. If any
00434  * value is null, then we pass null on to Ch_Initialize. */
00435 if( ((MCAgent_t)ChAgent)->mc_platform->interp_options == NULL ) {
00436 
00437 if(Ch_Initialize(&(((MCAgent_t)ChAgent)->agent_interp), 
00438 NULL))
00439 {
00440 printf("CH INIT ERROR \n");
00441 exit(EXIT_FAILURE);
00442 }
00443 } else {
00444 if(Ch_Initialize(&(((MCAgent_t)ChAgent)->agent_interp), 
00445 ((MCAgent_t)ChAgent)->mc_platform->interp_options))
00446 {
00447 printf("CH INIT ERROR \n");
00448 exit(EXIT_FAILURE);
00449 }
00450 }
00451 
00452 /* Declare special variables for holding the agent id and name */
00453 tmp_buf = malloc(sizeof(char) * 200);
00454 tmp_buf[0] = '0円';
00455 sprintf(tmp_buf, "int mc_agent_id=%d;", (int)agent->id);
00456 Ch_DeclareVar(
00457 agent->agent_interp,
00458 tmp_buf
00459 );
00460 
00461 tmp_buf[0] = '0円';
00462 sprintf(tmp_buf,
00463 "char mc_agent_name[]=\"%s\";",
00464 agent->name
00465 );
00466 Ch_DeclareVar(
00467 agent->agent_interp,
00468 tmp_buf
00469 );
00470 
00471 tmp_buf[0] = '0円';
00472 sprintf(tmp_buf, "void* mc_current_agent = (void*)%d;", (int)agent);
00473 Ch_DeclareVar(
00474 agent->agent_interp,
00475 tmp_buf
00476 );
00477 
00478 tmp_buf[0] = '0円';
00479 sprintf(tmp_buf, "char mc_host_name[] = \"%s\";",
00480 agent->mc_platform->hostname );
00481 Ch_DeclareVar(
00482 agent->agent_interp,
00483 tmp_buf
00484 );
00485 
00486 tmp_buf[0] = '0円';
00487 sprintf(tmp_buf, "int mc_host_port = %d;\n",
00488 agent->mc_platform->port );
00489 Ch_DeclareVar(
00490 agent->agent_interp,
00491 tmp_buf
00492 );
00493 
00494 tmp_buf[0] = '0円';
00495 sprintf(tmp_buf, "int mc_task_progress = %d;\n",
00496 agent->datastate->task_progress);
00497 Ch_DeclareVar(
00498 agent->agent_interp,
00499 tmp_buf
00500 );
00501 
00502 tmp_buf[0] = '0円';
00503 sprintf(tmp_buf, "int mc_num_tasks = %d;\n",
00504 agent->datastate->number_of_tasks );
00505 Ch_DeclareVar(
00506 agent->agent_interp,
00507 tmp_buf
00508 );
00509 
00510 /* Declare standard error code enum */
00511 tmp_buf[0] = '0円';
00512 sprintf(tmp_buf, "enum error_code_e {MC_SUCCESS = 0, MC_ERR, MC_ERR_CONNECT, MC_ERR_PARSE, MC_ERR_EMPTY, MC_ERR_INVALID, MC_ERR_INVALID_ARGS, MC_ERR_NOT_FOUND, MC_ERR_MEMORY, MC_ERR_SEND, MC_WARN_DUPLICATE };" );
00513 Ch_DeclareVar(
00514 agent->agent_interp,
00515 tmp_buf
00516 );
00517 
00518 tmp_buf[0] = '0円';
00519 sprintf(tmp_buf, "enum MC_SteerCommand_e {MC_RUN = 0, MC_SUSPEND, MC_RESTART, MC_STOP};" );
00520 Ch_DeclareVar(
00521 agent->agent_interp,
00522 tmp_buf
00523 );
00524 
00525 tmp_buf[0] = '0円';
00526 sprintf(tmp_buf, "enum mc_AgentStatus_e { MC_WAIT_CH, MC_WAIT_MESSGSEND, MC_AGENT_ACTIVE, MC_AGENT_NEUTRAL, MC_AGENT_SUSPENDED, MC_WAIT_FINISHED};"); 
00527 Ch_DeclareVar(
00528 agent->agent_interp,
00529 tmp_buf
00530 );
00531 
00532 free(tmp_buf);
00533 /* Add the MCAgent_t typedef */
00534 Ch_DeclareVar(
00535 agent->agent_interp,
00536 "void* MCAgent_t;"
00537 );
00538 Ch_DeclareTypedef(
00539 agent->agent_interp,
00540 "MCAgent_t"
00541 );
00542 
00543 /* Following are the declarations of the agent-space api functions. */
00544 Ch_DeclareFunc(
00545 agent->agent_interp,
00546 "int mc_AclDestroy(void* acl_message);",
00547 (ChFuncdl_t)MC_AclDestroy_chdl
00548 );
00549 Ch_DeclareFunc(
00550 agent->agent_interp,
00551 "void* mc_AclNew(void);",
00552 (ChFuncdl_t)MC_AclNew_chdl
00553 );
00554 Ch_DeclareFunc(
00555 agent->agent_interp,
00556 "void* mc_AclPost(void* agent, void* acl_message);",
00557 (ChFuncdl_t)MC_AclPost_chdl
00558 );
00559 Ch_DeclareFunc(
00560 agent->agent_interp,
00561 "void* mc_AclRetrieve(void* agent);",
00562 (ChFuncdl_t)MC_AclRetrieve_chdl
00563 );
00564 Ch_DeclareFunc(
00565 agent->agent_interp,
00566 "void* mc_AclReply(void* acl_message);",
00567 (ChFuncdl_t)MC_AclReply_chdl
00568 );
00569 Ch_DeclareFunc(
00570 agent->agent_interp,
00571 "int mc_AclSend(void* acl_message);",
00572 (ChFuncdl_t)MC_AclSend_chdl
00573 );
00574 Ch_DeclareFunc(
00575 agent->agent_interp,
00576 "void* mc_AclWaitRetrieve(void* agent);",
00577 (ChFuncdl_t)MC_AclWaitRetrieve_chdl
00578 );
00579 /* begin Acl Helper Functions */
00580 Ch_DeclareFunc(
00581 agent->agent_interp,
00582 "int mc_AclSetPerformative(void* acl_message, int performative);",
00583 (ChFuncdl_t)MC_AclSetPerformative_chdl
00584 );
00585 Ch_DeclareFunc(
00586 agent->agent_interp,
00587 "int mc_AclSetSender(void* acl_message, char* name, char* address);",
00588 (ChFuncdl_t)MC_AclSetSender_chdl
00589 );
00590 Ch_DeclareFunc(
00591 agent->agent_interp,
00592 "int mc_AclAddReceiver(void* acl_message, char* name, char* address);",
00593 (ChFuncdl_t)MC_AclAddReceiver_chdl
00594 );
00595 Ch_DeclareFunc(
00596 agent->agent_interp,
00597 "int mc_AclAddReplyTo(void* acl_message, char* name, char* address);",
00598 (ChFuncdl_t)MC_AclAddReplyTo_chdl
00599 );
00600 Ch_DeclareFunc(
00601 agent->agent_interp,
00602 "int mc_AclSetContent(void* acl_message, char* content);",
00603 (ChFuncdl_t)MC_AclSetContent_chdl
00604 );
00605 /* end Acl Helper Functions */
00606 Ch_DeclareFunc(
00607 agent->agent_interp,
00608 "int mc_AddAgent(void* agent);",
00609 (ChFuncdl_t)MC_AddAgent_chdl
00610 );
00611 Ch_DeclareFunc(
00612 agent->agent_interp,
00613 "const void* mc_AgentVariableRetrieve(void* agent, const char* var_name, int task_num);",
00614 (ChFuncdl_t)MC_AgentVariableRetrieve_chdl
00615 );
00616 Ch_DeclareFunc(
00617 agent->agent_interp,
00618 "int mc_AgentVariableSave(void* agent, const char* var_name);",
00619 (ChFuncdl_t)MC_AgentVariableSave_chdl
00620 );
00621 Ch_DeclareFunc(
00622 agent->agent_interp,
00623 "int mc_Barrier(int id);",
00624 (ChFuncdl_t)MC_Barrier_chdl
00625 );
00626 Ch_DeclareFunc(
00627 agent->agent_interp,
00628 "int mc_BarrierDelete(int id);",
00629 (ChFuncdl_t)MC_BarrierDelete_chdl
00630 );
00631 Ch_DeclareFunc(
00632 agent->agent_interp,
00633 "int mc_BarrierInit(int id, int num_procs);",
00634 (ChFuncdl_t)MC_BarrierInit_chdl
00635 );
00636 Ch_DeclareFunc(
00637 agent->agent_interp,
00638 "int mc_CallAgentFunc(MCAgent_t agent, const char* funcName, void* returnVal, ...);",
00639 (ChFuncdl_t)MC_CallAgentFunc_chdl
00640 );
00641 Ch_DeclareFunc(
00642 agent->agent_interp,
00643 "MCAgent_t mc_ComposeAgent(const char* name, *home, *owner, *code, *return_var_name, *server, int persistent);",
00644 (ChFuncdl_t)MC_ComposeAgent_chdl
00645 );
00646 Ch_DeclareFunc(
00647 agent->agent_interp,
00648 "int mc_CondBroadcast(int id);",
00649 (ChFuncdl_t)MC_CondBroadcast_chdl
00650 );
00651 Ch_DeclareFunc(
00652 agent->agent_interp,
00653 "int mc_CondSignal(int id);",
00654 (ChFuncdl_t)MC_CondSignal_chdl
00655 );
00656 Ch_DeclareFunc(
00657 agent->agent_interp,
00658 "int mc_CondReset(int id);",
00659 (ChFuncdl_t)MC_CondReset_chdl 
00660 );
00661 Ch_DeclareFunc(
00662 agent->agent_interp,
00663 "int mc_CondWait(int id);",
00664 (ChFuncdl_t)MC_CondWait_chdl 
00665 );
00666 Ch_DeclareFunc(
00667 agent->agent_interp,
00668 "int mc_DeleteAgent(MCAgent_t agent);",
00669 (ChFuncdl_t)MC_DeleteAgent_chdl 
00670 );
00671 Ch_DeclareFunc(
00672 agent->agent_interp,
00673 "int mc_DeregisterService(int agentID, char* serviceName);",
00674 (ChFuncdl_t)MC_DeregisterService_chdl
00675 );
00676 Ch_DeclareFunc(
00677 agent->agent_interp,
00678 "int mc_DestroyServiceSearchResult( char** agentName, char** serviceName, int* agentID, int numResult);",
00679 (ChFuncdl_t)MC_DestroyServiceSearchResult_chdl 
00680 );
00681 Ch_DeclareFunc(
00682 agent->agent_interp,
00683 "int mc_End(void);",
00684 (ChFuncdl_t)MC_End_chdl
00685 );
00686 Ch_DeclareFunc(
00687 agent->agent_interp,
00688 "void *mc_FindAgentByID(int id);",
00689 (ChFuncdl_t)MC_FindAgentByID_chdl
00690 );
00691 Ch_DeclareFunc(
00692 agent->agent_interp,
00693 "void *mc_FindAgentByName(const char *name);",
00694 (ChFuncdl_t)MC_FindAgentByName_chdl
00695 );
00696 /* FIXME -- This block of code does not work: Ch does not
00697  * understand 'time_t' */
00698 /*
00699  Ch_DeclareFunc(
00700  agent->agent_interp,
00701  "time_t mc_GetAgentArrivalTime(void* agent);",
00702  (ChFuncdl_t)MC_GetAgentArrivalTime_chdl
00703  );
00704  */
00705 Ch_DeclareFunc(
00706 agent->agent_interp,
00707 "int MC_GetAgentID(void* agent);",
00708 (ChFuncdl_t)MC_GetAgentStatus_chdl
00709 );
00710 Ch_DeclareFunc(
00711 agent->agent_interp,
00712 "char* MC_GetAgentName(void* agent);",
00713 (ChFuncdl_t)MC_GetAgentStatus_chdl
00714 );
00715 Ch_DeclareFunc(
00716 agent->agent_interp,
00717 "int mc_GetAgentStatus(void* agent);",
00718 (ChFuncdl_t)MC_GetAgentStatus_chdl
00719 );
00720 Ch_DeclareFunc(
00721 agent->agent_interp,
00722 "char *mc_GetAgentXMLString(void* agent);",
00723 (ChFuncdl_t)MC_GetAgentXMLString_chdl
00724 );
00725 
00726 #ifndef _WIN32
00727 Ch_DeclareFunc(
00728 agent->agent_interp,
00729 "int mc_gettimeofday(void* tv);",
00730 (ChFuncdl_t)MC_GetTimeOfDay_chdl
00731 );
00732 #endif
00733 
00734 Ch_DeclareFunc(
00735 agent->agent_interp,
00736 "int mc_HaltAgency(void);",
00737 (ChFuncdl_t)MC_HaltAgency_chdl
00738 );
00739 Ch_DeclareFunc(
00740 agent->agent_interp,
00741 "int mc_MutexLock(int id);",
00742 (ChFuncdl_t)MC_MutexLock_chdl
00743 );
00744 Ch_DeclareFunc(
00745 agent->agent_interp,
00746 "int mc_MutexUnlock(int id);",
00747 (ChFuncdl_t)MC_MutexUnlock_chdl
00748 );
00749 Ch_DeclareFunc(
00750 agent->agent_interp,
00751 "int mc_PrintAgentCode(void* agent);",
00752 (ChFuncdl_t)MC_PrintAgentCode_chdl
00753 );
00754 Ch_DeclareFunc(
00755 agent->agent_interp,
00756 "int mc_ResumeAgency(void);",
00757 (ChFuncdl_t)MC_ResumeAgency_chdl
00758 );
00759 Ch_DeclareFunc(
00760 agent->agent_interp,
00761 "int mc_SearchForService(const char* searchString, char*** agentNames, char*** serviceNames, int** agentIDs, int* numResults);",
00762 (ChFuncdl_t)MC_SearchForService_chdl
00763 );
00764 Ch_DeclareFunc(
00765 agent->agent_interp,
00766 "int mc_SendSteerCommand(enum MC_SteerCommand_e command);",
00767 (ChFuncdl_t)MC_SendSteerCommand_chdl
00768 );
00769 Ch_DeclareFunc(
00770 agent->agent_interp,
00771 "int mc_RegisterService(MCAgent_t agent, char **serviceNames, int numServices);",
00772 (ChFuncdl_t)MC_RegisterService_chdl
00773 );
00774 Ch_DeclareFunc(
00775 agent->agent_interp,
00776 "void *mc_RetrieveAgent(void);",
00777 (ChFuncdl_t)MC_RetrieveAgent_chdl
00778 );
00779 Ch_DeclareFunc(
00780 agent->agent_interp,
00781 "char *mc_RetrieveAgentCode(void* agent);",
00782 (ChFuncdl_t)MC_RetrieveAgentCode_chdl
00783 );
00784 Ch_DeclareFunc(
00785 agent->agent_interp,
00786 "int mc_SaveData(MCAgent_t agent, char* name, int size, void* data);",
00787 (ChFuncdl_t)MC_SaveData_chdl
00788 );
00789 Ch_DeclareFunc(
00790 agent->agent_interp,
00791 "int mc_SemaphoreWait(int id);",
00792 (ChFuncdl_t)MC_SemaphoreWait_chdl
00793 );
00794 Ch_DeclareFunc(
00795 agent->agent_interp,
00796 "int mc_SemaphorePost(int id);",
00797 (ChFuncdl_t)MC_SemaphorePost_chdl
00798 );
00799 Ch_DeclareFunc(
00800 agent->agent_interp,
00801 "int mc_SendAgentMigrationMessage(char *message, char *hostname, int port);",
00802 (ChFuncdl_t)MC_SendAgentMigrationMessage_chdl
00803 );
00804 Ch_DeclareFunc(
00805 agent->agent_interp,
00806 "int mc_SendAgentMigrationMessageFile(char *filename, char *hostname, int port);",
00807 (ChFuncdl_t)MC_SendAgentMigrationMessageFile_chdl
00808 );
00809 Ch_DeclareFunc(
00810 agent->agent_interp,
00811 "int mc_SetAgentStatus(void* agent, int status);",
00812 (ChFuncdl_t)MC_SetAgentStatus_chdl
00813 );
00814 Ch_DeclareFunc(
00815 agent->agent_interp,
00816 "int mc_SetDefaultAgentStatus(int status);",
00817 (ChFuncdl_t)MC_SetDefaultAgentStatus_chdl
00818 );
00819 Ch_DeclareFunc(
00820 agent->agent_interp,
00821 "int mc_SyncDelete(int id);",
00822 (ChFuncdl_t)MC_SyncDelete_chdl 
00823 );
00824 Ch_DeclareFunc(
00825 agent->agent_interp,
00826 "int mc_SyncInit(int id);",
00827 (ChFuncdl_t)MC_SyncInit_chdl 
00828 );
00829 Ch_DeclareFunc(
00830 agent->agent_interp,
00831 "int mc_TerminateAgent(void* agent);",
00832 (ChFuncdl_t)MC_TerminateAgent_chdl
00833 );
00834 Ch_DeclareFunc(
00835 agent->agent_interp,
00836 "int mc_GetAgentID(void* agent);",
00837 (ChFuncdl_t)MC_GetAgentID_chdl
00838 );
00839 Ch_DeclareFunc(
00840 agent->agent_interp,
00841 "char *mc_GetAgentName(void* agent);",
00842 (ChFuncdl_t)MC_GetAgentName_chdl
00843 );
00844 /* Originally, we hope to use append runscript if the buffer for code is less than 5120 bytes.
00845  Otherwise we must open a file and save the data to the filename.
00846  However, since the mobile agent codes for testing are complete programs 
00847  which contain preprocessing directives like "#include" and are larger than 51 bytes, we use
00848  the following statement to save the data to a file instead of putting it into the buffer. 
00849 
00850 FIXME: This is silly
00851 */
00852 if(strlen(agent->datastate->agent_code) < 51)
00853 {
00854 if(Ch_AppendRunScript(
00855 ((MCAgent_t)ChAgent)->agent_interp, 
00856 ((MCAgent_t)ChAgent)->datastate->agent_code))
00857 {
00858 printf("CH Failure \n");
00859 exit(EXIT_FAILURE);
00860 }
00861 if(Ch_CallFuncByName(((MCAgent_t)ChAgent)->agent_interp, "main", NULL))
00862 {
00863 printf("CH2 failure \n");
00864 exit(EXIT_FAILURE);
00865 }
00866 }
00867 else
00868 {
00869 
00870 #ifndef _WIN32
00871 /* save the agent to an external file %agentname%%d%d */
00872 temp_store_file = (char *)malloc(sizeof(char)*30);
00873 
00874 strcpy(temp_store_file, "agentchscriptXXXXXX");
00875 fd = mkstemp(temp_store_file);
00876 if (fd == -1) {
00877 fprintf(stderr, "Could not create temporary file:%s. %s:%d\n",
00878 temp_store_file,
00879 __FILE__,
00880 __LINE__ );
00881 exit(EXIT_FAILURE);
00882 }
00883 close(fd);
00884 #else
00885 temp_store_file = _tempnam(".", "agentchscript");
00886 #endif
00887 TEMP_FILE = fopen(temp_store_file, "w");
00888 
00889 /* write the data to a ch-file */
00890 n = fwrite(
00891 (void *)agent->datastate->agent_code, 
00892 sizeof(char), 
00893 strlen(agent->datastate->agent_code), 
00894 TEMP_FILE);
00895 
00896 fclose(TEMP_FILE);
00897 
00898 /* set the Ch Shell arguments as appropriate */
00899 ChShellArg[0] = temp_store_file;
00900 ChShellArg[1] = NULL;
00901 MUTEX_LOCK(agent->run_lock);
00902 Ch_RunScript(agent->agent_interp, ChShellArg); 
00903 MUTEX_UNLOCK(agent->run_lock);
00904 
00905 /* if(Ch_CallFuncByName(((MCAgent_t)ChAgent)->agent_interp, "main", NULL))
00906  {
00907  printf("CH2 failure \n");
00908  exit(EXIT_FAILURE);
00909  } */
00910 
00911 /* remove the temp file after its usage */
00912 remove(temp_store_file);
00913 #ifndef _WIN32
00914 free(temp_store_file);
00915 #endif
00916 }
00917 
00918 /* now add the data element returned from the Ch execution into the agent data structure */
00919 if(strcmp(agent->datastate->tasks[progress]->var_name, "no-return"))
00920 {
00921 result = interpreter_variable_data_InitializeFromAgent(agent);
00922 /* Free old result extracted from XML agent */
00923 interpreter_variable_data_Destroy(
00924 agent->datastate->tasks[progress]->agent_return_data
00925 );
00926 /* Replace with new freshly calculated one */
00927 agent->datastate->tasks[progress]->agent_return_data = 
00928 result;
00929 } else {
00930 interpreter_variable_data_Destroy(
00931 agent->datastate->tasks[progress]->agent_return_data );
00932 agent->datastate->tasks[progress]->agent_return_data = NULL;
00933 }
00934 
00935 /* This is where we want to save all of the agent variables that the agent
00936  * wishes to keep for its trip. */
00937 for(i = 0; i < agent->datastate->tasks[progress]->num_saved_variables; i++) {
00938 agent_variable_list_Add(
00939 agent->datastate->tasks[progress]->agent_variable_list,
00940 interpreter_variable_data_Initialize(
00941 agent,
00942 agent->datastate->tasks[progress]->saved_variables[i] )
00943 );
00944 }
00945 
00946 if (agent->datastate->persistent || 
00947 agent->datastate->tasks[progress]->persistent ) {
00948 /* TODO: We need a large while loop here that waits on a condition 
00949  variable. Upon waking up, we will need to check a 'mailbox' for
00950  a struct containing
00951  1. A message/command
00952  2. A void* to generic data
00953  3. The size of the data.
00954  It should then execute the command, and check to see if the
00955  persistent flag is still set. If it is, loop again. 
00956  */
00957 /* For now, let us just not end the Ch interpreter and set the 
00958  * agent_status to MC_AGENT_NEUTRAL to cause it to hang. */
00959 ((MCAgent_t) ChAgent)->agent_status = MC_AGENT_NEUTRAL;
00960 } else {
00961 if ((((MCAgent_t)ChAgent)->agent_interp) != NULL) {
00962 Ch_End(((MCAgent_t)ChAgent)->agent_interp);
00963 }
00964 
00965 /* Perform some housekeeping regarding agent status */
00966 if (
00967 (agent->datastate->task_progress ==
00968 (agent->datastate->number_of_tasks-1))
00969 ) 
00970 {
00971 /* If the agent is done... */
00972 ((MCAgent_t) ChAgent)->agent_status = MC_WAIT_FINISHED;
00973 /* If _any_ of the tasks have return data, we should generate
00974  * a return message. */
00975 for(i = 0; 
00976 i < agent->datastate->number_of_tasks;
00977 i++)
00978 {
00979 if (agent->datastate->tasks[i]->agent_return_data != NULL) {
00980 ((MCAgent_t) ChAgent)->agent_status = MC_WAIT_MESSGSEND;
00981 }
00982 }
00983 }
00984 else {
00985 ((MCAgent_t) ChAgent)->agent_status = MC_WAIT_MESSGSEND; 
00986 }
00987 }
00988 
00989 /* close the task, indicating that it has been completed */
00990 agent->datastate->
00991 tasks[agent->datastate->task_progress]->task_completed = 1;
00992 agent->datastate->task_progress++;
00993 
00994 if (
00995 (agent->datastate->task_progress >= agent->datastate->number_of_tasks)
00996 )
00997 {
00998 agent->agent_type = MC_RETURN_AGENT;
00999 }
01000 
01001 SIGNAL(
01002 mc_platform->MC_signal_cond,
01003 mc_platform->MC_signal_lock,
01004 mc_platform->MC_signal = MC_EXEC_AGENT;
01005 );
01006 
01007 MUTEX_LOCK( mc_platform->MC_signal_lock);
01008 MUTEX_UNLOCK( mc_platform->MC_signal_lock );
01009 MUTEX_LOCK(mc_platform->ams->runflag_lock);
01010 mc_platform->ams->run = 1;
01011 COND_SIGNAL(mc_platform->ams->runflag_cond);
01012 MUTEX_UNLOCK(mc_platform->ams->runflag_lock);
01013 
01014 #ifndef _WIN32
01015 pthread_exit(ChAgent); 
01016 #else
01017 return 0;
01018 #endif
01019 }

Generated on Tue Oct 28 17:03:22 2008 for Mobile-C by doxygen 1.5.5

AltStyle によって変換されたページ (->オリジナル) /