[gnet] Iterating the event loop within a callback



I'm trying to do something kind of strange here.  From previous list
communication, I know it's possible, but my test app does not work. 
Here's the logic flow:

on the main data call-back, if the routine sees a certain piece of data,
then it resets the data call-back to another call-back, asks for another
line of data, and then iterates the event loop (allowing the other
call-back to process data, and then return to the point in this
callback).  This of course, doesn't do anything.  I don't think it's
possible to do what I want the way I have done it (having browsed the
gnet code a bit).

My question is, how do I accomplish what  I want to do?  Again I want to
be able to, in the middle of a callback, ask for more data which will be
processed by a callback, and then return to the spot where I left off in
the original callback.

Attached is a short code segment that attempts to illustrate what I'm
trying to do.

thanks,

Michael

/* test program -- adapted from gnet example echo server
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <gnet.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <signal.h>
#include <fcntl.h>
#include <getopt.h>

static GServer* ob_server = NULL;
static void ob_sig_int (int signum);
static void
ob_sig_int (int signum)
{
  gnet_server_delete (ob_server);
  exit (EXIT_FAILURE);
}

/*in*
 * Private server functions
 **/
static void request_get_message (GConn *conn, 
                                 GConnEvent *event, 
                                 gpointer user_data);
static void request_get_extra_data (GConn *conn, 
                                 GConnEvent *event, 
                                 gpointer user_data);
static void
ob_server_func (GServer* server, GConn* conn, gpointer user_data);
int
main(int argc, char** argv)
{
	int port;
	GServer* server;
	GMainLoop* main_loop;
	int c;
	int digit_optind = 0;
	int option_index;
	int this_option_optind;

	gint flag;

	gnet_init ();

	/* Create the main loop */
	main_loop = g_main_new (FALSE);

	/* Create the server */
	server = gnet_server_new (NULL, 8899, ob_server_func, NULL);
	if (!server) {
		fprintf (stderr, "Error: Could not start server\n");
		exit (EXIT_FAILURE);
	}

	ob_server = server;
	signal (SIGINT, ob_sig_int);


	/* Start the main loop */
	g_main_run(main_loop);

	exit (EXIT_SUCCESS);
	return 0;
}


static void
ob_server_func (GServer* server, GConn* conn, gpointer user_data)
{

	gint *flag;

	if (conn) {
		g_log(G_LOG_DOMAIN,G_LOG_LEVEL_INFO,"Server connection");

		flag=g_malloc(sizeof(gint));
		*flag=0;

		gnet_conn_set_callback (conn, request_get_message,
		                        (gpointer)flag);
		gnet_conn_set_watch_error (conn, TRUE);

		/* make a connection to ldap, so we can proxy */
		gnet_conn_readline (conn);
	} else {
		/* Error */
		gnet_server_delete (server);
		exit (EXIT_FAILURE);
	}
}

static void request_get_message (GConn *conn,
                                    GConnEvent *event, 
                                    gpointer user_data)
{
	gint *flag;
	gchar *buffer[1024];


	flag=user_data;


	switch (event->type) {
	case GNET_CONN_READ:
		if(*flag > 1) {
			printf("got extra data\n");
			(*flag)--;
			gnet_conn_readline (conn);

		} else {
			event->buffer[event->length]=0; //dangerous
			g_print("received: %s\n",event->buffer);
			*flag = 1;
			if(!strncmp("ab",event->buffer,2)) {
				g_print("going to try for another line of data before I return\n");

				(*flag) = 2;
				while((*flag) > 1 ) {
					gnet_conn_set_callback (conn, request_get_extra_data,
		                        (gpointer)flag);
					gnet_conn_readline (conn);
					//iterate loop
					if(g_main_context_pending(NULL))
						g_main_context_iteration(NULL,FALSE);
//					else
//						g_print ("no events\n");
					g_usleep(500);
				}
				gnet_conn_set_callback (conn, request_get_message,
		                        (gpointer)flag);
				gnet_conn_readline (conn);
				printf("got extra data I wanted\n");
			}else {
				*flag=0;
				gnet_conn_readline (conn);
			}
		}
		break;
	case GNET_CONN_WRITE:
		/* Do nothing */
		break;
	case GNET_CONN_CLOSE:
	case GNET_CONN_TIMEOUT:
	case GNET_CONN_ERROR:
		gnet_conn_delete (conn);
		/* gotta do clean up in here, I think */
		break;
	default:
		g_assert_not_reached ();
	}
}

static void request_get_extra_data (GConn *conn,
                                   GConnEvent *event, 
                                   gpointer user_data)
{
	gint *flag;
	gchar *buffer[1024];


	flag=user_data;


	switch (event->type) {
	case GNET_CONN_READ:
		printf("got extra data\n");
		(*flag)--;
		gnet_conn_set_callback (conn, request_get_message,
		                        (gpointer)flag);
		break;
	case GNET_CONN_WRITE:
		/* Do nothing */
		break;
	case GNET_CONN_CLOSE:
	case GNET_CONN_TIMEOUT:
	case GNET_CONN_ERROR:
		gnet_conn_delete (conn);
		/* gotta do clean up in here, I think */
		break;
	default:
		g_assert_not_reached ();
	}

}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]