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 <pthread.h>
00038 #else
00039 #include <windows.h>
00040 #endif
00041 #include <embedch.h>
00042 
00043 #include <sys/types.h>
00044 #include <sys/stat.h>
00045 #ifndef _WIN32
00046 #include <sys/time.h>
00047 #else
00048 #include <time.h>
00049 #endif
00050 
00051 #include "include/libmc.h"
00052 #include "include/macros.h"
00053 #include "include/mc_platform.h"
00054 #include "include/message.h"
00055 #include "include/data_structures.h"
00056 #include "include/fipa_acl_envelope.h"
00057 #include "include/fipa_acl.h"
00058 #include "include/agent.h"
00059 #include "include/agent_task.h"
00060 #ifndef HOST_NAME_MAX
00061 #define HOST_NAME_MAX 255
00062 #endif
00063 
00064 
00065 mc_platform_p g_mc_platform;
00066 
00067 
00068 
00069 
00070 
00071 int 
00072 MC_AclDestroy(struct fipa_acl_message_s* message)
00073 {
00074   return fipa_acl_message_Destroy(message);
00075 }
00076 
00077 EXPORTMC fipa_acl_message_t* 
00078 MC_AclNew(void) {
00079   return fipa_acl_message_New();
00080 }
00081 
00082 EXPORTMC int 
00083 MC_AclPost(MCAgent_t agent, struct fipa_acl_message_s* message)
00084 {
00085   return agent_mailbox_Post(agent->mailbox, message);
00086 }
00087 
00088 EXPORTMC fipa_acl_message_t*
00089 MC_AclReply(fipa_acl_message_t* acl_message)
00090 {
00091   return fipa_Reply(acl_message);
00092 }
00093 
00094 EXPORTMC fipa_acl_message_t*
00095 MC_AclRetrieve(MCAgent_t agent)
00096 {
00097   return agent_mailbox_Retrieve(agent->mailbox);
00098 }
00099 
00100 EXPORTMC int
00101 MC_AclSend(MCAgency_t attr, fipa_acl_message_t* acl)
00102 {
00103   
00104 
00105 
00106   int i;
00107   int err;
00108   mtp_http_t* msg;
00109   dynstring_t* msg_string;
00110   message_p mc_message;
00111 
00112   char* host;
00113   int port;
00114   char* target;
00115   MCAgent_t agent;
00116   int num_addresses = 0;
00117 
00118   err = fipa_acl_Compose(&msg_string, acl);
00119   if( err ) {
00120     fprintf(stderr, "ACL Message Compose Error. %s:%d\n", __FILE__, __LINE__);
00121     return err;
00122   }
00123   for(i = 0; i < acl->receiver->num; i++) {
00124     
00125 
00126 
00127     if (acl->receiver->fipa_agent_identifiers[i]->addresses == NULL) {
00128       num_addresses = 0;
00129     } else {
00130       num_addresses = acl->receiver->fipa_agent_identifiers[i]->addresses->num;
00131     }
00132     if (num_addresses == 0) {
00133       agent = MC_FindAgentByName(
00134           attr,
00135           acl->receiver->fipa_agent_identifiers[i]->name );
00136       if (agent == NULL) {
00137         fprintf(stderr, "Could not find local agent:%s. %s:%d\n",
00138             acl->receiver->fipa_agent_identifiers[i]->name,
00139             __FILE__, __LINE__);
00140       }
00141       MC_AclPost(agent, acl);
00142     } else {
00143       msg = mtp_http_New();
00144       
00145       err = http_to_hostport(
00146           acl->receiver->fipa_agent_identifiers[i]->addresses->urls[0]->str,
00147           &host,
00148           &port,
00149           &target );
00150       if (err) {
00151         fprintf(stderr, "Invalid address. %s:%d\n", __FILE__, __LINE__);
00152         return err;
00153       }
00154       msg->host = strdup(host);
00155       msg->target = strdup(target);
00156       msg->message_parts = 2;
00157       msg->content = (mtp_http_content_t *)malloc(
00158           sizeof(mtp_http_content_t) * 2);
00159 
00160       
00161       msg->content[0].data = (void*)fipa_envelope_Compose(acl);
00162       
00163       msg->content[0].content_type = strdup("application/xml");
00164 
00165       
00166       msg->content[1].data = (void*)strdup(msg_string->message);
00167       msg->content[1].content_type = strdup("application/text");
00168 
00169       mc_message = mtp_http_CreateMessage(
00170           msg,
00171           host,
00172           port );
00173       mc_message->message_type = FIPA_ACL;
00174       mc_message->target = strdup("acc");
00175 
00176       message_Send
00177         (
00178          mc_message
00179         );
00180       message_Destroy(mc_message);
00181       mtp_http_Destroy(msg);
00182       free(host);
00183       free(target);
00184     }
00185   }
00186   dynstring_Destroy(msg_string);
00187   return 0;
00188 }
00189 
00190 EXPORTMC fipa_acl_message_t* 
00191 MC_AclWaitRetrieve(MCAgent_t agent)
00192 {
00193   return agent_mailbox_WaitRetrieve(agent->mailbox);
00194 }
00195 
00196 
00197 
00198 int MC_AclSetPerformative(
00199     fipa_acl_message_t* acl,
00200     enum fipa_performative_e performative )
00201 {
00202   acl->performative = performative;
00203   return 0;
00204 }
00205 
00206 int MC_AclSetSender(
00207     fipa_acl_message_t* acl,
00208     const char* name,
00209     const char* address )
00210 {
00211   if(acl->sender != NULL) {
00212     
00213     fipa_agent_identifier_Destroy(acl->sender);
00214   }
00215   acl->sender = fipa_agent_identifier_New();
00216   acl->sender->name = strdup(name);
00217   if (address != NULL) {
00218     acl->sender->addresses = fipa_url_sequence_New();
00219     acl->sender->addresses->num = 1;
00220     acl->sender->addresses->urls = (struct fipa_url_s**)malloc(
00221         sizeof(struct fipa_url_s*));
00222     acl->sender->addresses->urls[0] = fipa_url_New();
00223     acl->sender->addresses->urls[0]->str = strdup(address);
00224   }
00225 
00226   return 0;
00227 }
00228   
00229 int MC_AclAddReceiver(
00230     fipa_acl_message_t* acl,
00231     const char* name,
00232     const char* address )
00233 {
00234   int i;
00235   struct fipa_agent_identifier_s** tmp;
00236   if (acl->receiver == NULL) {
00237     acl->receiver = fipa_agent_identifier_set_New();
00238   }
00239   acl->receiver_num++;
00240 
00241   acl->receiver->num++;
00242   tmp = (struct fipa_agent_identifier_s**)malloc(
00243       sizeof(struct fipa_agent_identifier_s*)
00244       * acl->receiver->num);
00245   
00246   for(i = 0; i < acl->receiver->num-1; i++) {
00247     tmp[i] = acl->receiver->fipa_agent_identifiers[i];
00248   }
00249   
00250   tmp[i] = fipa_agent_identifier_New();
00251   tmp[i]->name = strdup(name);
00252   if(address != NULL) {
00253     tmp[i]->addresses = fipa_url_sequence_New();
00254     tmp[i]->addresses->num = 1;
00255     tmp[i]->addresses->urls = (struct fipa_url_s**)malloc(
00256         sizeof(struct fipa_url_s*));
00257     tmp[i]->addresses->urls[0] = fipa_url_New();
00258     tmp[i]->addresses->urls[0]->str = strdup(address);
00259   }
00260   free(acl->receiver->fipa_agent_identifiers);
00261   acl->receiver->fipa_agent_identifiers = tmp;
00262   return 0;
00263 }
00264 
00265 int MC_AclAddReplyTo(
00266     fipa_acl_message_t* acl,
00267     const char* name,
00268     const char* address)
00269 {
00270   int i;
00271   struct fipa_agent_identifier_s** tmp;
00272   if (acl->reply_to == NULL) {
00273     acl->reply_to = fipa_agent_identifier_set_New();
00274   }
00275 
00276   acl->reply_to->num++;
00277   tmp = (struct fipa_agent_identifier_s**)malloc(
00278       sizeof(struct fipa_agent_identifier_s*)
00279       * acl->reply_to->num);
00280   
00281   for(i = 0; i < acl->reply_to->num-1; i++) {
00282     tmp[i] = acl->reply_to->fipa_agent_identifiers[i];
00283   }
00284   
00285   tmp[i] = fipa_agent_identifier_New();
00286   tmp[i]->name = strdup(name);
00287   if(address != NULL) {
00288     tmp[i]->addresses = fipa_url_sequence_New();
00289     tmp[i]->addresses->num = 1;
00290     tmp[i]->addresses->urls = (struct fipa_url_s**)malloc(
00291         sizeof(struct fipa_url_s*));
00292     tmp[i]->addresses->urls[0] = fipa_url_New();
00293     tmp[i]->addresses->urls[0]->str = strdup(address);
00294   }
00295   free (acl->reply_to->fipa_agent_identifiers);
00296   acl->reply_to->fipa_agent_identifiers = tmp;
00297   return 0;
00298 }
00299 
00300 int MC_AclSetContent(
00301     fipa_acl_message_t* acl,
00302     const char* content )
00303 {
00304   if (acl->content != NULL) {
00305     
00306     fipa_string_Destroy(acl->content);
00307   }
00308   acl->content = fipa_string_New();
00309   acl->content->content = strdup(content);
00310 
00311   return 0;
00312 }
00313 
00314 
00315 
00316 EXPORTMC int 
00317 MC_AddAgent(MCAgency_t attr, MCAgent_t agent) 
00318 {
00319   agent->mc_platform = attr->mc_platform;
00320 
00321   agent_queue_Add(attr->mc_platform->agent_queue, agent);
00322 
00323   MUTEX_LOCK(attr->mc_platform->ams->runflag_lock);
00324   attr->mc_platform->ams->run = 1;
00325   COND_SIGNAL(attr->mc_platform->ams->runflag_cond);
00326   MUTEX_UNLOCK(attr->mc_platform->ams->runflag_lock);
00327   return 0;
00328 } 
00329 
00330 const void* MC_AgentVariableRetrieve(MCAgent_t agent, const char* var_name, int task_num)
00331 {
00332   interpreter_variable_data_t* interp_var;
00333 
00334   if (task_num >= agent->datastate->task_progress) {
00335     return NULL;
00336   }
00337 
00338   interp_var = agent_variable_list_Search(
00339       agent->datastate->tasks[task_num]->agent_variable_list,
00340       var_name );
00341   if (interp_var == NULL) {
00342     return NULL;
00343   }
00344 
00345   return interp_var->data;
00346 }
00347 
00348 int MC_AgentVariableSave(MCAgent_t agent, const char* var_name)
00349 {
00350   int current_task = agent->datastate->task_progress;
00351   const int default_num_vars = 50;
00352   agent_task_p task = agent->datastate->tasks[current_task];
00353 
00354   if(task->num_saved_variables == 0) {
00355     task->saved_variables = (char**)malloc(sizeof(char*)*default_num_vars);
00356     memset(task->saved_variables, 0, sizeof(char*)*default_num_vars);
00357   }
00358   task->saved_variables[task->num_saved_variables] = strdup(var_name);
00359   if(task->saved_variables[task->num_saved_variables] == NULL) {
00360     fprintf(stderr, "Memory error. %s:%d\n", __FILE__, __LINE__);
00361     return MC_ERR_MEMORY;
00362   }
00363   task->num_saved_variables++;
00364 
00365   return 0;
00366 }
00367 
00368 int 
00369 MC_Barrier(MCAgency_t attr, int id) 
00370 {
00371     barrier_queue_p list = attr->mc_platform->barrier_queue;
00372     barrier_node_p node;
00373     node = barrier_queue_Get(list, id);
00374     if(node == NULL) {
00375         return MC_ERR_NOT_FOUND;
00376     }
00377 
00378     MUTEX_LOCK(node->lock);
00379     node->num_waiting++;
00380     if (node->num_waiting >= node->num_registered) {
00381         
00382         COND_BROADCAST(node->cond);
00383         MUTEX_UNLOCK(node->lock);
00384         return MC_SUCCESS;
00385     } else {
00386         while (node->num_waiting < node->num_registered) {
00387             COND_WAIT(node->cond, node->lock);
00388         }
00389         MUTEX_UNLOCK(node->lock);
00390     }
00391     return MC_SUCCESS;
00392 } 
00393 
00394 EXPORTMC int
00395 MC_BarrierInit(MCAgency_t attr, int id, int num_procs) 
00396 {
00397     barrier_node_p node;
00398     
00399     node = barrier_queue_Get(attr->mc_platform->barrier_queue, id);
00400     if (node != NULL) {
00401       return MC_ERR;
00402     }
00403     node = barrier_node_Initialize(id, num_procs);
00404     barrier_queue_Add(attr->mc_platform->barrier_queue, node);
00405     return MC_SUCCESS;
00406 } 
00407 
00408 EXPORTMC int 
00409 MC_BarrierDelete(MCAgency_t attr, int id) 
00410 {
00411   return barrier_queue_Delete(id, attr->mc_platform->barrier_queue);
00412 } 
00413 
00414 EXPORTMC int
00415 MC_CallAgentFunc(
00416     MCAgent_t agent,
00417     const char* funcName,
00418     void* returnVal,
00419     int numArgs,
00420     ...)
00421 {
00422   int return_code;
00423   va_list vl;
00424   va_start(vl, numArgs);
00425   MUTEX_LOCK(agent->run_lock);
00426   return_code = Ch_CallFuncByNamev(
00427       agent->agent_interp,
00428       funcName,
00429       returnVal,
00430       vl );
00431   MUTEX_UNLOCK(agent->run_lock);
00432   return return_code;
00433 }
00434 
00435 EXPORTMC int 
00436 MC_CallAgentFuncArg( 
00437         MCAgent_t agent,
00438         const char* funcName,
00439         void* returnVal, 
00440         void* arg)
00441 {
00442     int return_code;
00443 
00444     MUTEX_LOCK(agent->run_lock); 
00445     return_code = Ch_CallFuncByName(
00446             agent->agent_interp,
00447             funcName,
00448             returnVal,
00449             arg);
00450     MUTEX_UNLOCK(agent->run_lock); 
00451     return return_code;
00452 }  
00453 
00454 EXPORTMC int
00455 MC_CallAgentFuncV(
00456     MCAgent_t agent,
00457     const char* funcName,
00458     void* returnVal,
00459     va_list ap)
00460 {
00461   int return_code;
00462   MUTEX_LOCK(agent->run_lock);
00463   return_code = Ch_CallFuncByNamev
00464     (
00465      agent->agent_interp,
00466      funcName,
00467      returnVal,
00468      ap
00469     );
00470   MUTEX_UNLOCK(agent->run_lock);
00471   return return_code;
00472 }
00473 
00474 EXPORTMC int
00475 MC_CallAgentFuncVar(
00476                     MCAgent_t agent,
00477                     const char* funcName,
00478                     void* returnVal,
00479                     ChVaList_t varg)
00480 {
00481   int return_code;
00482   MUTEX_LOCK(agent->run_lock);
00483   return_code = Ch_CallFuncByNameVar
00484     (
00485      agent->agent_interp,
00486      funcName,
00487      returnVal,
00488      varg
00489      );
00490   MUTEX_UNLOCK(agent->run_lock);
00491   return return_code;
00492 }
00493 
00494 EXPORTMC int 
00495 MC_ChInitializeOptions(MCAgency_t attr, ChOptions_t *options) { 
00496     if(attr->mc_platform == NULL) {
00497         fprintf(stderr, "MC_ChInitializeOptions must be called after MC_Start()\n");
00498         fprintf(stderr, "Using default interpretor options...\n");
00499         return 1;
00500     }
00501     else {
00502         if (attr->mc_platform->interp_options == NULL) {
00503           attr->mc_platform->interp_options = (ChOptions_t*)malloc(
00504               sizeof(ChOptions_t) );
00505         }
00506         *attr->mc_platform->interp_options = *options;
00507         attr->mc_platform->interp_options->chhome = strdup(options->chhome);
00508         return 0;
00509     }
00510 } 
00511 
00512 MCAgent_t
00513 MC_ComposeAgent(
00514     const char* name,
00515     const char* home,
00516     const char* owner, 
00517     const char* code,
00518     const char* return_var_name,
00519     const char* server,
00520     int persistent
00521     )
00522 {
00523   agent_p agent;
00524   agent = agent_New();
00525   if (agent == NULL) return NULL;
00526   agent->name = strdup(name);
00527   agent->home = strdup(home);
00528   agent->owner = strdup(owner);
00529 
00530   agent->orphan = 1;
00531 
00532   agent->agent_type = MC_LOCAL_AGENT;
00533   agent->agent_status = MC_WAIT_MESSGSEND;
00534 
00535   agent->datastate = agent_datastate_New();
00536   agent->datastate->number_of_tasks = 1;
00537   agent->datastate->persistent = persistent;
00538   agent->datastate->agent_code_ids = (char**)malloc(
00539       sizeof(char*)*2);
00540   if(agent->datastate->agent_code_ids == NULL) {
00541     fprintf(stderr, "Memory Error %s:%d\n", __FILE__, __LINE__);
00542   }
00543   agent->datastate->agent_code_ids[0] = strdup("");
00544   if(agent->datastate->agent_code_ids[0] == NULL) {
00545     fprintf(stderr, "Memory Error %s:%d\n", __FILE__, __LINE__);
00546   }
00547   agent->datastate->agent_code_ids[1] = NULL;
00548 
00549   agent->datastate->agent_codes = (char**)malloc(
00550       sizeof(char*)*2);
00551   if(agent->datastate->agent_codes == NULL) {
00552     fprintf(stderr, "Memory Error %s:%d\n", __FILE__, __LINE__);
00553   }
00554   agent->datastate->agent_codes[0] = strdup(code);
00555   if(agent->datastate->agent_codes[0] == NULL) {
00556     fprintf(stderr, "Memory Error %s:%d\n", __FILE__, __LINE__);
00557   }
00558   agent->datastate->agent_codes[1] = NULL;
00559 
00560   agent->datastate->agent_code = agent->datastate->agent_codes[0];
00561 
00562   agent->datastate->tasks = (agent_task_t**)malloc(
00563       sizeof(agent_task_t*));
00564   agent->datastate->tasks[0] = agent_task_New();
00565   if(return_var_name == NULL) {
00566     agent->datastate->tasks[0]->var_name = strdup("no-return");
00567   } else {
00568     agent->datastate->tasks[0]->var_name = strdup(return_var_name);
00569   }
00570   if(agent->datastate->tasks[0]->var_name == NULL) {
00571     fprintf(stderr, "Memory Error %s:%d\n", __FILE__, __LINE__);
00572   }
00573 
00574   agent->datastate->tasks[0]->server_name = strdup(server);
00575   if(agent->datastate->tasks[0]->server_name == NULL) {
00576     fprintf(stderr, "Memory Error %s:%d\n", __FILE__, __LINE__);
00577   }
00578   
00579   return agent;
00580 }
00581 
00582 EXPORTMC int 
00583 MC_CondBroadcast(MCAgency_t attr, int id) 
00584 {
00585     syncListNode_t *condnode;
00586     condnode = syncListFind(id, attr->mc_platform->syncList);
00587     if (condnode == NULL) {
00588         return MC_ERR_NOT_FOUND;
00589     }
00590     MUTEX_LOCK(condnode->lock);
00591     condnode->signalled=1;
00592     COND_BROADCAST(condnode->cond);
00593     MUTEX_UNLOCK(condnode->lock);
00594     return 0;
00595 } 
00596 
00597 EXPORTMC int 
00598 MC_CondSignal(MCAgency_t attr, int id) 
00599 {
00600     syncListNode_t *condnode;
00601     condnode = syncListFind(id, attr->mc_platform->syncList);
00602     if (condnode == NULL) {
00603         return MC_ERR_NOT_FOUND;
00604     }
00605     MUTEX_LOCK(condnode->lock);
00606     condnode->signalled=1;
00607     COND_SIGNAL(condnode->cond);
00608     MUTEX_UNLOCK(condnode->lock);
00609     return 0;
00610 } 
00611 
00612 EXPORTMC int 
00613 MC_CondWait(MCAgency_t attr, int id)  
00614 {
00615     syncListNode_t *condnode;
00616     condnode = syncListFind(id, attr->mc_platform->syncList);
00617     if (condnode == NULL) {
00618         return MC_ERR_NOT_FOUND;
00619     }
00620     MUTEX_LOCK(condnode->lock);
00621     if (condnode->signalled) {
00622         MUTEX_UNLOCK(condnode->lock);
00623         return 1;
00624     }
00625 
00626     while (condnode->signalled == 0) {
00627       COND_WAIT(condnode->cond, condnode->lock);
00628     }
00629     MUTEX_UNLOCK(condnode->lock);
00630 
00631     return 0;
00632 } 
00633 
00634 EXPORTMC int 
00635 MC_CondReset(MCAgency_t attr, int id) 
00636 {
00637     syncListNode_t *condnode;
00638     condnode = syncListFind(id, attr->mc_platform->syncList);
00639     if (condnode == NULL) {
00640         return MC_ERR_NOT_FOUND;
00641     }
00642     MUTEX_LOCK(condnode->lock);
00643     if (condnode->signalled) {
00644         condnode->signalled = 0;
00645         MUTEX_UNLOCK(condnode->lock);
00646         return 0;
00647     }
00648     MUTEX_UNLOCK(condnode->lock);
00649     return 1;
00650 } 
00651 
00652 int 
00653 MC_CopyAgent(MCAgent_t* agent_out, const MCAgent_t agent_in) 
00654 {
00655   *agent_out = agent_Copy(agent_in);
00656   return MC_SUCCESS;
00657 } 
00658 
00659 EXPORTMC int 
00660 MC_DeleteAgent(MCAgent_t agent) 
00661 {
00662     
00663     CHECK_NULL(agent, return MC_ERR_INVALID;);
00664 
00665     
00666     MC_TerminateAgent(agent);
00667 
00668     
00669 
00670     MC_SetAgentStatus(agent, MC_WAIT_FINISHED);
00671     return MC_SUCCESS;
00672 } 
00673 
00674 int MC_DestroyServiceSearchResult(
00675     char** agentName,
00676     char** serviceName,
00677     int* agentID,
00678     int numResult)
00679 {
00680   int i;
00681   for(i = 0;i < numResult; i++)
00682   {
00683     free(agentName[i]);
00684     free(serviceName[i]);
00685   }
00686   free(agentName);
00687   free(serviceName);
00688   free(agentID);
00689 
00690   return 0;
00691 }
00692 
00693 int 
00694 MC_DeregisterService( 
00695         MCAgency_t agency,
00696         int agentID,
00697         const char *serviceName)
00698 {
00699     int err_code;
00700 
00701     df_request_list_node_t *req_node;
00702     df_deregister_p deregister_data;
00703 
00704     req_node = df_request_list_node_New();
00705     req_node->command = (char*)malloc(sizeof(char)*11);
00706 
00707     strcpy((char*)req_node->command, "deregister");
00708 
00709     deregister_data = (df_deregister_p)malloc(sizeof(df_deregister_t));
00710     deregister_data->agent_id = agentID;
00711     deregister_data->service_name = (char*)serviceName;
00712 
00713     req_node->data = deregister_data;
00714 
00715     err_code = df_AddRequest(
00716             agency->mc_platform->df,
00717             req_node
00718             );
00719     return err_code;
00720 } 
00721 
00722 EXPORTMC int
00723 MC_End(MCAgency_t agency) 
00724 {
00725   
00726   
00727 
00728 
00729   MUTEX_LOCK(agency->mc_platform->quit_lock);
00730   agency->mc_platform->quit = 1;
00731   MUTEX_UNLOCK(agency->mc_platform->quit_lock);
00732 
00733   
00734   if( GET_THREAD_MODE( agency->threads, MC_THREAD_CP)) {
00735     THREAD_CANCEL( agency->mc_platform->cmd_prompt->thread );
00736   }
00737 
00738   
00739   if( GET_THREAD_MODE( agency->threads, MC_THREAD_ACC)) {
00740     THREAD_CANCEL( agency->mc_platform->acc->listen_thread );
00741   }
00742 
00743   
00744   COND_SIGNAL(agency->mc_platform->connection_queue->cond);
00745   if( GET_THREAD_MODE( agency->threads, MC_THREAD_ACC)) {
00746     THREAD_JOIN(agency->mc_platform->acc->thread);
00747   }
00748 
00749   
00750   COND_SIGNAL(agency->mc_platform->message_queue->cond);
00751   if( GET_THREAD_MODE( agency->threads, MC_THREAD_ACC)) {
00752     THREAD_JOIN(agency->mc_platform->acc->message_handler_thread);
00753   }
00754 
00755   
00756   COND_SIGNAL(agency->mc_platform->ams->runflag_cond);
00757   if( GET_THREAD_MODE( agency->threads, MC_THREAD_AMS)) {
00758     THREAD_JOIN(agency->mc_platform->ams->thread);
00759   }
00760 
00761   
00762   COND_SIGNAL(agency->mc_platform->df->request_list->cond);
00763   if( GET_THREAD_MODE( agency->threads, MC_THREAD_DF)) {
00764     THREAD_JOIN(agency->mc_platform->df->thread);
00765   }
00766 
00767   mc_platform_Destroy(agency->mc_platform);
00768 
00769   if (agency->hostName)
00770     free(agency->hostName); 
00771   free(agency);
00772 
00773   return 0;
00774 } 
00775 
00776 EXPORTMC MCAgent_t 
00777 MC_FindAgentByName( MCAgency_t attr, 
00778     const char *name) 
00779 {
00780   extern mc_platform_p g_mc_platform;
00781   if (attr == NULL) {
00782     return agent_queue_SearchName(g_mc_platform->agent_queue, name);
00783   } else {
00784     return agent_queue_SearchName(attr->mc_platform->agent_queue,
00785         name);
00786   }
00787 } 
00788 
00789 EXPORTMC MCAgent_t
00790 MC_FindAgentByID( MCAgency_t attr, 
00791     int ID)
00792 {
00793   extern mc_platform_p g_mc_platform;
00794   if (attr == NULL) {
00795     return agent_queue_Search(g_mc_platform->agent_queue, ID);
00796   } else {
00797     return agent_queue_Search(attr->mc_platform->agent_queue,
00798         ID);
00799   }
00800 } 
00801 
00802 #ifndef _WIN32
00803   time_t 
00804 #else
00805   SYSTEMTIME
00806 #endif
00807 MC_GetAgentArrivalTime(MCAgent_t agent) 
00808 {
00809   if (agent != NULL) {
00810     return agent->arrival_time;
00811   } else {
00812 #ifndef _WIN32
00813     return (time_t)-1;
00814 #else
00815     SYSTEMTIME oy;
00816     return oy;
00817 #endif
00818   }
00819 } 
00820 
00821 EXPORTMC int 
00822 MC_GetAgentStatus(MCAgent_t agent) 
00823 {
00824   int status;
00825   MUTEX_LOCK(agent->lock);
00826   status = agent->agent_status;
00827   MUTEX_UNLOCK(agent->lock);
00828   return status;
00829 } 
00830 
00831 EXPORTMC char*
00832 MC_GetAgentXMLString(MCAgent_t agent) 
00833 {
00834   char *ret;
00835   ret = mxmlSaveAllocString(
00836       agent->datastate->xml_agent_root,
00837       NULL
00838       );
00839   return ret;
00840 } 
00841 
00842 
00843 EXPORTMC void*
00844 MC_GetAgentExecEngine(MCAgent_t agent) 
00845 {
00846   return agent->agent_interp;
00847 } 
00848 
00849 EXPORTMC int 
00850 MC_GetAgentID( 
00851     MCAgent_t agent
00852     )
00853 {
00854   return agent->id;
00855 } 
00856 
00857 EXPORTMC char* 
00858 MC_GetAgentName( 
00859     MCAgent_t agent
00860     )
00861 {
00862   char *name;
00863   MUTEX_LOCK(agent->lock);
00864   name = (char*)malloc(sizeof(char) * 
00865       (strlen (agent->name) + 1)
00866       );
00867   strcpy(
00868       name,
00869       agent->name
00870       );
00871   MUTEX_UNLOCK(agent->lock);
00872   return name;
00873 } 
00874 
00875 EXPORTMC int
00876 MC_GetAgentReturnData( 
00877     MCAgent_t agent,
00878     int task_num,
00879     void **data,
00880     int *dim,
00881     int **extent) 
00882 {
00883   int num_elements;
00884   int size;
00885   int i;
00886   if (task_num >= agent->datastate->number_of_tasks) {
00887     *data = NULL;
00888     *dim = 0;
00889     *extent = NULL;
00890     return 1;
00891   }
00892   if (
00893       agent->datastate->tasks[task_num]->
00894       agent_return_data->data_type == -1
00895      )
00896   {
00897     return 1;
00898   }
00899   CH_DATATYPE_SIZE(
00900       agent->datastate->tasks[task_num]->agent_return_data->data_type,
00901       size);
00902   num_elements = 1;
00903   for (
00904       i = 0; 
00905       i < agent->datastate->tasks[task_num]->agent_return_data->array_dim;
00906       i++
00907       )
00908   {
00909     num_elements *= agent->datastate->
00910       tasks[task_num]->agent_return_data->array_extent[i];
00911   }
00912 
00913 
00914   *data = malloc(num_elements * size);
00915   memcpy(
00916       *data,
00917       agent->datastate->tasks[task_num]->
00918       agent_return_data->data,
00919       size * num_elements
00920       );
00921   *dim = agent->datastate->tasks[task_num]->agent_return_data->array_dim;
00922   *extent = (int*)malloc(
00923       sizeof(int) * 
00924       agent->datastate->tasks[task_num]->agent_return_data->array_dim
00925       );
00926   for (i = 0; i < *dim; i++) {
00927     (*extent)[i] = 
00928       agent->datastate->tasks[task_num]->agent_return_data->array_extent[i];
00929   }
00930   
00931 
00932 
00933 
00934 
00935   return 0;
00936 } 
00937 
00938 EXPORTMC int 
00939 MC_GetAgentNumTasks(MCAgent_t agent) 
00940 {
00941   return agent->datastate->number_of_tasks;
00942 } 
00943 
00944 EXPORTMC enum MC_AgentType_e
00945 MC_GetAgentType(MCAgent_t agent) 
00946 {
00947   if (agent != NULL) {
00948     return agent->agent_type;
00949   } else {
00950     return 0;
00951   }
00952 } 
00953 
00954 int 
00955 MC_GetAllAgents(MCAgency_t attr, MCAgent_t **agents, int* num_agents) 
00956 {
00957   int halt;
00958   int index = 0;
00959   MUTEX_LOCK(attr->mc_platform->giant_lock);
00960   halt = (attr->mc_platform->giant == 1) ? 1 : 0;
00961   MUTEX_UNLOCK(attr->mc_platform->giant_lock);
00962   if (halt)
00963     MC_HaltAgency(attr);
00964   
00965   while (agent_queue_SearchIndex(attr->mc_platform->agent_queue, index) != NULL) {
00966     index++;
00967   }
00968   *agents = (MCAgent_t *)malloc(sizeof(MCAgent_t*) * index);
00969   *num_agents = index;
00970   
00971   index = 0;
00972   while
00973     (
00974      (
00975       (*agents)[index] = agent_queue_SearchIndex
00976       (
00977        attr->mc_platform->agent_queue,
00978        index
00979       )
00980      )
00981     )
00982     {
00983       index++;
00984     }
00985   if(halt)
00986     MC_ResumeAgency(attr);
00987   return 0;
00988 } 
00989 
00990 EXPORTMC int
00991 MC_HaltAgency(MCAgency_t attr) 
00992 {
00993   MUTEX_LOCK(attr->mc_platform->giant_lock);
00994   attr->mc_platform->giant=0;
00995   MUTEX_UNLOCK(attr->mc_platform->giant_lock);
00996   return 0;
00997 } 
00998 
00999 EXPORTMC MCAgency_t 
01000 MC_Initialize( 
01001     int port,
01002     MCAgencyOptions_t *options)
01003 {
01004   MCAgency_t ret;
01005   int i=0;
01006   int options_malloc = 0;
01007   ret = (MCAgency_t)malloc(sizeof(struct agency_s));
01008   if (ret == NULL) {return NULL;}
01009 
01010   ret->hostName = malloc(HOST_NAME_MAX);
01011   if (ret->hostName == NULL) {return NULL;}
01012   gethostname(ret->hostName, HOST_NAME_MAX);
01013   
01014   CHECK_NULL(
01015       realloc(ret->hostName, sizeof(char)*(strlen(ret->hostName)+1)),
01016       return NULL;
01017       );
01018   if (ret->hostName == NULL) {return NULL;}
01019   ret->portno = port;
01020   ret->server = 1;
01021   ret->client = 0;
01022   ret->default_agentstatus = -1;
01023 #ifdef MC_SECURITY
01024   ret->enable_security = 1;
01025 #endif
01026 
01027   
01028   if(options==NULL) {
01029     options = (MCAgencyOptions_t*)malloc(sizeof(MCAgencyOptions_t));
01030     MC_InitializeAgencyOptions(options);
01031     options_malloc = 1;
01032   }
01033   ret->threads = options->threads;
01034   ret->default_agentstatus = options->default_agent_status;
01035 #ifdef MC_SECURITY
01036   ret->enable_security = options->enable_security;
01037 #endif
01038   for(i = 0; i < MC_THREAD_ALL; i++) {
01039     ret->stack_size[i] = options->stack_size[i];
01040   }
01041   
01042 
01043   ret->mc_platform = mc_platform_Initialize(ret);
01044 
01045   
01046   g_mc_platform = ret->mc_platform;
01047 
01048   if (options_malloc)
01049     free(options);
01050 
01051   return ret;
01052 } 
01053 
01054 EXPORTMC int 
01055 MC_InitializeAgencyOptions(struct MCAgencyOptions_s* options) 
01056 {
01057   int i;
01058   
01059   options->threads = 0xFFFF;
01060   options->default_agent_status = MC_WAIT_CH;
01061   options->modified = 0;
01062 #ifdef MC_SECURITY
01063   options->enable_security = 1;
01064 #endif
01065   for(i = 0; i < MC_THREAD_ALL; i++) {
01066     options->stack_size[i] = -1;
01067   }
01068   return 0;
01069 } 
01070 
01071 EXPORTMC int
01072 MC_LoadAgentFromFile(MCAgency_t attr, const char* filename)
01073 {
01074   struct stat filestat;
01075   char *buf;
01076   FILE *fp;
01077   message_p message;
01078   extern mc_platform_p g_mc_platform;
01079   buf = NULL;
01080   filestat.st_size = 0;
01081   stat(filename, &filestat);
01082   if (filestat.st_size != 0 ) {
01083     buf = malloc( sizeof(char) * (filestat.st_size+1) );
01084     memset(buf, 0, filestat.st_size+1);
01085   } else {
01086     fprintf(stderr, "Error: File %s not found.\n", filename);
01087     return 1;
01088   }
01089 
01090   fp = fopen(filename, "r");
01091   fread((void*)buf, filestat.st_size, 1, fp);
01092   fclose(fp);
01093 
01094   message = message_New();
01095   if ( 
01096       message_InitializeFromString (
01097       attr->mc_platform,
01098       message,
01099       buf,
01100       "",
01101       5050,
01102       "ams"
01103       )
01104      )
01105   {
01106     message_Destroy(message);
01107   }
01108   free(message->to_address);
01109   message->to_address = NULL;
01110   message->xml_root = mxmlLoadString(
01111       NULL,
01112       buf,
01113       NULL );
01114   if (message->xml_root == NULL) {
01115     fprintf(stderr, "Error loading agent. %s:%d\n", __FILE__, __LINE__);
01116     message_Destroy(message);
01117     return 1;
01118   }
01119   message->xml_payload = mxmlFindElement(
01120       message->xml_root,
01121       message->xml_root,
01122       "MOBILE_AGENT",
01123       NULL,
01124       NULL,
01125       MXML_DESCEND );
01126   if(message->xml_payload == NULL) {
01127     fprintf(stderr, "Error loading agent: <MOBILE_AGENT> tag not found. %s:%d\n",
01128         __FILE__, __LINE__ );
01129     message_Destroy(message);
01130     return 1;
01131   }
01132 
01133   message_queue_Add
01134     (
01135      attr->mc_platform->message_queue,
01136      message
01137     );
01138   return 0;
01139 }
01140 
01141 EXPORTMC int 
01142 MC_MutexLock(MCAgency_t attr, int id) 
01143 {
01144   syncListNode_t *syncnode;
01145   syncnode = syncListFind(id, attr->mc_platform->syncList);
01146   if (syncnode == NULL) {
01147     return 1;
01148   }
01149   MUTEX_LOCK(syncnode->lock);
01150   return 0;
01151 } 
01152 
01153 EXPORTMC int 
01154 MC_MutexUnlock(MCAgency_t attr, int id) 
01155 {
01156   syncListNode_t *syncnode;
01157   syncnode = syncListFind(id, attr->mc_platform->syncList);
01158   if (syncnode == NULL) {
01159     return 1;
01160   }
01161   MUTEX_UNLOCK(syncnode->lock);
01162   return 0;
01163 } 
01164 
01165 EXPORTMC int
01166 MC_PrintAgentCode(MCAgent_t agent) 
01167 {
01168   int progress;
01169   MUTEX_LOCK(agent->lock);
01170   progress = agent->datastate->task_progress;
01171   
01172   if (progress >= agent->datastate->number_of_tasks) {
01173     progress = agent->datastate->number_of_tasks - 1;
01174   }
01175   printf("%s\n",
01176       agent->datastate->agent_code);
01177   MUTEX_UNLOCK(agent->lock);
01178   return 0;
01179 } 
01180 
01181 EXPORTMC int 
01182 MC_RegisterService( 
01183     MCAgency_t agency,
01184     MCAgent_t agent,
01185     int agentID,
01186     const char *agentName,
01187     char **serviceNames,
01188     int numServices)
01189 {
01190   df_request_list_node_t *req_node;
01191   df_node_t *new_node;
01192   int i;
01193   
01194 
01195   if (agent == NULL && agentName == NULL) {
01196     return MC_ERR_INVALID_ARGS;
01197   }
01198   
01199   req_node = df_request_list_node_New();
01200   req_node->command = (char*)malloc(sizeof(char)*9);
01201   strcpy((char*)req_node->command, "register");
01202 
01203   new_node = (df_node_t*)malloc(sizeof(df_node_t));
01204   CHECK_NULL(new_node, return MC_ERR_MEMORY);
01205 
01206   
01207   new_node->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
01208   CHECK_NULL(new_node->lock, return MC_ERR_MEMORY);
01209   MUTEX_INIT(new_node->lock);
01210 
01211   
01212   if (agent==NULL) {
01213     new_node->agent_id = agentID;
01214   } else {
01215     new_node->agent_id = agent->id;
01216   }
01217 
01218   
01219   if (agent==NULL) {
01220     new_node->agent_name = 
01221       (char*)malloc(sizeof(char)*(strlen(agentName)+1));
01222     CHECK_NULL(new_node->agent_name, return MC_ERR_MEMORY;);
01223     strcpy(new_node->agent_name, agentName);
01224   } else {
01225     new_node->agent_name = 
01226       (char*)malloc(
01227           sizeof(char) * 
01228           (strlen(agent->name)+1)
01229           );
01230     CHECK_NULL(new_node->agent_name, return MC_ERR_MEMORY;);
01231     strcpy(new_node->agent_name, agent->name);
01232   }
01233 
01234   
01235   new_node->service_names = (char**)malloc(
01236       sizeof(char*) * numServices
01237       );
01238   CHECK_NULL(new_node->service_names, return MC_ERR_MEMORY;);
01239   for (i = 0; i < numServices; i++) {
01240     new_node->service_names[i] = (char*) malloc(
01241         sizeof(char) * (strlen(serviceNames[i]) + 1)
01242         );
01243     CHECK_NULL(new_node->service_names[i], return MC_ERR_MEMORY;);
01244     strcpy(
01245         new_node->service_names[i],
01246         serviceNames[i]
01247         );
01248   }
01249   new_node->num_services = numServices;
01250 
01251   req_node->data = (void*)new_node;
01252   req_node->data_size = (sizeof(new_node));
01253 
01254   return df_AddRequest(
01255       agency->mc_platform->df,
01256       req_node
01257       );
01258 } 
01259 
01260 EXPORTMC int 
01261 MC_ResumeAgency(MCAgency_t attr) 
01262 {
01263   MUTEX_LOCK(attr->mc_platform->giant_lock);
01264   attr->mc_platform->giant = 1;
01265   MUTEX_UNLOCK(attr->mc_platform->giant_lock);
01266   return 0;
01267 } 
01268 
01269 EXPORTMC MCAgent_t
01270 MC_RetrieveAgent(MCAgency_t attr) 
01271   
01272 
01273 
01274 {
01275   int i;
01276   MCAgent_t agent=NULL, ret;
01277   MUTEX_LOCK(attr->mc_platform->agent_queue->lock);
01278   for (i = 0; i < attr->mc_platform->agent_queue->size; i++) {
01279     agent = ListSearch(
01280         attr->mc_platform->agent_queue->list, i);
01281     if (agent->agent_status == MC_AGENT_NEUTRAL) {
01282       break;
01283     }
01284   }
01285   if (agent == NULL) {
01286     MUTEX_UNLOCK(attr->mc_platform->agent_queue->lock);
01287     return NULL;
01288   }
01289   if (agent->agent_status != MC_AGENT_NEUTRAL) {
01290     MUTEX_UNLOCK(attr->mc_platform->agent_queue->lock);
01291     return NULL;
01292   }
01293   ret = (MCAgent_t)malloc(sizeof(agent_t));
01294   *ret = *agent;
01295   MUTEX_UNLOCK(attr->mc_platform->agent_queue->lock);
01296   return ret;
01297 }
01298 
01299 EXPORTMC char * 
01300 MC_RetrieveAgentCode(MCAgent_t agent) 
01301 {
01302   char *buf;
01303   int len, progress;
01304   MUTEX_LOCK(agent->lock);
01305   progress = agent->datastate->task_progress;
01306   len = strlen(
01307       agent->datastate->agent_code);
01308   buf = (char*)malloc( (len+1)*sizeof(char));
01309   strcpy(buf,
01310       agent->datastate->agent_code);
01311   MUTEX_UNLOCK(agent->lock);
01312   return buf;
01313 } 
01314 
01315 EXPORTMC int 
01316 MC_ResetSignal(MCAgency_t attr) 
01317 {
01318   MUTEX_LOCK(attr->mc_platform->giant_lock);
01319   attr->mc_platform->giant = 1;
01320   attr->mc_platform->MC_signal = MC_NO_SIGNAL;
01321   COND_SIGNAL(attr->mc_platform->giant_cond);
01322   MUTEX_UNLOCK(attr->mc_platform->giant_lock);
01323   return 0;
01324 } 
01325 
01326 EXPORTMC int 
01327 MC_SearchForService( 
01328     
01329     MCAgency_t attr, 
01330     const char *searchString,
01331     
01332     char*** agentNames,
01333     char*** serviceNames,
01334     int** agentIDs,
01335     int* numResults)
01336 {
01337   df_request_search_p search;
01338   df_search_results_p results;
01339   df_request_list_node_p request;
01340   search = df_request_search_New();
01341   CHECK_NULL(search, return MC_ERR_MEMORY;);
01342   results = (df_search_results_p)malloc(sizeof(df_search_results_t));
01343   CHECK_NULL(results, return MC_ERR_MEMORY;);
01344   request = df_request_list_node_New();
01345   CHECK_NULL(request, return MC_ERR_MEMORY;);
01346 
01347 
01348   search->search_results = results;
01349   search->search_string = (char*)searchString;
01350 
01351   request->data = (void*)search;
01352   request->command = malloc(sizeof(char) * 7);
01353   strcpy((char*)request->command, "search");
01354   request->data_size = sizeof(df_request_search_t);
01355 
01356   COND_SLEEP_ACTION(
01357       search->cond,
01358       search->lock,
01359 
01360       df_AddRequest(attr->mc_platform->df, request);
01361       );
01362   
01363   *agentNames = search->search_results->agent_names;
01364   *serviceNames = search->search_results->service_names;
01365   *agentIDs = search->search_results->agent_ids;
01366   *numResults = search->search_results->num_results;
01367 
01368   
01369   free((void*)request->command);
01370   df_request_list_node_Destroy(request);
01371   df_request_search_Destroy(search);
01372 
01373   return MC_SUCCESS;
01374 } 
01375 
01376 EXPORTMC int 
01377 MC_SemaphorePost(MCAgency_t attr, int id) 
01378 {
01379   syncListNode_t *syncnode;
01380   syncnode = syncListFind(id, attr->mc_platform->syncList);
01381   if (syncnode == NULL) {
01382     return 1;
01383   }
01384   SEMAPHORE_POST(syncnode->sem);
01385   return 0;
01386 } 
01387 
01388 EXPORTMC int 
01389 MC_SemaphoreWait(MCAgency_t attr, int id) 
01390 {
01391   syncListNode_t *syncnode;
01392   syncnode = syncListFind(id, attr->mc_platform->syncList);
01393   if (syncnode == NULL) {
01394     return 1;
01395   }
01396   SEMAPHORE_WAIT(syncnode->sem);
01397   return 0;
01398 } 
01399 
01400 int
01401 MC_SendCh(MCAgency_t attr, 
01402     const char *filename,
01403     const char *remotehost,
01404     int port)
01405 {
01406   printf("Sorry, not implemented yet.\n");
01407   return -1;
01408 } 
01409 
01410 EXPORTMC int 
01411 MC_SendAgentMigrationMessage(MCAgency_t attr, 
01412     const char *string,
01413     const char *hostname,
01414     int port)
01415 {
01416   message_p message;
01417   message = message_New();
01418   if(
01419       message_InitializeFromString
01420       (
01421        attr->mc_platform,
01422        message,
01423        string,
01424        hostname,
01425        port,
01426        "ams"
01427       )
01428     )
01429   {
01430     message_Destroy(message);
01431     return MC_ERR;
01432   } else {
01433     return message_queue_Add
01434       (
01435        attr->mc_platform->message_queue,
01436        message
01437       );
01438   }
01439 } 
01440 
01441 EXPORTMC int
01442 MC_SendAgentMigrationMessageFile(MCAgency_t attr,  
01443     const char *filename, 
01444     const char *hostname,
01445     int port)
01446 {
01447   struct stat filestat;
01448   char *buf;
01449   FILE *fp;
01450   int ret;
01451   message_p message;
01452   extern mc_platform_p g_mc_platform;
01453   buf = NULL;
01454   filestat.st_size = 0;
01455   stat(filename, &filestat);
01456   if (filestat.st_size != 0 ) {
01457     buf = malloc( sizeof(char) * (filestat.st_size+1) );
01458     memset(buf, 0, filestat.st_size+1);
01459   } else {
01460     fprintf(stderr, "Error: File %s not found.\n", filename);
01461     return 1;
01462   }
01463 
01464   fp = fopen(filename, "r");
01465   fread((void*)buf, filestat.st_size, 1, fp);
01466   fclose(fp);
01467 
01468   if (attr!=NULL) {
01469     message = message_New();
01470     if( 
01471         message_InitializeFromString
01472         (
01473          attr->mc_platform,
01474          message,
01475          buf,
01476          hostname,
01477          port,
01478          "ams"
01479         )
01480       )
01481     {
01482       message_Destroy(message);
01483     } else {
01484       ret = message_queue_Add
01485         (
01486          attr->mc_platform->message_queue,
01487          message 
01488         );
01489     }
01490   } else {
01491     message = message_New();
01492     if(
01493         message_InitializeFromString
01494         (
01495          g_mc_platform,
01496          message,
01497          buf,
01498          hostname,
01499          port,
01500          "ams"
01501         )
01502       )
01503     {
01504       message_Destroy(message);
01505     } else {
01506       ret = message_queue_Add
01507         (
01508          g_mc_platform->message_queue,
01509          message
01510         );
01511     }
01512   }
01513   free(buf);
01514   return ret;
01515 } 
01516 
01517 EXPORTMC int 
01518 MC_SendSteerCommand(MCAgency_t attr, enum MC_SteerCommand_e cmd) 
01519 {
01520   MUTEX_LOCK(attr->mc_platform->MC_steer_lock);
01521   attr->mc_platform->MC_steer_command = cmd;
01522   COND_BROADCAST(attr->mc_platform->MC_steer_cond);
01523   MUTEX_UNLOCK(attr->mc_platform->MC_steer_lock);
01524   return 0;
01525 } 
01526 
01527 int
01528 MC_SetAgentStatus(MCAgent_t agent, int status) 
01529 {
01530   MUTEX_LOCK(agent->lock);
01531   agent->agent_status = status;
01532   if (!agent->orphan) {
01533     MUTEX_LOCK(agent->mc_platform->ams->runflag_lock);
01534     agent->mc_platform->ams->run = 1;
01535     COND_SIGNAL(agent->mc_platform->ams->runflag_cond);
01536     MUTEX_UNLOCK(agent->mc_platform->ams->runflag_lock);
01537   }
01538   MUTEX_UNLOCK(agent->lock);
01539   return 0;
01540 } 
01541 
01542 int 
01543 MC_SetDefaultAgentStatus(
01544     MCAgency_t agency,
01545     enum MC_AgentStatus_e status
01546     ) 
01547 {
01548   agency->mc_platform->default_agentstatus = status;
01549   return 0;
01550 } 
01551 
01552 EXPORTMC int 
01553 MC_SetThreadOn(MCAgencyOptions_t *options, enum MC_ThreadIndex_e index) 
01554 {
01555   SET_THREAD_ON(options->threads, index);
01556   return 0;
01557 } 
01558 
01559 EXPORTMC int 
01560 MC_SetThreadsAllOn(MCAgencyOptions_t* options)
01561 {
01562   int i;
01563   for(i = 0; i < MC_THREAD_ALL; i++) {
01564     SET_THREAD_ON(options->threads, i);
01565   }
01566   return 0;
01567 }
01568 
01569 EXPORTMC int
01570 MC_SetThreadOff(MCAgencyOptions_t *options, enum MC_ThreadIndex_e index) 
01571 {
01572   SET_THREAD_OFF(options->threads, index);
01573   return 0;
01574 } 
01575 
01576 EXPORTMC int
01577 MC_SetThreadsAllOff(MCAgencyOptions_t* options)
01578 {
01579   int i;
01580   for(i = 0; i < MC_THREAD_ALL; i++) {
01581     SET_THREAD_OFF(options->threads, i);
01582   }
01583   return 0;
01584 }
01585 
01586 EXPORTMC int 
01587 MC_Steer(                        
01588     MCAgency_t attr,
01589     int (*funcptr)(void* data),
01590     void *arg
01591     )
01592 {
01593   MUTEX_LOCK(attr->mc_platform->MC_steer_lock);
01594   do {
01595     attr->mc_platform->MC_steer_command = MC_RUN;
01596     MUTEX_UNLOCK(attr->mc_platform->MC_steer_lock);
01597     (*funcptr)(arg);
01598   } while 
01599   (
01600    attr->mc_platform->MC_steer_command == MC_RESTART 
01601   );
01602   return 0;
01603 } 
01604 
01605 EXPORTMC enum MC_SteerCommand_e 
01606 MC_SteerControl(void) 
01607 {
01608   extern mc_platform_p g_mc_platform;
01609   
01610   MUTEX_LOCK(g_mc_platform->MC_steer_lock);
01611   while (g_mc_platform->MC_steer_command == MC_SUSPEND) {
01612     COND_WAIT(
01613         g_mc_platform->MC_steer_cond,
01614         g_mc_platform->MC_steer_lock
01615         );
01616   }
01617   MUTEX_UNLOCK(g_mc_platform->MC_steer_lock);
01618   return g_mc_platform->MC_steer_command;
01619 } 
01620 
01621 EXPORTMC int 
01622 MC_SyncDelete(MCAgency_t attr, int id) 
01623 {
01624   syncListNode_t *sync_node;
01625   
01626   MUTEX_LOCK(attr->mc_platform->syncList->giant_lock);
01627 
01628   
01629   sync_node = syncListFind(id, attr->mc_platform->syncList);
01630   if (sync_node == NULL) {
01631     MUTEX_UNLOCK(attr->mc_platform->syncList->giant_lock);
01632     return MC_ERR_NOT_FOUND;
01633   }
01634   MUTEX_LOCK(sync_node->lock);
01635 
01636   
01637   if (syncListRemove(id, attr->mc_platform->syncList) == NULL) {
01638     fprintf(stderr, "Fatal error. %s:%d\n",
01639         __FILE__,
01640         __LINE__ );
01641     exit(0);
01642   }
01643 
01644   
01645   MUTEX_UNLOCK(sync_node->lock);
01646   MUTEX_UNLOCK(attr->mc_platform->syncList->giant_lock);
01647 
01648   return syncListNodeDestroy(sync_node);
01649 } 
01650 
01651 EXPORTMC int
01652 MC_SyncInit(MCAgency_t attr, int id) 
01653 {
01654   syncListNode_t *node;
01655   node = syncListNodeNew();
01656   MUTEX_LOCK(attr->mc_platform->syncList->giant_lock);
01657   if (id == 0) {
01658     id = rand();
01659   }
01660   while (
01661       syncListFind(id, attr->mc_platform->syncList) != NULL
01662       ) 
01663   {
01664     id = rand();
01665   }
01666 
01667   node->id = id;
01668   syncListAddNode(
01669       node,
01670       attr->mc_platform->syncList
01671       );
01672   MUTEX_UNLOCK(attr->mc_platform->syncList->giant_lock);
01673   return id;
01674 }
01675 
01676 EXPORTMC int 
01677 MC_TerminateAgent(MCAgent_t agent) 
01678 {
01679   int status=0;
01680   if(agent->agent_interp != NULL) {
01681     status = Ch_Abort (agent->agent_interp);
01682   }
01683   return status;
01684 } 
01685 
01686 
01687 #ifdef _WIN32
01688 EXPORTMC BOOL
01689 MC_MainLoop(MCAgency_t attr) 
01690 {
01691   
01692   Sleep (INFINITE);
01693   return 0;
01694 }
01695 #else
01696 int 
01697 MC_MainLoop(MCAgency_t attr) 
01698 {
01699   return pthread_join(attr->mc_platform->ams->thread, NULL);
01700 } 
01701 #endif
01702 
01703 EXPORTMC int
01704 MC_WaitAgent(MCAgency_t attr) 
01705 {
01706   int size;
01707   MUTEX_LOCK(attr->mc_platform->agent_queue->lock);
01708   while(1) {
01709     size = attr->mc_platform->agent_queue->size;
01710     COND_WAIT(
01711         attr->mc_platform->agent_queue->cond,
01712         attr->mc_platform->agent_queue->lock
01713         );
01714     if (size < attr->mc_platform->agent_queue->size) {
01715       MUTEX_UNLOCK(attr->mc_platform->agent_queue->lock);
01716       break;
01717     } 
01718   }
01719   MUTEX_UNLOCK(attr->mc_platform->agent_queue->lock);
01720   return 0;
01721 } 
01722 
01723 EXPORTMC MCAgent_t
01724 MC_WaitRetrieveAgent(MCAgency_t attr) 
01725 {
01726   int index;
01727   MCAgent_t agent;
01728   MC_WaitSignal(attr, MC_RECV_AGENT);
01729   MUTEX_LOCK(attr->mc_platform->agent_queue->lock);
01730   index = attr->mc_platform->agent_queue->size-1;
01731   agent = ListSearch(
01732       attr->mc_platform->agent_queue->list, index);
01733   MUTEX_UNLOCK(attr->mc_platform->agent_queue->lock);
01734   return agent;
01735 } 
01736 
01737 
01738 
01739 
01740 
01741 EXPORTMC int
01742 MC_WaitSignal(MCAgency_t attr, int signals) 
01743 {
01744   MUTEX_LOCK(attr->mc_platform->MC_signal_lock);
01745   while(! (signals & attr->mc_platform->MC_signal)) {
01746     COND_WAIT(
01747         attr->mc_platform->MC_signal_cond,
01748         attr->mc_platform->MC_signal_lock
01749         );
01750   }
01751   MUTEX_UNLOCK(attr->mc_platform->MC_signal_lock);
01752   MUTEX_LOCK(attr->mc_platform->giant_lock);
01753   attr->mc_platform->giant = 0;
01754   MUTEX_UNLOCK(attr->mc_platform->giant_lock);
01755   return 0;
01756 } 
01757 
01758 
01759 
01760 
01761 
01762 
01763 int MC_AclDestroy_chdl(void* varg)
01764 {
01765   int retval;
01766   fipa_acl_message_t* acl_message;
01767   ChInterp_t interp;
01768   ChVaList_t ap;
01769 
01770   Ch_VaStart(interp, ap, varg);
01771   acl_message = Ch_VaArg(interp, ap, fipa_acl_message_t*);
01772   retval = MC_AclDestroy(acl_message);
01773   Ch_VaEnd(interp, ap);
01774   return retval;
01775 }
01776 
01777 
01778 void* MC_AclNew_chdl(void* varg)
01779 {
01780   void* retval;
01781   retval = (void*)MC_AclNew();
01782   return retval;
01783 }
01784 
01785 
01786 int MC_AclPost_chdl(void* varg)
01787 {
01788   int retval;
01789   agent_p agent;
01790   fipa_acl_message_t* acl_message;
01791   ChInterp_t interp;
01792   ChVaList_t ap;
01793 
01794   Ch_VaStart(interp, ap, varg);
01795   agent = Ch_VaArg(interp, ap, agent_p);
01796   acl_message = Ch_VaArg(interp, ap, fipa_acl_message_t*);
01797   retval = MC_AclPost(agent, acl_message);
01798   Ch_VaEnd(interp, ap);
01799   return retval;
01800 }
01801 
01802 
01803 EXPORTCH void*
01804 MC_AclReply_chdl(void* varg)
01805 {
01806   void* retval;
01807   fipa_acl_message_t* acl_message;
01808   ChInterp_t interp;
01809   ChVaList_t ap;
01810 
01811   Ch_VaStart(interp, ap, varg);
01812   acl_message = Ch_VaArg(interp, ap, fipa_acl_message_t*);
01813   retval = (void*)MC_AclReply(acl_message);
01814   Ch_VaEnd(interp, ap);
01815   return retval;
01816 }
01817 
01818 
01819 EXPORTCH void*
01820 MC_AclRetrieve_chdl(void* varg)
01821 {
01822   void* retval;
01823   MCAgent_t agent;
01824   ChInterp_t interp;
01825   ChVaList_t ap;
01826 
01827   Ch_VaStart(interp, ap, varg);
01828   agent = Ch_VaArg(interp, ap, MCAgent_t);
01829   retval = MC_AclRetrieve(agent);
01830   Ch_VaEnd(interp, ap);
01831   return retval;
01832 }
01833 
01834 
01835 EXPORTCH int
01836 MC_AclSend_chdl(void* varg)
01837 {
01838   int retval;
01839   fipa_acl_message_t* acl_message;
01840   MCAgency_t temp_attr;
01841   extern mc_platform_p g_mc_platform;
01842 
01843   ChInterp_t interp;
01844   ChVaList_t ap;
01845 
01846   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
01847   CHECK_NULL(temp_attr, exit(-1));
01848   temp_attr->mc_platform = g_mc_platform;
01849 
01850   Ch_VaStart(interp, ap, varg);
01851   acl_message = (fipa_acl_message_t*) Ch_VaArg(interp, ap, void*);
01852   retval = MC_AclSend(temp_attr, acl_message);
01853   Ch_VaEnd(interp, ap);
01854   free(temp_attr);
01855   return retval;
01856 }
01857 
01858 
01859 EXPORTCH void*
01860 MC_AclWaitRetrieve_chdl(void *varg)
01861 {
01862   void* retval;
01863   MCAgent_t agent;
01864   ChInterp_t interp;
01865   ChVaList_t ap;
01866 
01867   Ch_VaStart(interp, ap, varg);
01868   agent = Ch_VaArg(interp, ap, MCAgent_t);
01869   retval = MC_AclWaitRetrieve(agent);
01870   Ch_VaEnd(interp, ap);
01871   return retval;
01872 }
01873 
01874 
01875 
01876 
01877 EXPORTCH int
01878 MC_AclSetPerformative_chdl(void* varg)
01879 {
01880   ChInterp_t interp;
01881   ChVaList_t ap;
01882   struct fipa_acl_message_s* acl;
01883   enum fipa_performative_e performative;
01884   int retval;
01885 
01886   Ch_VaStart(interp, ap, varg);
01887   acl = Ch_VaArg(interp, ap, struct fipa_acl_message_s*);
01888   performative = Ch_VaArg(interp, ap, enum fipa_performative_e);
01889   retval = MC_AclSetPerformative(acl, performative);
01890   Ch_VaEnd(interp, ap);
01891   return retval;
01892 }
01893 
01894 
01895 EXPORTCH int
01896 MC_AclSetSender_chdl(void* varg)
01897 {
01898   ChInterp_t interp;
01899   ChVaList_t ap;
01900   struct fipa_acl_message_s* acl;
01901   char* name;
01902   char* address;
01903   int retval;
01904 
01905   Ch_VaStart(interp, ap, varg);
01906   acl = Ch_VaArg(interp, ap, struct fipa_acl_message_s*);
01907   name = Ch_VaArg(interp, ap, char*);
01908   address = Ch_VaArg(interp, ap, char*);
01909   retval = MC_AclSetSender(acl, name, address);
01910   Ch_VaEnd(interp, ap);
01911   return retval;
01912 }
01913 
01914 
01915 EXPORTCH int
01916 MC_AclAddReceiver_chdl(void* varg)
01917 {
01918   ChInterp_t interp;
01919   ChVaList_t ap;
01920   struct fipa_acl_message_s* acl;
01921   char* name;
01922   char* address;
01923   int retval;
01924 
01925   Ch_VaStart(interp, ap, varg);
01926   acl = Ch_VaArg(interp, ap, struct fipa_acl_message_s*);
01927   name = Ch_VaArg(interp, ap, char*);
01928   address = Ch_VaArg(interp, ap, char*);
01929   retval = MC_AclAddReceiver(acl, name, address);
01930   Ch_VaEnd(interp, ap);
01931   return retval;
01932 }
01933 
01934 
01935 EXPORTCH int
01936 MC_AclAddReplyTo_chdl(void* varg)
01937 {
01938   ChInterp_t interp;
01939   ChVaList_t ap;
01940   struct fipa_acl_message_s* acl;
01941   char* name;
01942   char* address;
01943   int retval;
01944 
01945   Ch_VaStart(interp, ap, varg);
01946   acl = Ch_VaArg(interp, ap, struct fipa_acl_message_s*);
01947   name = Ch_VaArg(interp, ap, char*);
01948   address = Ch_VaArg(interp, ap, char*);
01949   retval = MC_AclAddReplyTo(acl, name, address);
01950   Ch_VaEnd(interp, ap);
01951   return retval;
01952 }
01953 
01954 
01955 EXPORTCH int
01956 MC_AclSetContent_chdl(void* varg)
01957 {
01958   ChInterp_t interp;
01959   ChVaList_t ap;
01960   struct fipa_acl_message_s* acl;
01961   char* content;
01962   int retval;
01963 
01964   Ch_VaStart(interp, ap, varg);
01965   acl = Ch_VaArg(interp, ap, struct fipa_acl_message_s*);
01966   content = Ch_VaArg(interp, ap, char*);
01967   retval = MC_AclSetContent(acl, content);
01968   Ch_VaEnd(interp, ap);
01969   return retval;
01970 }
01971 
01972 
01973 
01974 
01975 EXPORTCH int
01976 MC_AddAgent_chdl(void *varg) 
01977 {
01978   int retval;
01979   MCAgent_t agent;
01980   MCAgency_t temp_attr;
01981   extern mc_platform_p g_mc_platform;
01982 
01983   ChInterp_t interp;
01984   ChVaList_t ap;
01985 
01986   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
01987   CHECK_NULL(temp_attr, exit(-1));
01988   temp_attr->mc_platform = g_mc_platform;
01989 
01990   Ch_VaStart(interp, ap, varg);
01991   agent = (MCAgent_t) Ch_VaArg(interp, ap, void*);
01992   retval = MC_AddAgent(temp_attr, agent);
01993   Ch_VaEnd(interp, ap);
01994   free(temp_attr);
01995   return retval;
01996 } 
01997 
01998 
01999 EXPORTCH const void*
02000 MC_AgentVariableRetrieve_chdl(void* varg)
02001 {
02002   void* retval;
02003   MCAgent_t agent;
02004   const char* var_name;
02005   int task_num;
02006 
02007   ChInterp_t interp;
02008   ChVaList_t ap;
02009 
02010   Ch_VaStart(interp, ap, varg);
02011 
02012   agent = Ch_VaArg(interp, ap, MCAgent_t);
02013   var_name = Ch_VaArg(interp, ap, const char* );
02014   task_num = Ch_VaArg(interp, ap, int);
02015 
02016   retval = MC_AgentVariableRetrieve(agent, var_name, task_num);
02017 
02018   Ch_VaEnd(interp, ap);
02019   return retval;
02020 }
02021 
02022 
02023 EXPORTCH int
02024 MC_AgentVariableSave_chdl(void *varg)
02025 {
02026   int retval;
02027   MCAgent_t agent;
02028   const char* var_name;
02029 
02030   ChInterp_t interp;
02031   ChVaList_t ap;
02032 
02033   Ch_VaStart(interp, ap, varg);
02034 
02035   agent = Ch_VaArg(interp, ap, MCAgent_t);
02036   var_name = Ch_VaArg(interp, ap, const char*);
02037 
02038   retval = MC_AgentVariableSave(agent, var_name);
02039 
02040   Ch_VaEnd(interp, ap);
02041   return retval;
02042 }
02043 
02044 
02045 EXPORTCH int
02046 MC_CallAgentFunc_chdl(void *varg) 
02047 {
02048   int retval;
02049   
02050   MCAgent_t agent;
02051   const char* funcName;
02052   void* returnVal;
02053   ChVaList_t args;
02054 
02055   ChInterp_t interp;
02056   ChVaList_t ap;
02057 
02058   Ch_VaStart(interp, ap, varg);
02059 
02060   agent =     Ch_VaArg(interp, ap, MCAgent_t);
02061   funcName =  Ch_VaArg(interp, ap, const char*);
02062   returnVal = Ch_VaArg(interp, ap, void*);
02063   args =      Ch_VaArg(interp, ap, void*);
02064 
02065   retval = MC_CallAgentFuncVar(
02066       agent,
02067       funcName,
02068       returnVal,
02069       args);
02070   Ch_VaEnd(interp, ap);
02071   return retval;
02072 } 
02073 
02074 
02075 EXPORTCH int
02076 MC_Barrier_chdl(void *varg) 
02077 {
02078   MCAgency_t temp_attr;
02079   extern mc_platform_p g_mc_platform;
02080   int retval;
02081   ChInterp_t interp;
02082   ChVaList_t ap;
02083   int id;
02084 
02085   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02086   CHECK_NULL(temp_attr, exit(-1));
02087   temp_attr->mc_platform = g_mc_platform;
02088 
02089   Ch_VaStart(interp, ap, varg);
02090   id = Ch_VaArg(interp, ap, int);
02091   retval = MC_Barrier(temp_attr, id);
02092   Ch_VaEnd(interp, ap);
02093   free(temp_attr);
02094   return retval;
02095 } 
02096 
02097 
02098 EXPORTCH int
02099 MC_BarrierDelete_chdl(void *varg) 
02100 {
02101   MCAgency_t temp_attr;
02102   extern mc_platform_p g_mc_platform;
02103   int retval;
02104   ChInterp_t interp;
02105   ChVaList_t ap;
02106   int id;
02107 
02108   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02109   CHECK_NULL(temp_attr, exit(-1));
02110   temp_attr->mc_platform = g_mc_platform;
02111 
02112   Ch_VaStart(interp, ap, varg);
02113   id = Ch_VaArg(interp, ap, int);
02114   retval = MC_BarrierDelete(temp_attr, id);
02115   Ch_VaEnd(interp, ap);
02116   free(temp_attr);
02117   return retval;
02118 } 
02119 
02120 
02121 EXPORTCH int
02122 MC_BarrierInit_chdl(void *varg) 
02123 {
02124   MCAgency_t temp_attr;
02125   extern mc_platform_p g_mc_platform;
02126   int retval;
02127   ChInterp_t interp;
02128   ChVaList_t ap;
02129   int id;
02130   int num_procs;
02131 
02132   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02133   CHECK_NULL(temp_attr, exit(-1));
02134   temp_attr->mc_platform = g_mc_platform;
02135 
02136   Ch_VaStart(interp, ap, varg);
02137   id = Ch_VaArg(interp, ap, int);
02138   num_procs = Ch_VaArg(interp, ap, int);
02139   retval = MC_BarrierInit(temp_attr, id, num_procs);
02140   Ch_VaEnd(interp, ap);
02141   free(temp_attr);
02142   return retval;
02143 } 
02144 
02145 
02146 EXPORTCH int
02147 MC_CondBroadcast_chdl(void *varg) 
02148 {
02149   MCAgency_t temp_attr;
02150   extern mc_platform_p g_mc_platform;
02151   int retval;
02152   ChInterp_t interp;
02153   ChVaList_t ap;
02154   int id;
02155 
02156   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02157   CHECK_NULL(temp_attr, exit(-1));
02158   temp_attr->mc_platform = g_mc_platform;
02159 
02160   Ch_VaStart(interp, ap, varg);
02161   id = Ch_VaArg(interp, ap, int);
02162   retval = MC_CondBroadcast(temp_attr, id);
02163   Ch_VaEnd(interp, ap);
02164   free(temp_attr);
02165   return retval;
02166 } 
02167 
02168 
02169 EXPORTCH MCAgent_t 
02170 MC_ComposeAgent_chdl(void *varg) 
02171 {
02172   MCAgent_t retval;
02173 
02174   
02175   const char* name;
02176   const char* home;
02177   const char* owner;  
02178   const char* code;
02179   const char* return_var_name;
02180   const char* server;
02181   int persistent;
02182 
02183   ChInterp_t interp;
02184   ChVaList_t ap;
02185 
02186   Ch_VaStart(interp, ap, varg);
02187 
02188   name  = Ch_VaArg(interp, ap, const char*);
02189   home  = Ch_VaArg(interp, ap, const char*);
02190   owner = Ch_VaArg(interp, ap, const char*);
02191   code = Ch_VaArg(interp, ap, const char*);
02192   return_var_name = Ch_VaArg(interp, ap, const char*);
02193   server = Ch_VaArg(interp, ap, const char*);
02194   persistent = Ch_VaArg(interp, ap, int);
02195 
02196   retval= MC_ComposeAgent(
02197       name,
02198       home,
02199       owner,
02200       code,
02201       return_var_name,
02202       server,
02203       persistent);
02204   Ch_VaEnd(interp, ap);
02205   return retval;
02206 } 
02207 
02208 
02209 EXPORTCH int
02210 MC_CondSignal_chdl(void *varg) 
02211 {
02212   MCAgency_t temp_attr;
02213   extern mc_platform_p g_mc_platform;
02214   int retval;
02215   ChInterp_t interp;
02216   ChVaList_t ap;
02217   int id;
02218 
02219   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02220   CHECK_NULL(temp_attr, exit(-1));
02221   temp_attr->mc_platform = g_mc_platform;
02222 
02223   Ch_VaStart(interp, ap, varg);
02224   id = Ch_VaArg(interp, ap, int);
02225   retval = MC_CondSignal(temp_attr, id);
02226   Ch_VaEnd(interp, ap);
02227   free(temp_attr);
02228   return retval;
02229 } 
02230 
02231 
02232 EXPORTCH int
02233 MC_CondReset_chdl(void *varg)    
02234 {
02235   MCAgency_t temp_attr;
02236   extern mc_platform_p g_mc_platform;
02237   int retval;
02238   ChInterp_t interp;
02239   ChVaList_t ap;
02240   int id;
02241 
02242   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02243   CHECK_NULL(temp_attr, exit(-1));
02244   temp_attr->mc_platform = g_mc_platform;
02245 
02246   Ch_VaStart(interp, ap, varg);
02247   id = Ch_VaArg(interp, ap, int);
02248   retval = MC_CondReset(temp_attr, id);
02249   Ch_VaEnd(interp, ap);
02250   free(temp_attr);
02251   return retval;
02252 } 
02253 
02254 
02255 EXPORTCH int
02256 MC_CondWait_chdl(void *varg) 
02257 {
02258   MCAgency_t temp_attr;
02259   extern mc_platform_p g_mc_platform;
02260   int retval;
02261   ChInterp_t interp;
02262   ChVaList_t ap;
02263   int id;
02264 
02265   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02266   CHECK_NULL(temp_attr, exit(-1));
02267   temp_attr->mc_platform = g_mc_platform;
02268 
02269   Ch_VaStart(interp, ap, varg);
02270   id = Ch_VaArg(interp, ap, int);
02271   retval = MC_CondWait(temp_attr, id);
02272   Ch_VaEnd(interp, ap);
02273   free(temp_attr);
02274   return retval;
02275 } 
02276 
02277 EXPORTCH int
02278 MC_DeleteAgent_chdl(void *varg) 
02279 {
02280   ChInterp_t interp;
02281   ChVaList_t ap;
02282   MCAgent_t agent;
02283   int retval;
02284 
02285   Ch_VaStart(interp, ap, varg);
02286   agent = Ch_VaArg(interp, ap, MCAgent_t);
02287   retval = MC_DeleteAgent(agent);
02288   Ch_VaEnd(interp, ap);
02289   return retval;
02290 } 
02291 
02292 EXPORTCH int
02293 MC_DestroyServiceSearchResult_chdl(void* varg)
02294 {
02295   ChInterp_t interp;
02296   ChVaList_t ap;
02297   char** agentName;
02298   char** serviceName;
02299   int* agentID;
02300   int numResult;
02301   int retval;
02302 
02303   Ch_VaStart(interp, ap, varg);
02304   agentName = Ch_VaArg(interp, ap, char**);
02305   serviceName = Ch_VaArg(interp, ap, char**);
02306   agentID = Ch_VaArg(interp, ap, int*);
02307   numResult = Ch_VaArg(interp, ap, int);
02308 
02309   retval = MC_DestroyServiceSearchResult(
02310       agentName,
02311       serviceName,
02312       agentID,
02313       numResult );
02314   Ch_VaEnd(interp, ap);
02315   return retval;
02316 }
02317 
02318 
02319 EXPORTCH int
02320 MC_DeregisterService_chdl(void *varg) 
02321 {
02322   ChInterp_t interp;
02323   ChVaList_t ap;
02324   MCAgency_t temp_attr;
02325   extern mc_platform_p g_mc_platform;
02326   int agentID;
02327   char *serviceName;
02328   int retval;
02329 
02330   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02331   CHECK_NULL(temp_attr, exit(-1));
02332   temp_attr->mc_platform = g_mc_platform;
02333 
02334   Ch_VaStart(interp, ap, varg);
02335   agentID = Ch_VaArg(interp, ap, int);
02336   serviceName = (char*)Ch_VaArg(interp, ap, const char*);
02337   retval = MC_DeregisterService(
02338       temp_attr,
02339       agentID,
02340       serviceName );
02341   Ch_VaEnd(interp, ap);
02342   free(temp_attr);
02343   return retval;
02344 } 
02345 
02346 EXPORTCH int
02347 MC_End_chdl(void *varg) 
02348 {
02349   MCAgency_t temp_attr;
02350   extern mc_platform_p g_mc_platform;
02351   int retval;
02352 
02353   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02354   CHECK_NULL(temp_attr, exit(-1));
02355   temp_attr->mc_platform = g_mc_platform;
02356 
02357   retval = MC_End(temp_attr);
02358 
02359   return retval;
02360 } 
02361 
02362 
02363 EXPORTCH MCAgent_t
02364 MC_FindAgentByID_chdl(void *varg) 
02365 {
02366   MCAgency_t temp_attr;
02367   extern mc_platform_p g_mc_platform;
02368   MCAgent_t retval;
02369   ChInterp_t interp;
02370   ChVaList_t ap;
02371   int id;
02372 
02373   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02374   CHECK_NULL(temp_attr, exit(-1));
02375   temp_attr->mc_platform = g_mc_platform;
02376 
02377   Ch_VaStart(interp, ap, varg);
02378   id = Ch_VaArg(interp, ap, int);
02379   retval = MC_FindAgentByID(temp_attr, id);
02380   Ch_VaEnd(interp, ap);
02381   free(temp_attr);
02382   return retval;
02383 } 
02384 
02385 
02386 EXPORTCH MCAgent_t
02387 MC_FindAgentByName_chdl(void *varg) 
02388 {
02389   MCAgency_t temp_attr;
02390   extern mc_platform_p g_mc_platform;
02391   MCAgent_t retval;
02392   ChInterp_t interp;
02393   ChVaList_t ap;
02394   const char *name;
02395 
02396   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02397   CHECK_NULL(temp_attr, exit(-1));
02398   temp_attr->mc_platform = g_mc_platform;
02399 
02400   Ch_VaStart(interp, ap, varg);
02401   name = Ch_VaArg(interp, ap, const char *);
02402   retval = MC_FindAgentByName(temp_attr, name);
02403   Ch_VaEnd(interp, ap);
02404   free(temp_attr);
02405   return retval;
02406 } 
02407 
02408 
02409 #ifndef _WIN32
02410 EXPORTCH time_t
02411 #else
02412 EXPORTCH SYSTEMTIME
02413 #endif
02414 MC_GetAgentArrivalTime_chdl(void *varg) 
02415 {
02416   MCAgent_t agent;
02417   ChInterp_t interp;
02418   ChVaList_t ap;
02419 #ifndef _WIN32
02420   time_t arrival_time;
02421 #else
02422   SYSTEMTIME arrival_time;
02423 #endif
02424 
02425   Ch_VaStart(interp, ap, varg);
02426   agent = Ch_VaArg(interp, ap, MCAgent_t);
02427   arrival_time = MC_GetAgentArrivalTime(agent);
02428   Ch_VaEnd(interp, ap);
02429   return arrival_time;
02430 } 
02431 
02432 
02433 EXPORTCH int
02434 MC_GetAgentID_chdl(void *varg) 
02435 {
02436   MCAgent_t agent;
02437   ChInterp_t interp;
02438   ChVaList_t ap;
02439   int id;
02440 
02441   Ch_VaStart(interp, ap, varg);
02442   agent = Ch_VaArg(interp, ap, MCAgent_t);
02443   id = MC_GetAgentID(agent);
02444   Ch_VaEnd(interp, ap);
02445   return id;
02446 } 
02447 
02448 
02449 EXPORTCH char*
02450 MC_GetAgentName_chdl(void *varg) 
02451 {
02452   MCAgent_t agent;
02453   ChInterp_t interp;
02454   ChVaList_t ap;
02455   char* name;
02456 
02457   Ch_VaStart(interp, ap, varg);
02458   agent = Ch_VaArg(interp, ap, MCAgent_t);
02459   name = MC_GetAgentName(agent);
02460   Ch_VaEnd(interp, ap);
02461   return name;
02462 } 
02463 
02464 
02465 EXPORTCH int
02466 MC_GetAgentNumTasks_chdl(void *varg)
02467 {
02468   MCAgent_t agent;
02469   ChInterp_t interp;
02470   ChVaList_t ap;
02471   int num_tasks;
02472 
02473   Ch_VaStart(interp, ap, varg);
02474   agent = Ch_VaArg(interp, ap, MCAgent_t);
02475   num_tasks = MC_GetAgentNumTasks(agent);
02476   Ch_VaEnd(interp, ap);
02477   return num_tasks;
02478 }
02479 
02480 
02481 EXPORTCH int
02482 MC_GetAgentStatus_chdl(void *varg) 
02483 {
02484   MCAgent_t agent;
02485   int status;
02486   ChInterp_t interp;
02487   ChVaList_t ap;
02488 
02489   Ch_VaStart(interp, ap, varg);
02490   agent = Ch_VaArg(interp, ap, MCAgent_t);
02491   status = MC_GetAgentStatus(agent);
02492   Ch_VaEnd(interp, ap);
02493   return status;
02494 } 
02495 
02496 
02497 EXPORTCH char *
02498 MC_GetAgentXMLString_chdl(void *varg) 
02499 {
02500   ChInterp_t interp;
02501   ChVaList_t ap;
02502   MCAgent_t agent;
02503   char *retval;
02504 
02505   Ch_VaStart(interp, ap, varg);
02506   agent = Ch_VaArg(interp, ap, MCAgent_t);
02507   retval = MC_GetAgentXMLString(agent);
02508   Ch_VaEnd(interp, ap);
02509   return retval;
02510 } 
02511 
02512 #ifndef _WIN32
02513 EXPORTCH int
02514 MC_GetTimeOfDay_chdl(void *varg)
02515 {
02516   ChInterp_t interp;
02517   ChVaList_t ap;
02518   struct timeval *tv;
02519   Ch_VaStart(interp, ap, varg);
02520   tv = Ch_VaArg(interp, ap, struct timeval*);
02521   gettimeofday(tv, NULL);
02522   Ch_VaEnd(interp, ap);
02523   return 0;
02524 }
02525 #endif
02526 
02527 
02528 EXPORTCH int
02529 MC_HaltAgency_chdl(void *varg)
02530 {
02531   MCAgency_t temp_attr;
02532   int retval;
02533   extern mc_platform_p g_mc_platform;
02534 
02535   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02536   CHECK_NULL(temp_attr, exit(-1));
02537   temp_attr->mc_platform = g_mc_platform;
02538 
02539   retval = MC_HaltAgency(temp_attr);
02540 
02541   free(temp_attr);
02542   return retval;
02543 }
02544 
02545 
02546 EXPORTCH int
02547 MC_MutexLock_chdl(void *varg) 
02548 {
02549   MCAgency_t temp_attr;
02550   extern mc_platform_p g_mc_platform;
02551 
02552   ChInterp_t interp;
02553   ChVaList_t ap;
02554   int id;
02555   int retval;
02556 
02557   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02558   CHECK_NULL(temp_attr, exit(-1));
02559   temp_attr->mc_platform = g_mc_platform;
02560 
02561   Ch_VaStart(interp, ap, varg);
02562   id = Ch_VaArg(interp, ap, int );
02563   retval = MC_MutexLock(temp_attr, id);
02564   Ch_VaEnd(interp, ap);
02565   free(temp_attr);
02566   return retval;
02567 } 
02568 
02569 
02570 EXPORTCH int
02571 MC_MutexUnlock_chdl(void *varg) 
02572 {
02573   MCAgency_t temp_attr;
02574   extern mc_platform_p g_mc_platform;
02575 
02576   ChInterp_t interp;
02577   ChVaList_t ap;
02578   int id;
02579   int retval;
02580 
02581   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02582   CHECK_NULL(temp_attr, exit(-1));
02583   temp_attr->mc_platform = g_mc_platform;
02584 
02585   Ch_VaStart(interp, ap, varg);
02586   id = Ch_VaArg(interp, ap, int );
02587   retval = MC_MutexUnlock(temp_attr, id);
02588   Ch_VaEnd(interp, ap);
02589   free(temp_attr);
02590   return retval;
02591 } 
02592 
02593 
02594 EXPORTCH int
02595 MC_PrintAgentCode_chdl(void *varg) 
02596 {
02597   ChInterp_t interp;
02598   ChVaList_t ap;
02599   MCAgent_t agent;
02600   int retval;
02601 
02602   Ch_VaStart(interp, ap, varg);
02603   agent = Ch_VaArg(interp, ap, MCAgent_t);
02604   retval = MC_PrintAgentCode(agent);
02605   Ch_VaEnd(interp, ap);
02606   return retval;
02607 } 
02608 
02609 
02610 EXPORTCH int
02611 MC_RegisterService_chdl(void *varg) 
02612 {
02613   ChInterp_t interp;
02614   ChVaList_t ap;
02615   int retval;
02616   MCAgency_t temp_attr;
02617   extern mc_platform_p g_mc_platform;
02618 
02619   
02620   MCAgent_t agent;
02621   char **serviceNames;
02622   int numServices;
02623 
02624   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02625   CHECK_NULL(temp_attr, exit(-1));
02626   temp_attr->mc_platform = g_mc_platform;
02627 
02628   Ch_VaStart(interp, ap, varg);
02629   agent = Ch_VaArg(interp, ap, MCAgent_t);
02630   serviceNames = Ch_VaArg(interp, ap, char **);
02631   numServices = Ch_VaArg(interp, ap, int);
02632 
02633   retval = MC_RegisterService(
02634       temp_attr,      
02635       agent,           
02636       0,              
02637       NULL,           
02638       serviceNames,   
02639       numServices
02640       );
02641   Ch_VaEnd(interp, ap);
02642   free(temp_attr);
02643   return retval;
02644 } 
02645 
02646 
02647 EXPORTCH int
02648 MC_ResumeAgency_chdl(void *varg)
02649 {
02650   MCAgency_t temp_attr;
02651   int retval;
02652   extern mc_platform_p g_mc_platform;
02653 
02654   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02655   CHECK_NULL(temp_attr, exit(-1));
02656   temp_attr->mc_platform = g_mc_platform;
02657 
02658   retval = MC_ResumeAgency(temp_attr);
02659 
02660   free(temp_attr);
02661   return retval;
02662 }
02663 
02664 
02665 EXPORTCH MCAgent_t
02666 MC_RetrieveAgent_chdl(void *varg) 
02667 {
02668   MCAgency_t temp_attr;
02669   extern mc_platform_p g_mc_platform;
02670   MCAgent_t agent;
02671 
02672   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02673   CHECK_NULL(temp_attr, exit(-1));
02674   temp_attr->mc_platform = g_mc_platform;
02675 
02676   agent = MC_RetrieveAgent(temp_attr);
02677   free(temp_attr);
02678   return agent;
02679 } 
02680 
02681 
02682 EXPORTCH char *
02683 MC_RetrieveAgentCode_chdl(void *varg) 
02684 {
02685   ChInterp_t interp;
02686   ChVaList_t ap;
02687   MCAgent_t agent;
02688   char *retval;
02689 
02690   Ch_VaStart(interp, ap, varg);
02691   agent = Ch_VaArg(interp, ap, MCAgent_t);
02692   retval = MC_RetrieveAgentCode(agent);
02693   Ch_VaEnd(interp, ap);
02694   return retval;
02695 } 
02696 
02697 
02698 EXPORTCH int
02699 MC_SaveData_chdl(void* varg)
02700 {
02701   ChInterp_t interp;
02702   ChVaList_t ap;
02703   interpreter_variable_data_p interp_var_data;
02704   MCAgent_t agent;
02705   int progress;
02706   const char* name;
02707   int size;
02708   void* data;
02709   
02710   Ch_VaStart(interp, ap, varg);
02711   agent = Ch_VaArg(interp, ap, MCAgent_t);
02712   name = Ch_VaArg(interp, ap, char*);
02713   size = Ch_VaArg(interp, ap, int);
02714   data = Ch_VaArg(interp, ap, void*);
02715 
02716   progress = agent->datastate->task_progress;
02717 
02718   interp_var_data = interpreter_variable_data_New();
02719   interp_var_data->name = strdup(name);
02720   interp_var_data->size = size;
02721   interp_var_data->data_type = CH_VOIDPTRTYPE;
02722   interp_var_data->data = malloc(size);
02723   memcpy(interp_var_data->data, data, size);
02724 
02725   agent_variable_list_Add(
02726       agent->datastate->tasks[progress]->agent_variable_list,
02727       interp_var_data );
02728 
02729   return 0;
02730 }
02731 
02732 
02733 EXPORTCH int
02734 MC_SearchForService_chdl(void *varg) 
02735 {
02736   ChInterp_t interp;
02737   ChVaList_t ap;
02738   int retval;
02739   MCAgency_t temp_attr;
02740   extern mc_platform_p g_mc_platform;
02741 
02742   
02743   const char* searchString;
02744   char*** agentNames;
02745   char*** serviceNames;
02746   int** agentIDs;
02747   int* numResults;
02748 
02749   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02750   CHECK_NULL(temp_attr, exit(-1));
02751   temp_attr->mc_platform = g_mc_platform;
02752 
02753   Ch_VaStart(interp, ap, varg);
02754   searchString = Ch_VaArg(interp, ap, const char*);
02755   agentNames = Ch_VaArg(interp, ap, char***);
02756   serviceNames = Ch_VaArg(interp, ap, char***);
02757   agentIDs = Ch_VaArg(interp, ap, int**);
02758   numResults = Ch_VaArg(interp, ap, int*);
02759 
02760   retval = MC_SearchForService(
02761       temp_attr,
02762       searchString,
02763       agentNames,
02764       serviceNames,
02765       agentIDs,
02766       numResults
02767       );
02768   Ch_VaEnd(interp, ap);
02769   free(temp_attr);
02770   return retval;
02771 } 
02772 
02773 
02774 EXPORTCH int
02775 MC_SemaphorePost_chdl(void *varg) 
02776 {
02777   MCAgency_t temp_attr;
02778   extern mc_platform_p g_mc_platform;
02779 
02780   ChInterp_t interp;
02781   ChVaList_t ap;
02782   int id;
02783   int retval;
02784 
02785   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02786   CHECK_NULL(temp_attr, exit(-1));
02787   temp_attr->mc_platform = g_mc_platform;
02788 
02789   Ch_VaStart(interp, ap, varg);
02790   id = Ch_VaArg(interp, ap, int );
02791   retval = MC_SemaphorePost(temp_attr, id);
02792   Ch_VaEnd(interp, ap);
02793   free(temp_attr);
02794   return retval;
02795 } 
02796 
02797 
02798 EXPORTCH int 
02799 MC_SemaphoreWait_chdl(void *varg) 
02800 {   
02801   MCAgency_t temp_attr;
02802   extern mc_platform_p g_mc_platform;
02803 
02804   ChInterp_t interp;
02805   ChVaList_t ap;
02806   int id;
02807   int retval;
02808 
02809   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02810   CHECK_NULL(temp_attr, exit(-1));
02811   temp_attr->mc_platform = g_mc_platform;
02812 
02813   Ch_VaStart(interp, ap, varg);
02814   id = Ch_VaArg(interp, ap, int );
02815   retval = MC_SemaphoreWait(temp_attr, id);
02816   Ch_VaEnd(interp, ap);
02817   free(temp_attr);
02818   return retval;
02819 } 
02820 
02821 
02822 EXPORTCH int
02823 MC_SendAgentMigrationMessage_chdl(void *varg) 
02824 {
02825   MCAgency_t temp_attr;
02826   extern mc_platform_p g_mc_platform;
02827   const char *message, *hostname;
02828   int port, retval;
02829   ChInterp_t interp;
02830   ChVaList_t ap;
02831 
02832   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02833   CHECK_NULL(temp_attr, exit(-1));
02834   temp_attr->mc_platform = g_mc_platform;
02835 
02836   Ch_VaStart(interp, ap, varg);
02837   message = Ch_VaArg(interp, ap, char *);
02838   hostname = Ch_VaArg(interp, ap, char *);
02839   port = Ch_VaArg(interp, ap, int);
02840   retval = MC_SendAgentMigrationMessage(temp_attr, message, hostname, port);
02841   Ch_VaEnd(interp, ap);
02842   free(temp_attr);
02843   return retval;
02844 } 
02845 
02846 
02847 EXPORTCH int
02848 MC_SendAgentMigrationMessageFile_chdl(void *varg) 
02849 {
02850   MCAgency_t temp_attr;
02851   char *filename, *hostname;
02852   int port, retval;
02853   ChInterp_t interp;
02854   ChVaList_t ap;
02855 
02856   temp_attr = NULL;
02857 
02858   Ch_VaStart(interp, ap, varg);
02859   filename = Ch_VaArg(interp, ap, char *);
02860   hostname = Ch_VaArg(interp, ap, char *);
02861   port = Ch_VaArg(interp, ap, int);
02862   retval = MC_SendAgentMigrationMessageFile(temp_attr, filename, hostname, port);
02863   Ch_VaEnd(interp, ap);
02864   return retval;
02865 } 
02866 
02867 EXPORTCH int
02868 MC_SendSteerCommand_chdl(void *varg) 
02869 {
02870   MCAgency_t temp_attr;
02871   int retval;
02872   enum MC_SteerCommand_e command;
02873   extern mc_platform_p g_mc_platform;
02874   ChInterp_t interp;
02875   ChVaList_t ap;
02876 
02877   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02878   CHECK_NULL(temp_attr, exit(-1));
02879   temp_attr->mc_platform = g_mc_platform;
02880 
02881   Ch_VaStart(interp, ap, varg);
02882   command = Ch_VaArg(interp, ap, enum MC_SteerCommand_e );
02883   retval = MC_SendSteerCommand(temp_attr, command);
02884   Ch_VaEnd(interp, ap);
02885   free(temp_attr);
02886   return retval;
02887 } 
02888 
02889 
02890 EXPORTCH int
02891 MC_SetAgentStatus_chdl(void *varg) 
02892 {
02893   MCAgent_t agent;
02894   int status;
02895   int ret;
02896   ChInterp_t interp;
02897   ChVaList_t ap;
02898 
02899   Ch_VaStart(interp, ap, varg);
02900   agent = Ch_VaArg(interp, ap, MCAgent_t);
02901   status = Ch_VaArg(interp, ap, int);
02902   ret = MC_SetAgentStatus(agent, status);
02903   Ch_VaEnd(interp, ap);
02904   return ret;
02905 } 
02906 
02907 
02908 EXPORTCH int
02909 MC_SetDefaultAgentStatus_chdl(void *varg) 
02910 {
02911   MCAgency_t temp_attr;
02912   extern mc_platform_p g_mc_platform;
02913   int status;
02914   int ret;
02915   ChInterp_t interp;
02916   ChVaList_t ap;
02917 
02918   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02919   CHECK_NULL(temp_attr, exit(1););
02920   temp_attr->mc_platform = g_mc_platform;
02921 
02922   Ch_VaStart(interp, ap, varg);
02923   status = Ch_VaArg(interp, ap, int);
02924   ret = MC_SetDefaultAgentStatus(temp_attr, status);
02925   Ch_VaEnd(interp, ap);
02926   free(temp_attr);
02927   return ret;
02928 } 
02929 
02930 
02931 EXPORTCH int
02932 MC_SyncDelete_chdl(void *varg) 
02933 {
02934   MCAgency_t temp_attr;
02935   extern mc_platform_p g_mc_platform;
02936   int retval;
02937   ChInterp_t interp;
02938   ChVaList_t ap;
02939   int id;
02940 
02941   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02942   CHECK_NULL(temp_attr, exit(-1));
02943   temp_attr->mc_platform = g_mc_platform;
02944 
02945   Ch_VaStart(interp, ap, varg);
02946   id = Ch_VaArg(interp, ap, int);
02947   retval = MC_SyncDelete(temp_attr, id);
02948   Ch_VaEnd(interp, ap);
02949   free(temp_attr);
02950   return retval;
02951 } 
02952 
02953 
02954 EXPORTCH int
02955 MC_SyncInit_chdl(void *varg) 
02956 {
02957   MCAgency_t temp_attr;
02958   extern mc_platform_p g_mc_platform;
02959   int retval;
02960   ChInterp_t interp;
02961   ChVaList_t ap;
02962   int id;
02963 
02964   temp_attr = (MCAgency_t)malloc(sizeof(struct agency_s));
02965   CHECK_NULL(temp_attr, exit(-1));
02966   temp_attr->mc_platform = g_mc_platform;
02967 
02968   Ch_VaStart(interp, ap, varg);
02969   id = Ch_VaArg(interp, ap, int);
02970 
02971   retval = MC_SyncInit(temp_attr, id);
02972   Ch_VaEnd(interp, ap);
02973   free(temp_attr);
02974   return retval;
02975 } 
02976 
02977 
02978 EXPORTCH int
02979 MC_TerminateAgent_chdl(void *varg) 
02980 {
02981   ChInterp_t interp;
02982   ChVaList_t ap;
02983   MCAgent_t agent;
02984   int retval;
02985 
02986   Ch_VaStart(interp, ap, varg);
02987   agent = Ch_VaArg(interp, ap, MCAgent_t);
02988   retval = MC_TerminateAgent(agent);
02989   Ch_VaEnd(interp, ap);
02990   return retval;
02991 } 
02992