summaryrefslogtreecommitdiff
path: root/response.c
diff options
context:
space:
mode:
authorMichael J. Chudobiak <mjc@avtechpulse.com>2012-07-19 08:41:04 -0400
committerMichael J. Chudobiak <mjc@avtechpulse.com>2012-07-19 08:41:04 -0400
commit299b166ff820e8413f0c34ed5a2e7afac46cd477 (patch)
treeb0b8e1520af740e8a63fd132ebae82326054e12f /response.c
initial commit
Diffstat (limited to 'response.c')
-rw-r--r--response.c119
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);
+}