diff options
author | Michael J. Chudobiak <mjc@avtechpulse.com> | 2012-07-19 08:41:04 -0400 |
---|---|---|
committer | Michael J. Chudobiak <mjc@avtechpulse.com> | 2012-07-19 08:41:04 -0400 |
commit | 299b166ff820e8413f0c34ed5a2e7afac46cd477 (patch) | |
tree | b0b8e1520af740e8a63fd132ebae82326054e12f /response.c |
initial commit
Diffstat (limited to 'response.c')
-rw-r--r-- | response.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/response.c b/response.c new file mode 100644 index 0000000..1246f0b --- /dev/null +++ b/response.c @@ -0,0 +1,119 @@ +#include "response.h" +#include "socket-common.h" +#include <string.h> + +//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); +} |