89e59b7997df4356bee4a82afbf858831fcd89d9
[oweals/gnunet.git] / src / util / server_nc.c
1 /*
2      This file is part of GNUnet.
3      (C) 2010 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 2, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file util/server_nc.c
23  * @brief convenience functions for transmission of
24  *        a notification stream 
25  * @author Christian Grothoff
26  */
27
28 #include "platform.h"
29 #include "gnunet_common.h"
30 #include "gnunet_connection_lib.h"
31 #include "gnunet_scheduler_lib.h"
32 #include "gnunet_server_lib.h"
33 #include "gnunet_time_lib.h"
34
35
36 struct PendingMessageList
37 {
38
39   struct PendingMessageList *next;
40
41   const struct GNUNET_MessageHeader *msg;
42
43   int can_drop;
44
45 };
46
47
48 struct ClientList
49 {
50
51   struct ClientList *next;
52
53   struct GNUNET_SERVER_Client *client;
54
55   struct GNUNET_CONNECTION_TransmitHandle *th;
56
57   struct PendingMessageList *pending;
58
59   unsigned int num_pending;
60
61 };
62
63
64 /**
65  * The notification context is the key datastructure for a conveniance
66  * API used for transmission of notifications to the client until the
67  * client disconnects (or the notification context is destroyed, in
68  * which case we disconnect these clients).  Essentially, all
69  * (notification) messages are queued up until the client is able to
70  * read them.
71  */
72 struct GNUNET_SERVER_NotificationContext
73 {
74
75   struct GNUNET_SERVER_Handle *server;
76
77   struct ClientList *clients;
78
79   unsigned int queue_length;
80
81 };
82
83
84 static void
85 handle_client_disconnect (void *cls,
86                           struct GNUNET_SERVER_Client *client)
87 {
88   struct GNUNET_SERVER_NotificationContext *nc = cls;
89   struct ClientList *pos;
90   struct ClientList *prev;
91   struct PendingMessageList *pml;
92
93   prev = NULL;
94   pos = nc->clients;
95   while (NULL != pos)
96     {
97       if (pos->client == client)
98         break;
99       prev = pos;
100       pos = pos->next;
101     }
102   if (pos == NULL)
103     return;
104   if (prev == NULL)
105     nc->clients = pos->next;
106   else
107     prev->next = pos->next;
108   while (NULL != (pml = pos->pending))
109     {
110       pos->pending = pml->next;
111       GNUNET_free (pml);
112     }
113   GNUNET_free (pos);
114 }
115
116
117 /**
118  * Create a new notification context.
119  *
120  * @param server server for which this function creates the context
121  * @param queue_length maximum number of messages to keep in
122  *        the notification queue; optional messages are dropped
123  *        it the queue gets longer than this number of messages
124  * @return handle to the notification context
125  */
126 struct GNUNET_SERVER_NotificationContext *
127 GNUNET_SERVER_notification_context_create (struct GNUNET_SERVER_Handle *server,
128                                            unsigned int queue_length)
129 {
130   struct GNUNET_SERVER_NotificationContext *ret;
131
132   ret = GNUNET_malloc (sizeof (struct GNUNET_SERVER_NotificationContext));
133   ret->server = server;
134   ret->queue_length = queue_length;
135   GNUNET_SERVER_disconnect_notify (server,
136                                    &handle_client_disconnect,
137                                    ret);
138   return ret;
139 }
140
141
142 /**
143  * Destroy the context, force disconnect for all clients.
144  *
145  * @param nc context to destroy.
146  */
147 void
148 GNUNET_SERVER_notification_context_destroy (struct GNUNET_SERVER_NotificationContext *nc)
149 {
150   struct ClientList *pos;
151   struct PendingMessageList *pml;
152
153   while (NULL != (pos = nc->clients))
154     {
155       nc->clients = pos->next;
156       GNUNET_SERVER_receive_done (pos->client, GNUNET_NO);
157       GNUNET_SERVER_client_drop (pos->client); 
158       while (NULL != (pml = pos->pending))
159         {
160           pos->pending = pml->next;
161           GNUNET_free (pml);
162         }
163       GNUNET_free (pos);
164     }
165   GNUNET_SERVER_disconnect_notify_cancel (nc->server,
166                                           &handle_client_disconnect,
167                                           nc);
168   GNUNET_free (nc);
169 }
170
171
172 /**
173  * Add a client to the notification context.
174  *
175  * @param nc context to modify
176  * @param client client to add
177  */
178 void
179 GNUNET_SERVER_notification_context_add (struct GNUNET_SERVER_NotificationContext *nc,
180                                         struct GNUNET_SERVER_Client *client)
181 {
182 }
183
184
185 /**
186  * Send a message to a particular client; must have
187  * already been added to the notification context.
188  *
189  * @param nc context to modify
190  * @param client client to transmit to
191  * @param msg message to send
192  * @param can_drop can this message be dropped due to queue length limitations
193  */
194 void
195 GNUNET_SERVER_notification_context_unicast (struct GNUNET_SERVER_NotificationContext *nc,
196                                             struct GNUNET_SERVER_Client *client,
197                                             const struct GNUNET_MessageHeader *msg,
198                                             int can_drop)
199 {
200 }
201
202
203 /**
204  * Send a message to all clients of this context.
205  *
206  * @param nc context to modify
207  * @param msg message to send
208  * @param can_drop can this message be dropped due to queue length limitations
209  */
210 void
211 GNUNET_SERVER_notification_context_broadcast (struct GNUNET_SERVER_NotificationContext *nc,
212                                               const struct GNUNET_MessageHeader *msg,
213                                               int can_drop)
214 {
215 }
216
217
218 /* end of server_nc.c */