doc: Add serial to list of ci file reserved words
[charm.git] / src / conv-core / msgcallbacks.c
1 /***********************************************************************************************************
2 Callbacks for converse messages. Sameer Paranjpye 2/24/2000.
3 This module defines an interface for registering callbacks for converse messages. 
4 This is meant to be a machine level interface through which additional message processing capabilities can 
5 be added to converse. The idea is that if a message needs additional processing when it is sent or received
6 such as encryption/decryption, maintaining quiescence counters etc., then a callback is registered that provides 
7 this processing capability. Its only current application is keeping quiescence counts.
8
9 For now I'm assuming that callbacks are only registered in pairs, for every send callback there is a receice 
10 callback. But this can be easily changed by making CMsgRegisterCallback non-static.
11
12 CMsgCallbacksInit - Initializes the callback mechanism.
13
14 CMsgRegisterCallbackPair - Registers a message callback pair, one at the send side one at the recv side.
15
16 CMsgInvokeCallbacks - Invokes registered callbacks
17
18 ************************************************************************************************************/
19
20
21 #include "converse.h"
22 #define CALLBACKSETSIZE     5
23 #define MAXCALLBACKSETS     5 
24 #define SENDCALLBACK        0
25 #define RECVCALLBACK        1
26
27 typedef struct CMsgCallback {
28   CMsgProcFn fn;
29 } CMSGCALLBACK;
30
31 struct CMsgCallbackQ {
32         CMSGCALLBACK **cbQ;
33         int          size;
34 };
35
36 struct CMsgCallbackQ  cMsgSendCbQ;
37 struct CMsgCallbackQ  cMsgRecvCbQ;   
38
39 void CMsgCallbacksInit(void)
40 {
41         cMsgSendCbQ.cbQ  = (CMSGCALLBACK **) malloc(MAXCALLBACKSETS* 
42                                                                                                 sizeof(CMSGCALLBACK*));
43         cMsgSendCbQ.size = 0;
44         cMsgRecvCbQ.cbQ  = (CMSGCALLBACK **) malloc(MAXCALLBACKSETS* 
45                                                                                                 sizeof(CMSGCALLBACK*));
46         cMsgRecvCbQ.size = 0;
47 }
48
49 static int CMsgRegisterCallback(CMsgProcFn fnp, int type)
50 {
51         int setNum, setIdx;
52         struct CMsgCallbackQ* Q;
53         
54         if (type < 2)
55                 Q = (type)? (&cMsgRecvCbQ) : (&cMsgSendCbQ);
56         else 
57         {
58                 CmiPrintf("Unknown callback type, cannot register");
59                 return -1;
60         }
61
62         setNum = Q->size/CALLBACKSETSIZE;
63         setIdx = Q->size%CALLBACKSETSIZE;
64         
65         if (setNum >= MAXCALLBACKSETS) {
66                 CmiPrintf("Too many message callbacks, cannot register\n");
67                 return -1;
68         }
69         
70         if (!setIdx)
71                 Q->cbQ[setNum] = (CMSGCALLBACK *) malloc(CALLBACKSETSIZE*sizeof(CMSGCALLBACK));
72         
73         (Q->cbQ[setNum])[setIdx].fn = fnp;
74         Q->size++;
75
76         return 0;
77 }
78
79 int CMsgRegisterCallbackPair(CMsgProcFn sendFn, CMsgProcFn recvFn)
80 {
81         if(CMsgRegisterCallback(sendFn, SENDCALLBACK) < 0) 
82                 return -1;
83         if(CMsgRegisterCallback(recvFn, RECVCALLBACK) < 0) 
84                 return -1;
85         return 0;
86 }
87
88 void CMsgInvokeCallbacks(int type, char *msg)
89 {
90         int  i;
91         struct CMsgCallbackQ* Q;
92
93         if (type < 2)
94                 Q = (type)? (&cMsgRecvCbQ) : (&cMsgSendCbQ);
95         else 
96         {
97                 CmiPrintf("Unknown callback type, cannot invoke");
98                 return;
99         }
100
101         for(i=0; i < Q->size; i++)
102                 ((Q->cbQ[i/CALLBACKSETSIZE])[i%CALLBACKSETSIZE].fn)(msg);
103 }