GridLab
Grid Application Toolkit

A simple API for Grid Applications
GAT

Menu



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

GATPipe.c

Go to the documentation of this file.
00001 /** @file GATPipe.c
00002  * Main .c for the GATPipe class.
00003  * 
00004  * An GATPipe represents a connection to another process.
00005  * 
00006  * @date $Date: 2004/04/20 12:33:22 $
00007  * 
00008  * @version $Header: /export/cvs-gridlab/wp-1/Codes/GATEngine/C-reference/src/GATPipe.c,v 1.12 2004/04/20 12:33:22 hartmutkaiser Exp $
00009  *
00010  *  Copyright (C) Kelly Davis
00011  *  This is part of the GAT Engine.
00012  *  Contributed by Kelly Davis <kdavis@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/GATPipe.c,v 1.12 2004/04/20 12:33:22 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 "GAT.h"
00030 #include "GATPipe.h"
00031 #include "GATPipeCPI.h"
00032 #include "GATRegistry.h"
00033 #include "GATInternal.h"
00034 #include "GATXdsWrapper.h"
00035 #include "GATMetricEvent.h"
00036 
00037 /* define the vtable types */
00038 GATOBJECT_DEFINE_VTABLE(GATPipe);
00039 GATSTREAMABLE_DEFINE_VTABLE(GATPipe);
00040 GATMONITORABLE_DEFINE_VTABLE(GATPipe);
00041 
00042 /* Declare the converters to/from GATObject */
00043 GATOBJECT_DEFINE_CONVERTERS(GATPipe);
00044 
00045 /* Macros */
00046 
00047 /* Structures, unions and enums */
00048 struct GATPipe_S
00049 {
00050   /* supported interfaces */
00051   GATPipe_vtable *GATObject__vtable;
00052   GATPipe_IStreamable_vtable *GATStreamable__vtable;
00053   GATPipe_IMonitorable_vtable *GATMonitorable__vtable;
00054   
00055   /* instance data */
00056   GATPipeCPI_Instance data; /* instance data of the corresponding CPI object */
00057   GATPipeCPI cpi;           /* CPI object to use for all subsequent operations */
00058   GATPipeCPIList cpilist;   /* CPI list of appropriate CPI objects */
00059 };
00060 
00061 /* Static function prototypes */
00062 static GATResult
00063 GATPipe_GetCPIInstanceData(GATPipe pipe, void **data);
00064 
00065 
00066 /* Pipe scope variables */
00067 static GATPipe_vtable GATPipe__vtable = {
00068   GATPipe_GetType,
00069   GATPipe_Destroy,
00070   GATPipe_Equals,
00071   GATPipe_Clone,
00072   GATPipe_GetInterface,
00073   GATPipe_GetCPIInstanceData
00074 };
00075 
00076 static GATPipe_IStreamable_vtable GATPipe_IStreamable__vtable =
00077 {
00078   GATPipe_Read,
00079   GATPipe_Write,
00080   GATPipe_Seek,
00081   GATPipe_Close
00082 };
00083 
00084 static GATPipe_IMonitorable_vtable  GATPipe_IMonitorable__vtable = {
00085   GATPipe_AddMetricListener,
00086   GATPipe_RegisterPolling,
00087   GATPipe_RemoveRegisteredMetric,
00088   GATPipe_GetMetrics
00089 };
00090 
00091 /* External functions */
00092 
00093 /** GATPipe_Create
00094  *  Constructs an instance of this class.
00095  *
00096  * @param context Used to broker resources.
00097  * @param preferences User preferences for this instance.
00098  * @param information Other information required to construct a GATPipe.
00099  */
00100 GATPipe 
00101 GATPipe_Create(GATContext context, GATPreferences_const preferences, 
00102   void *information)
00103 {
00104   GAT_STATUS_APIENTRY(context, "GATPipe_Create");
00105   
00106   GATPipe new_pipe = (GATPipe) malloc(sizeof(struct GATPipe_S));
00107   if (NULL != new_pipe)
00108   {
00109     memset(new_pipe, 0, sizeof(struct GATPipe_S));
00110     new_pipe->GATObject__vtable = &GATPipe__vtable;
00111     new_pipe->GATStreamable__vtable = &GATPipe_IStreamable__vtable;
00112     new_pipe->GATMonitorable__vtable = &GATPipe_IMonitorable__vtable;
00113 
00114     new_pipe->data.context = context;
00115     new_pipe->data.source = GATPipe_ToGATObject_const(new_pipe);
00116 
00117     /* find a CPI object, which can handle the pipe */
00118     {
00119       GATRegistry_const registry = GATContext_internal_GetRegistry(context);
00120 
00121       /* use default preferences, if appropriate */
00122       if (NULL == preferences)
00123       {
00124         preferences = GATContext_GetPreferences(context);
00125       }
00126       new_pipe->cpilist = GATRegistry_FindGATPipeCPI(registry, preferences);
00127 
00128       if (NULL == new_pipe->cpilist)
00129       {
00130         GAT_CREATE_STATUS(GAT_NO_REGISTERED_CPI);
00131       } 
00132       else 
00133       {
00134         /* create a new instance of the CPI provider */
00135         GATBool found_cpi = GATFalse;
00136         GATPipeCPIList current = NULL;
00137         for(current = new_pipe->cpilist; NULL != current; current = current->next)
00138         {
00139           GAT_CREATE_STATUS(GATPipeCPI_CreateInstance(current->cpi, 
00140             &new_pipe->data, information));
00141           if (GAT_SUCCEEDED(GAT_CURRENT_STATUS()))
00142           {
00143             new_pipe->cpi = current->cpi;
00144             found_cpi = GATTrue;
00145             break;
00146           }
00147         }
00148 
00149         /* no available CPI object can handle this */
00150         if (GATFalse == found_cpi)
00151         {
00152           GAT_CREATE_STATUS(GAT_NO_REGISTERED_CPI);
00153         }
00154         else
00155         {
00156           /* now, initialise the monitoring framework with the help of the CPI 
00157              provider found */
00158           GATList_GATMetric metrics = NULL;
00159           GATResult retval = GATPipeCPI_GetMetrics(new_pipe->cpi, 
00160             &new_pipe->data, &metrics);            
00161 
00162           if (GAT_SUCCEEDED(retval))
00163           {
00164             new_pipe->data.monitorable = GATMonitorable_Impl_Create(metrics);
00165             if (NULL == new_pipe->data.monitorable)
00166             {
00167               GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00168             }
00169             GATList_GATMetric_Destroy(&metrics);
00170           }
00171           else if (GAT_NOTIMPL == retval)
00172           {
00173             retval = GAT_SUCCESS;   /* no monitoring supported here */
00174           }
00175           else
00176           {
00177             GAT_CREATE_STATUS(retval);
00178           }
00179 
00180           /* register this object with the engine */
00181           GAT_CREATE_STATUS(GATRegistry_AddGATPipeToCPIList(context, 
00182             new_pipe->cpi, new_pipe));
00183         }
00184       }
00185     }
00186   }
00187   else
00188   {
00189     GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00190   }
00191 
00192   /* error handling */
00193   if (GAT_FAILED(GAT_CURRENT_STATUS()))
00194   {
00195     GATPipe_Destroy(&new_pipe);
00196   }
00197   
00198   GAT_STORE_STATUS();
00199   return new_pipe;
00200 }
00201 
00202 
00203 /** GATPipe_Destroy
00204  *  The GATPipe destructor.
00205  *  This is the destructor for GATPipe objects.
00206  *
00207  * @param peep An old GATPipe
00208  */
00209 void GATPipe_Destroy(GATPipe *peep)
00210 {
00211   if(NULL != peep && NULL != *peep)
00212   {
00213     GATMonitorable_Impl_Destroy(&(*peep)->data.monitorable);
00214     if (NULL != (*peep)->cpi)
00215     {
00216       GATRegistry_RemoveGATPipeFromCPIList((*peep)->data.context, (*peep)->cpi, 
00217         *peep);
00218       GATPipeCPI_DestroyInstance((*peep)->cpi, &(*peep)->data);
00219     }
00220     GATPipeCPIList_Destroy((*peep)->cpilist);
00221     free(*peep);
00222     *peep = NULL;
00223   }
00224 }
00225 
00226 /** int GATPipe_GetType(GATPipe_const peep)
00227  *  @brief Return the type of the GATPipe
00228  *
00229  *  The function @c GATPipe_GetType always returns GATType_GATPipe. 
00230  *
00231  *  @param peep The object to inspect
00232  *
00233  *  @return returns always @c #GATType_GATPipe.
00234  */
00235 GATType GATPipe_GetType(GATPipe_const peep)
00236 {
00237   GAT_UNUSED_PARAMETER(peep);
00238   return GATType_GATPipe;
00239 }
00240 
00241 /** int GATPipe_Clone(GATPipe_const peep, GATPipe *new_peep)
00242  *  @brief Clone the given GATPipe
00243  *
00244  *  The function @c GATPipe_Clone generates a (deep) copy of the given
00245  *  GATPipe. 
00246  *
00247  *  @param new_object The object to clone
00248  *  @param new_peep The pointer, through which the result is to be 
00249  *        returned.
00250  *
00251  *  @return An error type.
00252  */
00253 GATResult 
00254 GATPipe_Clone(GATPipe_const pipe, GATPipe *new_object)
00255 {
00256   if (NULL != pipe)
00257   {
00258     GAT_STATUS_APIENTRY(pipe->data.context, "GATPipe_Clone");
00259 
00260     if (NULL != new_object)
00261     {
00262       struct GATPipe_S const *passedPipe = pipe;
00263       GATPipe new_pipe = (GATPipe) malloc(sizeof(struct GATPipe_S));
00264       
00265       *new_object = NULL;
00266       if (NULL == new_pipe)
00267       {
00268         GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00269       }
00270       else
00271       {
00272         memset(new_pipe, 0, sizeof(struct GATPipe_S));
00273         new_pipe->GATObject__vtable = &GATPipe__vtable;
00274         new_pipe->GATStreamable__vtable = &GATPipe_IStreamable__vtable;
00275         new_pipe->GATMonitorable__vtable = &GATPipe_IMonitorable__vtable;
00276         
00277         new_pipe->data.context = passedPipe->data.context;
00278         new_pipe->data.source = GATPipe_ToGATObject_const(new_pipe);
00279         new_pipe->cpilist = GATRegistry_CloneGATPipeCPIList(passedPipe->cpilist);
00280         
00281         if (NULL == new_pipe->cpilist)
00282         {
00283           GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00284         }
00285         else
00286         {
00287           /* re-find the cpi to use */
00288           GATPipeCPIList current = passedPipe->cpilist;
00289           GATPipeCPIList new_current = new_pipe->cpilist;
00290           
00291           for (/**/; NULL != current; 
00292                current = current->next, new_current = new_current->next)
00293           {
00294             if (current->cpi == passedPipe->cpi)
00295             {
00296               new_pipe->cpi = new_current->cpi;
00297               break;
00298             }
00299           }
00300           assert(NULL != new_pipe->cpi);
00301           
00302           /* clone the instance data */
00303           GAT_CREATE_STATUS(GATPipeCPI_CloneInstance(passedPipe->cpi, 
00304             &passedPipe->data, &new_pipe->data));
00305 
00306           /* clone the monitoring data */
00307           if (NULL != passedPipe->data.monitorable)
00308           {
00309             GAT_CREATE_STATUS(GATMonitorable_Impl_Clone(passedPipe->data.monitorable, 
00310               &new_pipe->data.monitorable));
00311           }
00312             
00313           GAT_CREATE_STATUS(GATRegistry_AddGATPipeToCPIList(new_pipe->data.context, 
00314             new_pipe->cpi, new_pipe));
00315         }
00316       }
00317 
00318       /* destroy the newly allocated object, if some error occured */
00319       if (GAT_FAILED(GAT_CURRENT_STATUS()))
00320       {
00321         GATPipe_Destroy(&new_pipe);
00322       }
00323       else
00324       {
00325         /* return the new object */
00326         *new_object = new_pipe;
00327       }
00328     }
00329     else
00330     {
00331       GAT_CREATE_STATUS(GAT_INVALID_PARAMETER);
00332     }
00333     
00334     return GAT_RETURN_STATUS();
00335   }
00336   return GAT_INVALID_HANDLE;
00337 }
00338 
00339 /** int GATPipe_Equals(GATPipe_const lhs, GATPipe_const rhs, GATBool *isequal)
00340  *  @brief Compares two GATPipe objects
00341  *
00342  *  The function @c GATPipe_Equals compares two peep objects of type 
00343  *  @c #GATPipe.
00344  *
00345  *  @param lhs The first peep object to compare
00346  *  @param rhs The second peep object to compare
00347  *  @param isequal The pointer to the GATBool variable, which should receive 
00348  *        the result if the comparision
00349  *
00350  *  @return An error code.
00351  */
00352 GATResult 
00353 GATPipe_Equals(GATPipe_const lhs, GATPipe_const rhs, GATBool *isequal)
00354 {
00355   if (NULL != lhs && NULL != rhs)
00356   {
00357     GAT_STATUS_APIENTRY(lhs->data.context, "GATPipe_Equals");
00358     if (NULL != isequal)
00359     {
00360       GAT_CREATE_STATUS(GATPipeCPI_EqualsInstance(lhs->cpi, &lhs->data, 
00361         &rhs->data, isequal));
00362     }
00363     else
00364     {
00365       GAT_CREATE_STATUS(GAT_INVALID_PARAMETER);
00366     }
00367     
00368     return GAT_RETURN_STATUS();
00369   }
00370   return GAT_INVALID_HANDLE;
00371 }
00372 
00373 /** int GATPipe_GetInterface(GATPipe_const peep, GATInterface iftype, void const **ifp)
00374  *  @brief Get an interface supported by a GATObject
00375  *
00376  *  The function GATPipe_GetInterface allows to get a pointer to an 
00377  *  additional interface supported by this GATPipe.
00378  *
00379  *  @param object The object to be asked for the new interface.
00380  *  @param iftype The interface the object is to be asked for.
00381  *  @param ifp The pointer, through which the result is to be returned.
00382  *
00383  *  @return An error type.
00384  */
00385 GATResult 
00386 GATPipe_GetInterface(GATPipe_const peep, GATInterface iftype, void const **ifp)
00387 {
00388   if (NULL != peep)
00389   {
00390     GAT_STATUS_APIENTRY(peep->data.context, "GATPipe_GetInterface");
00391 
00392     if (NULL != ifp)
00393     {
00394       if (GATInterface_IStreamable == iftype)
00395       {
00396         *ifp = (void const *) &peep->GATStreamable__vtable;
00397       }
00398       else if (GATInterface_IMonitorable == iftype && NULL != peep->data.monitorable)
00399       {
00400         *ifp = (void const *) &peep->GATMonitorable__vtable;
00401       }
00402       else
00403       {
00404         *ifp = NULL;
00405         GAT_CREATE_STATUS(GAT_NO_INTERFACE);
00406       }
00407     }
00408     else
00409     {
00410       GAT_CREATE_STATUS(GAT_INVALID_PARAMETER);
00411     }
00412     
00413     return GAT_RETURN_STATUS();
00414   }
00415   return GAT_INVALID_HANDLE;
00416 }
00417 
00418 /* GATMonitorable */
00419 
00420 /** GATPipe_AddMetricListener
00421  *
00422  *  The function GATPipe_AddMetricListener adds the passed instance of a 
00423  *  GATMetricListener to the list of GATMetricListeners which are notified of 
00424  *  fired GATMetricEvents of the type described by the provided GATMetric 
00425  *  instance.
00426  *
00427  *  @param peep The GATPipe instance to add the GATMetricListener to.
00428  *  @param listener The GTAMetricListener to call, when the corresponding 
00429  *        GATMetricEvent is fired.
00430  *  @param listener_data The client supplied data, which will be passed through
00431  *        to the GATMetricListener.
00432  *  @param metric The GATMetric instance describing the GATMetricEvent to pass
00433  *        to the GATMetricListener.
00434  *  @param cookie The returned value should be used to remove the 
00435  *        GATMetricListener from this GATMonitorable.
00436  *
00437  *  @return An error code.
00438  */ 
00439 GATResult 
00440 GATPipe_AddMetricListener(GATPipe peep, GATMetricListener listener,
00441   void *listener_data, GATMetric metric, GATuint32 *cookie)
00442 {
00443   if (NULL != peep)
00444   {
00445     GAT_STATUS_APIENTRY(peep->data.context, "GATPipe_AddMetricListener");
00446     
00447     if (NULL != peep->data.monitorable)
00448     {
00449       GAT_CREATE_STATUS(GATMonitorable_Impl_AddMetricListener(
00450         peep->data.monitorable, listener, listener_data, metric, cookie));
00451     } 
00452     else
00453     { 
00454       /* this may happen, if the adaptor has not registered any GATMetrics */
00455       GAT_CREATE_STATUS(GAT_NO_INTERFACE);
00456     }
00457 
00458     return GAT_RETURN_STATUS();
00459   }
00460   return GAT_INVALID_HANDLE;
00461 }
00462 
00463 /** GATPipe_RegisterPolling
00464  *
00465  *  The function GATPipe_RegisterPolling registers a continuous 
00466  *  metric with the given GATPipe instance.
00467  *
00468  *  @param peep The GATPipe instance to register the metric with.
00469  *  @param metric The GATMetric instance describing the GATMetricEvent to pass
00470  *        to the GATMetricListener. This metric instance must be of type
00471  *        GATMeasurementType_Continuous, otherwise an error is returned.
00472  *  @param event The pointer to a variable, which should receive the resulting
00473  *        GATMetricEvent. The GATMetricEvent instance should be freed by the 
00474  *        caller when it isn't used anymore.
00475  *  @param cookie The returned value should be used to remove the 
00476  *        GATMetricListener from this GATPipe.
00477  *
00478  *  @return An error code.
00479  */ 
00480 GATResult 
00481 GATPipe_RegisterPolling(GATPipe peep, GATMetric metric, GATMetricEvent *event, 
00482   GATuint32 *cookie)
00483 {
00484   if (NULL != peep)
00485   {
00486     GAT_STATUS_APIENTRY(peep->data.context, "GATPipe_RegisterPolling");
00487     
00488     if (NULL != peep->data.monitorable)
00489     {
00490       GAT_CREATE_STATUS(GATMonitorable_Impl_RegisterPolling(peep->data.monitorable, 
00491         metric, 0, cookie));
00492 
00493       /* ask the CPI provider to return the corresponding metric event */
00494       GAT_CREATE_STATUS(GATPipeCPI_GetMetricEvent(peep->cpi, &peep->data, 
00495         metric, event));
00496 
00497       if (GAT_SUCCEEDED(GAT_CURRENT_STATUS()) && NULL != cookie && 0 != *cookie)
00498       {
00499         GATMonitorable_Impl_RemoveRegisteredMetric(peep->data.monitorable,
00500           metric, *cookie);
00501         *cookie = 0;
00502       }
00503     } 
00504     else
00505     { 
00506       /* this may happen, if the adaptor has not registered any GATMetrics */
00507       GAT_CREATE_STATUS(GAT_NO_INTERFACE);
00508     }
00509     
00510     return GAT_RETURN_STATUS();
00511   }
00512   return GAT_INVALID_HANDLE;
00513 }
00514 
00515 /** GATPipe_RemoveRegisteredMetric
00516  *
00517  *  The function GATPipe_RemoveRegisteredMetric removes a GATMetricListener, 
00518  *  which was previously registered with GATPipe_AddMetricListener.
00519  *
00520  *  @param peep The GATPipe instance to remove the GATMetricListener from.
00521  *  @param metric The GATMetric instance describing the GATMetricEvent to pass
00522  *        to the GATMetricListener.
00523  *  @param cookie This value identifies the GATMetricListener to remove, it 
00524  *        was returned from the corresponding GATMonitorable_AddMetricListener 
00525  *        or GATMonitorable_MetricRegisterPolling functions.
00526  *  
00527  *  @return An error code.
00528  */
00529 GATResult 
00530 GATPipe_RemoveRegisteredMetric(GATPipe peep, GATMetric metric, GATuint32 cookie)
00531 {
00532   if (NULL != peep)
00533   {
00534     GAT_STATUS_APIENTRY(peep->data.context, "GATPipe_RemoveRegisteredMetric");
00535     
00536     if (NULL != peep->data.monitorable)
00537     {
00538       GAT_CREATE_STATUS(GATMonitorable_Impl_RemoveRegisteredMetric(
00539         peep->data.monitorable, metric, cookie));
00540     } 
00541     else
00542     { 
00543       /* this may happen, if the adaptor has not registered any GATMetrics */
00544       GAT_CREATE_STATUS(GAT_NO_INTERFACE);
00545     }
00546     
00547     return GAT_RETURN_STATUS();
00548   }
00549   return GAT_INVALID_HANDLE;
00550 }
00551 
00552 /** GATPipe_GetMetrics
00553  *
00554  *  The function GATPipe_GetMetrics returns a list of metrics supported by this
00555  *  GATPipe.
00556  *
00557  *  @param peep The GATPipe instance, for which the supported metrics should be 
00558  *        returned.
00559  *  @param metrics The pointer to the variable, which receives the resulting 
00560  *        list of metrics.
00561  *
00562  *  @return An error code.
00563  */
00564 GATResult GATPipe_GetMetrics(GATPipe_const peep, GATList_GATMetric *metrics)
00565 {
00566   if (NULL != peep)
00567   {
00568     GAT_STATUS_APIENTRY(peep->data.context, "GATPipe_GetMetrics");
00569 
00570     if (NULL != peep->data.monitorable)
00571     {
00572       GAT_CREATE_STATUS(GATMonitorable_Impl_GetMetrics(peep->data.monitorable, 
00573         metrics));
00574     } 
00575     else
00576     { 
00577       /* this may happen, if the adaptor has not registered any GATMetrics */
00578       GAT_CREATE_STATUS(GAT_NO_INTERFACE);
00579     }
00580     
00581     return GAT_RETURN_STATUS();
00582   }
00583   return GAT_INVALID_HANDLE;
00584 }
00585 
00586 
00587 /* IStreamable implementation */
00588 
00589 /* Reads from this GATStreamable into the given buffer */
00590 GATResult 
00591 GATPipe_Read(GATPipe object, void *buffer, GATuint32 size, 
00592   GATuint32 *read_bytes)
00593 {
00594   if (NULL != object)
00595   {
00596     GAT_STATUS_APIENTRY(object->data.context, "GATPipe_Read");
00597     GAT_CREATE_STATUS(GATPipeCPI_Read(object->cpi, &object->data, buffer, size, 
00598       read_bytes));
00599     return GAT_RETURN_STATUS();
00600   }
00601   return GAT_INVALID_HANDLE;
00602 }
00603 
00604 /* Writes data from the given Buffer through the GATStreamable */
00605 GATResult 
00606 GATPipe_Write(GATPipe object, void const *buffer, GATuint32 size, 
00607   GATuint32 *written_bytes)
00608 {
00609   if (NULL != object)
00610   {
00611     GAT_STATUS_APIENTRY(object->data.context, "GATPipe_Write");
00612     GAT_CREATE_STATUS(GATPipeCPI_Write(object->cpi, &object->data, buffer, 
00613       size, written_bytes));
00614     return GAT_RETURN_STATUS();
00615   }
00616   return GAT_INVALID_HANDLE;
00617 }
00618 
00619 /* reposition the internal stream position */
00620 GATResult 
00621 GATPipe_Seek(GATPipe object, GATOrigin origin, GATint32 offset, 
00622   GATuint32 *new_position)
00623 {
00624   if (NULL != object)
00625   {
00626     GAT_STATUS_APIENTRY(object->data.context, "GATPipe_Seek");
00627     GAT_CREATE_STATUS(GATPipeCPI_Seek(object->cpi, &object->data, origin, 
00628       offset, new_position));
00629     return GAT_RETURN_STATUS();
00630   }
00631   return GAT_INVALID_HANDLE;
00632 }
00633     
00634 /* Closes this GATStreamable instance. */
00635 GATResult 
00636 GATPipe_Close(GATPipe object)
00637 {
00638   if (NULL != object)
00639   {
00640     GAT_STATUS_APIENTRY(object->data.context, "GATPipe_Close");
00641     GAT_CREATE_STATUS(GATPipeCPI_Close(object->cpi, &object->data));
00642     return GAT_RETURN_STATUS();
00643   }
00644   return GAT_INVALID_HANDLE;
00645 }
00646 
00647 /* Local functions */
00648 /*  GATPipe_GetCPIInstanceData
00649  *  
00650  *  The function GATPipe_GetCPIInstanceData returns the CPI instance data, 
00651  *  associated with the given GATPipe object.
00652  *
00653  *  @param object The object, for which to return the CPI instance data.
00654  *  @param data The pointer to the variable, which should receive the
00655  *        resulting CPI instance data.
00656  *
00657  *  @return An error code.
00658  */
00659 static GATResult
00660 GATPipe_GetCPIInstanceData(GATPipe object, void **data)
00661 {
00662   if (NULL != object)
00663   {
00664     GAT_USES_STATUS(object->data.context, "GATPipe_GetCPIInstanceData");
00665     
00666     if (NULL != data)
00667     {
00668       *data = (void *)&object->data;
00669     }
00670     else
00671     {
00672       GAT_CREATE_STATUS(GAT_INVALID_PARAMETER);
00673     }
00674     
00675     return GAT_RETURN_STATUS();
00676   }
00677   return GAT_INVALID_HANDLE;
00678 }
00679