From 5bc4a01a5eee7264394ab2bf360ce76ffc80427f Mon Sep 17 00:00:00 2001 From: Sion Chaudhuri Date: Tue, 30 Apr 2013 00:20:52 -0700 Subject: [PATCH] Added generic buffer and queue implementation for audio buffering --- protocols/vnc/include/buffer.h | 64 +++++++++++++++++++++++++ protocols/vnc/include/queue.h | 42 +++++++++++++++++ protocols/vnc/src/buffer.c | 86 ++++++++++++++++++++++++++++++++++ protocols/vnc/src/queue.c | 71 ++++++++++++++++++++++++++++ 4 files changed, 263 insertions(+) create mode 100644 protocols/vnc/include/buffer.h create mode 100644 protocols/vnc/include/queue.h create mode 100644 protocols/vnc/src/buffer.c create mode 100644 protocols/vnc/src/queue.c diff --git a/protocols/vnc/include/buffer.h b/protocols/vnc/include/buffer.h new file mode 100644 index 00000000..c257201e --- /dev/null +++ b/protocols/vnc/include/buffer.h @@ -0,0 +1,64 @@ + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is buffer. + * + * The Initial Developers of the Original Code are + * Craig Hokanson + * Sion Chaudhuri + * Gio Perez + * + * Portions created by the Initial Developer are Copyright (C) 2013 + * the Initial Developers. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef __GUAC_VNC_BUFFER_H +#define __GUAC_VNC_BUFFER_H + +#include +#include +#include "queue.h" + +typedef struct { + queue data_queue; + pthread_mutex_t update_lock; + pthread_cond_t cond; +} buffer; + +void buffer_init(buffer* buf, int size_of_data); + +void buffer_free(buffer* buf); + +void buffer_close(buffer* buf); + +void buffer_insert(buffer* buf, void* data, int size_of_data); + +void buffer_remove(buffer* buf, void* data, int size_of_data, guac_client* client); + +#endif \ No newline at end of file diff --git a/protocols/vnc/include/queue.h b/protocols/vnc/include/queue.h new file mode 100644 index 00000000..be351290 --- /dev/null +++ b/protocols/vnc/include/queue.h @@ -0,0 +1,42 @@ + +/* ***** BEGIN LICENSE BLOCK ***** + * queue.c + * + * Implementation of a FIFO queue abstract data type. + * + * by: Steven Skiena + * begun: March 27, 2002 + * + * Copyright 2003 by Steven S. Skiena; all rights reserved. + * + * Permission is granted for use in non-commerical applications + * provided this copyright notice remains intact and unchanged. + * + * Modified for the Guacamole project by: + * Craig Hokanson + * Sion Chaudhuri + * Gio Perez + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef __GUAC_VNC_QUEUE_H +#define __GUAC_VNC_QUEUE_H + +#define QUEUESIZE 200 + +typedef struct { + void* items[QUEUESIZE+1]; /* body of queue */ + int first; /* position of first element */ + int last; /* position of last element */ + int count; /* number of queue elements */ +} queue; + +void queue_init(queue* q, int size_of_element); + +void queue_free(queue* q); + +int enqueue(queue* q, void* data, int size); + +int dequeue(queue* q, void* data, int size); + +#endif \ No newline at end of file diff --git a/protocols/vnc/src/buffer.c b/protocols/vnc/src/buffer.c new file mode 100644 index 00000000..5f5cbf97 --- /dev/null +++ b/protocols/vnc/src/buffer.c @@ -0,0 +1,86 @@ + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is buffer. + * + * The Initial Developers of the Original Code are + * Craig Hokanson + * Sion Chaudhuri + * Gio Perez + * + * Portions created by the Initial Developer are Copyright (C) 2013 + * the Initial Developers. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include +#include +#include "buffer.h" +#include "queue.h" + +void buffer_init(buffer* buf, int size_of_data) { + + queue_init(&(buf->data_queue), size_of_data); + +} + +void buffer_free(buffer* buf) { + + queue_free(&(buf->data_queue)); + +} + +void buffer_close(buffer* buf) { + + pthread_cond_signal(&(buf->cond)); + +} + +void buffer_insert(buffer* buf, void* data, int size_of_data) { + + pthread_mutex_lock(&(buf->update_lock)); + enqueue(&(buf->data_queue), data, size_of_data); + pthread_mutex_unlock(&(buf->update_lock)); + pthread_cond_signal(&(buf->cond)); + +} + +void buffer_remove(buffer* buf, void* data, int size_of_data, guac_client* client) { + + pthread_mutex_lock(&(buf->update_lock)); + if((buf->data_queue).count <= 0) + pthread_cond_wait(&(buf->cond), &(buf->update_lock)); + + /* If the thread was signaled during a close, + the queue might still be empty */ + if((buf->data_queue).count > 0) + dequeue(&(buf->data_queue), data, size_of_data); + + pthread_mutex_unlock(&(buf->update_lock)); + +} \ No newline at end of file diff --git a/protocols/vnc/src/queue.c b/protocols/vnc/src/queue.c new file mode 100644 index 00000000..de8768e9 --- /dev/null +++ b/protocols/vnc/src/queue.c @@ -0,0 +1,71 @@ + +/* ***** BEGIN LICENSE BLOCK ***** + * queue.c + * + * Implementation of a FIFO queue abstract data type. + * + * by: Steven Skiena + * begun: March 27, 2002 + * + * Copyright 2003 by Steven S. Skiena; all rights reserved. + * + * Permission is granted for use in non-commerical applications + * provided this copyright notice remains intact and unchanged. + * + * Modified for the Guacamole project by: + * Craig Hokanson + * Sion Chaudhuri + * Gio Perez + * + * ***** END LICENSE BLOCK ***** */ + +#include +#include +#include "queue.h" + +void queue_init(queue* q, int size_of_element) { + + int i; + + q->first = 0; + q->last = QUEUESIZE-1; + q->count = 0; + + for(i = 0; i < QUEUESIZE; i++) + q->items[i] = malloc(size_of_element); +} + +void queue_free(queue* q) { + + int i; + + for(i = 0; i < QUEUESIZE; i++) + free(q->items[i]); +} + + +int enqueue(queue* q, void* data, int size) { + + if (q->count >= QUEUESIZE) + return -1; + + q->last = (q->last+1) % QUEUESIZE; + memcpy(q->items[ q->last ], data, size); + q->count = q->count + 1; + + return 0; + +} + +int dequeue(queue* q, void* data, int size) { + + if (q->count <= 0) + return -1; + + memcpy(data, q->items[ q->first ], size); + q->first = (q->first+1) % QUEUESIZE; + q->count = q->count - 1; + + return 0; + +}