[gnet-dev] [PATCH] examples/echoserver-async.c should check condition G_IO_OUT first
- From: Benjamin Lee <benjaminlee users sf net>
- To: gnet-dev lists gnetlibrary org
- Subject: [gnet-dev] [PATCH] examples/echoserver-async.c should check condition G_IO_OUT first
- Date: Sun, 20 Nov 2005 21:14:52 +1100
Greetings list!
I just noticed that the examples/echoserver-async.c program has a
small corner condition bug.
If it receives some data... and then it receives a read 0 bytes... it
will not echo the received data it previously read... because it
thinks the other side wants to disconnect... when, although this is
true, it should really send the data back first (or try to), then
disconnect.
I've attached a trivial patch which swaps the check for G_IO_IN and
G_IO_OUT flags / events... which _should_ handle this condition.
Comments?
E.g. try this to reproduce the but (timing is also a factor):
./echoserver-async 46600
echo "12345678abcdefgh12345678abcdefgh12345678abcdefgh12345678abcdefgh12345678abcdefgh12345678abcdefgh12345678abcdefgh12345678abcdefgh" | nc -vv -q 10 localhost 46600
If you use any of the other echo*servers*, they return the data, then
handle the disconnect.
--
Benjamin Lee mailto:benjamin lee realthought net
Melbourne, Australia http://www.realthought.net
Linux / BSD / GNU tel:+61 4 16 BEN LEE
Open Source "... invest in your company, not their company..."
"... invest in your world, not one country..."
__________________________________________________________________________
Nothing is faster than the speed of light ...
To prove this to yourself, try opening the refrigerator door before the
light comes on.
? echoserver-async.c.original.cvs
Index: echoserver-async.c
===================================================================
RCS file: /cvs/gnome/gnet/examples/echoserver-async.c,v
retrieving revision 1.6
diff -u -r1.6 echoserver-async.c
--- echoserver-async.c 19 Sep 2005 15:25:55 -0000 1.6
+++ echoserver-async.c 20 Nov 2005 10:07:07 -0000
@@ -184,6 +184,54 @@
goto error;
}
+ if (condition & G_IO_OUT)
+ {
+ GIOError error;
+ gsize bytes_written;
+
+ /* Write the data out */
+ error = g_io_channel_write(iochannel, client_state->buffer,
+ client_state->n, &bytes_written);
+
+ if (error != G_IO_ERROR_NONE)
+ {
+ fprintf (stderr, "Client write error (%s:%d): %d\n",
+ client_state->name, client_state->port, error);
+ goto error;
+ }
+
+ else if (bytes_written > 0)
+ {
+ guint old_watch_flags;
+
+ /* Move the memory down some (you wouldn't want to do this
+ in a performance server because it's slow!) */
+ client_state->n -= bytes_written;
+ g_memmove(client_state->buffer,
+ &client_state->buffer[bytes_written],
+ client_state->n);
+
+ old_watch_flags = client_state->watch_flags;
+
+ /* Remove OUT watch if done */
+ if (client_state->n == 0)
+ client_state->watch_flags &= ~G_IO_OUT;
+
+ /* Add IN watch */
+ client_state->watch_flags |= G_IO_IN;
+
+ /* Update watch flags if they changed */
+ if (old_watch_flags != client_state->watch_flags)
+ {
+ g_source_remove (client_state->watch);
+ client_state->watch =
+ g_io_add_watch(iochannel, client_state->watch_flags,
+ async_client_iofunc, client_state);
+ rv = FALSE;
+ }
+ }
+ }
+
/* Check for data to be read (or if the socket was closed) */
if (condition & G_IO_IN)
{
@@ -243,54 +291,6 @@
}
}
- }
-
- if (condition & G_IO_OUT)
- {
- GIOError error;
- gsize bytes_written;
-
- /* Write the data out */
- error = g_io_channel_write(iochannel, client_state->buffer,
- client_state->n, &bytes_written);
-
- if (error != G_IO_ERROR_NONE)
- {
- fprintf (stderr, "Client write error (%s:%d): %d\n",
- client_state->name, client_state->port, error);
- goto error;
- }
-
- else if (bytes_written > 0)
- {
- guint old_watch_flags;
-
- /* Move the memory down some (you wouldn't want to do this
- in a performance server because it's slow!) */
- client_state->n -= bytes_written;
- g_memmove(client_state->buffer,
- &client_state->buffer[bytes_written],
- client_state->n);
-
- old_watch_flags = client_state->watch_flags;
-
- /* Remove OUT watch if done */
- if (client_state->n == 0)
- client_state->watch_flags &= ~G_IO_OUT;
-
- /* Add IN watch */
- client_state->watch_flags |= G_IO_IN;
-
- /* Update watch flags if they changed */
- if (old_watch_flags != client_state->watch_flags)
- {
- g_source_remove (client_state->watch);
- client_state->watch =
- g_io_add_watch(iochannel, client_state->watch_flags,
- async_client_iofunc, client_state);
- rv = FALSE;
- }
- }
}
return rv;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]