GridLab
Grid Application Toolkit

A simple API for Grid Applications
GAT

Menu



Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members  

GATRegistry.c

Go to the documentation of this file.
00001 /** @file GATRegistry.c
00002  * Main file for the GATRegsitry class.
00003  * 
00004  * The Registry keeps track of all capabilities and their providers.
00005  * 
00006  * @date Thu Sep 18 2003
00007  * 
00008  * @version $Header: /export/cvs-gridlab/wp-1/Codes/GATEngine/C-reference/src/GATRegistry.c,v 1.34 2004/04/18 18:35:10 hartmutkaiser Exp $
00009  *
00010  *  Copyright (C) Tom Goodale
00011  *  This file is part of the GAT Engine.
00012  *  Contributed by Tom Goodale <goodale@aei.mpg.de>.
00013  *
00014  *  Use, modification and distribution is subject to the Gridlab Software
00015  *  License. (See accompanying file GLlicense.txt or copy at
00016  *  http://www.gridlab.org/GLlicense.txt)
00017  */
00018 
00019 static const char *rcsid = "$Header: /export/cvs-gridlab/wp-1/Codes/GATEngine/C-reference/src/GATRegistry.c,v 1.34 2004/04/18 18:35:10 hartmutkaiser Exp $";
00020 
00021 /* System Header Files */
00022 
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <assert.h>
00027  
00028 /* GAT Header Files */
00029 #include "GATRegistry.h"
00030 
00031 #include "GATErrors.h"
00032 #include "GATPreferences.h"
00033 #include "GATList.h"
00034 #include "GATSelf.h"
00035 
00036 /* Macros */
00037 GATOBJECT_DEFINE_VTABLE(GATRegistry);
00038 GATLIST_DEFINE_QUALIFIED(static, GATObject, GATList_GATObject, 
00039   GATType_PlainOldData);
00040 
00041 #define CPILIST_NAME(object)  object ## _list
00042 
00043 #define CPI_FUNCTIONS(object)                                                 \
00044   \
00045   int GATRegistry_AddGAT ## object ## CPI(GATRegistry this,                   \
00046     GAT ## object ## CPI cpi, void *token, GATPreferences_const preferences)  \
00047   {                                                                           \
00048     return GATRegistry_internal_AddCPI(&(this->CPILIST_NAME(object)),         \
00049       cpi, token, preferences);                                               \
00050   }                                                                           \
00051   \
00052   GAT ## object ## CPIList GATRegistry_FindGAT ## object ## CPI(              \
00053     GATRegistry_const this, GATPreferences_const preferences)                 \
00054   {                                                                           \
00055     return (GAT ## object ## CPIList) GATRegistry_internal_FindCPI(           \
00056       this->CPILIST_NAME(object), preferences);                               \
00057   }                                                                           \
00058   \
00059   void GAT ## object ## CPIList_Destroy(GAT ## object ## CPIList list)        \
00060   {                                                                           \
00061     GATRegistry_internal_DestroyCPIList((CPIList)list);                       \
00062   }                                                                           \
00063   \
00064   GAT ## object ## CPIList GATRegistry_CloneGAT ## object ## CPIList(         \
00065     GAT ## object ## CPIList_const list)                                      \
00066   {                                                                           \
00067     return (GAT ## object ## CPIList) GATRegistry_internal_CloneCPIList(      \
00068       (CPIList_const) list);                                                  \
00069   }                                                                           \
00070   \
00071   GATResult GATRegistry_WalkGAT ## object ## CPIList(GATRegistry_const this,  \
00072     GATCPICallback callback, void *data)                                      \
00073   {                                                                           \
00074     return GATRegistry_internal_WalkCPIList(                                  \
00075       this->CPILIST_NAME(object), (GATCPICallback)callback, data);            \
00076   }                                                                           \
00077   \
00078   GATResult GATRegistry_AddGAT ## object ## ToCPIList(GATContext ctx,         \
00079     GAT ## object ## CPI cpi, GAT ## object obj)                              \
00080   {                                                                           \
00081     GATRegistry_const registry = GATContext_internal_GetRegistry(ctx);        \
00082     return GATRegistry_internal_AddGATObjectToCPIList(                        \
00083       registry->CPILIST_NAME(object), cpi,                                    \
00084       GAT ## object ## _ToGATObject(obj));                                    \
00085   }                                                                           \
00086   \
00087   GATResult GATRegistry_RemoveGAT ## object ## FromCPIList(                   \
00088     GATContext ctx, GAT ## object ## CPI cpi, GAT ## object obj)              \
00089   {                                                                           \
00090     GATRegistry_const registry = GATContext_internal_GetRegistry(ctx);        \
00091     return GATRegistry_internal_RemoveGATObjectFromCPIList(                   \
00092       registry->CPILIST_NAME(object), cpi,                                    \
00093       GAT ## object ## _ToGATObject(obj));                                    \
00094   }                                                                           \
00095   /**/
00096 
00097 /* Structures, unions and enums */
00098 struct CPIRegistryList_S
00099 {
00100   struct CPIRegistryList_S *next;   /* next cpi of this type */
00101   void *token;                      /* token of the accociated adaptor */
00102   GATPreferences preferences;       /* preferences registered for this CPI */
00103   void *cpi;                        /* pointer to function table */
00104   GATList_GATObject objects;  /* list of objects created by this CPI */
00105 };
00106 
00107 struct CPIList_S
00108 {
00109   struct CPIList_S *next;
00110   void *cpi;
00111 };
00112 
00113 typedef struct CPIList_S *CPIList;
00114 typedef struct CPIList_S const *CPIList_const;
00115 
00116 struct GATRegistry_S
00117 {
00118   GATRegistry_vtable *GATObject__vtable;
00119   CPIRegistryList CPILIST_NAME(Pipe);
00120   CPIRegistryList CPILIST_NAME(Endpoint);
00121   CPIRegistryList CPILIST_NAME(File);
00122   CPIRegistryList CPILIST_NAME(FileStream);
00123   CPIRegistryList CPILIST_NAME(LogicalFile);
00124   CPIRegistryList CPILIST_NAME(ResourceBroker);
00125   CPIRegistryList CPILIST_NAME(Reservation);
00126   CPIRegistryList CPILIST_NAME(Resource);
00127   CPIRegistryList CPILIST_NAME(Job);
00128   CPIRegistryList CPILIST_NAME(Self);
00129   CPIRegistryList CPILIST_NAME(Request);
00130   CPIRegistryList CPILIST_NAME(AdvertService);
00131 };
00132 
00133 
00134 /* generic part of every GAT...CPI structure */
00135 typedef void (*GATCPI_Adaptor_Destroy)(void *);
00136 typedef GATResult (*GATCPI_Adaptor_ServiceActions)(void *, void *, 
00137   GATTimePeriod_const);
00138 
00139 struct GATCPI_S
00140 {
00141   /* CPI data (type local data) */
00142   void *data;
00143   GATCPI_Adaptor_Destroy destroy;
00144   GATCPI_Adaptor_ServiceActions service_actions;
00145 };
00146 
00147 /* Static function prototypes */
00148 static int 
00149   GATRegistry_internal_AddCPI(CPIRegistryList *list, void *cpi,
00150     void *token, GATPreferences_const preferences);
00151 
00152 static CPIList 
00153   GATRegistry_internal_FindCPI(CPIRegistryList_const list,
00154     GATPreferences_const preferences);
00155 
00156 static CPIList 
00157   GATRegistry_internal_FindCPIWorker(CPIRegistryList_const list,
00158     GATPreferences_const preferences);
00159 
00160 static void 
00161   GATRegistry_internal_DestroyCPIList(CPIList list);
00162 
00163 static CPIList 
00164   GATRegistry_internal_CloneCPIList(CPIList_const list);
00165 
00166 static GATResult
00167   GATRegistry_internal_WalkCPIList(CPIRegistryList_const list, 
00168     GATCPICallback callback, void *data);
00169 
00170 static GATResult
00171   GATRegistry_ServiceActionsCallback(CPIRegistryList_const cpi, void *data);
00172 static GATResult
00173   GATRegistry_CorrectTimeout(GATTime start, GATTimePeriod *timeout);
00174 
00175 static GATResult
00176   GATRegistry_internal_AddGATObjectToCPIList(CPIRegistryList_const list, 
00177     void *cpi, GATObject object);
00178   
00179 static GATResult
00180   GATRegistry_internal_RemoveGATObjectFromCPIList(CPIRegistryList_const list, 
00181     void *cpi, GATObject object);
00182   
00183 /* type specific destroy functions */
00184 static void 
00185   GATRegistry_DestroyPipeCPIRegistryList(CPIRegistryList list);
00186 static void 
00187   GATRegistry_DestroyEndpointCPIRegistryList(CPIRegistryList list);
00188 static void 
00189   GATRegistry_DestroyFileCPIRegistryList(CPIRegistryList list);
00190 static void 
00191   GATRegistry_DestroyFileStreamCPIRegistryList(CPIRegistryList list);
00192 static void 
00193   GATRegistry_DestroyLogicalFileCPIRegistryList(CPIRegistryList list);
00194 static void 
00195   GATRegistry_DestroyResourceBrokerCPIRegistryList(CPIRegistryList list);
00196 static void 
00197   GATRegistry_DestroyReservationCPIRegistryList(CPIRegistryList list);
00198 static void 
00199   GATRegistry_DestroyResourceCPIRegistryList(CPIRegistryList list);
00200 static void 
00201   GATRegistry_DestroyJobCPIRegistryList(CPIRegistryList list);
00202 static void 
00203   GATRegistry_DestroySelfCPIRegistryList(CPIRegistryList list);
00204 static void 
00205   GATRegistry_DestroyRequestCPIRegistryList(CPIRegistryList list);
00206 static void 
00207   GATRegistry_DestroyAdvertServiceCPIRegistryList(CPIRegistryList list);
00208 
00209 /* Dummy functions for the vtable */
00210 static GATType 
00211   GATRegistry_GetType(GATRegistry_const file);
00212 static GATResult 
00213   GATRegistry_Equals(GATRegistry_const lhs, GATRegistry_const rhs, 
00214     GATBool *isequal);
00215 static GATResult 
00216   GATRegistry_Clone(GATRegistry_const object, GATRegistry *new_object);
00217 static GATResult  
00218   GATRegistry_GetInterface(GATRegistry_const object, GATInterface iftype, 
00219     void const **ifp);
00220 
00221 /* File scope variables */
00222 static GATRegistry_vtable GATRegistry__vtable = {
00223   GATRegistry_GetType,
00224   GATRegistry_Destroy,
00225   GATRegistry_Equals,
00226   GATRegistry_Clone,
00227   GATRegistry_GetInterface,
00228   0   /* this is needed for CPI based types only */
00229 };
00230 
00231 /* External functions */
00232 
00233 /** GATRegistry_Create
00234  *  The  GATRegistry constructor.
00235  *  This is the constructor for GATRegistry objects.
00236  *
00237  * @return A new GATRegistry
00238  */
00239 GATRegistry GATRegistry_Create(void)
00240 {
00241   GATRegistry registry = (GATRegistry)malloc(sizeof(struct GATRegistry_S));
00242 
00243   if(registry)
00244   {
00245     registry->GATObject__vtable = &GATRegistry__vtable;
00246     registry->CPILIST_NAME(Pipe) = NULL;
00247     registry->CPILIST_NAME(Endpoint) = NULL;
00248     registry->CPILIST_NAME(File) = NULL;
00249     registry->CPILIST_NAME(FileStream) = NULL;
00250     registry->CPILIST_NAME(LogicalFile) = NULL;
00251     registry->CPILIST_NAME(ResourceBroker) = NULL;
00252     registry->CPILIST_NAME(Reservation) = NULL;
00253     registry->CPILIST_NAME(Resource) = NULL;
00254     registry->CPILIST_NAME(Job) = NULL;
00255     registry->CPILIST_NAME(Self) = NULL;
00256     registry->CPILIST_NAME(Request) = NULL;
00257     registry->CPILIST_NAME(AdvertService) = NULL;
00258   }
00259   return registry;
00260 }
00261 
00262 /** GATRegistry_Destroy
00263  *  The GATRegistry destructor.
00264  *  This is the destructor for GATRegistry objects.
00265  *
00266  * @param this An old GATRegistry
00267  */
00268 void GATRegistry_Destroy(GATRegistry *registry)
00269 {
00270   if(NULL != registry && NULL != *registry)
00271   {
00272     /* free registered file CPI's */
00273     GATRegistry_DestroyPipeCPIRegistryList((*registry)->CPILIST_NAME(Pipe));
00274     GATRegistry_DestroyEndpointCPIRegistryList((*registry)->CPILIST_NAME(Endpoint));
00275     GATRegistry_DestroyFileCPIRegistryList((*registry)->CPILIST_NAME(File));
00276     GATRegistry_DestroyFileStreamCPIRegistryList((*registry)->CPILIST_NAME(FileStream));
00277     GATRegistry_DestroyLogicalFileCPIRegistryList(
00278       (*registry)->CPILIST_NAME(LogicalFile));
00279     GATRegistry_DestroyResourceBrokerCPIRegistryList(
00280       (*registry)->CPILIST_NAME(ResourceBroker));
00281     GATRegistry_DestroyReservationCPIRegistryList(
00282       (*registry)->CPILIST_NAME(Reservation));
00283     GATRegistry_DestroyResourceCPIRegistryList(
00284       (*registry)->CPILIST_NAME(Resource));
00285     GATRegistry_DestroyJobCPIRegistryList((*registry)->CPILIST_NAME(Job));
00286     GATRegistry_DestroySelfCPIRegistryList((*registry)->CPILIST_NAME(Self));
00287     GATRegistry_DestroyRequestCPIRegistryList((*registry)->CPILIST_NAME(Request));
00288     GATRegistry_DestroyRequestCPIRegistryList(
00289       (*registry)->CPILIST_NAME(AdvertService));
00290 
00291     free(*registry);
00292     *registry = NULL;
00293   }
00294 }
00295 
00296 /** GATType GATRegistry_GetType(GATRegistry_const file)
00297  *  @brief Return the type of the GATRegistry
00298  *
00299  *  The function @c GATRegistry_GetType always returns GATType_GATRegistry. 
00300  *
00301  *  @param object The object to inspect
00302  *
00303  *  @return returns always @c #GATType_GATRegistry.
00304  */
00305 static GATType 
00306 GATRegistry_GetType(GATRegistry_const file)
00307 {
00308   GAT_UNUSED_PARAMETER(file);
00309   return GATType_GATRegistry;
00310 }
00311 
00312 /** GATRegistry_Equals
00313  *  @brief Compare two GATRegistry objects
00314  *
00315  *  The function @c GATRegistry_Equals compares two objects of the
00316  *  @c GATRegistry type.
00317  *
00318  *  @param lhs The first list to compare
00319  *  @param rhs The second list to compare
00320  *  @param isequal The pointer to the GATBool variable, which should receive 
00321  *        the result if the comparision
00322  *
00323  *  @return An error code.
00324  */
00325 GATResult 
00326 GATRegistry_Equals(GATRegistry_const lhs, GATRegistry_const rhs, 
00327   GATBool *isequal)
00328 {
00329   return GAT_NOTIMPL;   /* shouldn't be called */
00330 }
00331 
00332 /** GATRegistry_Clone
00333  *  @brief Clone the given GATRegistry
00334  *
00335  *  The function @c GATRegistry_Clone generates a (deep) copy of 
00336  *  the given GATRegistry. 
00337  *
00338  *  @param description The object to clone
00339  *  @param new_object The pointer, through which the result is to be 
00340  *        returned.
00341  *
00342  *  @return An error type.
00343  */
00344 static GATResult 
00345 GATRegistry_Clone(GATRegistry_const handle, GATRegistry *new_handle)
00346 {
00347   return GAT_NOTIMPL;   /* shouldn't be called */
00348 }
00349 
00350 /** GATResult GATRegistry_GetInterface(GATRegistry_const file, GATInterface iftype, void const **ifp)
00351  *  @brief Get an interface supported by a GATObject
00352  *
00353  *  The function GATRegistry_GetInterface allows to get a pointer to an 
00354  *  additional interface supported by this GATRegistry.
00355  *
00356  *  @param object The object to be asked for the new interface.
00357  *  @param iftype The interface the object is to be asked for.
00358  *  @param ifp The pointer, through which the result is to be returned.
00359  *
00360  *  @return An error type.
00361  */
00362 static GATResult 
00363 GATRegistry_GetInterface(GATRegistry_const object, GATInterface iftype, 
00364   void const **ifp)
00365 {
00366   GATResult retval = GAT_INVALID_PARAMETER;
00367   if (NULL != ifp)
00368   {
00369     *ifp = NULL;
00370     retval = GAT_NO_INTERFACE;
00371   }
00372   return retval;
00373 }
00374 
00375 /* define the concrete CPI API functions */
00376 CPI_FUNCTIONS(Pipe)
00377 CPI_FUNCTIONS(Endpoint)
00378 CPI_FUNCTIONS(File)
00379 CPI_FUNCTIONS(FileStream)
00380 CPI_FUNCTIONS(LogicalFile)
00381 CPI_FUNCTIONS(ResourceBroker)
00382 CPI_FUNCTIONS(Reservation)
00383 CPI_FUNCTIONS(Resource)
00384 CPI_FUNCTIONS(Job)
00385 CPI_FUNCTIONS(Self)
00386 CPI_FUNCTIONS(Request)
00387 CPI_FUNCTIONS(AdvertService)
00388 
00389 /* Local functions */
00390 
00391 /** GATRegistry_internal_AddCPI
00392  *  Add a CPI to a given list of CPIs
00393  *  This adds the specified CPI object to the passed list.
00394  *  Used internally by the type-safe visible functions.
00395  *
00396  * @param list the list to be added to
00397  * @param cpi The CPI object
00398  * @param token An arbitrary token used by the loader
00399  * @param preferences The preferences which a user may match against to use this CPI.
00400  *
00401  * @return An error code.
00402  */
00403 static GATResult 
00404 GATRegistry_internal_AddCPI(CPIRegistryList *list, void *cpi, void *token, 
00405   GATPreferences_const preferences)
00406 {
00407   GATResult retcode;
00408 
00409   CPIRegistryList newcpi;
00410   CPIRegistryList current;
00411 
00412   newcpi = (CPIRegistryList)malloc(sizeof(struct CPIRegistryList_S));
00413 
00414   if(NULL != newcpi)
00415   {
00416     memset(newcpi, 0, sizeof(struct CPIRegistryList_S));
00417     newcpi->token = token;
00418     newcpi->cpi = cpi;
00419     newcpi->objects = GATList_GATObject_Create();
00420     if (NULL == newcpi->objects)
00421     {
00422       retcode = GAT_MEMORYFAILURE;
00423     }
00424     else
00425     {
00426       retcode = GATPreferences_Clone(preferences, &(newcpi->preferences));
00427     }
00428 
00429     if (GAT_SUCCESS == retcode)
00430     {
00431       if(NULL != *list)
00432       {
00433         /* Find end of list */
00434         for(current = *list; NULL != current->next; current = current->next)
00435         {
00436             /* Do nothing */
00437         }
00438         current->next = newcpi;
00439       }
00440       else
00441       {
00442         *list = newcpi;
00443       }
00444       retcode = GAT_SUCCESS;
00445     }
00446     else
00447     {
00448       GATList_GATObject_Destroy(&newcpi->objects);
00449       free(newcpi);
00450     }
00451   }
00452   else
00453   {
00454     retcode = GAT_MEMORYFAILURE;
00455   }
00456 
00457   return retcode;
00458 }
00459 
00460 /** GATRegistry_internal_FindCPI
00461  *  Find a CPI to a given list of CPIs and preferences.
00462  *  This searches the CPI list for matching ones and constructs a list to 
00463  *  return to the calling function.
00464  *  Used internally by the type-safe visible functions.
00465  *
00466  * @param list the list to be searched
00467  * @param preferences The preferences which must be matched.
00468  *
00469  * @return A list of CPIs.
00470  */
00471 static CPIList 
00472 GATRegistry_internal_FindCPI(CPIRegistryList_const list,
00473   GATPreferences_const preferences)
00474 {
00475   CPIList newlist = NULL;
00476   if (NULL != preferences)
00477   {
00478     newlist = GATRegistry_internal_FindCPIWorker(list, preferences);
00479   }
00480   else
00481   {
00482     /* no (default) given, try to use local adaptors first */
00483     GATPreferences localprefs = GATPreferences_Create();
00484     
00485     if (NULL != localprefs)
00486     {
00487       GATPreferences_Add(localprefs, "Local", "true");
00488       
00489       newlist = GATRegistry_internal_FindCPIWorker(list, localprefs);
00490       
00491       GATPreferences_Destroy(&localprefs);
00492     }
00493     
00494     if (NULL == newlist)
00495     {
00496       /* if this failed, try to use any adaptor */
00497       newlist = GATRegistry_internal_FindCPIWorker(list, 0);
00498     }
00499   }
00500   return newlist;
00501 }
00502 
00503 static CPIList 
00504 GATRegistry_internal_FindCPIWorker(CPIRegistryList_const list,
00505   GATPreferences_const preferences)
00506 {
00507   CPIList newlist = NULL;
00508   CPIList newcurrent = NULL;
00509   CPIList newelement = NULL;
00510   CPIRegistryList_const current = NULL;
00511 
00512   /* try to collect all adapters matching the given preferences */
00513   for(current = list; NULL != current; current = current->next)
00514   {
00515     if (GATPreferences_Match(current->preferences, preferences))
00516     {
00517       newelement = (CPIList)malloc(sizeof(*newelement));
00518       if(newelement)
00519       {
00520         newelement->cpi  = current->cpi;
00521         newelement->next = NULL;
00522 
00523         if(newcurrent)
00524         {
00525           newcurrent->next = newelement;
00526         }
00527         else
00528         {
00529           newlist = newelement;
00530         }
00531         newcurrent = newelement;
00532       }
00533       else
00534       {
00535         /* FIXME: Should use GATStatus object, but that's not been written yet */
00536         assert(newelement);
00537       }
00538     }
00539   }
00540   return newlist;
00541 }
00542 
00543 /** 
00544  *  
00545  */
00546 static CPIList 
00547 GATRegistry_internal_CloneCPIList(CPIList_const list)
00548 {
00549   CPIList newlist = NULL;
00550   CPIList newcurrent = NULL;
00551   CPIList_const current = list;
00552   
00553   for(/**/; NULL != current; current = current->next)
00554   {
00555     CPIList newelement = (CPIList) malloc(sizeof(struct CPIList_S));
00556     if(newelement)
00557     {
00558       newelement->cpi = current->cpi;
00559       newelement->next = NULL;
00560 
00561       if(NULL != newcurrent)
00562       {
00563         newcurrent->next = newelement;
00564       }
00565       else
00566       {
00567         newlist = newelement;
00568       }
00569       newcurrent = newelement;
00570     }
00571     else
00572     {
00573       GATRegistry_internal_DestroyCPIList(newlist);
00574       newlist = NULL;
00575       break;
00576     }
00577   }
00578   return newlist;
00579 }
00580 
00581 /*  GATRegistry_internal_WalkCPIList
00582  *  
00583  *  Walk through the list of registred CPI's in a given list
00584  */
00585 static GATResult
00586 GATRegistry_internal_WalkCPIList(CPIRegistryList_const list, 
00587   GATCPICallback callback, void *data)
00588 {
00589   CPIRegistryList_const current = list;
00590   GATResult retval = GAT_SUCCESS;
00591   
00592   for(/**/; NULL != current; current = current->next)
00593   {
00594     if (NULL != current->cpi)
00595     {
00596       retval = callback(current, data);
00597       if (GAT_FAILED(retval))
00598       {
00599         break;
00600       }
00601     }
00602   }
00603   return retval;
00604 }
00605 
00606 /*
00607  *  
00608  */
00609 static GATResult
00610 GATRegistry_internal_AddGATObjectToCPIList(CPIRegistryList_const list, void *cpi, 
00611   GATObject object)
00612 {
00613   GATResult retval = GAT_NO_MATCHING_CPI;
00614   CPIRegistryList_const current = list;
00615 
00616   /* find the given CPI */
00617   for(/**/; NULL != current; current = current->next)
00618   {
00619     if (NULL != current->cpi && cpi == current->cpi)
00620     {
00621       break;
00622     }
00623   }
00624   
00625   /* add the given object to the corresponing RegistryList element */
00626   if (NULL != current)
00627   {
00628     GATList_GATObject_Iterator it = 
00629       GATList_GATObject_Insert(current->objects, 
00630         GATList_GATObject_End(current->objects), object);
00631       
00632     if (NULL == it)
00633     {
00634       retval = GAT_MEMORYFAILURE;
00635     }
00636     else
00637     {
00638       retval = GAT_SUCCESS;
00639     }
00640   }
00641   return retval;
00642 }
00643 
00644 /*
00645  *  
00646  */
00647 static GATResult
00648 GATRegistry_internal_RemoveGATObjectFromCPIList(CPIRegistryList_const list, 
00649   void *cpi, GATObject object)
00650 {
00651   GATResult retval = GAT_NO_MATCHING_CPI;
00652   CPIRegistryList_const current = list;
00653 
00654   /* find the given CPI */
00655   for(/**/; NULL != current; current = current->next)
00656   {
00657     if (NULL != current->cpi && cpi == current->cpi)
00658     {
00659       break;
00660     }
00661   }
00662   
00663   /* remove the given object to the corresponing RegistryList element */
00664   if (NULL != current)
00665   {
00666     /* re-find the given object */
00667     GATBool found = GATFalse;
00668     GATList_GATObject_Iterator it = 
00669       GATList_GATObject_Begin(current->objects);
00670     GATList_GATObject_Iterator end = 
00671       GATList_GATObject_End(current->objects);
00672     for (/**/; it != end; it = GATList_GATObject_Next(it))
00673     {
00674       GATObject *obj = GATList_GATObject_Get(it);
00675       if (NULL == obj)
00676       {
00677         retval = GAT_FAIL;
00678         break;
00679       }
00680       else if (object == *obj)
00681       {
00682         GATList_GATObject_Iterator next = 
00683           GATList_GATObject_Erase(current->objects, it);
00684           
00685         if (NULL == next)
00686         {
00687           retval = GAT_FAIL;
00688         }
00689         else
00690         {
00691           retval = GAT_SUCCESS;
00692         }
00693         found = GATTrue;
00694         break;
00695       }
00696     }
00697     if (GATFalse == found)
00698     {
00699       /* object not registered from this CPI */
00700       retval = GAT_KEY_NOT_FOUND;
00701     }
00702   }
00703   return retval;
00704 }
00705 
00706 /** GATRegistry_internal_DestroyCPIList
00707  *  Destroy a CPIList
00708  *  Frees the memory associated with a CPI List.
00709  *  Used internally by the type-safe visible functions.
00710  *
00711  * @param list the list to be destroyed
00712  */
00713 static void GATRegistry_internal_DestroyCPIList(CPIList list)
00714 {
00715   CPIList current = list;
00716   while (NULL != current)
00717   {
00718     CPIList next = current->next;
00719     free(current);
00720     current = next;
00721   }
00722 }
00723 
00724 /** GATRegistry_DestroyFileStreamCPIRegistryList
00725  *  Destroy a RegistryCPList of FileStream CPI's. This destroys the embedded CPI's 
00726  *  as well.
00727  *
00728  *  @param list The registry list to be destroyed
00729  */
00730 static void
00731 GATRegistry_DestroyFileStreamCPIRegistryList(CPIRegistryList list)
00732 {
00733   CPIRegistryList current = list;
00734 
00735   while (NULL != current)
00736   {
00737     /* call the adaptor supplied destroy function */
00738     CPIRegistryList next = current->next;
00739 
00740     GATFileStreamCPI_Destroy((GATFileStreamCPI *) &current->cpi);
00741     GATPreferences_Destroy(&current->preferences);
00742     GATList_GATObject_Destroy(&current->objects);
00743     free(current);
00744     
00745     current = next;
00746   }
00747 }
00748 
00749 /** GATRegistry_DestroyPipeCPIRegistryList
00750  *  Destroy a RegistryCPList of Pipes CPI's. This destroys the embedded CPI's 
00751  *  as well.
00752  *
00753  *  @param list The registry list to be destroyed
00754  */
00755 static void
00756 GATRegistry_DestroyPipeCPIRegistryList(CPIRegistryList list)
00757 {
00758   CPIRegistryList current = list;
00759 
00760   while (NULL != current)
00761   {
00762     /* call the adaptor supplied destroy function */
00763     CPIRegistryList next = current->next;
00764 
00765     GATPipeCPI_Destroy((GATPipeCPI *) &current->cpi);
00766     GATPreferences_Destroy(&current->preferences);
00767     GATList_GATObject_Destroy(&current->objects);
00768     free(current);
00769     
00770     current = next;
00771   }
00772 }
00773 
00774 /** GATRegistry_DestroyEndpointCPIRegistryList
00775  *  Destroy a RegistryCPList of Endpoint CPI's. This destroys the embedded CPI's 
00776  *  as well.
00777  *
00778  *  @param list The registry list to be destroyed
00779  */
00780 static void
00781 GATRegistry_DestroyEndpointCPIRegistryList(CPIRegistryList list)
00782 {
00783   CPIRegistryList current = list;
00784 
00785   while (NULL != current)
00786   {
00787     /* call the adaptor supplied destroy function */
00788     CPIRegistryList next = current->next;
00789 
00790     GATEndpointCPI_Destroy((GATEndpointCPI *) &current->cpi);
00791     GATPreferences_Destroy(&current->preferences);
00792     GATList_GATObject_Destroy(&current->objects);
00793     free(current);
00794     
00795     current = next;
00796   }
00797 }
00798 
00799 /** GATRegistry_DestroyFileCPIRegistryList
00800  *  Destroy a RegistryCPList of File CPI's. This destroys the embedded CPI's 
00801  *  as well.
00802  *
00803  *  @param list The registry list to be destroyed
00804  */
00805 static void
00806 GATRegistry_DestroyFileCPIRegistryList(CPIRegistryList list)
00807 {
00808   CPIRegistryList current = list;
00809 
00810   while (NULL != current)
00811   {
00812     /* call the adaptor supplied destroy function */
00813     CPIRegistryList next = current->next;
00814 
00815     GATFileCPI_Destroy((GATFileCPI *) &current->cpi);
00816     GATPreferences_Destroy(&current->preferences);
00817     GATList_GATObject_Destroy(&current->objects);
00818     free(current);
00819     
00820     current = next;
00821   }
00822 }
00823 
00824 /** GATRegistry_DestroyLogicalFileCPIRegistryList
00825  *  Destroy a RegistryCPList of LogicalFile CPI's. This destroys the embedded 
00826  *  CPI's as well.
00827  *
00828  *  @param list The registry list to be destroyed
00829  */
00830 static void
00831 GATRegistry_DestroyLogicalFileCPIRegistryList(CPIRegistryList list)
00832 {
00833   CPIRegistryList current = list;
00834 
00835   while (NULL != current)
00836   {
00837     /* call the adaptor supplied destroy function */
00838     CPIRegistryList next = current->next;
00839 
00840     GATLogicalFileCPI_Destroy((GATLogicalFileCPI *) &current->cpi);
00841     GATPreferences_Destroy(&current->preferences);
00842     GATList_GATObject_Destroy(&current->objects);
00843     free(current);
00844     
00845     current = next;
00846   }
00847 }
00848 
00849 /** GATRegistry_DestroyResourceBrokerCPIRegistryList
00850  *  Destroy a RegistryCPList of resourceBroker CPI's. This destroys the 
00851  *  embedded CPI's as well.
00852  *
00853  *  @param list The registry list to be destroyed
00854  */
00855 static void 
00856 GATRegistry_DestroyResourceBrokerCPIRegistryList(CPIRegistryList list)
00857 {
00858   CPIRegistryList current = list;
00859 
00860   while (NULL != current)
00861   {
00862     /* call the adaptor supplied destroy function */
00863     CPIRegistryList next = current->next;
00864 
00865     GATResourceBrokerCPI_Destroy((GATResourceBrokerCPI *) &current->cpi);
00866     GATPreferences_Destroy(&current->preferences);
00867     GATList_GATObject_Destroy(&current->objects);
00868     free(current);
00869     
00870     current = next;
00871   }
00872 }
00873 
00874 /** GATRegistry_DestroyReservationCPIRegistryList
00875  *  Destroy a RegistryCPList of Reservation CPI's. This destroys the embedded 
00876  *  CPI's as well.
00877  *
00878  *  @param list The registry list to be destroyed
00879  */
00880 static void 
00881 GATRegistry_DestroyReservationCPIRegistryList(CPIRegistryList list)
00882 {
00883   CPIRegistryList current = list;
00884 
00885   while (NULL != current)
00886   {
00887     /* call the adaptor supplied destroy function */
00888     CPIRegistryList next = current->next;
00889 
00890     GATReservationCPI_Destroy((GATReservationCPI *) &current->cpi);
00891     GATPreferences_Destroy(&current->preferences);
00892     GATList_GATObject_Destroy(&current->objects);
00893     free(current);
00894     
00895     current = next;
00896   }
00897 }
00898 
00899 /** GATRegistry_DestroyResourceCPIRegistryList
00900  *  Destroy a RegistryCPList of Resource CPI's. This destroys the embedded 
00901  *  CPI's as well.
00902  *
00903  *  @param list The registry list to be destroyed
00904  */
00905 static void 
00906 GATRegistry_DestroyResourceCPIRegistryList(CPIRegistryList list)
00907 {
00908   CPIRegistryList current = list;
00909 
00910   while (NULL != current)
00911   {
00912     /* call the adaptor supplied destroy function */
00913     CPIRegistryList next = current->next;
00914 
00915     GATResourceCPI_Destroy((GATResourceCPI *) &current->cpi);
00916     GATPreferences_Destroy(&current->preferences);
00917     GATList_GATObject_Destroy(&current->objects);
00918     free(current);
00919     
00920     current = next;
00921   }
00922 }
00923 
00924 /** GATRegistry_DestroyJobCPIRegistryList
00925  *  Destroy a RegistryCPList of Job CPI's. This destroys the embedded 
00926  *  CPI's as well.
00927  *
00928  *  @param list The registry list to be destroyed
00929  */
00930 static void 
00931 GATRegistry_DestroyJobCPIRegistryList(CPIRegistryList list)
00932 {
00933   CPIRegistryList current = list;
00934 
00935   while (NULL != current)
00936   {
00937     /* call the adaptor supplied destroy function */
00938     CPIRegistryList next = current->next;
00939 
00940     GATJobCPI_Destroy((GATJobCPI *) &current->cpi);
00941     GATPreferences_Destroy(&current->preferences);
00942     GATList_GATObject_Destroy(&current->objects);
00943     free(current);
00944     
00945     current = next;
00946   }
00947 }
00948 
00949 /** GATRegistry_DestroySelfCPIRegistryList
00950  *  Destroy a RegistryCPList of Self CPI's. This destroys the embedded 
00951  *  CPI's as well.
00952  *
00953  *  @param list The registry list to be destroyed
00954  */
00955 static void
00956 GATRegistry_DestroySelfCPIRegistryList(CPIRegistryList list)
00957 {
00958   CPIRegistryList current = list;
00959 
00960   while (NULL != current)
00961   {
00962     /* call the adaptor supplied destroy function */
00963     CPIRegistryList next = current->next;
00964 
00965     GATSelfCPI_Destroy((GATSelfCPI *) &current->cpi);
00966     GATPreferences_Destroy(&current->preferences);
00967     GATList_GATObject_Destroy(&current->objects);
00968     free(current);
00969     
00970     current = next;
00971   }
00972 }
00973 
00974 /** GATRegistry_DestroyRequestCPIRegistryList
00975  *  Destroy a RegistryCPList of Request CPI's. This destroys the embedded 
00976  *  CPI's as well.
00977  *
00978  *  @param list The registry list to be destroyed
00979  */
00980 static void
00981 GATRegistry_DestroyRequestCPIRegistryList(CPIRegistryList list)
00982 {
00983   CPIRegistryList current = list;
00984 
00985   while (NULL != current)
00986   {
00987     /* call the adaptor supplied destroy function */
00988     CPIRegistryList next = current->next;
00989 
00990     GATRequestCPI_Destroy((GATRequestCPI *) &current->cpi);
00991     GATPreferences_Destroy(&current->preferences);
00992     GATList_GATObject_Destroy(&current->objects);
00993     free(current);
00994     
00995     current = next;
00996   }
00997 }
00998 
00999 /** GATRegistry_DestroyAdvertServiceCPIRegistryList
01000  *  Destroy a RegistryCPList of AdvertService CPI's. This destroys the embedded 
01001  *  CPI's as well.
01002  *
01003  *  @param list The registry list to be destroyed
01004  */
01005 static void
01006 GATRegistry_DestroyAdvertServiceCPIRegistryList(CPIRegistryList list)
01007 {
01008   CPIRegistryList current = list;
01009 
01010   while (NULL != current)
01011   {
01012     /* call the adaptor supplied destroy function */
01013     CPIRegistryList next = current->next;
01014 
01015     GATAdvertServiceCPI_Destroy((GATAdvertServiceCPI *) &current->cpi);
01016     GATPreferences_Destroy(&current->preferences);
01017     GATList_GATObject_Destroy(&current->objects);
01018     free(current);
01019     
01020     current = next;
01021   }
01022 }
01023 
01024 /*  GATRegistry_internal_ServiceAction
01025  *
01026  *  The ServiceActions call is used to allow the GAT Engine to service 
01027  *  asynchronous actions, such as GATRequests and GATMetricEvents. In a 
01028  *  single-threaded application it is likely that a timeout would be supplied, 
01029  *  in a multi-threaded application one thread may be used for the GAT by using 
01030  *  this call and no timeout. 
01031  *
01032  *  @param timeout This may be a 0 timeout to indicate no timeout at all, or
01033  *        a specific time length.
01034  *
01035  *  @return An error code.
01036  */
01037 GATResult
01038 GATRegistry_internal_ServiceActions(GATRegistry_const registry, 
01039   GATContext context, GATTimePeriod_const timeout)
01040 {
01041   GAT_USES_STATUS(context, "GATRegistry_internal_ServiceActions");
01042   
01043   GATTimePeriod period = NULL;
01044     
01045   if (NULL != timeout)
01046   {
01047     GAT_CREATE_STATUS(GATTimePeriod_Clone(timeout, &period));
01048   }
01049   
01050   GAT_CREATE_STATUS(GATRegistry_internal_WalkCPIList(
01051     registry->CPILIST_NAME(FileStream), GATRegistry_ServiceActionsCallback, 
01052     (void *)&period));
01053   GAT_CREATE_STATUS(GATRegistry_internal_WalkCPIList(
01054     registry->CPILIST_NAME(Pipe), GATRegistry_ServiceActionsCallback, 
01055     (void *)&period));
01056   GAT_CREATE_STATUS(GATRegistry_internal_WalkCPIList(
01057     registry->CPILIST_NAME(Endpoint), GATRegistry_ServiceActionsCallback, 
01058     (void *)&period));
01059   GAT_CREATE_STATUS(GATRegistry_internal_WalkCPIList(
01060     registry->CPILIST_NAME(File), GATRegistry_ServiceActionsCallback, 
01061     (void *)&period));
01062   GAT_CREATE_STATUS(GATRegistry_internal_WalkCPIList(
01063     registry->CPILIST_NAME(LogicalFile), GATRegistry_ServiceActionsCallback, 
01064     (void *)&period));
01065   GAT_CREATE_STATUS(GATRegistry_internal_WalkCPIList(
01066     registry->CPILIST_NAME(ResourceBroker), GATRegistry_ServiceActionsCallback, 
01067     (void *)&period));
01068   GAT_CREATE_STATUS(GATRegistry_internal_WalkCPIList(
01069     registry->CPILIST_NAME(Reservation), GATRegistry_ServiceActionsCallback, 
01070     (void *)&period));
01071   GAT_CREATE_STATUS(GATRegistry_internal_WalkCPIList(
01072     registry->CPILIST_NAME(Resource), GATRegistry_ServiceActionsCallback, 
01073     (void *)&period));
01074   GAT_CREATE_STATUS(GATRegistry_internal_WalkCPIList(
01075     registry->CPILIST_NAME(Job), GATRegistry_ServiceActionsCallback, 
01076     (void *)&period));
01077   GAT_CREATE_STATUS(GATRegistry_internal_WalkCPIList(
01078     registry->CPILIST_NAME(Self), GATRegistry_ServiceActionsCallback, 
01079     (void *)&period));
01080   GAT_CREATE_STATUS(GATRegistry_internal_WalkCPIList(
01081     registry->CPILIST_NAME(Request), GATRegistry_ServiceActionsCallback, 
01082     (void *)&period));
01083   GAT_CREATE_STATUS(GATRegistry_internal_WalkCPIList(
01084     registry->CPILIST_NAME(AdvertService), GATRegistry_ServiceActionsCallback, 
01085     (void *)&period));
01086       
01087   GATTimePeriod_Destroy(&period);
01088 
01089   return GAT_RETURN_STATUS();
01090 }
01091 
01092 /*  GATRegistry_CorrectTimeout
01093  *  
01094  *  Calculate the duration since the given start time.
01095  *
01096  *  @return An error value.
01097  */
01098 static GATResult
01099 GATRegistry_CorrectTimeout(GATTime start, GATTimePeriod *timeout)
01100 {
01101   GATResult retval = GAT_INVALID_PARAMETER;
01102   if (NULL != start && NULL != timeout)
01103   {
01104     GATTime now = GATTime_Create(0);
01105     if (NULL == now)
01106     {
01107       retval = GAT_MEMORYFAILURE;
01108     }
01109     else
01110     {
01111       /* calculate the duration of the previous call */
01112       GATTimePeriod call_duration = GATTimePeriod_Create_Difference(start, now);
01113       if (NULL == call_duration)
01114       {
01115         retval = GAT_MEMORYFAILURE;
01116       }
01117       else
01118       {
01119         GATdouble64 diff = GATTimePeriod_GetDuration(*timeout) - 
01120           GATTimePeriod_GetDuration(call_duration);
01121         GATTimePeriod period = GATTimePeriod_Create(diff);
01122         if (NULL == period)
01123         {
01124           retval = GAT_MEMORYFAILURE;
01125         }
01126         else
01127         {
01128           /* replace the old timeout value with the remaining time */
01129           GATTimePeriod_Destroy(timeout);
01130           *timeout = period;
01131         }
01132         
01133         GATTimePeriod_Destroy(&call_duration);
01134       }
01135       GATTime_Destroy(&now);
01136     }
01137   }
01138   return retval;
01139 }
01140 
01141 static GATResult
01142 GATRegistry_ServiceActionsCallback(CPIRegistryList_const cpilist, void *data)
01143 {
01144   GATResult retval = GAT_SUCCESS;
01145   struct GATCPI_S *cpi = (struct GATCPI_S *)cpilist->cpi;
01146   if (NULL != cpi->service_actions)
01147   {
01148     /* call the serviceaction procedure for every registered object */
01149     GATList_GATObject_Iterator it = 
01150       GATList_GATObject_Begin(cpilist->objects);
01151     GATList_GATObject_Iterator end = 
01152       GATList_GATObject_End(cpilist->objects);
01153     for (/**/; it != end; it = GATList_GATObject_Next(it))
01154     {
01155       GATObject *obj = GATList_GATObject_Get(it);
01156       if (NULL == obj)
01157       {
01158         retval = GAT_FAIL;
01159         break;
01160       }
01161       
01162       {
01163         GATTimePeriod *timeout = (GATTimePeriod *) ((NULL != data) ? data : 0);
01164         if (timeout != 0 && NULL != *timeout)
01165         {
01166           // there is a timeout given
01167           GATTime start = GATTime_Create(0);
01168           if (NULL == start)
01169           {
01170             retval = GAT_MEMORYFAILURE;
01171           }
01172           else
01173           {
01174             void *cpidata = NULL;
01175             retval = GATObject_GetCPIInstanceData(*obj, &cpidata);
01176             if (GAT_SUCCEEDED(retval))
01177             {
01178               retval = cpi->service_actions(cpi->data, cpidata, *timeout);
01179             }
01180             if (GAT_SUCCEEDED(retval))
01181             {
01182               retval = GATRegistry_CorrectTimeout(start, timeout);
01183             }
01184             
01185             if (GAT_NOTIMPL == retval)
01186             {
01187               retval = GAT_SUCCESS;
01188             }
01189           }
01190           GATTime_Destroy(&start);
01191         }
01192         else
01193         {
01194           // no timeout given
01195           void *cpidata = NULL;
01196           retval = GATObject_GetCPIInstanceData(*obj, &cpidata);
01197           if (GAT_SUCCEEDED(retval))
01198           {
01199             retval = cpi->service_actions(cpi->data, cpidata, 0);
01200             if (GAT_NOTIMPL == retval)
01201             {
01202               retval = GAT_SUCCESS;
01203             }
01204           }
01205         }
01206       }
01207     }
01208   }
01209   return retval;
01210 }
01211 
01212 /* Registry Helper functions, for internal use only */
01213 GATResult
01214 GATRegistry_internal_AddGATSelfToCPIList(GATRegistry registry, GATSelfCPI cpi, 
01215   GATSelf object)
01216 {
01217   GATResult retval = GAT_INVALID_HANDLE;
01218   if (NULL != registry)
01219   {
01220     retval = GATRegistry_internal_AddGATObjectToCPIList(
01221       registry->CPILIST_NAME(Self), cpi, GATSelf_ToGATObject(object));
01222   }
01223   return retval;
01224 }
01225 
01226 GATResult
01227 GATRegistry_internal_RemoveGATSelfFromCPIList(GATRegistry registry, 
01228   GATSelfCPI cpi, GATSelf object)
01229 {
01230   GATResult retval = GAT_INVALID_HANDLE;
01231   if (NULL != registry)
01232   {
01233     retval = GATRegistry_internal_RemoveGATObjectFromCPIList(
01234     registry->CPILIST_NAME(Self), cpi, GATSelf_ToGATObject(object));
01235   }
01236   return retval;
01237 }
01238