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 #include "include/ams.h"
00036 #include "include/agent.h"
00037 #include "include/data_structures.h"
00038 #include "include/mc_platform.h"
00039 
00040   int
00041 ams_Destroy(ams_p ams)
00042 {
00043   MUTEX_DESTROY(ams->runflag_lock);
00044   free(ams->runflag_lock);
00045   COND_DESTROY(ams->runflag_cond);
00046   free(ams->runflag_cond);
00047   free(ams);
00048   return MC_SUCCESS;
00049 }
00050 
00051   ams_p 
00052 ams_Initialize(mc_platform_p mc_platform)
00053 {
00054   ams_p ams;
00055   ams = (ams_p)malloc(sizeof(ams_t));
00056   CHECK_NULL(ams, exit(0););
00057   ams->mc_platform = mc_platform;
00058 
00059   ams->runflag_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00060   CHECK_NULL(ams->runflag_lock, exit(0););
00061   MUTEX_INIT(ams->runflag_lock);
00062 
00063   ams->runflag_cond = (COND_T*)malloc(sizeof(COND_T));
00064   CHECK_NULL(ams->runflag_cond, exit(0););
00065   COND_INIT(ams->runflag_cond);
00066 
00067   ams->run = 0;
00068 
00069   ams->waiting = 0;
00070   ams->waiting_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00071   MUTEX_INIT(ams->waiting_lock);
00072   ams->waiting_cond = (COND_T*)malloc(sizeof(COND_T));
00073   COND_INIT(ams->waiting_cond);
00074 
00075   return ams;
00076 }
00077 
00078   void 
00079 ams_Print(ams_p ams)
00080 {
00081   int i;
00082   MCAgent_t agent;
00083   agent_queue_p alist;
00084 
00085   alist = ams->mc_platform->agent_queue;
00086 
00087   MUTEX_LOCK(alist->lock);
00088 
00089   if(alist->size == 0) 
00090   {
00091     MUTEX_UNLOCK(alist->lock);
00092     return;
00093   }
00094 
00095   
00096   printf("%d total agents on board.\n", alist->size);
00097   for(i=0; i<alist->size; i++)
00098   {
00099     agent = (MCAgent_t)ListSearch(alist->list, i);
00100     printf("Agent id: %lu, Connect id: %lu, status: %u\n",
00101         agent->id,
00102         agent->connect_id,
00103         agent->agent_status);
00104   }
00105 
00106   MUTEX_UNLOCK(alist->lock);
00107   return;
00108 }
00109 
00110   extern int 
00111 ams_ManageAgentList(ams_p ams)
00112 {
00113   
00114   MCAgent_t current_agent;
00115   int index;
00116   agent_queue_p alist;
00117   mc_platform_p global;
00118   message_p message;
00119 
00120   alist = ams->mc_platform->agent_queue;
00121   global = ams->mc_platform;
00122 
00123   
00124 
00125   MUTEX_LOCK(alist->lock);
00126   for(index=0; index<alist->size; index++)
00127   {
00128     if((current_agent = ListSearch(alist->list, index)))
00129     {
00130       MUTEX_UNLOCK(alist->lock);
00131       MUTEX_LOCK(current_agent->lock);
00132       current_agent->orphan = 0;
00133       switch(current_agent->agent_status)
00134       {
00135         case MC_WAIT_CH :
00136           MUTEX_UNLOCK(current_agent->lock);
00137           agent_RunChScript(current_agent, global);
00138           break;
00139         case MC_AGENT_ACTIVE :
00140           MUTEX_UNLOCK(current_agent->lock);
00141           
00142           break;
00143         case MC_WAIT_MESSGSEND :
00144           current_agent->agent_status = MC_WAIT_FINISHED;
00145           MUTEX_UNLOCK(current_agent->lock);
00146           MUTEX_LOCK(ams->runflag_lock);
00147           ams->run = 1;
00148           MUTEX_UNLOCK(ams->runflag_lock);
00149           MUTEX_UNLOCK(current_agent->lock);
00150           message = message_New();
00151           if (
00152               message_InitializeFromAgent
00153               (
00154                ams->mc_platform,
00155                message,
00156                current_agent
00157               )
00158              )
00159           {
00160             message_Destroy(message);
00161             message = NULL;
00162           } else {
00163             message_queue_Add(
00164                 ams->mc_platform->message_queue,
00165                 message
00166                 );
00167           }
00168           break;
00169         case MC_AGENT_NEUTRAL :
00170           MUTEX_UNLOCK(current_agent->lock);
00171           break;
00172         case MC_WAIT_FINISHED :
00173           MUTEX_UNLOCK(current_agent->lock);
00174           agent_queue_RemoveIndex(alist, index);
00175           index=0;
00176           break;
00177         default : 
00178           printf("ERROR IN AGENT FORMAT"); 
00179           printf("Agent Format %d not recognized.",
00180               current_agent->agent_status);
00181           
00182           current_agent->agent_status = MC_WAIT_FINISHED;
00183           MUTEX_UNLOCK(current_agent->lock);
00184       }
00185     } else {
00186       MUTEX_UNLOCK( alist->lock );
00187     }
00188     MUTEX_LOCK( alist->lock );
00189   }
00190   MUTEX_UNLOCK( alist->lock );
00191   return 0 ;
00192 }
00193 
00194   void
00195 ams_Start(mc_platform_p mc_platform)
00196 {
00197   ams_p ams = mc_platform->ams;
00198 #ifndef _WIN32
00199   pthread_attr_t attr;
00200   pthread_attr_init(&attr);
00201   if(mc_platform->stack_size[MC_THREAD_AMS] != -1) {
00202     pthread_attr_setstacksize
00203       (
00204        &attr,
00205        mc_platform->stack_size[MC_THREAD_AMS]
00206       );
00207   }
00208 #else
00209   int stack_size;
00210   if (mc_platform->stack_size[MC_THREAD_AMS] < 1) {
00211     
00212     stack_size = mc_platform->stack_size[MC_THREAD_AMS]+1;
00213   } else {
00214     stack_size = mc_platform->stack_size[MC_THREAD_AMS];
00215   }
00216 #endif
00217   THREAD_CREATE
00218     (
00219      &ams->thread,
00220      ams_Thread,
00221      mc_platform
00222     );
00223 }
00224 #ifndef _WIN32
00225   void*
00226 ams_Thread(void* arg)
00227 #else
00228   DWORD WINAPI
00229 ams_Thread( LPVOID arg )
00230 #endif
00231 {
00232   mc_platform_p mc_platform = (mc_platform_p)arg;
00233   ams_p ams = mc_platform->ams;
00234 
00235   while(1) {
00236     MUTEX_LOCK(ams->runflag_lock);
00237     MUTEX_LOCK(mc_platform->quit_lock);
00238     while(ams->run == 0 && !mc_platform->quit) {
00239       MUTEX_UNLOCK(mc_platform->quit_lock);
00240       
00241       MUTEX_LOCK(ams->waiting_lock);
00242       ams->waiting = 1;
00243       COND_BROADCAST(ams->waiting_cond);
00244       MUTEX_UNLOCK(ams->waiting_lock);
00245       
00246       COND_WAIT
00247         (
00248          ams->runflag_cond,
00249          ams->runflag_lock
00250         );
00251       MUTEX_LOCK(mc_platform->quit_lock);
00252     }
00253     
00254     MUTEX_LOCK(ams->waiting_lock);
00255     ams->waiting = 0;
00256     COND_BROADCAST(ams->waiting_cond);
00257     MUTEX_UNLOCK(ams->waiting_lock);
00258     if (ams->run == 0 && mc_platform->quit) {
00259       MUTEX_UNLOCK(mc_platform->quit_lock);
00260       MUTEX_UNLOCK(ams->runflag_lock);
00261       return 0;
00262     }
00263     ams->run = 0;
00264     MUTEX_UNLOCK(mc_platform->quit_lock);
00265     MUTEX_UNLOCK(ams->runflag_lock);
00266     ams_ManageAgentList(ams);
00267   }
00268   return NULL;
00269 }