#include "response.h" #include "socket-common.h" #include #include //RESPONSE related functions from the server extern guint signalMyCb; //signal id extern GAsyncQueue* stdinQueue; //our queue SignalObject* signalObject; //the signal object which registered the signal id //write output to client static gssize writeOutput(GPollableOutputStream* stream, gchar* data, gssize size); //callback for client output, this is where the queue messages are sent to the client gboolean cbClientOutput(gpointer data, gpointer additional) { GPollableOutputStream* outStream = (GPollableOutputStream*)data; GAsyncQueue* queue = (GAsyncQueue*)additional; if(g_async_queue_length(queue) <= 0) { return FALSE; } gpointer elem; g_print_debug("Try pop\n"); //try to pop an element from the queue elem=g_async_queue_try_pop(queue); g_print_debug("after pop\n"); if(elem) { char* buf = (char*)elem; g_print_debug("Extracted %s\n", buf); gssize size = strlen(buf); gssize written = 0; written=g_pollable_output_stream_write_nonblocking(outStream, buf, size+1, NULL, NULL); if(written==-1) { g_printerr("Could not write to client\n"); } //free the alloc'ed memory free(buf); } return FALSE; } //the client input callback gboolean cbClientInput(gpointer data, gpointer additional) { char buffer[1024]; gssize size=0; memset(buffer,0,1024); GPollableInputStream* inStream = (GPollableInputStream*)data; GPollableOutputStream* outStream = (GPollableOutputStream*)additional; size=g_pollable_input_stream_read_nonblocking(inStream, buffer, 1024, NULL, NULL); if(size <=0 || size == G_IO_ERROR_WOULD_BLOCK) { g_print_debug("Got: %d\n", size); return FALSE; } //emit a signal which calls the echoCb function SignalObjectClass myStruct; myStruct.instance = NULL; myStruct.cb = writeOutput; myStruct.data = buffer; myStruct.size = size; myStruct.inStream = inStream; myStruct.outStream = outStream; g_signal_emit(signalObject, signalMyCb, 0, &myStruct, NULL); return TRUE; } //write output to client static gssize writeOutput(GPollableOutputStream* stream, gchar* data, gssize size) { gssize what=0; what=g_pollable_output_stream_write_nonblocking(stream, data, size, NULL, NULL); if(what < 0 || what == G_IO_ERROR_WOULD_BLOCK) { return -1; } return what; } //initialize the signals void initSignals(guint *signal) { *signal = g_signal_new("runEchoService", SIGNAL_OBJECT_TYPE, G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__POINTER , G_TYPE_NONE, 1, G_TYPE_POINTER); signalObject = g_object_new(SIGNAL_OBJECT_TYPE, NULL); g_signal_connect (signalObject, "runEchoService", G_CALLBACK (echoCb), NULL); } //echo 3 times and send to client one time void echoCb(gpointer instance, GObject *arg1, gpointer user_data) { static GStaticMutex mutex = G_STATIC_MUTEX_INIT; g_static_mutex_lock (&mutex); SignalObjectClass *data = (SignalObjectClass*)arg1; GPollableOutputStream* stream = (GPollableOutputStream*)data->outStream; gchar* str = data->data; gssize len = data->size; gssize written = 0; gchar* upper = g_ascii_strup(str, len); int i; for(i=0; i<3; i++) { g_print("%s\n", upper); } //send response back to client written = data->cb(stream, upper, len); g_free(upper); g_static_mutex_unlock (&mutex); }