00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 #ifndef __P_CLUSTERCACHEINTERNAL_H__
00030 #define __P_CLUSTERCACHEINTERNAL_H__
00031 #include "P_ClusterCache.h"
00032 #include "I_OneWayTunnel.h"
00033 
00034 
00035 
00036 
00037 #define CACHE_USE_OPEN_VIO              0       // EXPERIMENTAL: not fully tested
00038 #define DO_REPLICATION                  0       // EXPERIMENTAL: not fully tested
00039 
00040 
00041 
00042 
00043 #define META_DATA_FAST_ALLOC_LIMIT      1
00044 #define CACHE_CLUSTER_TIMEOUT           HRTIME_MSECONDS(5000)
00045 #define CACHE_RETRY_PERIOD              HRTIME_MSECONDS(10)
00046 #define REMOTE_CONNECT_HASH             (16 * 1024)
00047 
00048 
00049 
00050 
00051 #define FOLDHASH(_ip,_seq) (_seq % REMOTE_CONNECT_HASH)
00052 #define ALIGN_DOUBLE(_p)   ((((uintptr_t) (_p)) + 7) & ~7)
00053 #define ALLOCA_DOUBLE(_sz) ALIGN_DOUBLE(alloca((_sz) + 8))
00054 
00055 
00056 
00057 
00058 
00059 #define TEST(_x)
00060 
00061 
00062 
00063 
00064 
00065 #define TTEST(_x)
00066 
00067 
00068 #define TIMEOUT_TEST(_x)
00069 
00070 extern int cache_migrate_on_demand;
00071 extern int ET_CLUSTER;
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 #define PROBE_LOCAL_CACHE_FIRST        DO_REPLICATION
00082 #define PROBE_LOCAL_CACHE_LAST         false
00083 
00084 
00085 
00086 
00087 
00088 struct CacheContinuation;
00089 typedef int (CacheContinuation::*CacheContHandler) (int, void *);
00090 struct CacheContinuation:public Continuation
00091 {
00092   enum
00093   {
00094     MagicNo = 0x92183123
00095   };
00096   int magicno;
00097   void *callback_data;
00098   void *callback_data_2;
00099   INK_MD5 url_md5;
00100   Event *timeout;
00101   Action action;
00102   ClusterMachine *target_machine;
00103   int probe_depth;
00104   ClusterMachine *past_probes[CONFIGURATION_HISTORY_PROBE_DEPTH];
00105   ink_hrtime start_time;
00106   ClusterMachine *from;
00107   ClusterHandler *ch;
00108   VConnection *cache_vc;
00109   bool cache_read;
00110   int result;                   
00111   int result_error;             
00112   ClusterVCToken token;
00113   unsigned int seq_number;
00114   uint16_t cfl_flags;             
00115   CacheFragType frag_type;
00116   int nbytes;
00117   unsigned int target_ip;
00118   int request_opcode;
00119   bool request_purge;
00120   bool local_lookup_only;
00121   bool no_reply_message;
00122   bool request_timeout;         
00123   
00124   bool expect_cache_callback;
00125 
00126   
00127   bool use_deferred_callback;
00128 
00129   
00130 
00131   time_t pin_in_cache;
00132 
00133   
00134 
00135     Ptr<IOBufferData> rw_buf_msg;
00136   int rw_buf_msg_len;
00137 
00138   
00139 
00140   ClusterVConnection *read_cluster_vc;
00141   ClusterVConnection *write_cluster_vc;
00142   int cluster_vc_channel;
00143   ClusterVCToken open_local_token;
00144 
00145   
00146 
00147   int caller_buf_freebytes;     
00148   
00149   VIO *readahead_vio;
00150   IOBufferReader *readahead_reader;
00151     Ptr<IOBufferBlock> readahead_data;
00152   bool have_all_data;           
00153 
00154   CacheHTTPInfo cache_vc_info;
00155   OneWayTunnel *tunnel;
00156     Ptr<ProxyMutex> tunnel_mutex;
00157   CacheContinuation *tunnel_cont;
00158   bool tunnel_closed;
00159   Action *cache_action;
00160   Event *lookup_open_write_vc_event;
00161 
00162   
00163 
00164   Arena ic_arena;
00165   CacheHTTPHdr ic_request;
00166   CacheHTTPHdr ic_response;
00167   CacheLookupHttpConfig *ic_params;
00168   CacheHTTPInfo ic_old_info;
00169   CacheHTTPInfo ic_new_info;
00170     Ptr<IOBufferData> ic_hostname;
00171   int ic_hostname_len;
00172 
00173   
00174   int cache_op_ClusterFunction;
00175 
00176   int lookupEvent(int event, void *d);
00177   int probeLookupEvent(int event, void *d);
00178   int remoteOpEvent(int event, Event * e);
00179   int replyLookupEvent(int event, void *d);
00180   int replyOpEvent(int event, VConnection * vc);
00181   int handleReplyEvent(int event, Event * e);
00182   int callbackEvent(int event, Event * e);
00183   int setupVCdataRead(int event, VConnection * vc);
00184   int VCdataRead(int event, VIO * target_vio);
00185   int setupReadWriteVC(int, VConnection *);
00186   ClusterVConnection *lookupOpenWriteVC();
00187   int lookupOpenWriteVCEvent(int, Event *);
00188   int localVCsetupEvent(int event, ClusterVConnection * vc);
00189   void insert_cache_callback_user(ClusterVConnection *, int, void *);
00190   int insertCallbackEvent(int, Event *);
00191   void callback_user(int result, void *d);
00192   void defer_callback_result(int result, void *d);
00193   int callbackResultEvent(int event, Event * e);
00194   void setupReadBufTunnel(VConnection *, VConnection *);
00195   int tunnelClosedEvent(int event, void *);
00196   int remove_and_delete(int, Event *);
00197 
00198 
00199   inline void setMsgBufferLen(int l, IOBufferData * b = 0) {
00200     ink_assert(rw_buf_msg == 0);
00201     ink_assert(rw_buf_msg_len == 0);
00202 
00203     rw_buf_msg = b;
00204     rw_buf_msg_len = l;
00205   }
00206 
00207   inline int getMsgBufferLen()
00208   {
00209     return rw_buf_msg_len;
00210   }
00211 
00212   inline void allocMsgBuffer()
00213   {
00214     ink_assert(rw_buf_msg == 0);
00215     ink_assert(rw_buf_msg_len);
00216     if (rw_buf_msg_len <= DEFAULT_MAX_BUFFER_SIZE) {
00217       rw_buf_msg = new_IOBufferData(buffer_size_to_index(rw_buf_msg_len, MAX_BUFFER_SIZE_INDEX));
00218     } else {
00219       rw_buf_msg = new_xmalloc_IOBufferData(ats_malloc(rw_buf_msg_len), rw_buf_msg_len);
00220     }
00221   }
00222 
00223   inline char *getMsgBuffer()
00224   {
00225     ink_assert(rw_buf_msg);
00226     return rw_buf_msg->data();
00227   }
00228 
00229   inline IOBufferData *getMsgBufferIOBData()
00230   {
00231     return rw_buf_msg;
00232   }
00233 
00234   inline void freeMsgBuffer()
00235   {
00236     if (rw_buf_msg) {
00237       rw_buf_msg = 0;
00238       rw_buf_msg_len = 0;
00239     }
00240   }
00241 
00242   inline void free()
00243   {
00244     token.clear();
00245 
00246     if (cache_vc_info.valid()) {
00247       cache_vc_info.destroy();
00248     }
00249     
00250     if (ic_params) {
00251       delete ic_params;
00252       ic_params = 0;
00253     }
00254     if (ic_request.valid()) {
00255       ic_request.clear();
00256     }
00257     if (ic_response.valid()) {
00258       ic_response.clear();
00259     }
00260     if (ic_old_info.valid()) {
00261       ic_old_info.destroy();
00262     }
00263     if (ic_new_info.valid()) {
00264       ic_new_info.destroy();
00265     }
00266     ic_arena.reset();
00267     freeMsgBuffer();
00268 
00269     tunnel_mutex = 0;
00270     readahead_data = 0;
00271     ic_hostname = 0;
00272   }
00273 
00274 CacheContinuation():
00275   Continuation(NULL),
00276     magicno(MagicNo),
00277     callback_data(0),
00278     callback_data_2(0),
00279     timeout(0),
00280     target_machine(0),
00281     probe_depth(0),
00282     start_time(0),
00283     cache_read(false),
00284     result(0),
00285     result_error(0),
00286     seq_number(0),
00287     cfl_flags(0),
00288     frag_type(CACHE_FRAG_TYPE_NONE),
00289     nbytes(0),
00290     target_ip(0),
00291     request_opcode(0),
00292     request_purge(false),
00293     local_lookup_only(0),
00294     no_reply_message(0),
00295     request_timeout(0),
00296     expect_cache_callback(true),
00297     use_deferred_callback(0),
00298     pin_in_cache(0),
00299     rw_buf_msg_len(0),
00300     read_cluster_vc(0),
00301     write_cluster_vc(0),
00302     cluster_vc_channel(0),
00303     caller_buf_freebytes(0),
00304     readahead_vio(0),
00305     readahead_reader(0),
00306     have_all_data(false),
00307     cache_vc_info(),
00308     tunnel(0),
00309     tunnel_cont(0),
00310     tunnel_closed(0),
00311     lookup_open_write_vc_event(0),
00312     ic_arena(),
00313     ic_request(),
00314     ic_response(), ic_params(0), ic_old_info(), ic_new_info(), ic_hostname_len(0), cache_op_ClusterFunction(0) {
00315     token.clear();
00316     SET_HANDLER((CacheContHandler) & CacheContinuation::remoteOpEvent);
00317   }
00318 
00319   inline static bool is_ClusterThread(EThread * et)
00320   {
00321     int etype = ET_CLUSTER;
00322     int i;
00323     for (i = 0; i < eventProcessor.n_threads_for_type[etype]; ++i) {
00324       if (et == eventProcessor.eventthread[etype][i]) {
00325         return true;
00326       }
00327     }
00328     return false;
00329   }
00330 
00331   
00332   static int init();
00333   static CacheContinuation *cacheContAllocator_alloc();
00334   static void cacheContAllocator_free(CacheContinuation *);
00335   inkcoreapi static Action *callback_failure(Action *, int, int, CacheContinuation * this_cc = 0);
00336   static Action *do_remote_lookup(Continuation *, CacheKey *, CacheContinuation *, CacheFragType, char *, int);
00337   inkcoreapi static Action *do_op(Continuation *, ClusterMachine *, void *, int, char *, int,
00338                                   int nbytes = -1, MIOBuffer * b = 0);
00339   static int setup_local_vc(char *data, int data_len, CacheContinuation * cc, ClusterMachine * mp, Action **);
00340   static void disposeOfDataBuffer(void *buf);
00341   static int handleDisposeEvent(int event, CacheContinuation * cc);
00342   static int32_t getObjectSize(VConnection *, int, CacheHTTPInfo *);
00343 };
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 #define CFL_OVERWRITE_ON_WRITE          (1 << 1)
00352 #define CFL_REMOVE_USER_AGENTS          (1 << 2)
00353 #define CFL_REMOVE_LINK                 (1 << 3)
00354 #define CFL_LOPENWRITE_HAVE_OLDINFO     (1 << 4)
00355 #define CFL_ALLOW_MULTIPLE_WRITES       (1 << 5)
00356 #define CFL_MAX                         (1 << 15)
00357 
00358 struct CacheOpArgs_General
00359 {
00360   INK_MD5 *url_md5;
00361   time_t pin_in_cache;          
00362   CacheFragType frag_type;
00363   uint16_t cfl_flags;
00364 
00365     CacheOpArgs_General():url_md5(NULL), pin_in_cache(0), frag_type(CACHE_FRAG_TYPE_NONE), cfl_flags(0)
00366   {
00367   }
00368 };
00369 
00370 struct CacheOpArgs_Link
00371 {
00372   INK_MD5 *from;
00373   INK_MD5 *to;
00374   uint16_t cfl_flags;             
00375   CacheFragType frag_type;
00376 
00377     CacheOpArgs_Link():from(NULL), to(NULL), cfl_flags(0), frag_type(CACHE_FRAG_TYPE_NONE)
00378   {
00379   }
00380 };
00381 
00382 struct CacheOpArgs_Deref
00383 {
00384   INK_MD5 *md5;
00385   uint16_t cfl_flags;             
00386   CacheFragType frag_type;
00387 
00388     CacheOpArgs_Deref():md5(NULL), cfl_flags(0), frag_type(CACHE_FRAG_TYPE_NONE)
00389   {
00390   }
00391 };
00392 
00393 
00394 
00395 
00396 struct CacheLookupMsg:public ClusterMessageHeader
00397 {
00398   INK_MD5 url_md5;
00399   uint32_t seq_number;
00400   uint32_t frag_type;
00401   Alias32 moi;
00402   enum
00403   {
00404     MIN_VERSION = 1,
00405     MAX_VERSION = 1,
00406     CACHE_LOOKUP_MESSAGE_VERSION = MAX_VERSION
00407   };
00408   CacheLookupMsg(uint16_t vers = CACHE_LOOKUP_MESSAGE_VERSION):
00409   ClusterMessageHeader(vers), seq_number(0), frag_type(0) {
00410     moi.u32 = 0;
00411   }
00412 
00413 
00414   static int protoToVersion(int protoMajor)
00415   {
00416     (void) protoMajor;
00417     return CACHE_LOOKUP_MESSAGE_VERSION;
00418   }
00419   static int sizeof_fixedlen_msg()
00420   {
00421     return (int) ALIGN_DOUBLE(offsetof(CacheLookupMsg, moi));
00422   }
00423   void init(uint16_t vers = CACHE_LOOKUP_MESSAGE_VERSION) {
00424     _init(vers);
00425   }
00426   inline void SwapBytes()
00427   {
00428     if (NeedByteSwap()) {
00429       ink_release_assert(!"No byte swap for INK_MD5");
00430       ats_swap32(&seq_number);
00431       ats_swap32(&frag_type);
00432     }
00433   }
00434 
00435 };
00436 
00437 struct CacheOpMsg_long:public ClusterMessageHeader
00438 {
00439   uint8_t opcode;
00440   uint8_t frag_type;
00441   uint16_t cfl_flags;             
00442   INK_MD5 url_md5;
00443   uint32_t seq_number;
00444   uint32_t nbytes;
00445   uint32_t data;                  
00446   int32_t channel;                
00447   ClusterVCToken token;
00448   int32_t buffer_size;            
00449   Alias32 moi;
00450   enum
00451   {
00452     MIN_VERSION = 1,
00453     MAX_VERSION = 1,
00454     CACHE_OP_LONG_MESSAGE_VERSION = MAX_VERSION
00455   };
00456   CacheOpMsg_long(uint16_t vers = CACHE_OP_LONG_MESSAGE_VERSION):
00457   ClusterMessageHeader(vers),
00458     opcode(0), frag_type(0), cfl_flags(0), seq_number(0), nbytes(0), data(0), channel(0), buffer_size(0) {
00459     moi.u32 = 0;
00460   }
00461 
00462 
00463   static int protoToVersion(int protoMajor)
00464   {
00465     (void) protoMajor;
00466     return CACHE_OP_LONG_MESSAGE_VERSION;
00467   }
00468   static int sizeof_fixedlen_msg()
00469   {
00470     return (int) ALIGN_DOUBLE(offsetof(CacheOpMsg_long, moi));
00471   }
00472   void init(uint16_t vers = CACHE_OP_LONG_MESSAGE_VERSION) {
00473     _init(vers);
00474   }
00475   inline void SwapBytes()
00476   {
00477     if (NeedByteSwap()) {
00478       ink_release_assert(!"No byte swap for INK_MD5");
00479       ats_swap16(&cfl_flags);
00480       ats_swap32(&seq_number);
00481       ats_swap32(&nbytes);
00482       ats_swap32(&data);
00483       ats_swap32((uint32_t *) & channel);
00484       token.SwapBytes();
00485       ats_swap32((uint32_t *) & buffer_size);
00486       ats_swap32((uint32_t *) & frag_type);
00487     }
00488   }
00489 
00490 };
00491 
00492 struct CacheOpMsg_short:public ClusterMessageHeader
00493 {
00494   uint8_t opcode;
00495   uint8_t frag_type;              
00496   uint16_t cfl_flags;             
00497   INK_MD5 md5;
00498   uint32_t seq_number;
00499   uint32_t nbytes;
00500   uint32_t data;                  
00501   int32_t channel;                
00502   ClusterVCToken token;         
00503   int32_t buffer_size;            
00504 
00505   
00506   Alias32 moi;
00507   enum
00508   {
00509     MIN_VERSION = 1,
00510     MAX_VERSION = 1,
00511     CACHE_OP_SHORT_MESSAGE_VERSION = MAX_VERSION
00512   };
00513   CacheOpMsg_short(uint16_t vers = CACHE_OP_SHORT_MESSAGE_VERSION):
00514   ClusterMessageHeader(vers),
00515     opcode(0), frag_type(0), cfl_flags(0), seq_number(0), nbytes(0), data(0), channel(0), buffer_size(0) {
00516     moi.u32 = 0;
00517   }
00518 
00519 
00520   static int protoToVersion(int protoMajor)
00521   {
00522     (void) protoMajor;
00523     return CACHE_OP_SHORT_MESSAGE_VERSION;
00524   }
00525   static int sizeof_fixedlen_msg()
00526   {
00527     return (int) ALIGN_DOUBLE(offsetof(CacheOpMsg_short, moi));
00528   }
00529   void init(uint16_t vers = CACHE_OP_SHORT_MESSAGE_VERSION) {
00530     _init(vers);
00531   }
00532   inline void SwapBytes()
00533   {
00534     if (NeedByteSwap()) {
00535       ink_release_assert(!"No byte swap for INK_MD5");
00536       ats_swap16(&cfl_flags);
00537       ats_swap32(&seq_number);
00538       ats_swap32(&nbytes);
00539       ats_swap32(&data);
00540       if (opcode == CACHE_OPEN_READ) {
00541         ats_swap32((uint32_t *) & buffer_size);
00542         ats_swap32((uint32_t *) & channel);
00543         token.SwapBytes();
00544       }
00545     }
00546   }
00547 
00548 };
00549 
00550 struct CacheOpMsg_short_2:public ClusterMessageHeader
00551 {
00552   uint8_t opcode;
00553   uint8_t frag_type;
00554   uint16_t cfl_flags;             
00555   INK_MD5 md5_1;
00556   INK_MD5 md5_2;
00557   uint32_t seq_number;
00558   Alias32 moi;
00559   enum
00560   {
00561     MIN_VERSION = 1,
00562     MAX_VERSION = 1,
00563     CACHE_OP_SHORT_2_MESSAGE_VERSION = MAX_VERSION
00564   };
00565   CacheOpMsg_short_2(uint16_t vers = CACHE_OP_SHORT_2_MESSAGE_VERSION)
00566     :  ClusterMessageHeader(vers), opcode(0), frag_type(0), cfl_flags(0), seq_number(0) {
00567     moi.u32 = 0;
00568   }
00569 
00570   static int protoToVersion(int protoMajor)
00571   {
00572     (void) protoMajor;
00573     return CACHE_OP_SHORT_2_MESSAGE_VERSION;
00574   }
00575   static int sizeof_fixedlen_msg()
00576   {
00577     return (int) ALIGN_DOUBLE(offsetof(CacheOpMsg_short_2, moi));
00578   }
00579   void init(uint16_t vers = CACHE_OP_SHORT_2_MESSAGE_VERSION) {
00580     _init(vers);
00581   }
00582   inline void SwapBytes()
00583   {
00584     if (NeedByteSwap()) {
00585       ink_release_assert(!"No byte swap for MD5_1");
00586       ink_release_assert(!"No byte swap for MD5_2");
00587       ats_swap16(&cfl_flags);
00588       ats_swap32(&seq_number);
00589     }
00590   }
00591 
00592 };
00593 
00594 struct CacheOpReplyMsg:public ClusterMessageHeader
00595 {
00596   uint32_t seq_number;
00597   int32_t result;
00598   ClusterVCToken token;
00599   bool is_ram_cache_hit;          
00600   Alias32 moi;                 
00601   enum
00602   {
00603     MIN_VERSION = 1,
00604     MAX_VERSION = 1,
00605     CACHE_OP_REPLY_MESSAGE_VERSION = MAX_VERSION
00606   };
00607   CacheOpReplyMsg(uint16_t vers = CACHE_OP_REPLY_MESSAGE_VERSION)
00608     : ClusterMessageHeader(vers), seq_number(0), result(0), is_ram_cache_hit(false) {
00609     moi.u32 = 0;
00610   }
00611 
00612 
00613   static int protoToVersion(int protoMajor)
00614   {
00615     (void) protoMajor;
00616     return CACHE_OP_REPLY_MESSAGE_VERSION;
00617   }
00618   static int sizeof_fixedlen_msg()
00619   {
00620     return (int) ALIGN_DOUBLE(offsetof(CacheOpReplyMsg, moi));
00621   }
00622   void init(uint16_t vers = CACHE_OP_REPLY_MESSAGE_VERSION) {
00623     _init(vers);
00624   }
00625   inline void SwapBytes()
00626   {
00627     if (NeedByteSwap()) {
00628       ats_swap32(&seq_number);
00629       ats_swap32((uint32_t *) & result);
00630       token.SwapBytes();
00631     }
00632   }
00633 
00634 };
00635 
00636 inline int
00637 maxval(int a, int b)
00638 {
00639   return ((a > b) ? a : b);
00640 }
00641 
00642 inline int
00643 op_to_sizeof_fixedlen_msg(int op)
00644 {
00645   switch (op) {
00646   case CACHE_LOOKUP_OP:
00647     {
00648       return CacheLookupMsg::sizeof_fixedlen_msg();
00649     }
00650   case CACHE_OPEN_WRITE_BUFFER:
00651   case CACHE_OPEN_WRITE_BUFFER_LONG:
00652     {
00653       ink_release_assert(!"op_to_sizeof_fixedlen_msg() op not supported");
00654       return 0;
00655     }
00656   case CACHE_OPEN_WRITE:
00657   case CACHE_OPEN_READ:
00658   case CACHE_OPEN_READ_BUFFER:
00659     {
00660       return CacheOpMsg_short::sizeof_fixedlen_msg();
00661     }
00662   case CACHE_OPEN_READ_LONG:
00663   case CACHE_OPEN_READ_BUFFER_LONG:
00664   case CACHE_OPEN_WRITE_LONG:
00665     {
00666       return CacheOpMsg_long::sizeof_fixedlen_msg();
00667     }
00668   case CACHE_UPDATE:
00669   case CACHE_REMOVE:
00670   case CACHE_DEREF:
00671     {
00672       return CacheOpMsg_short::sizeof_fixedlen_msg();
00673     }
00674   case CACHE_LINK:
00675     {
00676       return CacheOpMsg_short_2::sizeof_fixedlen_msg();
00677     }
00678   default:
00679     {
00680       ink_release_assert(!"op_to_sizeof_fixedlen_msg() unknown op");
00681       return 0;
00682     }
00683   }                             
00684 }
00685 
00686 
00687 
00688 static inline bool
00689 event_is_lookup(int event)
00690 {
00691   switch (event) {
00692   default:
00693     return false;
00694   case CACHE_EVENT_LOOKUP:
00695   case CACHE_EVENT_LOOKUP_FAILED:
00696     return true;
00697   }
00698 }
00699 
00700 static inline bool
00701 event_is_open(int event)
00702 {
00703   switch (event) {
00704   default:
00705     return false;
00706   case CACHE_EVENT_OPEN_READ:
00707   case CACHE_EVENT_OPEN_WRITE:
00708     return true;
00709   }
00710 }
00711 
00712 static inline bool
00713 op_is_read(int opcode)
00714 {
00715   switch (opcode) {
00716   case CACHE_OPEN_READ:
00717   case CACHE_OPEN_READ_LONG:
00718   case CACHE_OPEN_READ_BUFFER:
00719   case CACHE_OPEN_READ_BUFFER_LONG:
00720     return true;
00721   default:
00722     return false;
00723   }
00724 }
00725 
00726 static inline bool
00727 op_is_shortform(int opcode)
00728 {
00729   switch (opcode) {
00730   case CACHE_OPEN_READ:
00731   case CACHE_OPEN_READ_BUFFER:
00732   case CACHE_OPEN_WRITE:
00733   case CACHE_OPEN_WRITE_BUFFER:
00734     return true;
00735   default:
00736     return false;
00737   }
00738 }
00739 
00740 static inline int
00741 op_failure(int opcode)
00742 {
00743   switch (opcode) {
00744   case CACHE_OPEN_WRITE:
00745   case CACHE_OPEN_WRITE_LONG:
00746   case CACHE_OPEN_WRITE_BUFFER:
00747   case CACHE_OPEN_WRITE_BUFFER_LONG:
00748     return CACHE_EVENT_OPEN_WRITE_FAILED;
00749 
00750   case CACHE_OPEN_READ:
00751   case CACHE_OPEN_READ_LONG:
00752   case CACHE_OPEN_READ_BUFFER:
00753   case CACHE_OPEN_READ_BUFFER_LONG:
00754     return CACHE_EVENT_OPEN_READ_FAILED;
00755 
00756   case CACHE_UPDATE:
00757     return CACHE_EVENT_UPDATE_FAILED;
00758   case CACHE_REMOVE:
00759     return CACHE_EVENT_REMOVE_FAILED;
00760   case CACHE_LINK:
00761     return CACHE_EVENT_LINK_FAILED;
00762   case CACHE_DEREF:
00763     return CACHE_EVENT_DEREF_FAILED;
00764   }
00765   return -1;
00766 }
00767 
00768 static inline int
00769 op_needs_marshalled_coi(int opcode)
00770 {
00771   switch (opcode) {
00772   case CACHE_OPEN_WRITE:
00773   case CACHE_OPEN_WRITE_BUFFER:
00774   case CACHE_OPEN_READ:
00775   case CACHE_OPEN_READ_BUFFER:
00776   case CACHE_REMOVE:
00777   case CACHE_LINK:
00778   case CACHE_DEREF:
00779     return 0;
00780 
00781   case CACHE_OPEN_WRITE_LONG:
00782   case CACHE_OPEN_WRITE_BUFFER_LONG:
00783   case CACHE_OPEN_READ_LONG:
00784   case CACHE_OPEN_READ_BUFFER_LONG:
00785   case CACHE_UPDATE:
00786     return 0;
00787 
00788   default:
00789     return 0;
00790   }
00791 }
00792 
00793 static inline int
00794 event_reply_may_have_moi(int event)
00795 {
00796   switch (event) {
00797   case CACHE_EVENT_OPEN_READ:
00798   case CACHE_EVENT_LINK:
00799   case CACHE_EVENT_LINK_FAILED:
00800   case CACHE_EVENT_OPEN_READ_FAILED:
00801   case CACHE_EVENT_OPEN_WRITE_FAILED:
00802   case CACHE_EVENT_REMOVE_FAILED:
00803   case CACHE_EVENT_UPDATE_FAILED:
00804   case CACHE_EVENT_DEREF_FAILED:
00805     return true;
00806   default:
00807     return false;
00808   }
00809 }
00810 
00811 static inline int
00812 event_is_failure(int event)
00813 {
00814   switch (event) {
00815   case CACHE_EVENT_LOOKUP_FAILED:
00816   case CACHE_EVENT_OPEN_READ_FAILED:
00817   case CACHE_EVENT_OPEN_WRITE_FAILED:
00818   case CACHE_EVENT_UPDATE_FAILED:
00819   case CACHE_EVENT_REMOVE_FAILED:
00820   case CACHE_EVENT_LINK_FAILED:
00821   case CACHE_EVENT_DEREF_FAILED:
00822     return true;
00823   default:
00824     return false;
00825   }
00826 }
00827 
00828 #endif // __CLUSTERCACHEINTERNAL_H__