Re: [gupnp] handling of sequence numbers in gupnp-service-proxy.c
- From: Sven Neumann <s neumann phase-zero de>
- To: gupnp o-hand com
- Subject: Re: [gupnp] handling of sequence numbers in gupnp-service-proxy.c
- Date: Thu, 26 Mar 2009 13:12:48 +0100
Hi,
On Wed, 2009-03-25 at 20:04 +0200, Zeeshan Ali (Khattak) wrote:
> > If we receive messages out-of-order, does that really mean that we have
> > missed a message? Isn't it possible that the message order is changed
> > due to asynchronous code?
>
> No, that will only happen because of some bug in libsoup since
> SoupServer is guaranteed to call the server_handler for each message
> synchronously as they arrive (assuming they are on the same
> connection, which afaik is true in our case). I am telling you this
> after confirming my assumption with Dan Winship on IRC.
Attached is a small test case that my colleague wrote. It sets up a
SoupServer listening on a local port and then uses a SoupSession to send
messages to this port. These messages have a sequence number and a
random payload of up to 5MB. The server looks at the sequence number of
the incoming messages and will abort if the messages are received out of
order. This test fails reliably after a few messages.
As far as I can see this setup is comparable to what GUPnP does. So is
this really a bug in libsoup? I think not. IMO the bug is that
GUPnPService makes a wrong assumption about the libsoup behavior here.
Or is there something wrong about our test case?
Sven
PKGS = libsoup-2.4
CFLAGS = `pkg-config --cflags $(PKGS)` -O0 -g -Wall
LDFLAGS = `pkg-config --libs $(PKGS)`
OBJS = Outrunner.o
TARGET = Outrunner
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
$(TARGET): $(OBJS)
$(CC) $(LDFLAGS) $(OBJS) -o $@
all: $(TARGET)
clean:
rm -f $(OBJS) $(TARGET)
//============================================================================
// Name : Outrunner.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Proof of two soup messages, outrunning each other
//============================================================================
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <libsoup/soup.h>
static GMainLoop *theMainLoop = NULL;
static int latestReceivedNumber = 0;
static int latestSentNumber = 0;
static guint port = 49152; // first port to try
static void
server_callback (SoupServer *soup_server,
SoupMessage *msg)
{
const char *sequenceNumber;
int number;
sequenceNumber = soup_message_headers_get (msg->request_headers,
"SequenceNumber");
number = atoi (sequenceNumber);
g_printerr (" %d", number);
g_assert (number > latestReceivedNumber);
latestReceivedNumber = number;
}
static gboolean
queueSomeMessages (SoupSession *session)
{
GRand *rand = g_rand_new_with_seed (time (NULL));
gint i;
char txt[128];
for (i = 0; i < 10; i++)
{
SoupMessage *msg;
int len;
sprintf (txt, "http://localhost:%d", port);
msg = soup_message_new ("GET", txt);
sprintf (txt, "%d", ++latestSentNumber);
soup_message_headers_append (msg->request_headers, "SequenceNumber", txt);
soup_session_queue_message (session, msg, NULL, NULL);
// append a body with random length
len = g_rand_int_range (rand, 10, 1024 * 1024 * 5);
soup_message_body_append (msg->request_body,
SOUP_MEMORY_TAKE, g_malloc (len), len);
}
g_rand_free (rand);
return TRUE; // infinite, until the error occurs
}
static void
quit (int sig)
{
if (theMainLoop)
{
g_main_loop_quit (theMainLoop);
theMainLoop = NULL;
}
}
int
main (void)
{
SoupServer *server;
SoupSession *session;
signal(SIGINT, quit);
g_type_init ();
g_thread_init (NULL);
do
{
server = soup_server_new (SOUP_SERVER_PORT, ++port, NULL);
}
while (!server && port < 55000);
if (server)
{
soup_server_add_handler (server, NULL,
(SoupServerCallback) server_callback,
NULL, NULL);
soup_server_run_async (server);
}
session = soup_session_async_new ();
theMainLoop = g_main_loop_new (NULL, FALSE);
g_idle_add ((GSourceFunc) &queueSomeMessages, session);
g_main_loop_run (theMainLoop);
g_main_loop_unref (theMainLoop);
return EXIT_SUCCESS;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]