[xiph-commits] r8144 - in icecast/trunk/libshout: examples
include/shout src
brendan at motherfish-iii.xiph.org
brendan at motherfish-iii.xiph.org
Fri Oct 29 18:24:48 PDT 2004
Author: brendan
Date: 2004-10-29 18:24:47 -0700 (Fri, 29 Oct 2004)
New Revision: 8144
Added:
icecast/trunk/libshout/examples/nonblocking.c
Modified:
icecast/trunk/libshout/examples/Makefile.am
icecast/trunk/libshout/examples/example.c
icecast/trunk/libshout/include/shout/shout.h.in
icecast/trunk/libshout/src/shout.c
icecast/trunk/libshout/src/shout_private.h
Log:
Add shout_queuelen to expose the current length in bytes of the write queue.
To do this without having to recalculate, I had to create a queue structure to hold
the linked list itself and its length. Might be worth putting a pointer to the tail
here too.
Modified: icecast/trunk/libshout/examples/Makefile.am
===================================================================
--- icecast/trunk/libshout/examples/Makefile.am 2004-10-29 20:36:03 UTC (rev 8143)
+++ icecast/trunk/libshout/examples/Makefile.am 2004-10-30 01:24:47 UTC (rev 8144)
@@ -2,9 +2,13 @@
AUTOMAKE_OPTIONS = foreign
-noinst_PROGRAMS = example
+noinst_PROGRAMS = example nonblocking
example_SOURCES = example.c
example_LDADD = $(top_builddir)/src/libshout.la
+
+nonblocking_SOURCES = nonblocking.c
+nonblocking_LDADD = $(top_builddir)/src/libshout.la
+
AM_CFLAGS = @XIPH_CFLAGS@
AM_CPPFLAGS = @XIPH_CPPFLAGS@ -I$(top_builddir)/include
Modified: icecast/trunk/libshout/examples/example.c
===================================================================
--- icecast/trunk/libshout/examples/example.c 2004-10-29 20:36:03 UTC (rev 8143)
+++ icecast/trunk/libshout/examples/example.c 2004-10-30 01:24:47 UTC (rev 8144)
@@ -1,4 +1,6 @@
-/* example.c: Demonstration of the libshout API. */
+/* example.c: Demonstration of the libshout API.
+ * $Id$
+ */
#include <stdio.h>
#include <stdlib.h>
Property changes on: icecast/trunk/libshout/examples/example.c
___________________________________________________________________
Name: svn:keywords
+ Id
Added: icecast/trunk/libshout/examples/nonblocking.c
===================================================================
--- icecast/trunk/libshout/examples/nonblocking.c 2004-10-29 20:36:03 UTC (rev 8143)
+++ icecast/trunk/libshout/examples/nonblocking.c 2004-10-30 01:24:47 UTC (rev 8144)
@@ -0,0 +1,104 @@
+/* -*- c-basic-offset: 8; -*-
+ * example.c: Demonstration of the libshout API.
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <shout/shout.h>
+
+int main()
+{
+ shout_t *shout;
+ char buff[4096];
+ long read, ret, total;
+
+ shout_init();
+
+ if (!(shout = shout_new())) {
+ printf("Could not allocate shout_t\n");
+ return 1;
+ }
+
+ if (shout_set_host(shout, "127.0.0.1") != SHOUTERR_SUCCESS) {
+ printf("Error setting hostname: %s\n", shout_get_error(shout));
+ return 1;
+ }
+
+ if (shout_set_protocol(shout, SHOUT_PROTOCOL_HTTP) != SHOUTERR_SUCCESS) {
+ printf("Error setting protocol: %s\n", shout_get_error(shout));
+ return 1;
+ }
+
+ if (shout_set_port(shout, 8000) != SHOUTERR_SUCCESS) {
+ printf("Error setting port: %s\n", shout_get_error(shout));
+ return 1;
+ }
+
+ if (shout_set_password(shout, "hackme") != SHOUTERR_SUCCESS) {
+ printf("Error setting password: %s\n", shout_get_error(shout));
+ return 1;
+ }
+ if (shout_set_mount(shout, "/example.ogg") != SHOUTERR_SUCCESS) {
+ printf("Error setting mount: %s\n", shout_get_error(shout));
+ return 1;
+ }
+
+ if (shout_set_user(shout, "source") != SHOUTERR_SUCCESS) {
+ printf("Error setting user: %s\n", shout_get_error(shout));
+ return 1;
+ }
+
+ if (shout_set_format(shout, SHOUT_FORMAT_OGG) != SHOUTERR_SUCCESS) {
+ printf("Error setting user: %s\n", shout_get_error(shout));
+ return 1;
+ }
+
+ if (shout_set_nonblocking(shout, 1) != SHOUTERR_SUCCESS) {
+ printf("Error setting non-blocking mode: %s\n", shout_get_error(shout));
+ return 1;
+ }
+
+ ret = shout_open(shout);
+ if (ret == SHOUTERR_SUCCESS)
+ ret = SHOUTERR_CONNECTED;
+
+ while (ret == SHOUTERR_BUSY) {
+ printf("Connection pending. Sleeping...\n");
+ sleep(1);
+ ret = shout_get_connected(shout);
+ }
+
+ if (ret == SHOUTERR_CONNECTED) {
+ printf("Connected to server...\n");
+ total = 0;
+ while (1) {
+ read = fread(buff, 1, sizeof(buff), stdin);
+ total = total + read;
+
+ if (read > 0) {
+ ret = shout_send(shout, buff, read);
+ if (ret != SHOUTERR_SUCCESS) {
+ printf("DEBUG: Send error: %s\n", shout_get_error(shout));
+ break;
+ }
+ } else {
+ break;
+ }
+ if (shout_queuelen(shout) > 0)
+ printf("DEBUG: queue length: %d\n", shout_queuelen(shout));
+
+ shout_sync(shout);
+ }
+ } else {
+ printf("Error connecting: %s\n", shout_get_error(shout));
+ }
+
+ shout_close(shout);
+
+ shout_shutdown();
+
+ return 0;
+}
Property changes on: icecast/trunk/libshout/examples/nonblocking.c
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Modified: icecast/trunk/libshout/include/shout/shout.h.in
===================================================================
--- icecast/trunk/libshout/include/shout/shout.h.in 2004-10-29 20:36:03 UTC (rev 8143)
+++ icecast/trunk/libshout/include/shout/shout.h.in 2004-10-30 01:24:47 UTC (rev 8144)
@@ -159,12 +159,16 @@
*/
ssize_t shout_send_raw(shout_t *self, const unsigned char *data, size_t len);
+/* return the number of bytes currently on the write queue (only makes sense in
+ * nonblocking mode). */
+ssize_t shout_queuelen(shout_t *self);
+
/* Puts caller to sleep until it is time to send more data to the server */
void shout_sync(shout_t *self);
/* Amount of time in ms caller should wait before sending again */
int shout_delay(shout_t *self);
-
+
/* Sets MP3 metadata.
* Returns:
* SHOUTERR_SUCCESS
Modified: icecast/trunk/libshout/src/shout.c
===================================================================
--- icecast/trunk/libshout/src/shout.c 2004-10-29 20:36:03 UTC (rev 8143)
+++ icecast/trunk/libshout/src/shout.c 2004-10-30 01:24:47 UTC (rev 8144)
@@ -39,10 +39,10 @@
#include "util.h"
/* -- local prototypes -- */
-static int queue_data(shout_buf_t **queue, const unsigned char *data, size_t len);
+static int queue_data(shout_queue_t *queue, const unsigned char *data, size_t len);
static int queue_str(shout_t *self, const char *str);
static int queue_printf(shout_t *self, const char *fmt, ...);
-static void queue_free(shout_buf_t *queue);
+static void queue_free(shout_queue_t *queue);
static int send_queue(shout_t *self);
static int get_response(shout_t *self);
static int try_connect (shout_t *self);
@@ -202,7 +202,7 @@
self->error = SHOUTERR_SUCCESS;
/* send immediately if possible (should be the common case) */
- if (len && ! self->wqueue) {
+ if (len && ! self->wqueue.len) {
if ((ret = try_write(self, data, len)) < 0)
return self->error;
if (ret < len) {
@@ -225,6 +225,15 @@
return ret;
}
+ssize_t shout_queuelen(shout_t *self)
+{
+ if (!self)
+ return SHOUTERR_INSANE;
+
+ return (ssize_t)self->wqueue.len;
+}
+
+
void shout_sync(shout_t *self)
{
int64_t sleep;
@@ -771,7 +780,7 @@
/* -- static function definitions -- */
/* queue data in pages of SHOUT_BUFSIZE bytes */
-static int queue_data(shout_buf_t **queue, const unsigned char *data, size_t len)
+static int queue_data(shout_queue_t *queue, const unsigned char *data, size_t len)
{
shout_buf_t *buf;
size_t plen;
@@ -779,13 +788,13 @@
if (!len)
return SHOUTERR_SUCCESS;
- if (!*queue) {
- *queue = calloc(1, sizeof (shout_buf_t));
- if (! *queue)
+ if (!queue->len) {
+ queue->head = calloc(1, sizeof (shout_buf_t));
+ if (! queue->head)
return SHOUTERR_MALLOC;
}
- for (buf = *queue; buf->next; buf = buf->next);
+ for (buf = queue->head; buf->next; buf = buf->next);
/* Maybe any added data should be freed if we hit a malloc error?
* Otherwise it'd be impossible to tell where to start requeueing.
@@ -804,6 +813,7 @@
buf->len += plen;
data += plen;
len -= plen;
+ queue->len += plen;
}
return SHOUTERR_SUCCESS;
@@ -850,15 +860,16 @@
return self->error;
}
-static inline void queue_free(shout_buf_t *queue)
+static inline void queue_free(shout_queue_t *queue)
{
shout_buf_t *prev;
- while (queue) {
- prev = queue;
- queue = queue->next;
+ while (queue->head) {
+ prev = queue->head;
+ queue->head = queue->head->next;
free(prev);
}
+ queue->len = 0;
}
static int get_response(shout_t *self)
@@ -881,7 +892,7 @@
/* work from the back looking for \r?\n\r?\n. Anything else means more
* is coming. */
- for (queue = self->rqueue; queue->next; queue = queue->next);
+ for (queue = self->rqueue.head; queue->next; queue = queue->next);
pc = queue->data + queue->len - 1;
blen = queue->len;
while (blen) {
@@ -1028,20 +1039,21 @@
shout_buf_t *buf;
int ret;
- if (!self->wqueue)
+ if (!self->wqueue.len)
return SHOUTERR_SUCCESS;
- buf = self->wqueue;
+ buf = self->wqueue.head;
while (buf) {
ret = try_write (self, buf->data + buf->pos, buf->len - buf->pos);
if (ret < 0)
return self->error;
buf->pos += ret;
+ self->wqueue.len -= ret;
if (buf->pos == buf->len) {
- self->wqueue = buf->next;
+ self->wqueue.head = buf->next;
free(buf);
- buf = self->wqueue;
+ buf = self->wqueue.head;
if (buf)
buf->prev = NULL;
} else /* incomplete write */
@@ -1165,11 +1177,10 @@
#endif
/* all this copying! */
- hlen = collect_queue(self->rqueue, &header);
+ hlen = collect_queue(self->rqueue.head, &header);
if (hlen <= 0)
return SHOUTERR_MALLOC;
- queue_free(self->rqueue);
- self->rqueue = NULL;
+ queue_free(&self->rqueue);
parser = httpp_create_parser();
httpp_initialize(parser, NULL);
@@ -1228,10 +1239,9 @@
{
char *response;
- if (collect_queue(self->rqueue, &response) <= 0)
+ if (collect_queue(self->rqueue.head, &response) <= 0)
return SHOUTERR_MALLOC;
- queue_free(self->rqueue);
- self->rqueue = NULL;
+ queue_free(&self->rqueue);
if (!strstr(response, "OK")) {
free(response);
Modified: icecast/trunk/libshout/src/shout_private.h
===================================================================
--- icecast/trunk/libshout/src/shout_private.h 2004-10-29 20:36:03 UTC (rev 8143)
+++ icecast/trunk/libshout/src/shout_private.h 2004-10-30 01:24:47 UTC (rev 8144)
@@ -41,6 +41,11 @@
struct _shout_buf *next;
} shout_buf_t;
+typedef struct {
+ shout_buf_t *head;
+ size_t len;
+} shout_queue_t;
+
typedef enum {
SHOUT_STATE_UNCONNECTED = 0,
SHOUT_STATE_CONNECT_PENDING,
@@ -91,8 +96,8 @@
int (*send)(shout_t* self, const unsigned char* buff, size_t len);
void (*close)(shout_t* self);
- shout_buf_t *rqueue;
- shout_buf_t *wqueue;
+ shout_queue_t rqueue;
+ shout_queue_t wqueue;
/* start of this period's timeclock */
uint64_t starttime;
More information about the commits
mailing list