summaryrefslogtreecommitdiff
path: root/response.c.orig
blob: 93d38b3a929a6a8bf2ea0cf28228b5a718d567d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#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);
}