make sure it happens on a login as well
[spider.git] / src / cmsg.c
1 /*
2  * cmsg.c
3  * 
4  * create and free message buffers
5  * 
6  * Copyright 1996 (c) D-J Koopman
7  * 
8  * $Header$
9  */
10
11
12 static char rcsid[] = "$Id$";
13
14 #include <time.h>
15 #include <stdlib.h>
16
17 #include "chain.h"
18 #include "cmsg.h"
19
20 long cmsg_count = 0;
21
22 #ifdef DB_CMSG
23 #include <malloc.h>
24 #include <stdio.h>
25
26
27 #define MAXSORT 20
28 #define INTERVAL 10
29 #define FN "msg_stats"
30
31 static struct {
32         long new;
33         long free;
34 } stats[MAXSORT+1];
35
36 static void store()
37 {
38         static time_t t;
39         time_t systime;
40         
41         time(&systime);
42         if (systime - t > INTERVAL) {
43                 FILE *f = fopen(FN, "w");
44                 if (f) {
45                         int i;
46                         struct mallinfo m;                      
47                         fprintf(f, "\nMSG STATISTICS\n");
48                         fprintf(f,   "==============\n\n");
49                         fprintf(f, "cmsg_count = %ld\n\n", cmsg_count);
50                         for (i = 0; i < MAXSORT+1; ++i) {
51                                 if (stats[i].new == 0 && stats[i].free == 0)
52                                         continue;
53                                 fprintf(f, "%d new: %ld free: %ld outstanding: %ld\n", i, stats[i].new, stats[i].free, stats[i].new-stats[i].free);
54                         }
55                         m = mallinfo();
56                         fprintf(f, "\nmalloc total arena used: %ld used: %ld free: %ld\n\n", m.arena, m.uordblks, m.fordblks);
57                         fclose(f);
58                 }
59                 t = systime;
60         }
61 }
62
63 void cmsg_clear_stats()
64 {
65         memset(stats, 0, sizeof stats);
66         store();
67 }
68
69 #endif
70
71 cmsg_t *cmsg_new(int size, int sort, void *pp)
72 {
73         cmsg_t *mp;
74         
75         mp = malloc(sizeof(cmsg_t) + size);
76         if (!mp)
77                 die("no room in cmsg_new");
78         mp->size = 0;
79         mp->sort = sort & CMSG_SORTMASK;
80         mp->portp = pp;
81         mp->state = mp->reply = 0;
82         mp->inp = mp->data;
83         mp->callback = 0;
84         ++cmsg_count;
85 #ifdef DB_CMSG
86         if (sort > MAXSORT)
87                 sort = MAXSORT;
88         ++stats[sort].new;      
89         store();
90 #endif
91         return mp;
92 }
93
94 void cmsg_send(reft *base, cmsg_t *mp, void (*callback)())
95 {
96         time(&mp->t);
97         mp->size = mp->inp - mp->data;     /* calc the real size */
98         mp->callback = callback;                   /* store the reply address */
99         chain_insert(base, mp);
100 #ifdef DB_CMSG
101         store();
102 #endif
103 }
104
105 void cmsg_priority_send(reft *base, cmsg_t *mp, void (*callback)())
106 {
107         time(&mp->t);
108         mp->size = mp->inp - mp->data;     /* calc the real size */
109         mp->callback = callback;                   /* store the reply address */
110         chain_add(base, mp);
111 #ifdef DB_CMSG
112         store();
113 #endif
114 }
115
116 /*
117  * get the next cmsg (from the front), this removes the message from the chain
118  */
119
120 cmsg_t *cmsg_next(reft *base)
121 {
122         cmsg_t *mp = chain_get_next(base, 0);
123         if (mp)
124                 chain_delete(mp);
125 #ifdef DB_CMSG
126         store();
127 #endif
128         return mp;
129 }
130
131 /*
132  * get the prev cmsg (from the back), this removes the message from the chain
133  */
134
135 cmsg_t *cmsg_prev(reft *base)
136 {
137         cmsg_t *mp = chain_get_prev(base, 0);
138         if (mp)
139                 chain_delete(mp);
140 #ifdef DB_CMSG
141         store();
142 #endif
143         return mp;
144 }
145
146 void cmsg_callback(cmsg_t *m, int reply)
147 {
148         if (m->callback)
149                 (m->callback)(m, reply);
150         cmsg_free(m);
151 }
152
153 void cmsg_free(cmsg_t *m)
154 {
155         --cmsg_count;
156 #ifdef DB_CMSG
157         if (m->sort > MAXSORT)
158                 m->sort = MAXSORT;
159         ++stats[m->sort].free;  
160         store();
161 #endif
162         free(m);
163 }
164
165 void cmsg_flush(reft *base, int reply)
166 {
167         cmsg_t *m;
168         
169         while (m = cmsg_next(base)) {
170                 cmsg_callback(m, reply);
171         }
172 #ifdef DB_CMSG
173         store();
174 #endif
175 }               
176
177 /*
178  * 
179  * $Log$
180  * Revision 1.2  2000-07-20 14:16:00  minima
181  * can use Sourceforge now!
182  * added user->qra cleaning
183  * added 4 digit qra to user broadcast dxspots if available
184  *
185  * Revision 1.1  2000/03/26 00:03:30  djk
186  * first cut of client
187  *
188  * Revision 1.12  1998/05/05 14:01:27  djk
189  * Tidied up various global variables in the hope that there is likely
190  * to be less undefined interaction between modules.
191  * Added some extra LINUX debugging to check for possible cmsg memory leaks.
192  *
193  * Revision 1.11  1998/01/02 19:39:58  djk
194  * made various changes to cope with glibc
195  * fixed problem with extended status in etsi_router
196  *
197  * Revision 1.10  1997/06/13 16:51:17  djk
198  * fixed various library problems
199  * got the taipstack and hayes to the point of half duplex reliability
200  * hayes now successfully communicates with taiptest and has part of the
201  * command level taip stuff in.
202  *
203  * Revision 1.9  1997/05/20 20:45:14  djk
204  * The 1.22 version more or less unchanged
205  *
206  * Revision 1.8  1997/03/25 18:12:55  djk
207  * dunno
208  *
209  * Revision 1.7  1997/03/19 09:57:28  djk
210  * added a count to check for leaks
211  *
212  * Revision 1.6  1997/02/13 17:02:04  djk
213  * forgotten?
214  *
215  * Revision 1.5  1997/02/04 17:47:04  djk
216  * brought into line with public2
217  *
218  * Revision 1.4  1997/02/04 01:27:37  djk
219  * altered size semantics on create (size now = 0 not creation size)
220  *
221  * Revision 1.3  1997/01/20 22:29:27  djk
222  * added status back
223  *
224  * Revision 1.2  1997/01/13 23:34:29  djk
225  * The first working test version of smsd
226  *
227  * Revision 1.1  1997/01/03 23:42:21  djk
228  * added a general message handling module (still developing)
229  * added parity handling to ser.c
230  *
231  */