00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef _WIN32
00036 #include <unistd.h>
00037 #include "config.h"
00038 #else
00039 #include "winconfig.h"
00040 #endif
00041
00042 #include <embedch.h>
00043
00044 #include "include/libmc.h"
00045 #include "include/agent.h"
00046 #include "include/mc_platform.h"
00047 #include "include/message.h"
00048 #include "include/agent_lib.h"
00049 #include "include/interpreter_variable_data.h"
00050 #include "include/xml_parser.h"
00051
00052 int agent_AddPersistentVariable(agent_p agent, int task_num, const char* var_name)
00053 {
00054 int i;
00055 int size;
00056 int data_type_size;
00057 int progress;
00058 interpreter_variable_data_t *agent_variable_data;
00059 agent_variable_data = (interpreter_variable_data_t*)malloc(sizeof(interpreter_variable_data_t));
00060 agent_variable_data->name = strdup(var_name);
00061
00062
00063 agent_variable_data->data_type = Ch_DataType(
00064 *agent->agent_interp,
00065 var_name );
00066
00067 if (agent_variable_data->data_type == CH_UNDEFINETYPE) {
00068 free(agent_variable_data);
00069 fprintf(stderr, "Warning: agent %s attempted saving of invalid variable, %s. %s:%d\n",
00070 agent->name, var_name, __FILE__, __LINE__);
00071 return MC_ERR;
00072 }
00073
00074 agent_variable_data->array_dim = Ch_ArrayDim(
00075 *agent->agent_interp,
00076 var_name );
00077
00078 agent_variable_data->array_extent = (int*)malloc(
00079 sizeof(int) * agent_variable_data->array_dim );
00080 for (i=0; i<agent_variable_data->array_dim; i++) {
00081 agent_variable_data->array_extent[i] =
00082 Ch_ArrayExtent(
00083 *agent->agent_interp,
00084 var_name,
00085 i );
00086 }
00087
00088 size = 1;
00089 for (i=0; i < agent_variable_data->array_dim; i++) {
00090 size *= agent_variable_data->array_extent[i];
00091 }
00092
00093
00094 CH_DATATYPE_SIZE(agent_variable_data->data_type, data_type_size);
00095
00096 agent_variable_data->data = (void*)malloc(size * data_type_size);
00097 CHECK_NULL(agent_variable_data->data, exit(0));
00098
00099
00100 progress = agent->datastate->task_progress;
00101 i = 0;
00102
00103 if (agent_variable_data->array_dim == 0) {
00104 memcpy(
00105 agent_variable_data->data,
00106 (void*)Ch_GlobalSymbolAddrByName(
00107 *agent->agent_interp,
00108 var_name),
00109 size*data_type_size
00110 );
00111
00112 } else {
00113 memcpy(
00114 agent_variable_data->data,
00115 (void*)Ch_GlobalSymbolAddrByName(
00116 *agent->agent_interp,
00117 var_name),
00118 size*data_type_size
00119 );
00120 }
00121 agent_variable_data->size = size*data_type_size;
00122
00123
00124 agent_variable_list_Remove(
00125 agent->datastate->tasks[task_num]->agent_variable_list,
00126 var_name);
00127 agent_variable_list_Add(
00128 agent->datastate->tasks[task_num]->agent_variable_list,
00129 agent_variable_data);
00130 return 0;
00131 }
00132
00133 agent_p
00134 agent_Copy(const agent_p agent)
00135 {
00136 agent_p cp_agent;
00137 cp_agent = (agent_p)malloc(sizeof(agent_t));
00138
00139 MUTEX_LOCK(agent->lock);
00140
00141 cp_agent->id = agent->id;
00142
00143 cp_agent->name = (char*)malloc
00144 (
00145 sizeof(char) *
00146 (strlen(agent->name) + 1)
00147 );
00148 strcpy(cp_agent->name, agent->name);
00149
00150
00151 cp_agent->arrival_time = agent->arrival_time;
00152
00153 cp_agent->owner = (char*)malloc
00154 (
00155 sizeof(char) *
00156 (strlen(agent->owner) + 1)
00157 );
00158 strcpy(cp_agent->owner, agent->owner);
00159
00160 cp_agent->home = (char*)malloc
00161 (
00162 sizeof(char) *
00163 (strlen(agent->home) + 1)
00164 );
00165 strcpy(cp_agent->home, agent->home);
00166
00167 cp_agent->home_port = agent->home_port;
00168
00169 cp_agent->datastate = agent_datastate_Copy(agent->datastate);
00170
00171 cp_agent->orphan = 1;
00172
00173 cp_agent->agent_type = agent->agent_type;
00174
00175 cp_agent->agent_status = agent->agent_status;
00176
00177 cp_agent->return_data = agent->return_data;
00178
00179 cp_agent->agent_interp = NULL;
00180
00181 cp_agent->run_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00182 MUTEX_INIT(cp_agent->run_lock);
00183
00184 cp_agent->agent_persistent = agent->agent_persistent;
00185
00186
00187 cp_agent->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00188 MUTEX_INIT(cp_agent->lock);
00189 MUTEX_NEW(cp_agent->agent_status_lock);
00190 MUTEX_INIT(cp_agent->agent_status_lock);
00191 COND_NEW(cp_agent->agent_status_cond);
00192 COND_INIT(cp_agent->agent_status_cond);
00193
00194
00195 cp_agent->mailbox = agent_mailbox_New();
00196
00197 return cp_agent;
00198 }
00199
00200 agent_p
00201 agent_New(void)
00202 {
00203 agent_p agent;
00204 agent = (agent_p)malloc(sizeof(agent_t));
00205 if(agent==NULL) {
00206 fprintf(stderr, "Memory error at %s:%d\n",
00207 __FILE__, __LINE__);
00208 return NULL;
00209 }
00210
00211 memset(agent, 0, sizeof(agent_t));
00212
00213
00214 MUTEX_NEW(agent->run_lock);
00215 MUTEX_INIT(agent->run_lock);
00216
00217 MUTEX_NEW(agent->lock);
00218 MUTEX_INIT(agent->lock);
00219
00220 MUTEX_NEW(agent->agent_status_lock);
00221 MUTEX_INIT(agent->agent_status_lock);
00222 COND_NEW(agent->agent_status_cond);
00223 COND_INIT(agent->agent_status_cond);
00224
00225 agent->mailbox = agent_mailbox_New();
00226
00227 return agent;
00228 }
00229
00230 agent_p
00231 agent_NewBinary( struct mc_platform_s *mc_platform)
00232 {
00233 agent_p agent;
00234
00235
00236 agent = (MCAgent_t)malloc(sizeof(agent_t));
00237 memset(agent, 0, sizeof(agent_t));
00238
00239
00240 agent->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00241 MUTEX_INIT(agent->lock);
00242
00243
00244 MUTEX_NEW(agent->agent_status_lock);
00245 MUTEX_INIT(agent->agent_status_lock);
00246 COND_NEW(agent->agent_status_cond);
00247 COND_INIT(agent->agent_status_cond);
00248
00249
00250 agent->run_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00251 MUTEX_INIT(agent->run_lock);
00252
00253
00254 agent->id = rand();
00255 #ifndef _WIN32
00256 agent->arrival_time = time(NULL);
00257 #else
00258 GetSystemTime( &(agent->arrival_time) );
00259 #endif
00260
00261 agent->home = NULL;
00262 agent->sender = NULL;
00263
00264
00265 agent->orphan = 0;
00266 agent->agent_script_ready = 1;
00267 agent->agent_pipe_ready_to_read = 0;
00268 agent->agent_ready_to_send = 0;
00269 agent->agent_pipe_active = 0;
00270 agent->binary = 1;
00271
00272
00273 agent->agent_thread_id = 0;
00274
00275
00276 agent->mailbox = agent_mailbox_New();
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 MUTEX_LOCK(agent->agent_status_lock);
00290 agent->agent_status = MC_AGENT_ACTIVE;
00291 COND_BROADCAST(agent->agent_status_cond);
00292 MUTEX_UNLOCK(agent->agent_status_lock);
00293
00294 agent->mc_platform = mc_platform;
00295
00296 agent->agent_address = (char*)malloc(sizeof(char) *
00297 (strlen(agent->mc_platform->hostname) + 12 + 10)
00298 );
00299 if (agent->agent_address == NULL) {
00300 fprintf(stderr, "Memory error. %s:%d\n", __FILE__, __LINE__);
00301 exit(-1);
00302 }
00303 sprintf(agent->agent_address,
00304 "http://%s:%d/acc",
00305 agent->mc_platform->hostname,
00306 agent->mc_platform->port
00307 );
00308
00309 return agent;
00310 }
00311 agent_p
00312 agent_Initialize(
00313 struct mc_platform_s *mc_platform,
00314 message_p message,
00315 int id)
00316 {
00317 agent_p agent;
00318 int err_code;
00319
00320
00321 agent = (MCAgent_t)malloc(sizeof(agent_t));
00322 memset(agent, 0, sizeof(agent_t));
00323
00324
00325 agent->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00326 MUTEX_INIT(agent->lock);
00327
00328
00329 MUTEX_NEW(agent->agent_status_lock);
00330 MUTEX_INIT(agent->agent_status_lock);
00331 COND_NEW(agent->agent_status_cond);
00332 COND_INIT(agent->agent_status_cond);
00333
00334
00335 agent->run_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00336 MUTEX_INIT(agent->run_lock);
00337
00338
00339 agent->id = id;
00340 #ifndef _WIN32
00341 agent->arrival_time = time(NULL);
00342 #else
00343 GetSystemTime( &(agent->arrival_time) );
00344 #endif
00345
00346 agent->home = NULL;
00347 agent->sender = NULL;
00348
00349
00350 agent->orphan = 0;
00351 agent->agent_script_ready = 1;
00352 agent->agent_pipe_ready_to_read = 0;
00353 agent->agent_ready_to_send = 0;
00354 agent->agent_pipe_active = 0;
00355
00356
00357 agent->agent_thread_id = 0;
00358
00359
00360 agent->mailbox = agent_mailbox_New();
00361
00362
00363 agent->datastate = agent_datastate_New();
00364 agent->datastate->xml_agent_root = message->xml_payload;
00365 agent->datastate->xml_root = message->xml_root;
00366 message->agent_xml_flag = 1;
00367
00368 if (agent->datastate->xml_agent_root != NULL) {
00369 switch(message->message_type) {
00370 case MOBILE_AGENT:
00371 agent->agent_type = MC_REMOTE_AGENT;
00372 if( (err_code = agent_xml_parse(agent))) {
00373 fprintf(stderr, "error code %d. %s:%d\n",
00374 err_code, __FILE__, __LINE__ );
00375 agent_Destroy(agent);
00376 return NULL;
00377 }
00378 if (mc_platform->default_agentstatus != -1) {
00379 MUTEX_LOCK(agent->agent_status_lock);
00380 agent->agent_status = (enum MC_AgentStatus_e)mc_platform->default_agentstatus;
00381 COND_BROADCAST(agent->agent_status_cond);
00382 MUTEX_UNLOCK(agent->agent_status_lock);
00383 }
00384 break;
00385 case RETURN_MSG:
00386 agent->agent_type = MC_RETURN_AGENT;
00387 if( (err_code = agent_xml_parse(agent))) {
00388 fprintf(stderr, "error code %d. %s:%d\n",
00389 err_code, __FILE__, __LINE__ );
00390 agent_Destroy(agent);
00391 return NULL;
00392 }
00393 break;
00394 default:
00395 fprintf(stderr, "Invalid agent type: %d %s:%d\n",
00396 agent->agent_type, __FILE__, __LINE__ );
00397 }
00398 } else {
00399 mc_platform->err = MC_ERR_PARSE;
00400
00401 MUTEX_DESTROY(agent->lock);
00402 free(agent->lock);
00403 MUTEX_DESTROY(agent->run_lock);
00404 free(agent->run_lock);
00405 MUTEX_DESTROY(agent->agent_status_lock);
00406 free(agent->agent_status_lock);
00407 COND_DESTROY(agent->agent_status_cond);
00408 free(agent->agent_status_cond);
00409
00410 free(agent);
00411 return NULL;
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 MUTEX_LOCK(agent->agent_status_lock);
00426 agent->agent_status = MC_WAIT_CH;
00427 COND_BROADCAST(agent->agent_status_cond);
00428 MUTEX_UNLOCK(agent->agent_status_lock);
00429
00430 agent->mc_platform = mc_platform;
00431
00432 agent->agent_address = (char*)malloc(sizeof(char) *
00433 (strlen(agent->mc_platform->hostname) + 12 + 10)
00434 );
00435 if (agent->agent_address == NULL) {
00436 fprintf(stderr, "Memory error. %s:%d\n", __FILE__, __LINE__);
00437 exit(-1);
00438 }
00439 sprintf(agent->agent_address,
00440 "http://%s:%d/acc",
00441 agent->mc_platform->hostname,
00442 agent->mc_platform->port
00443 );
00444
00445 return agent;
00446 }
00447
00448 int
00449 agent_Destroy(agent_p agent)
00450 {
00451 if (agent == NULL) {
00452 return MC_SUCCESS;
00453 }
00454 MUTEX_LOCK(agent->lock);
00455 if (agent->name != NULL) {
00456 free(agent->name);
00457 }
00458 if (agent->owner != NULL) {
00459 free(agent->owner);
00460 }
00461 if (agent->home != NULL) {
00462 free(agent->home);
00463 }
00464 if (agent->sender != NULL) {
00465 free(agent->sender);
00466 }
00467 if (agent->wg_code != NULL) {
00468 free(agent->wg_code);
00469 }
00470 if (agent->agent_address != NULL) {
00471 free(agent->agent_address);
00472 }
00473
00474 MUTEX_DESTROY(agent->lock);
00475 MUTEX_LOCK(agent->agent_status_lock);
00476 if (agent->agent_status == MC_AGENT_NEUTRAL) {
00477 MUTEX_UNLOCK(agent->agent_status_lock);
00478 if ((agent->agent_interp) != NULL) {
00479 Ch_Reset(*agent->agent_interp);
00480 interpreter_queue_Add(agent->mc_platform->interpreter_queue, (struct AP_GENERIC_s*)agent->agent_interp);
00481 }
00482 } else {
00483 MUTEX_UNLOCK(agent->agent_status_lock);
00484 }
00485 MUTEX_DESTROY(agent->agent_status_lock);
00486 free(agent->agent_status_lock);
00487 COND_DESTROY(agent->agent_status_cond);
00488 free(agent->agent_status_cond);
00489
00490
00491 free(agent->lock);
00492 agent_datastate_Destroy(agent->datastate);
00493 free(agent->run_lock);
00494 agent_mailbox_Destroy(agent->mailbox);
00495
00496 free(agent);
00497 agent = NULL;
00498 return MC_SUCCESS;
00499 }
00500
00501 extern void
00502 agent_RunChScript(agent_p agent, mc_platform_p mc_platform)
00503 {
00504 #ifndef _WIN32
00505 pthread_attr_t attr;
00506 pthread_attr_init(&attr);
00507 if(mc_platform->stack_size[MC_THREAD_AGENT] != -1) {
00508 pthread_attr_setstacksize
00509 (
00510 &attr,
00511 mc_platform->stack_size[MC_THREAD_AGENT]
00512 );
00513 }
00514 pthread_attr_setdetachstate
00515 (
00516 &attr,
00517 PTHREAD_CREATE_DETACHED
00518 );
00519 #else
00520 int stack_size;
00521 if (mc_platform->stack_size[MC_THREAD_AGENT] < 1) {
00522 stack_size = mc_platform->stack_size[MC_THREAD_AGENT]+1;
00523 } else {
00524 stack_size = mc_platform->stack_size[MC_THREAD_AGENT];
00525 }
00526 #endif
00527 MUTEX_LOCK(agent->agent_status_lock);
00528 agent->agent_status = MC_AGENT_ACTIVE;
00529 COND_BROADCAST(agent->agent_status_cond);
00530 MUTEX_UNLOCK(agent->agent_status_lock);
00531 agent->mc_platform = mc_platform;
00532
00533 THREAD_CREATE(&agent->agent_thread,
00534 agent_RunChScriptThread,
00535 agent );
00536
00537 return;
00538 }
00539
00540
00541
00542 void *
00543 agent_ChScriptInitVar(ChInterp_t* interp)
00544 {
00545 char *tmp_buf;
00546
00547
00548 tmp_buf = (char*)malloc(sizeof(char) * 200);
00549 tmp_buf[0] = '\0';
00550 sprintf(tmp_buf, "int mc_agent_id = -1;");
00551 Ch_DeclareVar(
00552 *interp,
00553 tmp_buf
00554 );
00555
00556 tmp_buf[0] = '\0';
00557
00558 sprintf(tmp_buf, "char* mc_agent_name = NULL;");
00559 Ch_DeclareVar(
00560 *interp,
00561 tmp_buf
00562 );
00563
00564 tmp_buf[0] = '\0';
00565 sprintf(tmp_buf, "void* mc_current_agent = NULL;");
00566 Ch_DeclareVar(
00567 *interp,
00568 tmp_buf
00569 );
00570
00571 tmp_buf[0] = '\0';
00572
00573 sprintf(tmp_buf, "char* mc_host_name = NULL;");
00574 Ch_DeclareVar(
00575 *interp,
00576 tmp_buf
00577 );
00578
00579 tmp_buf[0] = '\0';
00580 sprintf(tmp_buf, "int mc_host_port = -1;\n");
00581 Ch_DeclareVar(
00582 *interp,
00583 tmp_buf
00584 );
00585
00586 tmp_buf[0] = '\0';
00587 sprintf(tmp_buf, "int mc_task_progress = -1;\n");
00588 Ch_DeclareVar(
00589 *interp,
00590 tmp_buf
00591 );
00592
00593 tmp_buf[0] = '\0';
00594 sprintf(tmp_buf, "int mc_num_tasks = -1;\n");
00595 Ch_DeclareVar(
00596 *interp,
00597 tmp_buf
00598 );
00599
00600
00601 tmp_buf[0] = '\0';
00602 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 };" );
00603 Ch_DeclareVar(
00604 *interp,
00605 tmp_buf
00606 );
00607
00608 Ch_DeclareVar(
00609 *interp,
00610 "char* mc_agent_address;"
00611 );
00612
00613
00614 tmp_buf[0] = '\0';
00615 sprintf(tmp_buf, "enum MC_SteerCommand_e {MC_RUN = 0, MC_SUSPEND, MC_RESTART, MC_STOP};" );
00616 Ch_DeclareVar(
00617 *interp,
00618 tmp_buf
00619 );
00620
00621 tmp_buf[0] = '\0';
00622 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};");
00623 Ch_DeclareVar(
00624 *interp,
00625 tmp_buf
00626 );
00627
00628 free(tmp_buf);
00629
00630 Ch_DeclareVar(
00631 *interp,
00632 "void* MCAgent_t;"
00633 );
00634 Ch_DeclareTypedef(
00635 *interp,
00636 "MCAgent_t"
00637 );
00638
00639
00640 Ch_DeclareFunc(
00641 *interp,
00642 "int mc_AclDestroy(void* acl_message);",
00643 (ChFuncdl_t)MC_AclDestroy_chdl
00644 );
00645 Ch_DeclareFunc(
00646 *interp,
00647 "void* mc_AclNew(void);",
00648 (ChFuncdl_t)MC_AclNew_chdl
00649 );
00650 Ch_DeclareFunc(
00651 *interp,
00652 "int mc_AclPost(void* agent, void* acl_message);",
00653 (ChFuncdl_t)MC_AclPost_chdl
00654 );
00655 Ch_DeclareFunc(
00656 *interp,
00657 "void* mc_AclRetrieve(void* agent);",
00658 (ChFuncdl_t)MC_AclRetrieve_chdl
00659 );
00660 Ch_DeclareFunc(
00661 *interp,
00662 "void* mc_AclReply(void* acl_message);",
00663 (ChFuncdl_t)MC_AclReply_chdl
00664 );
00665 Ch_DeclareFunc(
00666 *interp,
00667 "int mc_AclSend(void* acl_message);",
00668 (ChFuncdl_t)MC_AclSend_chdl
00669 );
00670 Ch_DeclareFunc(
00671 *interp,
00672 "void* mc_AclWaitRetrieve(void* agent);",
00673 (ChFuncdl_t)MC_AclWaitRetrieve_chdl
00674 );
00675
00676 Ch_DeclareFunc(
00677 *interp,
00678 "int mc_AclGetProtocol(void* acl_message);",
00679 (ChFuncdl_t)MC_AclGetProtocol_chdl
00680 );
00681 Ch_DeclareFunc(
00682 *interp,
00683 "char* mc_AclGetConversationID(void* acl_message);",
00684 (ChFuncdl_t)MC_AclGetConversationID_chdl
00685 );
00686 Ch_DeclareFunc(
00687 *interp,
00688 "int mc_AclGetPerformative(void* acl_message);",
00689 (ChFuncdl_t)MC_AclGetPerformative_chdl
00690 );
00691 Ch_DeclareFunc(
00692 *interp,
00693 "int mc_AclGetSender(void* acl_message, char** name, char** address);",
00694 (ChFuncdl_t)MC_AclGetSender_chdl
00695 );
00696 Ch_DeclareFunc(
00697 *interp,
00698 "char* mc_AclGetContent(void* acl_message);",
00699 (ChFuncdl_t)MC_AclGetContent_chdl
00700 );
00701
00702 Ch_DeclareFunc(
00703 *interp,
00704 "int mc_AclSetProtocol(void* acl_message, int protocol);",
00705 (ChFuncdl_t)MC_AclSetProtocol_chdl
00706 );
00707 Ch_DeclareFunc(
00708 *interp,
00709 "int mc_AclSetConversationID(void* acl_message, char* id);",
00710 (ChFuncdl_t)MC_AclSetConversationID_chdl
00711 );
00712 Ch_DeclareFunc(
00713 *interp,
00714 "int mc_AclSetPerformative(void* acl_message, int performative);",
00715 (ChFuncdl_t)MC_AclSetPerformative_chdl
00716 );
00717 Ch_DeclareFunc(
00718 *interp,
00719 "int mc_AclSetSender(void* acl_message, char* name, char* address);",
00720 (ChFuncdl_t)MC_AclSetSender_chdl
00721 );
00722 Ch_DeclareFunc(
00723 *interp,
00724 "int mc_AclAddReceiver(void* acl_message, char* name, char* address);",
00725 (ChFuncdl_t)MC_AclAddReceiver_chdl
00726 );
00727 Ch_DeclareFunc(
00728 *interp,
00729 "int mc_AclAddReplyTo(void* acl_message, char* name, char* address);",
00730 (ChFuncdl_t)MC_AclAddReplyTo_chdl
00731 );
00732 Ch_DeclareFunc(
00733 *interp,
00734 "int mc_AclSetContent(void* acl_message, char* content);",
00735 (ChFuncdl_t)MC_AclSetContent_chdl
00736 );
00737
00738 Ch_DeclareFunc(
00739 *interp,
00740 "int mc_AddAgent(void* agent);",
00741 (ChFuncdl_t)MC_AddAgent_chdl
00742 );
00743 Ch_DeclareFunc(
00744 *interp,
00745 "int mc_AgentAddTask(void* agent, const char* code, const char* return_var_name, const char* server, int persistent);",
00746 (ChFuncdl_t)MC_AgentAddTask_chdl
00747 );
00748 Ch_DeclareFunc(
00749 *interp,
00750 "int mc_AgentAttachFile(void* agent, const char* name, const char* filepath);",
00751 (ChFuncdl_t)MC_AgentAttachFile_chdl
00752 );
00753 Ch_DeclareFunc(
00754 *interp,
00755 "int mc_AgentListFiles(void* agent, int task_num, char*** names, int* num_files);",
00756 (ChFuncdl_t)MC_AgentListFiles_chdl
00757 );
00758 Ch_DeclareFunc(
00759 *interp,
00760 "int mc_AgentRetrieveFile(void* agent, int task_num, const char* name, const char* save_path);",
00761 (ChFuncdl_t)MC_AgentRetrieveFile_chdl
00762 );
00763 Ch_DeclareFunc(
00764 *interp,
00765 "const void* mc_AgentVariableRetrieve(void* agent, const char* var_name, int task_num);",
00766 (ChFuncdl_t)MC_AgentVariableRetrieve_chdl
00767 );
00768 Ch_DeclareFunc(
00769 *interp,
00770 "int mc_AgentVariableSave(void* agent, const char* var_name);",
00771 (ChFuncdl_t)MC_AgentVariableSave_chdl
00772 );
00773 Ch_DeclareFunc(
00774 *interp,
00775 "int mc_Barrier(int id);",
00776 (ChFuncdl_t)MC_Barrier_chdl
00777 );
00778 Ch_DeclareFunc(
00779 *interp,
00780 "int mc_BarrierDelete(int id);",
00781 (ChFuncdl_t)MC_BarrierDelete_chdl
00782 );
00783 Ch_DeclareFunc(
00784 *interp,
00785 "int mc_BarrierInit(int id, int num_procs);",
00786 (ChFuncdl_t)MC_BarrierInit_chdl
00787 );
00788 Ch_DeclareFunc(
00789 *interp,
00790 "int mc_CallAgentFunc(char* agentName, const char* funcName, void* returnVal, ...);",
00791 (ChFuncdl_t)MC_CallAgentFunc_chdl
00792 );
00793 Ch_DeclareFunc(
00794 *interp,
00795 "MCAgent_t mc_ComposeAgent(const char* name, *home, *owner, *code, *return_var_name, *server, int persistent);",
00796 (ChFuncdl_t)MC_ComposeAgent_chdl
00797 );
00798 Ch_DeclareFunc(
00799 *interp,
00800 "MCAgent_t mc_ComposeAgentS(const char* name, *home, *owner, *code, *return_var_name, *server, *workgroup_code, int persistent);",
00801 (ChFuncdl_t)MC_ComposeAgentWithWorkgroup_chdl
00802 );
00803 Ch_DeclareFunc(
00804 *interp,
00805 "MCAgent_t mc_ComposeAgentWithWorkgroup(const char* name, *home, *owner, *code, *return_var_name, *server, *workgroup_code, int persistent);",
00806 (ChFuncdl_t)MC_ComposeAgentWithWorkgroup_chdl
00807 );
00808 Ch_DeclareFunc(
00809 *interp,
00810 "MCAgent_t mc_ComposeAgentFromFile(const char* name, *home, *owner, *filename, *return_var_name, *server, int persistent);",
00811 (ChFuncdl_t)MC_ComposeAgentFromFile_chdl
00812 );
00813 Ch_DeclareFunc(
00814 *interp,
00815 "MCAgent_t mc_ComposeAgentFromFileWithWorkgroup(const char* name, *home, *owner, *filename, *return_var_name, *server, *workgroup_code, int persistent);",
00816 (ChFuncdl_t)MC_ComposeAgentFromFileWithWorkgroup_chdl
00817 );
00818 Ch_DeclareFunc(
00819 *interp,
00820 "int mc_CondBroadcast(int id);",
00821 (ChFuncdl_t)MC_CondBroadcast_chdl
00822 );
00823 Ch_DeclareFunc(
00824 *interp,
00825 "int mc_CondSignal(int id);",
00826 (ChFuncdl_t)MC_CondSignal_chdl
00827 );
00828 Ch_DeclareFunc(
00829 *interp,
00830 "int mc_CondReset(int id);",
00831 (ChFuncdl_t)MC_CondReset_chdl
00832 );
00833 Ch_DeclareFunc(
00834 *interp,
00835 "int mc_CondWait(int id);",
00836 (ChFuncdl_t)MC_CondWait_chdl
00837 );
00838 Ch_DeclareFunc(
00839 *interp,
00840 "int mc_DeleteAgent(const char* agentName);",
00841 (ChFuncdl_t)MC_DeleteAgent_chdl
00842 );
00843 Ch_DeclareFunc(
00844 *interp,
00845 "int mc_DeleteAgentWG(MCAgent_t calling_agent, const char* agentName);",
00846 (ChFuncdl_t)MC_DeleteAgentWG_chdl
00847 );
00848 Ch_DeclareFunc(
00849 *interp,
00850 "int mc_DeregisterService(int agentID, char* serviceName);",
00851 (ChFuncdl_t)MC_DeregisterService_chdl
00852 );
00853 Ch_DeclareFunc(
00854 *interp,
00855 "int mc_DestroyServiceSearchResult( char** agentName, char** serviceName, int* agentID, int numResult);",
00856 (ChFuncdl_t)MC_DestroyServiceSearchResult_chdl
00857 );
00858 Ch_DeclareFunc(
00859 *interp,
00860 "int mc_End(void);",
00861 (ChFuncdl_t)MC_End_chdl
00862 );
00863 Ch_DeclareFunc(
00864 *interp,
00865 "void *mc_FindAgentByID(int id);",
00866 (ChFuncdl_t)MC_FindAgentByID_chdl
00867 );
00868
00869 Ch_DeclareFunc(
00870 *interp,
00871 "void *mc_FindAgentByName(const char *name);",
00872 (ChFuncdl_t)MC_FindAgentByName_chdl
00873 );
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883 Ch_DeclareFunc(
00884 *interp,
00885 "int MC_GetAgentID(void* agent);",
00886 (ChFuncdl_t)MC_GetAgentStatus_chdl
00887 );
00888 Ch_DeclareFunc(
00889 *interp,
00890 "char* MC_GetAgentName(void* agent);",
00891 (ChFuncdl_t)MC_GetAgentStatus_chdl
00892 );
00893 Ch_DeclareFunc(
00894 *interp,
00895 "int mc_GetAgentStatus(void* agent);",
00896 (ChFuncdl_t)MC_GetAgentStatus_chdl
00897 );
00898 Ch_DeclareFunc(
00899 *interp,
00900 "char *mc_GetAgentXMLString(void* agent);",
00901 (ChFuncdl_t)MC_GetAgentXMLString_chdl
00902 );
00903
00904 #ifndef _WIN32
00905 Ch_DeclareFunc(
00906 *interp,
00907 "int mc_gettimeofday(void* tv);",
00908 (ChFuncdl_t)MC_GetTimeOfDay_chdl
00909 );
00910 #endif
00911
00912 Ch_DeclareFunc(
00913 *interp,
00914 "int mc_HaltAgency(void);",
00915 (ChFuncdl_t)MC_HaltAgency_chdl
00916 );
00917 Ch_DeclareFunc(
00918 *interp,
00919 "int mc_MigrateAgent(void* agent, const char* hostname, int port);",
00920 (ChFuncdl_t)MC_MigrateAgent_chdl
00921 );
00922 Ch_DeclareFunc(
00923 *interp,
00924 "int mc_MutexLock(int id);",
00925 (ChFuncdl_t)MC_MutexLock_chdl
00926 );
00927 Ch_DeclareFunc(
00928 *interp,
00929 "int mc_MutexUnlock(int id);",
00930 (ChFuncdl_t)MC_MutexUnlock_chdl
00931 );
00932 Ch_DeclareFunc(
00933 *interp,
00934 "int mc_PrintAgentCode(void* agent);",
00935 (ChFuncdl_t)MC_PrintAgentCode_chdl
00936 );
00937 Ch_DeclareFunc(
00938 *interp,
00939 "int mc_ResumeAgency(void);",
00940 (ChFuncdl_t)MC_ResumeAgency_chdl
00941 );
00942 Ch_DeclareFunc(
00943 *interp,
00944 "int mc_SearchForService(const char* searchString, char*** agentNames, char*** serviceNames, int** agentIDs, int* numResults);",
00945 (ChFuncdl_t)MC_SearchForService_chdl
00946 );
00947 Ch_DeclareFunc(
00948 *interp,
00949 "int mc_SendSteerCommand(enum MC_SteerCommand_e command);",
00950 (ChFuncdl_t)MC_SendSteerCommand_chdl
00951 );
00952 Ch_DeclareFunc(
00953 *interp,
00954 "int mc_RegisterService(MCAgent_t agent, char **serviceNames, int numServices);",
00955 (ChFuncdl_t)MC_RegisterService_chdl
00956 );
00957 Ch_DeclareFunc(
00958 *interp,
00959 "void *mc_RetrieveAgent(void);",
00960 (ChFuncdl_t)MC_RetrieveAgent_chdl
00961 );
00962 Ch_DeclareFunc(
00963 *interp,
00964 "char *mc_RetrieveAgentCode(void* agent);",
00965 (ChFuncdl_t)MC_RetrieveAgentCode_chdl
00966 );
00967 Ch_DeclareFunc(
00968 *interp,
00969 "int mc_SaveData(MCAgent_t agent, char* name, int size, void* data);",
00970 (ChFuncdl_t)MC_SaveData_chdl
00971 );
00972 Ch_DeclareFunc(
00973 *interp,
00974 "int mc_SemaphoreWait(int id);",
00975 (ChFuncdl_t)MC_SemaphoreWait_chdl
00976 );
00977 Ch_DeclareFunc(
00978 *interp,
00979 "int mc_SemaphorePost(int id);",
00980 (ChFuncdl_t)MC_SemaphorePost_chdl
00981 );
00982 Ch_DeclareFunc(
00983 *interp,
00984 "int mc_SendAgentMigrationMessage(char *message, char *hostname, int port);",
00985 (ChFuncdl_t)MC_SendAgentMigrationMessage_chdl
00986 );
00987 Ch_DeclareFunc(
00988 *interp,
00989 "int mc_SendAgentMigrationMessageFile(char *filename, char *hostname, int port);",
00990 (ChFuncdl_t)MC_SendAgentMigrationMessageFile_chdl
00991 );
00992 Ch_DeclareFunc(
00993 *interp,
00994 "int mc_SetAgentStatus(void* agent, int status);",
00995 (ChFuncdl_t)MC_SetAgentStatus_chdl
00996 );
00997 Ch_DeclareFunc(
00998 *interp,
00999 "int mc_SetDefaultAgentStatus(int status);",
01000 (ChFuncdl_t)MC_SetDefaultAgentStatus_chdl
01001 );
01002 Ch_DeclareFunc(
01003 *interp,
01004 "int mc_SyncDelete(int id);",
01005 (ChFuncdl_t)MC_SyncDelete_chdl
01006 );
01007 Ch_DeclareFunc(
01008 *interp,
01009 "int mc_SyncInit(int id);",
01010 (ChFuncdl_t)MC_SyncInit_chdl
01011 );
01012 Ch_DeclareFunc(
01013 *interp,
01014 "int mc_TerminateAgent(const char* agentName);",
01015 (ChFuncdl_t)MC_TerminateAgent_chdl
01016 );
01017 Ch_DeclareFunc(
01018 *interp,
01019 "int mc_TerminateAgentWG(void* callingAgent, const char* agentName);",
01020 (ChFuncdl_t)MC_TerminateAgentWG_chdl
01021 );
01022 Ch_DeclareFunc(
01023 *interp,
01024 "int mc_GetAgentID(void* agent);",
01025 (ChFuncdl_t)MC_GetAgentID_chdl
01026 );
01027 Ch_DeclareFunc(
01028 *interp,
01029 "char *mc_GetAgentName(void* agent);",
01030 (ChFuncdl_t)MC_GetAgentName_chdl
01031 );
01032
01033 return NULL;
01034 }
01035
01036 #ifndef _WIN32
01037 void*
01038 agent_RunChScriptThread(void * ChAgent)
01039 #else
01040 DWORD WINAPI
01041 agent_RunChScriptThread(void* ChAgent)
01042 #endif
01043 {
01044 #ifndef _WIN32
01045 int fd;
01046 #endif
01047 MCAgent_t agent;
01048 mc_platform_p mc_platform;
01049 int i,n;
01050 FILE *TEMP_FILE;
01051 char *temp_store_file;
01052 char *ChShellArg[2];
01053 void *result;
01054 int progress;
01055 int callbackErrCode;
01056 interpreter_variable_data_t* temp_interp_data;
01057 int persistent = 0;
01058
01059
01060 agent = (MCAgent_t)ChAgent;
01061 progress = agent->datastate->task_progress;
01062 mc_platform = agent->mc_platform;
01063
01064 setbuf(stdout, NULL);
01065 setbuf(stderr, NULL);
01066
01067 if(ChAgent == NULL)
01068 {
01069 printf("ERROR, AGENT NULL \n");
01070 #ifndef _WIN32
01071 return NULL;
01072 #else
01073 return 0;
01074 #endif
01075 }
01076
01077
01078 agent->agent_interp = (ChInterp_t *)interpreter_queue_CreateRetrieve(mc_platform->interpreter_queue,
01079 agent->mc_platform->interp_options );
01080 if(agent->agent_interp == NULL) {
01081
01082 WARN("Could not initialize another Ch interperter. Please make more copies of the chmt*.dl file.\n");
01083 return NULL;
01084 }
01085
01086
01087
01088 Ch_SetVar(*agent->agent_interp, "mc_agent_id",
01089 CH_INTTYPE, (int)agent->id);
01090
01091 Ch_SetVar(*agent->agent_interp, "mc_agent_name",
01092 CH_CHARPTRTYPE, agent->name);
01093
01094 Ch_SetVar(*agent->agent_interp, "mc_current_agent",
01095 CH_VOIDPTRTYPE, (void*)((size_t)agent));
01096
01097 Ch_SetVar(*agent->agent_interp, "mc_host_name",
01098 CH_CHARPTRTYPE, agent->mc_platform->hostname);
01099
01100 Ch_SetVar(*agent->agent_interp, "mc_host_port",
01101 CH_INTTYPE, (int)agent->mc_platform->port);
01102
01103 Ch_SetVar(*agent->agent_interp, "mc_task_progress",
01104 CH_INTTYPE, (int)agent->datastate->task_progress);
01105
01106 Ch_SetVar(*agent->agent_interp, "mc_num_tasks",
01107 CH_INTTYPE, (int)agent->datastate->number_of_tasks);
01108
01109 Ch_SetVar(*agent->agent_interp, "mc_agent_address",
01110 CH_CHARPTRTYPE, agent->agent_address);
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121 if(strlen(agent->datastate->agent_code) < 5)
01122 {
01123 MUTEX_LOCK(agent->run_lock);
01124 if(Ch_AppendRunScript(
01125 *((MCAgent_t)ChAgent)->agent_interp,
01126 ((MCAgent_t)ChAgent)->datastate->agent_code))
01127 {
01128
01129 printf("CH Failure \n");
01130 printf("***************************************************\nCode was:\n%s\n\n", agent->datastate->agent_code);
01131
01132 }
01133 if(Ch_CallFuncByName(*((MCAgent_t)ChAgent)->agent_interp, "main", NULL))
01134 {
01135 printf("CH2 failure \n");
01136 exit(EXIT_FAILURE);
01137 }
01138 MUTEX_UNLOCK(agent->run_lock);
01139 }
01140 else
01141 {
01142
01143
01144 if(mc_platform->agency->agentInitCallback) {
01145 callbackErrCode = (mc_platform->agency->agentInitCallback)(
01146 *agent->agent_interp,
01147 (struct agent_s*)agent,
01148 mc_platform->agency->agentInitUserData );
01149 if(callbackErrCode) {
01150
01151 ((MCAgent_t) ChAgent)->agent_status = MC_AGENT_NEUTRAL;
01152 #ifndef _WIN32
01153 pthread_exit(ChAgent);
01154 #else
01155 return 0;
01156 #endif
01157 }
01158 }
01159
01160 #ifndef _WIN32
01161
01162 temp_store_file = (char *)malloc(sizeof(char)*30);
01163
01164 strcpy(temp_store_file, "agentchscriptXXXXXX");
01165 fd = mkstemp(temp_store_file);
01166 if (fd == -1) {
01167 fprintf(stderr, "Could not create temporary file:%s. %s:%d\n",
01168 temp_store_file,
01169 __FILE__,
01170 __LINE__ );
01171 exit(EXIT_FAILURE);
01172 }
01173 close(fd);
01174 #else
01175 temp_store_file = _tempnam(".", "agentchscript");
01176 #endif
01177 TEMP_FILE = fopen(temp_store_file, "w");
01178
01179
01180 n = fwrite(
01181 (void *)agent->datastate->agent_code,
01182 sizeof(char),
01183 strlen(agent->datastate->agent_code),
01184 TEMP_FILE);
01185
01186 fclose(TEMP_FILE);
01187
01188
01189 ChShellArg[0] = temp_store_file;
01190 ChShellArg[1] = NULL;
01191 MUTEX_LOCK(agent->run_lock);
01192 if(Ch_RunScript(*agent->agent_interp, ChShellArg) < 0) {
01193 fprintf(stderr, "Ch_RunScript error. %s:%d\n", __FILE__, __LINE__);
01194 } else {
01195
01196 fflush(stdout);
01197 }
01198
01199
01200
01201
01202
01203
01204
01205
01206 remove(temp_store_file);
01207 #ifndef _WIN32
01208 free(temp_store_file);
01209 #endif
01210 MUTEX_UNLOCK(agent->run_lock);
01211 }
01212
01213
01214 if(
01215 agent->datastate->tasks[progress]->var_name != NULL &&
01216 strcmp(agent->datastate->tasks[progress]->var_name, "no-return")
01217 )
01218 {
01219 result = interpreter_variable_data_InitializeFromAgent(agent);
01220
01221 interpreter_variable_data_Destroy(
01222 agent->datastate->tasks[progress]->agent_return_data
01223 );
01224
01225 agent->datastate->tasks[progress]->agent_return_data =
01226 (interpreter_variable_data_t*)result;
01227 } else {
01228 interpreter_variable_data_Destroy(
01229 agent->datastate->tasks[progress]->agent_return_data );
01230 agent->datastate->tasks[progress]->agent_return_data = NULL;
01231 }
01232
01233
01234
01235 while (
01236 (
01237 temp_interp_data =
01238 agent_variable_list_Pop(agent->datastate->tasks[progress]->agent_variable_list)
01239 )
01240 )
01241 {
01242 interpreter_variable_data_Destroy(temp_interp_data);
01243 }
01244 for(i = 0; i < agent->datastate->tasks[progress]->num_saved_variables; i++) {
01245
01246
01247
01248
01249 agent_variable_list_Add(
01250 agent->datastate->tasks[progress]->agent_variable_list,
01251 interpreter_variable_data_Initialize(
01252 agent,
01253 agent->datastate->tasks[progress]->saved_variables[i] )
01254 );
01255 }
01256
01257
01258 agent->datastate->task_progress += agent->datastate->progress_modifier;
01259
01260 if (agent->datastate->persistent ||
01261 agent->datastate->tasks[progress]->persistent ) {
01262 persistent = 1;
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274 ((MCAgent_t) ChAgent)->agent_status = MC_AGENT_NEUTRAL;
01275 } else {
01276 if ((((MCAgent_t)ChAgent)->agent_interp) != NULL) {
01277
01278 Ch_Reset(*agent->agent_interp);
01279 interpreter_queue_Add(mc_platform->interpreter_queue, (struct AP_GENERIC_s*)agent->agent_interp);
01280 }
01281
01282
01283 if (
01284 (agent->datastate->task_progress ==
01285 (agent->datastate->number_of_tasks-1))
01286 )
01287 {
01288
01289 ((MCAgent_t) ChAgent)->agent_status = MC_WAIT_FINISHED;
01290
01291
01292 for(i = 0;
01293 i < agent->datastate->number_of_tasks;
01294 i++)
01295 {
01296 if (agent->datastate->tasks[i]->agent_return_data != NULL) {
01297 ((MCAgent_t) ChAgent)->agent_status = MC_WAIT_MESSGSEND;
01298 }
01299 }
01300 }
01301 else {
01302 ((MCAgent_t) ChAgent)->agent_status = MC_WAIT_MESSGSEND;
01303 }
01304 }
01305
01306
01307 agent->datastate->task_progress++;
01308
01309 if (
01310 (agent->datastate->task_progress >= agent->datastate->number_of_tasks)
01311 )
01312 {
01313 agent->agent_type = MC_RETURN_AGENT;
01314 }
01315
01316 SIGNAL(
01317 mc_platform->MC_signal_cond,
01318 mc_platform->MC_signal_lock,
01319 mc_platform->MC_signal = MC_EXEC_AGENT;
01320 );
01321
01322 MUTEX_LOCK( mc_platform->MC_signal_lock);
01323 MUTEX_UNLOCK( mc_platform->MC_signal_lock );
01324 MUTEX_LOCK(mc_platform->ams->runflag_lock);
01325 mc_platform->ams->run = 1;
01326 COND_SIGNAL(mc_platform->ams->runflag_cond);
01327 MUTEX_UNLOCK(mc_platform->ams->runflag_lock);
01328
01329 if(persistent)
01330 {
01331
01332
01333 MUTEX_LOCK(agent->agent_status_lock);
01334 while(agent->agent_status == MC_AGENT_NEUTRAL) {
01335 COND_WAIT(agent->agent_status_cond, agent->agent_status_lock);
01336 }
01337 MUTEX_UNLOCK(agent->agent_status_lock);
01338 }
01339 #ifndef _WIN32
01340 pthread_exit(ChAgent);
01341 #else
01342 return 0;
01343 #endif
01344 }