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

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

Generated on Fri May 16 14:49:54 2008 for Mobile-C by  doxygen 1.5.4