1 /* GNet - Networking library
2 * Copyright (C) 2000 David Helder
3 * Copyright (C) 2003-2004 Andrew Lanoix
4 * Copyright (C) 2007 Tim-Philipp Müller <tim centricular net>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22
23 #include "conn.h"
24
25 #include <stdio.h>
26 #include <memory.h> /* required for windows */
27 #include <string.h> /* needed for g_memmove/memmove */
28
29 #include "gnet-private.h"
30
31 #define IS_CONNECTED(C) ((C)->socket != NULL)
32 #define BUFFER_LEN 1024
33
34 /* FIXME: these macros are horrid, get rid of them */
35 #define IS_WATCHING(C, FLAG) (((C)->watch_flags & (FLAG))?TRUE:FALSE)
36
37 #define ADD_WATCH(C, FLAG) do { \
38 if (!IS_WATCHING(C,FLAG)) { \
39 (C)->watch_flags |= (FLAG); \
40 if ((C)->iochannel) { \
41 if ((C)->watch) \
42 _gnet_source_remove ((C)->context, (C)->watch); \
43 (C)->watch = _gnet_io_watch_add_full ((C)->context,\
44 G_PRIORITY_DEFAULT, (C)->iochannel, \
45 (C)->watch_flags, async_cb, (C), NULL); \
46 }}} while (0)
47
48 #define REMOVE_WATCH(C, FLAG) do { \
49 if (IS_WATCHING(C,FLAG)) { \
50 (C)->watch_flags &= ~(FLAG); \
51 if ((C)->iochannel) { \
52 if ((C)->watch) \
53 _gnet_source_remove ((C)->context, (C)->watch); \
54 (C)->watch = 0; \
55 if ((C)->watch_flags != 0) \
56 (C)->watch = _gnet_io_watch_add_full ((C)->context, \
57 G_PRIORITY_DEFAULT, (C)->iochannel, \
58 (C)->watch_flags, async_cb, (C), NULL); \
59 }}} while (0)
60
61 #define UNSET_WATCH (C, FLAG)
62
63
64 typedef struct _Write
65 {
66 gchar* buffer;
67 gint length;
68 GDestroyNotify buffer_destroy_cb;
69 } Write;
70
71
72 typedef struct _Read
73 {
74 gint mode;
75
76 } Read;
77
78
79
80 static void ref_internal (GConn* conn);
81 static void unref_internal (GConn* conn);
82
83 static void conn_new_cb (GTcpSocket* socket, gpointer user_data);
84
85 static void conn_connect_cb (GTcpSocket* socket,
86 GTcpSocketConnectAsyncStatus status,
87 gpointer user_data);
88
89
90
91 static gboolean async_cb (GIOChannel* iochannel, GIOCondition condition,
92 gpointer data);
93
94 static void conn_read_full (GConn* conn, gint mode);
95 static void conn_check_read_queue (GConn* conn);
96 static void conn_read_async_cb (GConn* conn);
97 static gboolean process_read_buffer_cb (gpointer data);
98 static gint bytes_processable (GConn* conn);
99 static gint process_read_buffer (GConn* conn);
100
101
102 static void conn_write_async_cb (GConn* conn);
103 static void conn_check_write_queue (GConn* conn);
104
105 static gboolean conn_timeout_cb (gpointer data);
106
107
108
109
110 /**
111 * gnet_conn_new
112 * @hostname: name of host to connect to
113 * @port: port to connect to
114 * @func: function to call on #GConn events
115 * @user_data: data to pass to @func on callbacks
116 *
117 * Creates a #GConn. A connection is not made until
118 * gnet_conn_connect() is called. The callback @func is called when
119 * events occur.
120 *
121 * Returns: a #GConn.
122 *
123 **/
124 GConn*
gnet_conn_new(const gchar * hostname,gint port,GConnFunc func,gpointer user_data)125 gnet_conn_new (const gchar* hostname, gint port,
126 GConnFunc func, gpointer user_data)
127 {
128 GConn* conn;
129
130 g_return_val_if_fail (hostname, NULL);
131
132 conn = g_new0 (GConn, 1);
133 conn->ref_count = 1;
134 conn->hostname = g_strdup(hostname);
135 conn->port = port;
136 conn->inetaddr = gnet_inetaddr_new_nonblock (hostname, port);
137 conn->func = func;
138 conn->user_data = user_data;
139
140 return conn;
141 }
142
143
144
145 /**
146 * gnet_conn_new_inetaddr
147 * @inetaddr: address of host to connect to
148 * @func: function to call on #GConn events
149 * @user_data: data to pass to @func on callbacks
150 *
151 * Creates a #GConn. A connection is not made until
152 * gnet_conn_connect() is called. The callback @func is called when
153 * events occur.
154 *
155 * Returns: a #GConn.
156 *
157 **/
158 GConn*
gnet_conn_new_inetaddr(const GInetAddr * inetaddr,GConnFunc func,gpointer user_data)159 gnet_conn_new_inetaddr (const GInetAddr* inetaddr,
160 GConnFunc func, gpointer user_data)
161 {
162 GConn* conn;
163
164 g_return_val_if_fail (inetaddr, NULL);
165
166 conn = g_new0 (GConn, 1);
167 conn->ref_count = 1;
168 conn->hostname = gnet_inetaddr_get_canonical_name (inetaddr);
169 conn->port = gnet_inetaddr_get_port (inetaddr);
170 conn->inetaddr = gnet_inetaddr_clone (inetaddr);
171 conn->func = func;
172 conn->user_data = user_data;
173
174 return conn;
175 }
176
177
178
179 /**
180 * gnet_conn_new_socket
181 * @socket: TCP Socket (callee owned)
182 * @func: function to call on #GConn events
183 * @user_data: data to pass to @func on callbacks
184 *
185 * Creates a #GConn. The #GConn is created from the @socket. The
186 * socket is callee owned - do not delete it (meaning: #GConn will take
187 * ownership of the socket). The callback is called when events occur.
188 *
189 * Returns: a #GConn.
190 *
191 **/
192 GConn*
gnet_conn_new_socket(GTcpSocket * socket,GConnFunc func,gpointer user_data)193 gnet_conn_new_socket (GTcpSocket* socket,
194 GConnFunc func, gpointer user_data)
195 {
196 GConn* conn;
197
198 g_return_val_if_fail (socket, NULL);
199
200 conn = g_new0 (GConn, 1);
201 conn->ref_count = 1;
202 conn->socket = socket;
203 conn->iochannel = gnet_tcp_socket_get_io_channel (socket);
204 conn->inetaddr = gnet_tcp_socket_get_remote_inetaddr (socket);
205 conn->hostname = gnet_inetaddr_get_canonical_name (conn->inetaddr);
206 conn->port = gnet_inetaddr_get_port (conn->inetaddr);
207 conn->func = func;
208 conn->user_data = user_data;
209
210 return conn;
211
212 }
213
214 /**
215 * gnet_conn_set_main_context
216 * @conn: a #GConn
217 * @context: a #GMainContext, or NULL to use the default GLib main context
218 *
219 * Sets the GLib #GMainContext to use for asynchronous operations. You should
220 * call this function right after you create @conn. You must not call this
221 * function after the actual connection process has started or watches have
222 * been set up (e.g. for reading, writing or errors).
223 *
224 * You are very unlikely to ever need this function.
225 *
226 * Returns: TRUE on success, FALSE on failure.
227 *
228 * Since: 2.0.8
229 **/
230 gboolean
gnet_conn_set_main_context(GConn * conn,GMainContext * context)231 gnet_conn_set_main_context (GConn * conn, GMainContext * context)
232 {
233 g_return_val_if_fail (conn != NULL, FALSE);
234
235 /* Must not be called if already connected or connection pending; should
236 * be okay if the socket is connected but no watches set up yet */
237 g_return_val_if_fail (conn->connect_id == 0 && conn->new_id == 0, FALSE);
238 g_return_val_if_fail (conn->watch == 0, FALSE);
239
240 if (conn->context != context) {
241 if (conn->context)
242 g_main_context_unref (conn->context);
243 if (context)
244 conn->context = g_main_context_ref (context);
245 else
246 conn->context = NULL;
247 }
248
249 return TRUE;
250 }
251
252 /**
253 * gnet_conn_delete
254 * @conn: a #GConn
255 *
256 * Deletes a #GConn.
257 *
258 * Deprecated: Use g_conn_unref(), which does the same.
259 **/
260 void
gnet_conn_delete(GConn * conn)261 gnet_conn_delete (GConn* conn)
262 {
263 if (conn != NULL)
264 gnet_conn_unref(conn);
265 }
266
267
268 /**
269 * gnet_conn_ref
270 * @conn: a #GConn
271 *
272 * Adds a reference to a #GConn.
273 *
274 **/
275 void
gnet_conn_ref(GConn * conn)276 gnet_conn_ref (GConn* conn)
277 {
278 g_return_if_fail (conn);
279
280 conn->ref_count++;
281 }
282
283
284 /**
285 * gnet_conn_unref
286 * @conn: a #GConn
287 *
288 * Removes a reference from a #GConn. A #GConn is deleted when the
289 * reference count reaches 0.
290 *
291 **/
292 void
gnet_conn_unref(GConn * conn)293 gnet_conn_unref (GConn* conn)
294 {
295 g_return_if_fail (conn);
296
297 conn->ref_count--;
298 if (conn->ref_count > 0 || conn->ref_count_internal > 0)
299 return;
300
301 gnet_conn_disconnect (conn);
302
303 g_free (conn->hostname);
304
305 if (conn->inetaddr)
306 gnet_inetaddr_delete (conn->inetaddr);
307
308 g_free (conn->buffer);
309
310 g_free (conn);
311 }
312
313
314 /* increment internal ref count. This is used to prevent deletion
315 during a callback. We don't want the conn to be deleted during a
316 callback if we must still access the conn after the callback. */
317 static void
ref_internal(GConn * conn)318 ref_internal (GConn* conn)
319 {
320 g_return_if_fail (conn);
321
322 conn->ref_count_internal++;
323 }
324
325
326 static void
unref_internal(GConn * conn)327 unref_internal (GConn* conn)
328 {
329 g_return_if_fail (conn);
330
331 conn->ref_count_internal--;
332 if (conn->ref_count == 0 && conn->ref_count_internal == 0)
333 {
334 /* set ref_count to 1 to force deletion on unref. */
335 conn->ref_count = 1;
336 gnet_conn_unref (conn);
337 }
338 }
339
340
341
342 /**
343 * gnet_conn_set_callback
344 * @conn: a #GConn
345 * @func: function to call on #GConn events
346 * @user_data: data to pass to @func on callbacks
347 *
348 * Sets the #GConnEvent callback for a #GConn. The callback @func is
349 * called when events occur.
350 *
351 **/
352 void
gnet_conn_set_callback(GConn * conn,GConnFunc func,gpointer user_data)353 gnet_conn_set_callback (GConn* conn, GConnFunc func, gpointer user_data)
354 {
355 g_return_if_fail (conn);
356 conn->func = func;
357 conn->user_data = user_data;
358 }
359
360
361
362 /**
363 * gnet_conn_connect
364 * @conn: a #GConn
365 *
366 * Establishes a connection. If the connection is pending or already
367 * established, this function does nothing. The callback is called
368 * when the connection is established or an error occurs.
369 *
370 **/
371 void
gnet_conn_connect(GConn * conn)372 gnet_conn_connect (GConn * conn)
373 {
374 g_return_if_fail (conn != NULL);
375 g_return_if_fail (conn->func != NULL);
376
377 /* Ignore if connected or connection pending */
378 if (conn->connect_id != 0 || conn->new_id != 0 || conn->socket != NULL)
379 return;
380
381 /* Make asynchronous connection */
382 if (conn->inetaddr) {
383 conn->new_id = gnet_tcp_socket_new_async_full (conn->inetaddr,
384 conn_new_cb, conn, (GDestroyNotify) NULL, conn->context,
385 G_PRIORITY_DEFAULT);
386 } else if (conn->hostname) {
387 conn->connect_id = gnet_tcp_socket_connect_async_full (conn->hostname,
388 conn->port, conn_connect_cb, conn, (GDestroyNotify) NULL,
389 conn->context, G_PRIORITY_DEFAULT);
390 } else {
391 g_return_if_reached ();
392 }
393 }
394
395
396 static void
conn_new_cb(GTcpSocket * socket,gpointer user_data)397 conn_new_cb (GTcpSocket* socket, gpointer user_data)
398 {
399 GConn* conn = (GConn*) user_data;
400 GConnEvent event;
401
402 g_return_if_fail (conn);
403
404 conn->new_id = NULL;
405
406 if (socket)
407 {
408 conn->socket = socket;
409 conn->iochannel = gnet_tcp_socket_get_io_channel (socket);
410
411 conn_check_write_queue (conn);
412 conn_check_read_queue (conn);
413 if (conn->watch_flags) ADD_WATCH(conn, 0);
414
415 event.type = GNET_CONN_CONNECT;
416 }
417 else
418 {
419 event.type = GNET_CONN_ERROR;
420 }
421
422 event.buffer = NULL;
423 event.length = 0;
424 (conn->func)(conn, &event, conn->user_data);
425 }
426
427
428 static void
conn_connect_cb(GTcpSocket * socket,GTcpSocketConnectAsyncStatus status,gpointer user_data)429 conn_connect_cb (GTcpSocket* socket,
430 GTcpSocketConnectAsyncStatus status,
431 gpointer user_data)
432 {
433 GConn* conn = (GConn*) user_data;
434 GConnEvent event;
435
436 g_return_if_fail (conn);
437
438 conn->connect_id = NULL;
439
440 if (status == GTCP_SOCKET_CONNECT_ASYNC_STATUS_OK)
441 {
442 conn->socket = socket;
443 conn->inetaddr = gnet_tcp_socket_get_remote_inetaddr (socket);
444 conn->iochannel = gnet_tcp_socket_get_io_channel (socket);
445
446 conn_check_write_queue (conn);
447 conn_check_read_queue (conn);
448 if (conn->watch_flags) ADD_WATCH(conn, 0);
449
450 event.type = GNET_CONN_CONNECT;
451 }
452 else
453 {
454 event.type = GNET_CONN_ERROR;
455 }
456
457 event.buffer = NULL;
458 event.length = 0;
459 (conn->func)(conn, &event, conn->user_data);
460 }
461
462
463 static void
conn_write_free(Write * write)464 conn_write_free(Write *write)
465 {
466 if (write->buffer_destroy_cb)
467 write->buffer_destroy_cb(write->buffer);
468 g_free (write);
469 }
470
471
472 /**
473 * gnet_conn_disconnect
474 * @conn: a #GConn
475 *
476 * Closes the connection. The connection can later be reestablished
477 * by calling gnet_conn_connect() again. If the connection was not
478 * established, this function does nothing.
479 *
480 **/
481 void
gnet_conn_disconnect(GConn * conn)482 gnet_conn_disconnect (GConn* conn)
483 {
484 GList* i;
485
486 g_return_if_fail (conn);
487
488 if (conn->watch)
489 {
490 _gnet_source_remove (conn->context, conn->watch);
491 conn->watch = 0;
492 }
493 conn->watch_flags = 0;
494
495 conn->watch_readable = FALSE;
496 conn->watch_writable = FALSE;
497
498 if (conn->iochannel)
499 conn->iochannel = NULL; /* do not unref */
500
501 if (conn->socket)
502 {
503 gnet_tcp_socket_delete (conn->socket);
504 conn->socket = NULL;
505 }
506
507 if (conn->connect_id)
508 {
509 gnet_tcp_socket_connect_async_cancel (conn->connect_id);
510 conn->connect_id = NULL;
511 }
512
513 if (conn->new_id)
514 {
515 gnet_tcp_socket_new_async_cancel (conn->new_id);
516 conn->new_id = NULL;
517 }
518
519 for (i = conn->write_queue; i != NULL; i = i->next)
520 {
521 conn_write_free(i->data);
522 }
523 g_list_free (conn->write_queue);
524 conn->write_queue = NULL;
525 conn->bytes_written = 0;
526
527 for (i = conn->read_queue; i != NULL; i = i->next)
528 {
529 Read* read = i->data;
530 g_free (read);
531 }
532 g_list_free (conn->read_queue);
533 conn->read_queue = NULL;
534 conn->bytes_read = 0;
535 conn->read_eof = FALSE;
536 if (conn->process_buffer_timeout)
537 {
538 _gnet_source_remove (conn->context, conn->process_buffer_timeout);
539 conn->process_buffer_timeout = 0;
540 }
541
542 if (conn->timer)
543 {
544 _gnet_source_remove (conn->context, conn->timer);
545 conn->timer = 0;
546 }
547 }
548
549
550 /**
551 * gnet_conn_is_connected
552 * @conn: a #GConn
553 *
554 * Checks if the connection is established.
555 *
556 * Returns: TRUE if the connection is established, FALSE otherwise.
557 *
558 **/
559 gboolean
gnet_conn_is_connected(const GConn * conn)560 gnet_conn_is_connected (const GConn* conn)
561 {
562 g_return_val_if_fail (conn, FALSE);
563
564 if (IS_CONNECTED(conn))
565 return TRUE;
566
567 return FALSE;
568 }
569
570
571 /* **************************************** */
572
573 static gboolean
async_cb(GIOChannel * iochannel,GIOCondition condition,gpointer data)574 async_cb (GIOChannel* iochannel, GIOCondition condition, gpointer data)
575 {
576 GConn* conn = (GConn*) data;
577 GConnEvent event = {GNET_CONN_ERROR, NULL, 0};
578
579 ref_internal (conn);
580
581 if (condition & (G_IO_ERR | G_IO_NVAL))
582 {
583 /* Upcall ERROR */
584 gnet_conn_disconnect (conn);
585 if (conn->func)
586 (conn->func) (conn, &event, conn->user_data);
587
588 unref_internal (conn);
589 return FALSE;
590 }
591
592 if (condition & G_IO_IN)
593 {
594 /* Upcall */
595 if (conn->watch_readable) /* READABLE */
596 {
597 GConnEvent event;
598
599 event.type = GNET_CONN_READABLE;
600 event.buffer = NULL;
601 event.length = 0;
602
603 g_return_val_if_fail (conn->func, FALSE);
604 (conn->func) (conn, &event, conn->user_data);
605 }
606 else
607 {
608 conn_read_async_cb (conn); /* READ? */
609 }
610
611 if (conn->ref_count == 0 || !IS_CONNECTED(conn))
612 {
613 unref_internal (conn);
614 return FALSE;
615 }
616 }
617
618 if (condition & G_IO_OUT)
619 {
620 /* Upcall */
621 if (conn->watch_writable) /* WRITABLE */
622 {
623 GConnEvent event;
624
625 event.type = GNET_CONN_WRITABLE;
626 event.buffer = NULL;
627 event.length = 0;
628
629 g_return_val_if_fail (conn->func, FALSE);
630 (conn->func) (conn, &event, conn->user_data);
631 }
632 else /* WRITE? */
633 {
634 conn_write_async_cb (conn);
635 }
636
637 if (conn->ref_count == 0 || !IS_CONNECTED(conn))
638 {
639 unref_internal (conn);
640 return FALSE;
641 }
642 }
643
644 if (condition & G_IO_HUP)
645 {
646 gnet_conn_disconnect (conn);
647 event.type = GNET_CONN_CLOSE;
648 if (conn->func)
649 (conn->func) (conn, &event, conn->user_data);
650 }
651
652 unref_internal (conn);
653 /* Assume we want another callback, even though the source may have
654 been destroyed though. The Glib main loop handles this
655 properly. */
656
657 return TRUE;
658 }
659
660
661 /* **************************************** */
662
663
664 /**
665 * gnet_conn_read:
666 * @conn: a #GConn
667 *
668 * Begins an asynchronous read. The connection callback is called
669 * when any data has been read. This function may be called again
670 * before the asynchronous read completes.
671 *
672 **/
673 void
gnet_conn_read(GConn * conn)674 gnet_conn_read (GConn* conn)
675 {
676 g_return_if_fail (conn);
677 g_return_if_fail (conn->func);
678
679 conn_read_full (conn, 0);
680 }
681
682
683 /**
684 * gnet_conn_readn:
685 * @conn: a #GConn
686 * @length: Number of bytes to read
687 *
688 * Begins an asynchronous read of exactly @length bytes. The
689 * connection callback is called when the data has been read. This
690 * function may be called again before the asynchronous read
691 * completes.
692 *
693 **/
694 void
gnet_conn_readn(GConn * conn,gint n)695 gnet_conn_readn (GConn* conn, gint n)
696 {
697 g_return_if_fail (conn);
698 g_return_if_fail (conn->func);
699 g_return_if_fail (n > 0);
700
701 conn_read_full (conn, n);
702
703 }
704
705
706
707 /**
708 * gnet_conn_readline:
709 * @conn: a #GConn
710 *
711 * Begins an asynchronous line read. The connection callback is
712 * called when a line has been read. Lines are terminated with \n,
713 * \r, \r\n, or \0. The terminator is \0'ed out in the buffer. The
714 * terminating \0 is accounted for in the buffer length. This
715 * function may be called again before the asynchronous read
716 * completes.
717 *
718 **/
719 void
gnet_conn_readline(GConn * conn)720 gnet_conn_readline (GConn* conn)
721 {
722 g_return_if_fail (conn);
723 g_return_if_fail (conn->func);
724
725 conn_read_full (conn, -1);
726 }
727
728
729
730 static void
conn_read_full(GConn * conn,gint mode)731 conn_read_full (GConn* conn, gint mode)
732 {
733 Read* read;
734
735 g_return_if_fail (conn);
736
737 /* Create the buffer */
738 if (!conn->buffer)
739 {
740 conn->buffer = g_malloc (BUFFER_LEN);
741 conn->length = BUFFER_LEN;
742 conn->bytes_read = 0;
743 }
744
745 /* Add to read queue */
746 read = g_new0 (Read, 1);
747 read->mode = mode;
748 conn->read_queue = g_list_append (conn->read_queue, read);
749
750 /* Check the read queue */
751 conn_check_read_queue (conn);
752 }
753
754
755 static void
conn_check_read_queue(GConn * conn)756 conn_check_read_queue (GConn* conn)
757 {
758 /* Ignore if we are unconnected or there are no reads */
759 if (!IS_CONNECTED(conn) || !conn->read_queue)
760 return;
761
762 /* Ignore if we will process the buffer or are already watch IN */
763 if (conn->process_buffer_timeout || IS_WATCHING(conn, G_IO_IN))
764 return;
765
766
767 /* Set up process_read_buffer_cb() if there's data available and we
768 can process it, OR if we've read EOF. EOF is
769
770 EOF is handled when it is read, regardless of the read queue. We
771 don't worry about it here.
772
773 OPTIMIZATION: There may be reads in the queue that cannot be
774 processed given the data we have and we would need to read in
775 more data. We watch IO_IN in this case. */
776 if ((conn->bytes_read && bytes_processable(conn) > 0) || conn->read_eof) {
777 conn->process_buffer_timeout = _gnet_timeout_add_full (conn->context,
778 G_PRIORITY_DEFAULT, 0, process_read_buffer_cb, conn, NULL);
779 } else {
780 /* Otherwise, if there is no read watch, set one, so we can read
781 * more bytes */
782 ADD_WATCH(conn, G_IO_IN);
783 }
784 }
785
786
787 static void
conn_read_async_cb(GConn * conn)788 conn_read_async_cb (GConn* conn)
789 {
790 guint bytes_to_read;
791 gchar* buffer_start;
792 GIOError error;
793 gsize bytes_read;
794
795 /* Resize the buffer if it's full. */
796 if (conn->length == conn->bytes_read)
797 {
798 conn->length *= 2;
799 conn->buffer = g_realloc(conn->buffer, conn->length);
800 }
801
802 /* Calculate buffer start and length */
803 bytes_to_read = conn->length - conn->bytes_read;
804 buffer_start = &conn->buffer[conn->bytes_read];
805 g_return_if_fail (bytes_to_read > 0);
806
807 /* Read data into buffer */
808 error = g_io_channel_read (conn->iochannel, buffer_start,
809 bytes_to_read, &bytes_read);
810
811 /* Try again later if necessary */
812 if (error == G_IO_ERROR_AGAIN)
813 return;
814
815 /* Fail if this is an error */
816 else if (error != G_IO_ERROR_NONE)
817 {
818 GConnEvent event = {GNET_CONN_ERROR, NULL, 0};
819
820 ref_internal (conn);
821
822 gnet_conn_disconnect (conn);
823 (conn->func) (conn, &event, conn->user_data);
824
825 unref_internal (conn);
826
827 return;
828 }
829
830 /* If we read nothing, that means EOF and we're done. We do not
831 callback with anything that might be in the buffer. */
832 else if (bytes_read == 0)
833 {
834 conn->read_eof = TRUE;
835 }
836
837 /* Otherwise, we read something */
838 else
839 {
840 conn->bytes_read += bytes_read;
841 }
842
843 /*** Process what we read *** */
844
845 /* Process the read buffer */
846 ref_internal (conn);
847 do
848 {
849 /* Process data */
850 bytes_read = process_read_buffer (conn);
851 /* conn may be disconnected at this point */
852
853 /* Stop if conn deleted */
854 if (conn->ref_count == 0)
855 {
856 unref_internal (conn);
857 return;
858 }
859
860 } while (bytes_read > 0);
861
862 unref_internal (conn);
863 /* conn is still good (though possibly disconnected). Otherwise, we
864 would have returned in the do-loop. */
865
866 /* Process EOF if:
867 - we read EOF
868 - the connection is still open
869 - there are reads in the read queue (we won't give the user
870 a CLOSE unless they make a read that triggers it.)
871 */
872 if (conn->read_eof && IS_CONNECTED(conn) && conn->read_queue)
873 {
874 GConnEvent event = {GNET_CONN_CLOSE, NULL, 0};
875
876 /* (we know conn is still good - otherwise it would have been
877 deleted in the do-loop) */
878
879 gnet_conn_disconnect (conn);
880 (conn->func) (conn, &event, conn->user_data);
881 return; /* we're done with conn for now */
882 }
883
884 /* Remove read watch if no more reads */
885 if (!conn->read_queue)
886 {
887 REMOVE_WATCH(conn, G_IO_IN);
888 }
889 }
890
891
892
893 /* Called to dispatch reads to user callback */
894 static gboolean
process_read_buffer_cb(gpointer data)895 process_read_buffer_cb (gpointer data)
896 {
897 GConn* conn = (GConn*) data;
898 gint bytes_read;
899
900 g_return_val_if_fail (conn, FALSE);
901
902 conn->process_buffer_timeout = 0;
903
904 /* Ignore if nothing to read */
905 if (conn->bytes_read == 0 || conn->read_queue == NULL)
906 return FALSE;
907
908 /* Process reads */
909 ref_internal (conn);
910 do
911 {
912 /* Process data */
913 bytes_read = process_read_buffer (conn);
914 /* conn may be disconnected at this point */
915
916 /* Stop if conn deleted */
917 if (conn->ref_count == 0)
918 {
919 unref_internal (conn);
920 return FALSE;
921 }
922 } while (bytes_read > 0);
923
924 unref_internal (conn);
925 /* conn is still good (though possibly disconnected). Otherwise, we
926 would have returned in the do-loop. */
927
928 /* Process EOF (if we read EOF) and are still connected */
929 if (conn->read_eof && IS_CONNECTED(conn))
930 {
931 GConnEvent event = {GNET_CONN_CLOSE, NULL, 0};
932
933 gnet_conn_disconnect (conn);
934 (conn->func) (conn, &event, conn->user_data);
935 return FALSE; /* we're done with conn for now*/
936 }
937
938 /* Set read watch if we're still connected and there's more to read */
939 if (IS_CONNECTED(conn) && conn->read_queue)
940 {
941 ADD_WATCH (conn, G_IO_IN);
942 }
943
944 return FALSE;
945 }
946
947
948 /* Calculate number of bytes that can be processed by the top read */
949 static gint
bytes_processable(GConn * conn)950 bytes_processable (GConn* conn)
951 {
952 Read* read;
953
954 g_return_val_if_fail (conn, 0);
955
956 /* If there is no data to process or reads to process, return 0 */
957 if (conn->bytes_read == 0 || conn->read_queue == NULL)
958 return 0;
959
960 /* Get a read off the queue */
961 read = (Read*) conn->read_queue->data;
962
963 switch (read->mode)
964 {
965 /* Read any */
966 case 0:
967 {
968 return conn->bytes_read;
969 break;
970 }
971
972 /* Read line */
973 case -1:
974 {
975 guint i;
976
977 /* Look for \n, \r, or \r\n */
978 for (i = 0; i < conn->bytes_read; ++i)
979 {
980 /* \n and \0 */
981 if (conn->buffer[i] == '\0' ||
982 conn->buffer[i] == '\n')
983 return i+1;
984
985 /* \r Only counted if we know the next character. If
986 it's a \n, it'd need to be \0'ed out. */
987 else if (conn->buffer[i] == '\r' &&
988 ((i+1) < conn->bytes_read))
989 {
990 if (conn->buffer[i+1] == '\n')
991 return i+2;
992 else
993 return i+1;
994 }
995 }
996 break;
997 }
998
999 default: /* Read n */
1000 {
1001 if (conn->bytes_read >= read->mode)
1002 return read->mode;
1003 break;
1004 }
1005 }
1006
1007 return 0;
1008 }
1009
1010
1011 /* Return bytes read */
1012 static gint
process_read_buffer(GConn * conn)1013 process_read_buffer (GConn* conn)
1014 {
1015 Read* read;
1016 gint bytes_processed = 0;
1017 gint bytes_read = 0;
1018
1019 g_return_val_if_fail (conn, FALSE);
1020
1021 /* If there is no data to process or reads to process, return 0 */
1022 if (conn->bytes_read == 0 || conn->read_queue == NULL)
1023 return 0;
1024
1025 /* Get a read off the queue */
1026 read = (Read*) conn->read_queue->data;
1027
1028 ref_internal (conn);
1029
1030 switch (read->mode)
1031 {
1032 /* Read any */
1033 case 0:
1034 {
1035 bytes_processed = bytes_read = conn->bytes_read;
1036
1037 break;
1038 }
1039
1040 /* Read line */
1041 case -1:
1042 {
1043 guint i;
1044
1045 /* Look for \n, \r, or \r\n */
1046 for (i = 0; i < conn->bytes_read; ++i)
1047 {
1048 /* \0 */
1049 if (conn->buffer[i] == '\0')
1050 {
1051 bytes_processed = bytes_read = i + 1;
1052 break;
1053 }
1054
1055 /* \n */
1056 else if (conn->buffer[i] == '\n')
1057 {
1058 conn->buffer[i] = '\0';
1059 bytes_processed = bytes_read = i + 1;
1060 break;
1061 }
1062
1063 /* \r Only counted if we know the next character. If it's
1064 a \n, it needs to be \0'ed out. */
1065 else if (conn->buffer[i] == '\r' &&
1066 ((i+1) < conn->bytes_read))
1067 {
1068 if (conn->buffer[i+1] == '\n')
1069 {
1070 conn->buffer[i] = '\0';
1071 conn->buffer[i+1] = '\0';
1072 bytes_read = i + 1;
1073 bytes_processed = i + 2;
1074 }
1075 else
1076 {
1077 conn->buffer[i] = '\0';
1078 bytes_processed = bytes_read = i + 1;
1079 }
1080 break;
1081 }
1082 }
1083
1084 break;
1085 }
1086
1087 default: /* Read n */
1088 {
1089 if (conn->bytes_read >= read->mode)
1090 bytes_processed = bytes_read = read->mode;
1091
1092 break;
1093 }
1094 }
1095
1096 if (bytes_read)
1097 {
1098 GConnEvent event;
1099
1100 event.type = GNET_CONN_READ;
1101 event.buffer = conn->buffer;
1102 event.length = bytes_read;
1103
1104 (conn->func) (conn, &event, conn->user_data);
1105 }
1106 /* Note: User may have disconnected after the callback */
1107
1108 /* If read successful and we're still connected, move bytes over and
1109 remove read */
1110 if (bytes_processed && IS_CONNECTED(conn))
1111 {
1112 g_assert (conn->bytes_read >= bytes_processed);/* Sanity check */
1113
1114 /* Move bytes over */
1115 g_memmove (conn->buffer, &conn->buffer[bytes_processed],
1116 conn->bytes_read - bytes_processed);
1117 conn->bytes_read -= bytes_processed;
1118
1119 /* Remove read from queue */
1120 conn->read_queue = g_list_remove (conn->read_queue, read);
1121 g_free (read);
1122 }
1123
1124 unref_internal (conn);
1125
1126 return bytes_processed;
1127 }
1128
1129
1130
1131
1132 /* **************************************** */
1133
1134
1135
1136 /**
1137 * gnet_conn_write_direct
1138 * @conn: a #GConn
1139 * @buffer: buffer to write from
1140 * @length: length of @buffer
1141 * @buffer_destroy_cb: function to call when buffer is no longer needed
1142 *
1143 * Sets up an asynchronous write to @conn from @buffer. The buffer is
1144 * created by the caller and will not be copied. The caller needs to
1145 * make sure the buffer stays valid until @buffer_destroy_cb is called.
1146 * This function can be called again before the asynchronous write
1147 * completes. @buffer_destroy_cb may be %NULL.
1148 *
1149 **/
1150 void
gnet_conn_write_direct(GConn * conn,gchar * buffer,gint length,GDestroyNotify buffer_destroy_cb)1151 gnet_conn_write_direct (GConn* conn, gchar* buffer, gint length,
1152 GDestroyNotify buffer_destroy_cb)
1153 {
1154 Write* write;
1155
1156 g_return_if_fail (conn != NULL);
1157 g_return_if_fail (buffer != NULL);
1158 g_return_if_fail (length >= 0);
1159
1160 if (length == 0)
1161 return;
1162
1163 /* Add to queue */
1164 write = g_new0 (Write, 1);
1165 write->buffer = buffer;
1166 write->length = length;
1167 write->buffer_destroy_cb = buffer_destroy_cb;
1168 conn->write_queue = g_list_append (conn->write_queue, write);
1169
1170 conn_check_write_queue (conn);
1171 }
1172
1173 /**
1174 * gnet_conn_write
1175 * @conn: a #GConn
1176 * @buffer: buffer to write from
1177 * @length: length of @buffer
1178 *
1179 * Sets up an asynchronous write to @conn from @buffer. The buffer is
1180 * copied, so it may be deleted by the caller. This function can be
1181 * called again before the asynchronous write completes.
1182 *
1183 **/
1184 void
gnet_conn_write(GConn * conn,gchar * buffer,gint length)1185 gnet_conn_write (GConn* conn, gchar* buffer, gint length)
1186 {
1187 gchar *copy;
1188
1189 g_return_if_fail (conn != NULL);
1190 g_return_if_fail (buffer != NULL);
1191 g_return_if_fail (length >= 0);
1192
1193 if (length == 0)
1194 return;
1195
1196 copy = g_memdup (buffer, length);
1197 gnet_conn_write_direct (conn, copy, length, (GDestroyNotify) g_free);
1198 }
1199
1200
1201 static void
conn_check_write_queue(GConn * conn)1202 conn_check_write_queue (GConn* conn)
1203 {
1204 /* Ignore if we are unconnected or there is no writes */
1205 if (!IS_CONNECTED(conn) || !conn->write_queue)
1206 return;
1207
1208 /* Ignore if we are already watching OUT */
1209 if (IS_WATCHING(conn, G_IO_OUT))
1210 return;
1211
1212 /* Watch for write */
1213 ADD_WATCH (conn, G_IO_OUT);
1214 }
1215
1216
1217 static void
conn_write_async_cb(GConn * conn)1218 conn_write_async_cb (GConn* conn)
1219 {
1220 Write* write;
1221 GIOError error;
1222 guint bytes_to_write;
1223 gchar* buffer_start;
1224 gsize bytes_written;
1225 GConnEvent event = {GNET_CONN_ERROR, NULL, 0};
1226
1227 write = (Write*) conn->write_queue->data;
1228 g_return_if_fail (write != NULL);
1229
1230 /* Calculate start of buffer */
1231 buffer_start = &write->buffer[conn->bytes_written];
1232 bytes_to_write = write->length - conn->bytes_written;
1233
1234 /* Write */
1235 error = g_io_channel_write(conn->iochannel, buffer_start,
1236 bytes_to_write, &bytes_written);
1237
1238 /* Check for error. If error, disconnect and notify */
1239 if (error != G_IO_ERROR_NONE)
1240 {
1241 gnet_conn_disconnect (conn);
1242 (conn->func) (conn, &event, conn->user_data);
1243 /* conn may be deleted now */
1244 return;
1245 }
1246 /* Otherwise, write is good */
1247
1248 /* Increment bytes written count */
1249 conn->bytes_written += bytes_written;
1250
1251 /* Check if we're done writing this queued write */
1252 if (conn->bytes_written == write->length)
1253 {
1254 /* Remove and delete the queued write */
1255 conn->write_queue = g_list_remove (conn->write_queue, write);
1256 conn_write_free(write);
1257
1258 conn->bytes_written = 0;
1259
1260 /* Remove watch if there are no more queued writes */
1261 if (conn->write_queue == NULL)
1262 REMOVE_WATCH (conn, G_IO_OUT);
1263
1264 /* Notify */
1265 event.type = GNET_CONN_WRITE;
1266 (conn->func)(conn, &event, conn->user_data);
1267 /* conn may be disconnected or deleted now */
1268 }
1269
1270 /* Otherwise, keep watching for output */
1271 return;
1272 }
1273
1274
1275
1276 /* **************************************** */
1277
1278 /**
1279 * gnet_conn_set_watch_error
1280 * @conn: a #GConn
1281 * @enable: enable the %GNET_CONN_READABLE event?
1282 *
1283 * Enables (or disables) the %GNET_CONN_ERROR event for a #GConn. If
1284 * enabled, the %GNET_CONN_ERROR event occurs when an error occurs.
1285 * The @conn is disconnected before the callback is made.
1286 *
1287 **/
1288 void
gnet_conn_set_watch_error(GConn * conn,gboolean enable)1289 gnet_conn_set_watch_error (GConn* conn, gboolean enable)
1290 {
1291 g_return_if_fail (conn);
1292
1293 if (enable)
1294 ADD_WATCH(conn, G_IO_ERR | G_IO_HUP | G_IO_NVAL);
1295 else
1296 REMOVE_WATCH(conn, G_IO_ERR | G_IO_HUP | G_IO_NVAL);
1297 }
1298
1299
1300 /**
1301 * gnet_conn_set_watch_readable
1302 * @conn: a #GConn
1303 * @enable: enable the %GNET_CONN_READABLE event?
1304 *
1305 * Enables (or disables) the %GNET_CONN_READABLE event for a #GConn.
1306 * If enabled, the %GNET_CONN_READABLE event occurs when data can be
1307 * read from the socket. Read from the iochannel member of the @conn.
1308 * Do not enable this while using gnet_conn_read(), gnet_conn_readn(),
1309 * or gnet_conn_readline().
1310 *
1311 **/
1312 void
gnet_conn_set_watch_readable(GConn * conn,gboolean enable)1313 gnet_conn_set_watch_readable (GConn* conn, gboolean enable)
1314 {
1315 g_return_if_fail (conn);
1316 g_return_if_fail (conn->func);
1317
1318 conn->watch_readable = enable;
1319 if (enable)
1320 ADD_WATCH (conn, G_IO_IN);
1321 else
1322 REMOVE_WATCH (conn, G_IO_IN);
1323 }
1324
1325
1326 /**
1327 * gnet_conn_set_watch_writable
1328 * @conn: a #GConn
1329 * @enable: enable the #GNET_CONN_WRITABLE event?
1330 *
1331 * Enables (or disables) the %GNET_CONN_WRITABLE event for a #GConn.
1332 * If enabled, the #GNET_CONN_WRITABLE event occurs when data can be
1333 * written to the socket. Write to the iochannel member of the @conn.
1334 * Do not enable this while using gnet_conn_write().
1335 *
1336 **/
1337 void
gnet_conn_set_watch_writable(GConn * conn,gboolean enable)1338 gnet_conn_set_watch_writable (GConn* conn, gboolean enable)
1339 {
1340 g_return_if_fail (conn);
1341
1342 conn->watch_writable = enable;
1343 if (enable)
1344 ADD_WATCH (conn, G_IO_OUT);
1345 else
1346 REMOVE_WATCH (conn, G_IO_OUT);
1347 }
1348
1349
1350 /* **************************************** */
1351
1352
1353 /**
1354 * gnet_conn_timeout
1355 * @conn: a #GConn
1356 * @timeout: Timeout (in milliseconds)
1357 *
1358 * Sets a timeout on a #GConn. When the timer expires, the
1359 * %GNET_CONN_STATUS_TIMEOUT event occurs. If there already is a
1360 * timeout set on @conn, the old timeout is canceled. Set @timeout
1361 * to 0 to cancel the current timeout.
1362 *
1363 **/
1364 void
gnet_conn_timeout(GConn * conn,guint timeout)1365 gnet_conn_timeout (GConn* conn, guint timeout)
1366 {
1367 g_return_if_fail (conn != NULL);
1368
1369 if (conn->timer) {
1370 _gnet_source_remove (conn->context, conn->timer);
1371 conn->timer = 0;
1372 }
1373
1374 if (timeout) {
1375 g_return_if_fail (conn->func != NULL);
1376 conn->timer = _gnet_timeout_add_full (conn->context, G_PRIORITY_DEFAULT,
1377 timeout, conn_timeout_cb, conn, (GDestroyNotify) NULL);
1378 }
1379 }
1380
1381
1382 static gboolean
conn_timeout_cb(gpointer data)1383 conn_timeout_cb (gpointer data)
1384 {
1385 GConn* conn = (GConn*) data;
1386 GConnEvent event;
1387
1388 g_return_val_if_fail (conn, FALSE);
1389
1390 conn->timer = 0;
1391
1392 event.type = GNET_CONN_TIMEOUT;
1393 event.buffer = NULL;
1394 event.length = 0;
1395 (conn->func)(conn, &event, conn->user_data);
1396
1397 return FALSE;
1398 }
1399