GridLab
Grid Application Toolkit

A simple API for Grid Applications
GAT

Menu



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

GATResource.c

Go to the documentation of this file.
00001 /** @file GATResource.c
00002  *  Source file for the GATResource class.
00003  *
00004  *  @date Thu Oct 23 2003
00005  *
00006  *  @version $Header: /export/cvs-gridlab/wp-1/Codes/GATEngine/C-reference/src/GATResource.c,v 1.19 2004/05/10 15:17:32 hartmutkaiser Exp $
00007  *
00008  *  Copyright (C) Hartmut Kaiser
00009  *  This file is part of the GAT Engine.
00010  *  Contributed by Hartmut Kaiser <hartmutkaiser [at] t-online [dot] de>.
00011  *
00012  *  Use, modification and distribution is subject to the Gridlab Software
00013  *  License. (See accompanying file GLlicense.txt or copy at
00014  *  http://www.gridlab.org/GLlicense.txt)
00015  */
00016  
00017 static const char *rcsid = "$Header: /export/cvs-gridlab/wp-1/Codes/GATEngine/C-reference/src/GATResource.c,v 1.19 2004/05/10 15:17:32 hartmutkaiser Exp $";
00018  
00019 /* System Header objects */
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include <assert.h>
00023 
00024 /* GAT Header objects */
00025 #include "GAT.h"
00026 #include "GATInternal.h"
00027 #include "GATRegistry.h"
00028 #include "GATResourceCPI.h"
00029 #include "GATXdsWrapper.h"
00030 #include "GATMetricEvent.h"
00031 
00032 /* define the vtable types */
00033 GATOBJECT_DEFINE_VTABLE(GATResource);
00034 GATSERIALISABLE_DEFINE_VTABLE(GATResource);
00035 GATMONITORABLE_DEFINE_VTABLE(GATResource);
00036 GATRESOURCE_DEFINE_VTABLE(GATResource);
00037 
00038 /* define the converters to/from GATObject */
00039 GATOBJECT_DEFINE_CONVERTERS(GATResource)
00040 
00041 /* Macros */
00042 #define GATRESOURCE_IMPLEMENTATION(type)                                      \
00043   GATOBJECT_DEFINE_CONVERTERS(type);                                          \
00044   GATOBJECT_DEFINE_CONVERTERS_QUALIFIED_EX(extern, type, GATType_ ## type,    \
00045     GATResource);                                                             \
00046   \
00047   type type ## _Create(GATContext context, GATPreferences_const prefs,        \
00048     void *instance_data)                                                      \
00049   {                                                                           \
00050     return (type) GATResource_Impl_Create(GATType_ ## type, context, prefs,   \
00051       instance_data);                                                         \
00052   }                                                                           \
00053   \
00054   void type ## _Destroy(type *object)                                         \
00055   {                                                                           \
00056     GATResource_Destroy((GATResource *)object);                               \
00057   }                                                                           \
00058   \
00059   GATResult type ## _Equals(type ## _const lhs, type ## _const rhs,           \
00060     GATBool *isequal)                                                         \
00061   {                                                                           \
00062     return GATResource_Equals((GATResource_const) lhs,                        \
00063       (GATResource_const) rhs, isequal);                                      \
00064   }                                                                           \
00065   \
00066   GATResult type ## _Clone(type ## _const object, type *new_object)           \
00067   {                                                                           \
00068     return GATResource_Clone((GATResource_const) object,                      \
00069       (GATResource *)new_object);                                             \
00070   }                                                                           \
00071   \
00072   GATType type ## _GetType(type ## _const object)                             \
00073   {                                                                           \
00074     return GATResource_GetType((GATResource_const) object);                   \
00075   }                                                                           \
00076   \
00077   GATResult type ## _GetInterface(type ## _const object, GATInterface iftype, \
00078     void const **ifp)                                                         \
00079   {                                                                           \
00080     return GATResource_GetInterface((GATResource_const) object, iftype,       \
00081       ifp);                                                                   \
00082   }                                                                           \
00083   \
00084   GATResult type ## _GetResourceDescription(type ## _const object,            \
00085     type ## Description_const *description)                                   \
00086   {                                                                           \
00087     return GATResource_Impl_GetResourceDescription((GATResource_const) object,\
00088        (GATResourceDescription_const *) description);                         \
00089   }                                                                           \
00090   GATResult type ## _GetReservation(type ## _const object,                    \
00091     GATReservation_const *reservation)                                        \
00092   {                                                                           \
00093     return GATResource_Impl_GetReservation((GATResource_const) object,        \
00094       reservation);                                                           \
00095   }                                                                           \
00096   \
00097   GATResult type ## _AddMetricListener(type object, GATMetricListener listener,\
00098     void *listener_data, GATMetric metric, GATuint32 *cookie)                 \
00099   {                                                                           \
00100     return GATResource_Impl_AddMetricListener((GATResource) object, listener, \
00101       listener_data, metric, cookie);                                         \
00102   }                                                                           \
00103   \
00104   GATResult type ## _RegisterPolling(type object, GATMetric metric,           \
00105     GATMetricEvent *event, GATuint32 *cookie)                                 \
00106   {                                                                           \
00107     return GATResource_Impl_RegisterPolling((GATResource) object, metric,     \
00108       event, cookie);                                                         \
00109   }                                                                           \
00110   \
00111   GATResult type ## _RemoveRegisteredMetric(type object, GATMetric metric,    \
00112     GATuint32 cookie)                                                         \
00113   {                                                                           \
00114     return GATResource_Impl_RemoveRegisteredMetric((GATResource) object,      \
00115       metric, cookie);                                                        \
00116   }                                                                           \
00117   \
00118   GATResult type ## _GetMetrics(type ## _const object,                        \
00119     GATList_GATMetric *metrics)                                               \
00120   {                                                                           \
00121     return GATResource_Impl_GetMetrics((GATResource_const) object, metrics);  \
00122   }                                                                           \
00123   \
00124   GATResult type ## _Serialise(type object, GATObject stream,                 \
00125     GATBool clear_dirty)                                                      \
00126   {                                                                           \
00127     return GATResource_Serialise((GATResource) object, stream,                \
00128       clear_dirty);                                                           \
00129   }                                                                           \
00130   \
00131   type type ## _DeSerialise(GATContext context, GATObject stream,             \
00132     GATResult *result)                                                        \
00133   {                                                                           \
00134     return (type) GATResource_DeSerialise(context, stream, result);           \
00135   }                                                                           \
00136   \
00137   GATResult type ## _GetIsDirty(type ## _const object, GATBool *isdirty)      \
00138   {                                                                           \
00139     return GATResource_GetIsDirty((GATResource_const) object, isdirty);       \
00140   }                                                                           \
00141   /**/
00142 
00143 
00144 /* Structures, unions and enums */
00145 struct GATResource_S {
00146   /* supported interfaces */
00147   GATResource_vtable *GATObject__vtable;
00148   GATResource_ISerialisable_vtable *GATSerialisable__vtable;
00149   GATResource_IMonitorable_vtable *GATMonitorable__vtable;
00150   GATResource_IResource_vtable *GATResource__vtable;
00151 
00152   /* instance data */
00153   GATResourceCPI_Instance data; /* instance data of the corresponding CPI object */
00154   GATResourceCPI cpi;         /* CPI object to use for all subsequent operations */
00155   GATResourceCPIList cpilist; /* CPI list of appropriate CPI objects */
00156 };
00157 
00158 
00159 /* Static function prototypes */
00160 static GATResult
00161 GATResource_DeSerialise_Create(GATContext context, GATObject stream, 
00162   GATuint32 type, GATResource *new_object);
00163 
00164 /* GATObject specific functions */
00165 static GATResource 
00166   GATResource_Impl_Create(GATType type, GATContext context, 
00167     GATPreferences_const preferences, void *instance_data);
00168 
00169 
00170 /* GATResource API */
00171 static GATResult
00172   GATResource_Impl_GetResourceDescription(GATResource_const object,
00173     GATResourceDescription_const *description);
00174 
00175 static GATResult
00176   GATResource_Impl_GetReservation(GATResource_const object, 
00177     GATReservation_const *reservation);
00178   
00179   
00180 /* GATMonitorable API */
00181 static GATResult 
00182   GATResource_Impl_AddMetricListener(GATResource object, 
00183     GATMetricListener listener, void *listener_data, GATMetric metric,
00184     GATuint32 *cookie);
00185 
00186 static GATResult 
00187   GATResource_Impl_RegisterPolling(GATResource object, GATMetric metric, 
00188     GATMetricEvent *event, GATuint32 *cookie);
00189 
00190 static GATResult 
00191   GATResource_Impl_RemoveRegisteredMetric(GATResource object, 
00192     GATMetric metric, GATuint32 cookie);
00193 
00194 static GATResult 
00195   GATResource_Impl_GetMetrics(GATResource_const object, 
00196     GATList_GATMetric *metrics);
00197 
00198 static GATResult
00199   GATResource_GetCPIInstanceData(GATResource object, void **data);
00200 
00201 /* file scope variables */
00202 GATResource_vtable GATResource__vtable = {
00203   GATResource_GetType,
00204   GATResource_Destroy,
00205   GATResource_Equals,
00206   GATResource_Clone,
00207   GATResource_GetInterface,
00208   GATResource_GetCPIInstanceData
00209 };
00210 
00211 static GATResource_ISerialisable_vtable 
00212   GATResource_ISerialisable__vtable = 
00213 {
00214   GATResource_Serialise,
00215   GATResource_DeSerialise,
00216   GATResource_GetIsDirty,
00217 };
00218 
00219 static GATResource_IMonitorable_vtable 
00220   GATResource_IMonitorable__vtable = 
00221 {
00222   GATResource_Impl_AddMetricListener,
00223   GATResource_Impl_RegisterPolling,
00224   GATResource_Impl_RemoveRegisteredMetric,
00225   GATResource_Impl_GetMetrics
00226 };
00227 
00228 static GATResource_IResource_vtable 
00229   GATResource_IResource__vtable = 
00230 {
00231   GATResource_Impl_GetResourceDescription,
00232   GATResource_Impl_GetReservation
00233 };
00234 
00235 /* External functions */
00236 
00237 GATRESOURCE_IMPLEMENTATION(GATSoftwareResource);
00238 GATRESOURCE_IMPLEMENTATION(GATHardwareResource);
00239 
00240 /** GATResource_Impl_Register_GATSerialisable
00241  *  The GATResource_Impl_Register_GATSerialisable function registers the serialization
00242  *  vtable with the GAT engine to allow generic object creation.
00243  *  This function is called by the GAT engine, there is no need to use it 
00244  *  directly.
00245  */
00246 GATResult GATResource_Register_GATSerialisable(void)
00247 {
00248   GATResult retval = GATObject_Register_GATSerialisable(
00249     GATType_GATHardwareResource, &GATResource_ISerialisable__vtable);
00250 
00251   if (GAT_SUCCESS == retval)
00252   {
00253     retval = GATObject_Register_GATSerialisable(GATType_GATSoftwareResource, 
00254       &GATResource_ISerialisable__vtable);
00255   }
00256   return retval;
00257 }
00258 
00259 
00260 /* local functions */
00261 
00262 /** GATResource_Impl_Create
00263  *  @brief Create a new GATResource object
00264  *
00265  *  The function @c GATResource_Impl_Create creates a new 
00266  *  GATResource object. This function is used from an adaptor only and not by 
00267  *  any GATEngine client code.
00268  *
00269  *  @param type The concrete GATType of the implemented object.
00270  *  @param context The GAT context to use while the initialisation of the 
00271  *        new object.
00272  *  @param preferences The preferences to use wile selecting the adaptor for 
00273  *        the corresponding CPI.
00274  *
00275  *  @return Returns a handle to the newly created GATResource object.
00276  *        Returns 0 (zero) if an error occurs.
00277  *
00278  *  @remark The concrete function name to use is determined by the type to be
00279  *        stored inside the list. For instance, a list containing @c int's 
00280  *        would  be destroyed with the function @c GATList_int_Destroy.
00281  */
00282 static GATResource 
00283 GATResource_Impl_Create(GATType type, GATContext context, 
00284   GATPreferences_const preferences, void *instance_data)
00285 {
00286   GATResult err_code = GAT_MEMORYFAILURE;
00287   GATResource retval = (GATResource) malloc(
00288     sizeof(struct GATResource_S));
00289       
00290   if (NULL != retval)
00291   {
00292     memset(retval, 0, sizeof(struct GATResource_S));
00293     retval->GATObject__vtable = &GATResource__vtable;
00294     retval->GATSerialisable__vtable = &GATResource_ISerialisable__vtable;
00295     retval->GATMonitorable__vtable = &GATResource_IMonitorable__vtable;
00296     retval->GATResource__vtable = &GATResource_IResource__vtable;
00297 
00298     retval->data.context = context;
00299     retval->data.type = type;
00300     retval->data.isdirty = GATFalse;
00301     retval->data.source = GATResource_ToGATObject_const(retval);
00302 
00303     /* find a CPI object, which can handle this object  */
00304     {
00305       GATBool found_cpi = GATFalse;
00306       GATResourceCPIList current = NULL;
00307       GATRegistry_const registry = GATContext_internal_GetRegistry(context);
00308       
00309       /* use default preferences, if appropriate */
00310       if (NULL == preferences)
00311       {
00312         preferences = GATContext_GetPreferences(context);
00313       }
00314       retval->cpilist = GATRegistry_FindGATResourceCPI(registry, preferences);
00315       if (NULL == retval->cpilist)
00316       {
00317         GATResource_Destroy(&retval);
00318         /* GATStatus(GAT_NO_REGISTERED_CPI) */
00319       }
00320       else 
00321       {
00322         /* create a new instance of the CPI provider */
00323         err_code = GAT_NO_MATCHING_CPI;
00324         for(current = retval->cpilist; NULL != current; current = current->next)
00325         {
00326           err_code = GATResourceCPI_CreateInstance(current->cpi, 
00327             &retval->data, instance_data);
00328             
00329           if (GAT_SUCCESS == err_code)
00330           {
00331             retval->cpi = current->cpi;
00332             found_cpi = GATTrue;
00333             break;
00334           }
00335         }
00336 
00337         if (GATTrue == found_cpi)
00338         {
00339           /* now, initialise the monitoring framework with the help of the
00340              CPI provider found */
00341           GATList_GATMetric metrics = NULL;
00342 
00343           err_code = GATResourceCPI_GetMetrics(retval->cpi, 
00344             &retval->data, &metrics);            
00345           if (GAT_SUCCEEDED(err_code))
00346           {
00347             retval->data.monitorable = GATMonitorable_Impl_Create(metrics);
00348             if (NULL == retval->data.monitorable)
00349             {
00350               err_code = GAT_MEMORYFAILURE;
00351             }
00352             GATList_GATMetric_Destroy(&metrics);
00353           }
00354           else if (GAT_NOTIMPL == err_code)
00355           {
00356             err_code = GAT_SUCCESS;   /* no monitoring supported here */
00357           }
00358 
00359           /* register this object with the engine */
00360           if (GAT_SUCCEEDED(retval))
00361           {
00362             err_code = GATRegistry_AddGATResourceToCPIList(context, retval->cpi, 
00363               retval);
00364           }
00365         }
00366       }
00367     }
00368   }
00369   
00370   /* error handling */
00371   if (GAT_FAILED(err_code))
00372   {
00373     GATResource_Destroy(&retval);
00374   }
00375   return retval;
00376 }
00377 
00378 /** void GATResource_Destroy(GATResource *resource)
00379  *
00380  *  The function GATResource_Destroy is the destructor used to
00381  *  free all the memory allocated by an GATResource instance.
00382  *
00383  *  @param description The pointer to the GATResource to destroy
00384  *
00385  *  @remark The concrete function name to use is determined by the type to be
00386  *        stored inside the list. For instance, a list containing @c int's 
00387  *        would  be destroyed with the function @c GATList_int_Destroy.
00388  */
00389 void
00390 GATResource_Destroy(GATResource *object)
00391 {
00392   if (NULL != object && NULL != *object)
00393   {
00394     /* TODO: free your internal object data here */
00395     GATMonitorable_Impl_Destroy(&(*object)->data.monitorable);
00396     if (NULL != (*object)->cpi)  /* during creation this may be zero */
00397     {
00398       GATRegistry_RemoveGATResourceFromCPIList((*object)->data.context, (*object)->cpi, 
00399         *object);
00400       GATResourceCPI_DestroyInstance((*object)->cpi, &(*object)->data);
00401     }
00402     GATResourceCPIList_Destroy((*object)->cpilist);
00403     free(*object);
00404     *object = NULL;
00405   }
00406 }
00407 
00408 /** GATResource_Equals
00409  *  @brief Compare two GATResource objects
00410  *
00411  *  The function @c GATResource_Equals compares two objects of the
00412  *  @c GATResource type.
00413  *
00414  *  @param lhs The first list to compare
00415  *  @param rhs The second list to compare
00416  *  @param isequal The pointer to the GATBool variable, which should receive 
00417  *        the result if the comparision
00418  *
00419  *  @return An error code.
00420  *
00421  *  @remark The concrete function name to use is determined by the type to be
00422  *        stored inside the list. For instance, a list containing @c int's 
00423  *        would  be destroyed with the function @c GATList_int_Destroy.
00424  */
00425 GATResult
00426 GATResource_Equals(GATResource_const lhs,
00427   GATResource_const rhs, GATBool *isequal)
00428 {
00429   GATResult retval = GAT_INVALID_HANDLE;
00430 
00431   if (NULL != lhs && NULL != rhs)
00432   {
00433     retval = GAT_INVALID_PARAMETER;
00434     if (NULL != isequal)
00435     {
00436 
00437 /* TODO: compare your instance data here */
00438 
00439       retval = GATResourceCPI_EqualsInstance(lhs->cpi, &lhs->data, 
00440         &rhs->data, isequal);
00441     }
00442   }
00443   return retval;
00444 }
00445 
00446 /** GATResource_Clone
00447  *  @brief Clone the given GATResource
00448  *
00449  *  The function @c GATResource_Clone generates a (deep) copy of 
00450  *  the given GATResource. 
00451  *
00452  *  @param description The object to clone
00453  *  @param new_object The pointer, through which the result is to be 
00454  *        returned.
00455  *
00456  *  @return An error type.
00457  *
00458  *  @remark The concrete function name to use is determined by the type to be
00459  *        stored inside the list. For instance, a list containing @c int's 
00460  *        would  be destroyed with the function @c GATList_int_Destroy.
00461  */
00462 GATResult
00463 GATResource_Clone(GATResource_const handle, 
00464   GATResource *new_handle)
00465 {
00466   GATResult retval = GAT_INVALID_HANDLE;
00467   if (NULL != handle)
00468   {
00469     if (NULL == new_handle)
00470     {
00471       retval = GAT_INVALID_PARAMETER;
00472     }
00473     else
00474     {
00475       struct GATResource_S const *object = handle;
00476       GATResource new_object = (GATResource) malloc(sizeof(struct GATResource_S));
00477       
00478       *new_handle = NULL;
00479       if (NULL == new_object)
00480       {
00481         retval = GAT_MEMORYFAILURE;
00482       }
00483       else
00484       {
00485         memset(new_object, 0, sizeof(struct GATResource_S));
00486         new_object->GATObject__vtable = &GATResource__vtable;
00487         new_object->GATSerialisable__vtable = &GATResource_ISerialisable__vtable;
00488         new_object->GATMonitorable__vtable = &GATResource_IMonitorable__vtable;
00489         new_object->GATResource__vtable = &GATResource_IResource__vtable;
00490         
00491         new_object->data.context = object->data.context;
00492         new_object->data.type = object->data.type;
00493         new_object->data.isdirty = GATFalse;
00494         new_object->data.source = GATResource_ToGATObject_const(new_object);
00495 
00496 /* TODO: insert cloning of your constructor supplied data here */
00497 
00498         new_object->cpilist = GATRegistry_CloneGATResourceCPIList(object->cpilist);
00499         if (NULL == new_object->cpilist)
00500         {
00501           retval = GAT_MEMORYFAILURE;
00502           GATResource_Destroy(&new_object);
00503         }
00504         else
00505         {
00506           /* re-find the cpi to use */
00507           GATResourceCPIList current = object->cpilist;
00508           GATResourceCPIList new_current = new_object->cpilist;
00509           
00510           for (/**/; NULL != current; 
00511                current = current->next, new_current = new_current->next)
00512           {
00513             if (current->cpi == object->cpi)
00514             {
00515               new_object->cpi = new_current->cpi;
00516               break;
00517             }
00518           }
00519           assert(NULL != new_object->cpi);
00520           
00521           /* clone the instance data */
00522           retval = GATResourceCPI_CloneInstance(object->cpi, &object->data, 
00523             &new_object->data);
00524           if (GAT_SUCCESS != retval)
00525           {
00526             GATResource_Destroy(&new_object);
00527           }
00528           else
00529           {
00530             /* clone the monitoring data */
00531             if (NULL != object->data.monitorable)
00532             {
00533               retval = GATMonitorable_Impl_Clone(object->data.monitorable, 
00534                 &new_object->data.monitorable);
00535             }
00536  
00537             /* register this object with the engine */
00538             if (GAT_SUCCEEDED(retval))
00539             {
00540               retval = GATRegistry_AddGATResourceToCPIList(
00541                 new_object->data.context, new_object->cpi, new_object);
00542             }
00543 
00544             if (GAT_FAILED(retval))
00545             {
00546               GATResource_Destroy(&new_object);
00547             }
00548             else
00549             {
00550               /* return the new object */
00551               *new_handle = new_object;
00552             }
00553           }
00554         }
00555       }
00556     }
00557   }
00558   return retval;
00559 }
00560 
00561 /** GATType GATResource_GetType(GATResource_const resource)
00562  *  @brief Return the type of the GATResource
00563  *
00564  *  The function @c GATResource_GetType always returns 
00565  *  @c #GATType_GATResource. 
00566  *
00567  *  @param object The object to inspect
00568  *
00569  *  @return Returns always @c #GATType_GATResource. 
00570  *
00571  *  @remark The concrete function name to use is determined by the type to be
00572  *        stored inside the list. For instance, a list containing @c int's 
00573  *        would  be destroyed with the function @c GATList_int_Destroy.
00574  */
00575 GATType
00576 GATResource_GetType(GATResource_const object)
00577 {
00578   GATType retval = GATType_NoType;
00579   if (NULL != object)
00580   {
00581     retval = object->data.type;
00582   }
00583   return retval;
00584 }
00585 
00586 /** int GATResource_GetInterface(GATResource_const file, GATInterface iftype, void const **ifp)
00587  *  @brief Get an interface supported by a GATObject
00588  *
00589  *  The function GATResource_GetInterface allows to get a pointer to an 
00590  *  additional interface supported by this GATResource.
00591  *
00592  *  @param object The object to be asked for the new interface.
00593  *  @param iftype The interface the object is to be asked for.
00594  *  @param ifp The pointer, through which the result is to be returned.
00595  *
00596  *  @return An error type.
00597  *
00598  *  @remark The concrete function name to use is determined by the type to be
00599  *        stored inside the list. For instance, a list containing @c int's 
00600  *        would  be destroyed with the function @c GATList_int_Destroy.
00601  */
00602 GATResult 
00603 GATResource_GetInterface(GATResource_const object, GATInterface iftype, 
00604   void const **ifp)
00605 {
00606   GATResult retval = GAT_INVALID_PARAMETER;
00607 
00608   if (NULL != ifp)
00609   {
00610     *ifp = NULL;
00611     if (GATInterface_ISerialisable == iftype || 
00612         GATInterface_IAdvertisable == iftype)
00613     {
00614       *ifp = (void const *) &object->GATSerialisable__vtable;
00615       retval = GAT_SUCCESS;
00616     }
00617     else
00618     if (GATInterface_IResource == iftype)
00619     {
00620       *ifp = (void const *) &object->GATResource__vtable;
00621       retval = GAT_SUCCESS;
00622     }
00623     else
00624     if (GATInterface_IMonitorable == iftype && NULL != object->data.monitorable)
00625     {
00626       *ifp = (void const *) &object->GATMonitorable__vtable;
00627       retval = GAT_SUCCESS;
00628     }
00629     else
00630     {
00631       retval = GAT_NO_INTERFACE;
00632     }
00633   }
00634   return retval;
00635 }
00636 
00637 
00638 /* GATResource API */
00639 
00640 /** int GATResource_Impl_GetResourceDescription(GATResource_const object, GATResourceDescription_const *description)
00641  *
00642  *  The function GATResource_Impl_GetResourceDescription returns the 
00643  *  GATResourceDescription which describes this GATResource instance.
00644  *
00645  *  @param object The GATResource instance to ask for its resource description.
00646  *  @param description The pointer to the variable, which receives the 
00647  *        resulting resource description.
00648  *
00649  *  @return An error code.
00650  *
00651  *  @remark The concrete function name to use is determined by the type to be
00652  *        stored inside the list. For instance, a list containing @c int's 
00653  *        would  be destroyed with the function @c GATList_int_Destroy.
00654  */
00655 static GATResult
00656 GATResource_Impl_GetResourceDescription(GATResource_const object,
00657   GATResourceDescription_const *description)
00658 {
00659   return GATResourceCPI_GetResourceDescription(object->cpi, &object->data, 
00660     description);
00661 }
00662 
00663 /** int GATResource_Impl_GetReservation(GATResource_const object, GATReservation_const *reservation)
00664  *
00665  *  The function GATResource_Impl_GetReservation returns the GATReservation
00666  *  which is associated with this GATResource.
00667  *
00668  *  @param object The GATResource instance to ask for its associated 
00669  *        reservation.
00670  *  @param reservation The pointer to a variable, which receives the resulting
00671  *        reservation.
00672  *
00673  *  @return An error code.
00674  *
00675  *  @remark The concrete function name to use is determined by the type to be
00676  *        stored inside the list. For instance, a list containing @c int's 
00677  *        would  be destroyed with the function @c GATList_int_Destroy.
00678  */
00679 static GATResult
00680 GATResource_Impl_GetReservation(GATResource_const object, 
00681   GATReservation_const *reservation)
00682 {
00683   return GATResourceCPI_GetReservation(object->cpi, &object->data, reservation);
00684 }  
00685 
00686 /* GATMonitorable API */
00687 
00688 /** GATResource_Impl_AddMetricListener
00689  *
00690  *  The function GATResource_Impl_AddMetricListener adds the passed instance of a 
00691  *  GATMetricListener to the list of GATMetricListeners which are notified of 
00692  *  fired GATMetricEvents of the type described by the provided GATMetric 
00693  *  instance.
00694  *
00695  *  @param object The GATResource instance to add the GATMetricListener to.
00696  *  @param listener The GATMetricListener to call, when the corresponding 
00697  *        GATMetricEvent is fired.
00698  *  @param listener_data The client supplied data, which will be passed through
00699  *        to the GATMetricListener.
00700  *  @param metric The GATMetric instance describing the GATMetricEvent to pass
00701  *        to the GATMetricListener.
00702  *  @param cookie The returned value should be used to remove the 
00703  *        GATMetricListener from this GATMonitorable.
00704  *
00705  *  @return An error code.
00706  *
00707  *  @remark The concrete function name to use is determined by the type to be
00708  *        stored inside the list. For instance, a list containing @c int's 
00709  *        would  be destroyed with the function @c GATList_int_Destroy.
00710  */
00711 static GATResult 
00712 GATResource_Impl_AddMetricListener(GATResource object, 
00713   GATMetricListener listener, void *listener_data, GATMetric metric,
00714   GATuint32 *cookie)
00715 {
00716   GATResult retval = GAT_INVALID_HANDLE;
00717   if (NULL != object)
00718   {
00719     if (NULL != object->data.monitorable)
00720     {
00721       retval = GATMonitorable_Impl_AddMetricListener(object->data.monitorable, 
00722         listener, listener_data, metric, cookie);
00723     } 
00724     else
00725     { 
00726       /* this may happen, if the adaptor has not registered any GATMetrics */
00727       retval = GAT_NO_INTERFACE;
00728     }
00729   }
00730   return retval;
00731 }
00732 
00733 /** GATResource_Impl_RegisterPolling
00734  *
00735  *  The function GATResource_Impl_RegisterPolling registers a continuous 
00736  *  metric with the given GATResource instance.
00737  *
00738  *  @param object The GATResource instance to register the metric with.
00739  *  @param metric The GATMetric instance describing the GATMetricEvent to pass
00740  *        to the GATMetricListener. This metric instance must be of type
00741  *        GATMeasurementType_Continuous, otherwise an error is returned.
00742  *  @param event The pointer to a variable, which should receive the resulting
00743  *        GATMetricEvent. The GATMetricEvent instance should be freed by the 
00744  *        caller when it isn't used anymore.
00745  *  @param cookie The returned value should be used to remove the 
00746  *        GATMetricListener from this GATResource.
00747  *
00748  *  @return An error code.
00749  *
00750  *  @remark The concrete function name to use is determined by the type to be
00751  *        stored inside the list. For instance, a list containing @c int's 
00752  *        would  be destroyed with the function @c GATList_int_Destroy.
00753  */
00754 static GATResult 
00755 GATResource_Impl_RegisterPolling(GATResource object, GATMetric metric, 
00756   GATMetricEvent *event, GATuint32 *cookie)
00757 {
00758   GATResult retval = GAT_INVALID_HANDLE;
00759   if (NULL != object)
00760   {
00761     if (NULL != object->data.monitorable)
00762     {
00763       retval = GATMonitorable_Impl_RegisterPolling(object->data.monitorable, 
00764         metric, 0, cookie);
00765       if (GAT_SUCCESS == retval)
00766       {
00767         /* ask the CPI provider to return the corresponding metric event */
00768         retval = GATResourceCPI_GetMetricEvent(object->cpi, &object->data, 
00769           metric, event);
00770         if (GAT_SUCCESS != retval)
00771         {
00772           GATMonitorable_Impl_RemoveRegisteredMetric(object->data.monitorable,
00773             metric, *cookie);
00774           *cookie = 0;
00775         }
00776       }
00777     } 
00778     else
00779     { 
00780       /* this may happen, if the adaptor has not registered any GATMetrics */
00781       retval = GAT_NO_INTERFACE;
00782     }
00783   }
00784   return retval;
00785 }
00786 
00787 /** GATResource_Impl_RemoveRegisteredMetric
00788  *
00789  *  The function GATResource_Impl_RemoveRegisteredMetric removes a GATMetricListener, 
00790  *  which was previously registered with GATResource_Impl_AddMetricListener.
00791  *
00792  *  @param object The GATResource instance to remove the GATMetricListener from.
00793  *  @param listener The GTAMetricListener to call, when the corresponding 
00794  *        GATMetricEvent is fired.
00795  *  @param metric The GATMetric instance describing the GATMetricEvent to pass
00796  *        to the GATMetricListener.
00797  *  @param cookie This value identifies the GATMetricListener to remove, it 
00798  *        was returned from the corresponding GATMonitorable_AddMetricListener 
00799  *        or GATMonitorable_MetricRegisterPolling functions.
00800  *  
00801  *  @return An error code.
00802  *
00803  *  @remark The concrete function name to use is determined by the type to be
00804  *        stored inside the list. For instance, a list containing @c int's 
00805  *        would  be destroyed with the function @c GATList_int_Destroy.
00806  */
00807 static GATResult 
00808 GATResource_Impl_RemoveRegisteredMetric(GATResource object, 
00809   GATMetric metric, GATuint32 cookie)
00810 {
00811   GATResult retval = GAT_INVALID_HANDLE;
00812   if (NULL != object)
00813   {
00814     if (NULL != object->data.monitorable)
00815     {
00816       retval = GATMonitorable_Impl_RemoveRegisteredMetric(
00817         object->data.monitorable, metric, cookie);
00818     } 
00819     else
00820     { 
00821       /* this may happen, if the adaptor has not registered any GATMetrics */
00822       retval = GAT_NO_INTERFACE;
00823     }
00824   }
00825   return retval;
00826 }
00827 
00828 /** GATResource_Impl_GetMetrics
00829  *
00830  *  The function GATResource_Impl_GetMetrics returns a list of metrics supported 
00831  *  by this GATResource.
00832  *
00833  *  @param object The GATResource instance, for which the supported metrics 
00834  *        should be returned.
00835  *  @param metrics The pointer to the variable, which receives the resulting 
00836  *        list of metrics.
00837  *
00838  *  @return An error code.
00839  *
00840  *  @remark The concrete function name to use is determined by the type to be
00841  *        stored inside the list. For instance, a list containing @c int's 
00842  *        would  be destroyed with the function @c GATList_int_Destroy.
00843  */
00844 static GATResult 
00845 GATResource_Impl_GetMetrics(GATResource_const object, 
00846   GATList_GATMetric *metrics)
00847 {
00848   GATResult retval = GAT_INVALID_HANDLE;
00849   if (NULL != object)
00850   {
00851     if (NULL != object->data.monitorable)
00852     {
00853       retval = GATMonitorable_Impl_GetMetrics(object->data.monitorable, metrics);
00854     } 
00855     else
00856     { 
00857       /* this may happen, if the adaptor has not registered any GATMetrics */
00858       retval = GAT_NO_INTERFACE;
00859     }
00860   }
00861   return retval;
00862 }
00863 
00864 
00865 /* GATAdvertiseable API */
00866 
00867 /** GATResourceCPI_SerialiseCallback
00868  *
00869  *  The function GATResourceCPI_SerialiseCallback is used as a callback 
00870  *  function for the serialisation of a GATResource object. 
00871  *  It should be provided to serialise the associated CPI provider data for 
00872  *  the given object.
00873  *
00874  *  @param object The object to serialise. This is the same as the object 
00875  *        passed as the first parameter to the function GATXds_SerialiseObject.
00876  *  @param stream The stream interface to use for the serialisation.
00877  *  @param clear_dirty If the clear_dirty parameter is set to GATTrue, the 
00878  *        internal dirty flag of this object is to be reset (no used here)
00879  *
00880  *  @return An error code.
00881  *
00882  *  @remark This function is called from the GAT engine, there is no need to 
00883  *        call it directly.
00884  *
00885  *  @remark The concrete function name to use is determined by the type to be
00886  *        stored inside the list. For instance, a list containing @c int's 
00887  *        would  be destroyed with the function @c GATList_int_Destroy.
00888  */
00889 static GATResult 
00890 GATResourceCPI_SerialiseCallback(GATObject handle, GATObject stream, 
00891   GATBool clear_dirty)
00892 {
00893   GATResult retval = GAT_INVALID_PARAMETER;
00894   GATType type = GATObject_GetType(handle);
00895   
00896   if (GATType_GATSoftwareResource == type)
00897   {
00898     GATResource object = (GATResource) GATObject_ToGATSoftwareResource(handle);
00899     retval = GATResourceCPI_Serialise(object->cpi, &object->data, stream, 
00900       clear_dirty);
00901     if (GAT_SUCCEEDED(retval) && GATTrue == clear_dirty)
00902     {
00903       object->data.isdirty = GATFalse;
00904     }
00905   }
00906   else if (GATType_GATHardwareResource == type) 
00907   {
00908     GATResource object = (GATResource) GATObject_ToGATHardwareResource(handle);
00909     retval = GATResourceCPI_Serialise(object->cpi, &object->data, stream,
00910       clear_dirty);
00911     if (GAT_SUCCEEDED(retval) && GATTrue == clear_dirty)
00912     {
00913       object->data.isdirty = GATFalse;
00914     }
00915   }
00916   return retval;
00917 }
00918 
00919 /** int GATResource_Serialise(GATResource object, GATObject stream, GATBool clear_dirty)
00920  *  @brief Serialise a GATResource object
00921  *
00922  *  The function GATResource_Serialise serialises the given GATFIle object into 
00923  *  the given stream. 
00924  *
00925  *  @param object The GATResource object to serialise.
00926  *  @param stream The stream interface to use for the serialisation.
00927  *  @param clear_dirty If the clear_dirty parameter is set to GATTrue, the 
00928  *        internal dirty flag of this object is to be reset (no used here)
00929  *
00930  *  @return An error code.
00931  *
00932  *  @remark The concrete function name to use is determined by the type to be
00933  *        stored inside the list. For instance, a list containing @c int's 
00934  *        would  be destroyed with the function @c GATList_int_Destroy.
00935  */
00936 GATResult 
00937 GATResource_Serialise(GATResource object, GATObject stream, 
00938   GATBool clear_dirty)
00939 {
00940   GATResult retval = GAT_INVALID_HANDLE;
00941   if (NULL != object)
00942   {
00943     retval = GATXds_SerialiseObject(GATResource_ToGATObject(object), stream, 
00944       clear_dirty, GATResourceCPI_SerialiseCallback, "uint32 uint32",
00945       GATRESOURCE_VERSION1, (GATuint32)object->data.type);
00946 
00947     if (GAT_SUCCEEDED(retval) && clear_dirty)
00948     {
00949       object->data.isdirty = GATFalse;
00950     }
00951   }
00952   return retval;
00953 }
00954 
00955 /** GATResource_Impl_VersionCallback
00956  *
00957  *  The function GATResource_Impl_VersionCallback is used as a callback function
00958  *  during the de-serialisation of a GATResource. It should be provided to test,
00959  *  whether the de-serialised version matches the expected version.
00960  *
00961  *  @param version The version number, which was de-serialised from the stream.
00962  *
00963  *  @return This function should return GATTrue, if the version matches the 
00964  *        expected value (version is valid), GATFalse otherwise.
00965  *
00966  *  @remark This function is called from the GAT engine, there is no need to 
00967  *        call it directly.
00968  *
00969  *  @remark The concrete function name to use is determined by the type to be
00970  *        stored inside the list. For instance, a list containing @c int's 
00971  *        would  be destroyed with the function @c GATList_int_Destroy.
00972  */
00973 static GATBool
00974 GATResource_Impl_VersionCallback(GATuint32 version)
00975 {
00976   GATBool retval = GATFalse;
00977   if ((version & ~GATRESOURCE_MINOR_MASK) <= GATRESOURCE_LASTVERSION)
00978   {
00979     retval = GATTrue;
00980   }
00981   return retval;
00982 }
00983 
00984 /** GATResource_DeSerialiseCallback
00985  *
00986  *  The function GATResource_DeSerialiseCallback is used as a callback function
00987  *  during the de-serialisation of a GATResource. It should be provided for the
00988  *  instantiation of the new GATResource object based on the already de-serialised 
00989  *  data items and the de-serialisation of the associated CPI provider data for 
00990  *  the given object.
00991  *
00992  *  @param context The GAT context to be used for object construction.
00993  *  @param stream The stream interface to use for the serialisation.
00994  *  @param object The pointer to the variable, which should receive the newly 
00995  *        constructed object.
00996  *  @param version The version of the saved data read from the input stream.
00997  *  @param args This parameter is the pointer to the va_list containing 
00998  *        pointers to the already de-serialised data items accordingly to the
00999  *        format string, provided during the call to the 
01000  *        GATResource_DeSerialise function.
01001  *
01002  *  @return An error code.
01003  *
01004  *  @remark This function is called from the GAT engine, there is no need to 
01005  *        call it directly.
01006  *
01007  *  @remark The concrete function name to use is determined by the type to be
01008  *        stored inside the list. For instance, a list containing @c int's 
01009  *        would  be destroyed with the function @c GATList_int_Destroy.
01010  */
01011 static GATResult
01012 GATResource_DeSerialiseCallback(GATContext context, GATObject stream, 
01013   GATObject *new_object, GATuint32 version, va_list args)
01014 {
01015   /* the version was eaten already */
01016   GATuint32 *type = va_arg(args, GATuint32 *);    /* GATType */
01017   GATResource object = NULL;
01018   
01019   /* construct the new object */
01020   GATResult retval = GATResource_DeSerialise_Create(context, stream, *type, 
01021     &object);
01022 
01023   GAT_UNUSED_PARAMETER(version);
01024 
01025   if (GAT_SUCCESS == retval)
01026   {
01027     if (NULL != object)
01028     {
01029       *new_object = GATResource_ToGATObject(object);
01030     }
01031     else
01032     {
01033       GATResource_Destroy(&object);
01034       retval = GAT_INVALID_PARAMETER;
01035     }
01036   }
01037   return retval;
01038 }
01039 
01040 /** GATResource GATResource_DeSerialise(GATContext context, GATObject stream, GATBool clear_dirty)
01041  *  @brief De-serialise a GATResource object
01042  *
01043  *  The function GATResource_DeSerialise de-serialises a streamed  
01044  *  GATResource object from the given stream  It constructs a new instance of 
01045  *  the de-serialised object.
01046  *
01047  *  @param context The GAT context to be used for object construction.
01048  *  @param stream The stream interface to use for the serialisation.
01049  *  @param result The pointer to a variable, which receives the status code of
01050  *        the operation.
01051  *
01052  *  @return The newly constructed GATResource object.
01053  *
01054  *  @remark The concrete function name to use is determined by the type to be
01055  *        stored inside the list. For instance, a list containing @c int's 
01056  *        would  be destroyed with the function @c GATList_int_Destroy.
01057  */
01058 GATResource 
01059 GATResource_DeSerialise(GATContext context, GATObject stream, 
01060   GATResult *result)
01061 {
01062   GATObject object = NULL;     /* the new object will be created here */
01063   
01064   /* we must provide all instance data items to be de-serialised for this
01065      GATResource object accordingly to the provided format string */
01066   GATuint32 version = 0;
01067   GATuint32 type = GATType_NoType;  
01068 
01069   /* read the data */
01070   GATResult retval = GATXds_DeSerialiseObject(context, stream, 
01071     GATResource_DeSerialiseCallback, GATResource_Impl_VersionCallback, 
01072     &object, "uint32 uint32", &version, &type);
01073 
01074   /* FIXME: GATStatus(retval); */
01075   if (NULL != result)
01076   { 
01077     *result = retval;
01078   }
01079   return (GATResource) object;
01080 }
01081 
01082 /** GATResource_GetIsDirty
01083  *  
01084  *  The function GATResource_GetIsDirty retrieves the status of the dirty 
01085  *  flag of this GATResource object.
01086  *
01087  *  @param file The GATResource object to inspect for its dirty status.
01088  *  @param isdirty The pointer to a variable, which receives the dirty status.
01089  *
01090  *  @return An error code.
01091  *
01092  *  @remark The concrete function name to use is determined by the type to be
01093  *        stored inside the list. For instance, a list containing @c int's 
01094  *        would  be destroyed with the function @c GATList_int_Destroy.
01095  */
01096 GATResult 
01097 GATResource_GetIsDirty(GATResource_const object, GATBool *isdirty)
01098 {
01099   GATResult retval = GAT_INVALID_HANDLE;
01100   if (NULL != object)
01101   {
01102     if (NULL != isdirty)
01103     {
01104       *isdirty = object->data.isdirty;
01105       retval = GAT_SUCCESS;
01106     }
01107     else
01108     {
01109       retval = GAT_INVALID_PARAMETER;
01110     }
01111   }  
01112   return retval;
01113 }
01114 
01115 /** GATResource_DeSerialise_Create
01116  *
01117  *  The function GATResource_DeSerialise_Create creates a new GATResource 
01118  *  object.
01119  *  Further it tries find a CPI provider to associate with this file object. 
01120  *  The CPI provider is selected by testing, which adapter is able to handle 
01121  *  the streamed instance data of the original CPI provider.
01122  *
01123  *  @param context The GAT context to use for creation of the GATResource 
01124  *        object.
01125  *  @param stream The object from which the adaptor should read the streamed
01126  *        instance data.
01127  *  @param type The actual type of the object to create.
01128  *  @param new_object The pointer to the variable, which should receive the 
01129  *        newly constructed GATResource object.
01130  *
01131  *  @return An error code.
01132  */
01133 static GATResult
01134 GATResource_DeSerialise_Create(GATContext context, GATObject stream, 
01135   GATuint32 type, GATResource *object)
01136 {
01137   GATResult retval = GAT_MEMORYFAILURE;
01138   GATResource new_object = (GATResource) malloc(sizeof(struct GATResource_S));
01139 
01140   if(NULL != new_object)
01141   {
01142     memset(new_object, 0, sizeof(struct GATResource_S));
01143     new_object->GATObject__vtable = &GATResource__vtable;
01144     new_object->GATSerialisable__vtable = &GATResource_ISerialisable__vtable;
01145     new_object->GATMonitorable__vtable = &GATResource_IMonitorable__vtable;
01146     new_object->GATResource__vtable = &GATResource_IResource__vtable;
01147     
01148     new_object->data.context = context;
01149     new_object->data.type = (GATType)type;
01150     new_object->data.isdirty = GATFalse;
01151     new_object->data.source = GATResource_ToGATObject_const(new_object);
01152 
01153     /* find a CPI object, which can handle the data at the given stream 
01154        location */
01155     {
01156       GATRegistry_const registry = GATContext_internal_GetRegistry(context);
01157       GATPreferences_const preferences = NULL;
01158             
01159       /* use default preferences, if appropriate */
01160       if (NULL == preferences)
01161       {
01162         preferences = GATContext_GetPreferences(context);
01163       }
01164 
01165       new_object->cpilist = GATRegistry_FindGATResourceCPI(registry, preferences);
01166       if (NULL == new_object->cpilist)
01167       {
01168         retval = GAT_NO_REGISTERED_CPI;
01169       }
01170       else 
01171       {
01172         /* find out the current stream position */
01173         GATuint32 offset = 0;
01174         GATBool found_cpi = GATFalse;
01175         GATResourceCPIList current = NULL;
01176         
01177         retval = GATStreamable_Seek(stream, GATOrigin_Current, 0, &offset);
01178         if (GAT_SUCCESS == retval)
01179         {
01180           /* create new instance data of the CPI provider */
01181           for(current = new_object->cpilist; NULL != current; current = current->next)
01182           {
01183             /* try, whether this CPI can handle the input */
01184             retval = GATResourceCPI_DeSerialise(current->cpi, stream, 
01185               &new_object->data);
01186             if (GAT_SUCCESS == retval)
01187             {
01188               new_object->cpi = current->cpi;
01189               found_cpi = GATTrue;
01190               break;
01191             }
01192             
01193             /* reset stream pointer to the beginning of the CPI instance data */
01194             retval = GATStreamable_Seek(stream, GATOrigin_Set, offset, 0);
01195             if (GAT_SUCCESS != retval)
01196             {
01197               break;
01198             }
01199           }
01200         }
01201         
01202         /* no available CPI object can handle this */
01203         if (GATFalse == found_cpi)
01204         {
01205           retval = GAT_NO_MATCHING_CPI;
01206         }
01207         else
01208         {
01209           /* try to re-init the monitoring support, since the adaptor found may
01210              support another set of GATMetric's, than the original one. */
01211           GATList_GATMetric metrics = NULL;
01212 
01213           retval = GATResourceCPI_GetMetrics(new_object->cpi, &new_object->data, 
01214             &metrics);            
01215           if (GAT_SUCCEEDED(retval))
01216           {
01217             new_object->data.monitorable = GATMonitorable_Impl_Create(metrics);
01218             if (NULL != new_object->data.monitorable)
01219             {
01220               retval = GAT_MEMORYFAILURE;
01221             }
01222             GATList_GATMetric_Destroy(&metrics);
01223           }
01224           else if (GAT_NOTIMPL == retval)
01225           {
01226             retval = GAT_SUCCESS;   /* no monitoring supported here */
01227           }
01228 
01229           if (GAT_SUCCEEDED(retval))
01230           {
01231             retval = GATRegistry_AddGATResourceToCPIList(
01232               new_object->data.context, new_object->cpi, new_object);
01233           }
01234         }
01235       }
01236     }
01237   }
01238   
01239   if (GAT_SUCCESS == retval)
01240   {
01241     if (NULL != new_object)
01242     {
01243       *object = new_object;
01244     }
01245     else
01246     {
01247       GATResource_Destroy(&new_object);
01248       retval = GAT_INVALID_PARAMETER;
01249     }
01250   }
01251   else
01252   {
01253     GATResource_Destroy(&new_object);
01254   }
01255   return retval;
01256 }
01257 
01258 /*  GATResource_GetCPIInstanceData
01259  *  
01260  *  The function GATResource_GetCPIInstanceData returns the CPI instance data, 
01261  *  associated with the given GATResource object.
01262  *
01263  *  @param object The object, for which to return the CPI instance data.
01264  *  @param data The pointer to the variable, which should receive the
01265  *        resulting CPI instance data.
01266  *
01267  *  @return An error code.
01268  */
01269 static GATResult
01270 GATResource_GetCPIInstanceData(GATResource object, void **data)
01271 {
01272   GATResult retval = GAT_INVALID_HANDLE;
01273   if (NULL != object)
01274   {
01275     if (NULL != data)
01276     {
01277       *data = (void *)&object->data;
01278       retval = GAT_SUCCESS;
01279     }
01280     else
01281     {
01282       retval = GAT_INVALID_PARAMETER;
01283     }
01284   }
01285   return retval;
01286 }
01287