summaryrefslogtreecommitdiffstats
path: root/polyp/protocol-esound.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2004-11-18 20:50:44 +0000
committerLennart Poettering <lennart@poettering.net>2004-11-18 20:50:44 +0000
commit8641af3c6d11e3e6710cb946e9a93d0e9f639519 (patch)
treece72b56c7460fed94808ee8023fad89df27c7e12 /polyp/protocol-esound.c
parenteef235d8795df740eb63cb135bd187b7ab9ac4ea (diff)
* some iochannel fixes
* introduce reference counting in ioline * fix memory leak in socket-client.c * fix double-free error in protocol-esound.c git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@293 fefdeb5f-60dc-0310-8127-8f9354f1896f
Diffstat (limited to 'polyp/protocol-esound.c')
-rw-r--r--polyp/protocol-esound.c73
1 files changed, 44 insertions, 29 deletions
diff --git a/polyp/protocol-esound.c b/polyp/protocol-esound.c
index 11a33315..a32a9bd8 100644
--- a/polyp/protocol-esound.c
+++ b/polyp/protocol-esound.c
@@ -267,8 +267,10 @@ static int esd_proto_connect(struct connection *c, esd_proto_t request, const vo
}
c->authorized = 1;
- if (c->auth_timeout_event)
+ if (c->auth_timeout_event) {
c->protocol->core->mainloop->time_free(c->auth_timeout_event);
+ c->auth_timeout_event = NULL;
+ }
}
ekey = *(uint32_t*)((uint8_t*) data+ESD_KEY_LEN);
@@ -301,11 +303,13 @@ static int esd_proto_stream_play(struct connection *c, esd_proto_t request, cons
ss.rate = rate;
format_esd2native(format, &ss);
- if (!pa_sample_spec_valid(&ss))
+ if (!pa_sample_spec_valid(&ss)) {
+ pa_log(__FILE__": invalid sample specification\n");
return -1;
+ }
if (!(sink = pa_namereg_get(c->protocol->core, c->protocol->sink_name, PA_NAMEREG_SINK, 1))) {
- pa_log(__FILE__": No output sink\n");
+ pa_log(__FILE__": no such sink\n");
return -1;
}
@@ -314,17 +318,17 @@ static int esd_proto_stream_play(struct connection *c, esd_proto_t request, cons
pa_client_set_name(c->client, name);
- assert(!c->input_memblockq);
+ assert(!c->sink_input && !c->input_memblockq);
+
+ if (!(c->sink_input = pa_sink_input_new(sink, name, &ss, 0, -1))) {
+ pa_log(__FILE__": failed to create sink input.\n");
+ return -1;
+ }
l = (size_t) (pa_bytes_per_second(&ss)*PLAYBACK_BUFFER_SECONDS);
c->input_memblockq = pa_memblockq_new(l, 0, pa_frame_size(&ss), l/2, l/PLAYBACK_BUFFER_FRAGMENTS, c->protocol->core->memblock_stat);
- assert(c->input_memblockq);
pa_iochannel_socket_set_rcvbuf(c->io, l/PLAYBACK_BUFFER_FRAGMENTS*2);
c->playback.fragment_size = l/10;
-
- assert(!c->sink_input);
- c->sink_input = pa_sink_input_new(sink, name, &ss, 0, -1);
- assert(c->sink_input);
c->sink_input->owner = c->protocol->module;
c->sink_input->client = c->client;
@@ -355,22 +359,30 @@ static int esd_proto_stream_record(struct connection *c, esd_proto_t request, co
ss.rate = rate;
format_esd2native(format, &ss);
- if (!pa_sample_spec_valid(&ss))
+ if (!pa_sample_spec_valid(&ss)) {
+ pa_log(__FILE__": invalid sample specification.\n");
return -1;
+ }
if (request == ESD_PROTO_STREAM_MON) {
struct pa_sink* sink;
- if (!(sink = pa_namereg_get(c->protocol->core, c->protocol->sink_name, PA_NAMEREG_SINK, 1)))
+ if (!(sink = pa_namereg_get(c->protocol->core, c->protocol->sink_name, PA_NAMEREG_SINK, 1))) {
+ pa_log(__FILE__": no such sink.\n");
return -1;
+ }
- if (!(source = sink->monitor_source))
+ if (!(source = sink->monitor_source)) {
+ pa_log(__FILE__": no such monitor source.\n");
return -1;
+ }
} else {
assert(request == ESD_PROTO_STREAM_REC);
- if (!(source = pa_namereg_get(c->protocol->core, c->protocol->source_name, PA_NAMEREG_SOURCE, 1)))
+ if (!(source = pa_namereg_get(c->protocol->core, c->protocol->source_name, PA_NAMEREG_SOURCE, 1))) {
+ pa_log(__FILE__": no such source.\n");
return -1;
+ }
}
strncpy(name, (char*) data + sizeof(int)*2, sizeof(name));
@@ -378,17 +390,17 @@ static int esd_proto_stream_record(struct connection *c, esd_proto_t request, co
pa_client_set_name(c->client, name);
- assert(!c->output_memblockq);
+ assert(!c->output_memblockq && !c->source_output);
+
+ if (!(c->source_output = pa_source_output_new(source, name, &ss, -1))) {
+ pa_log(__FILE__": failed to create source output\n");
+ return -1;
+ }
l = (size_t) (pa_bytes_per_second(&ss)*RECORD_BUFFER_SECONDS);
c->output_memblockq = pa_memblockq_new(l, 0, pa_frame_size(&ss), 0, 0, c->protocol->core->memblock_stat);
- assert(c->output_memblockq);
pa_iochannel_socket_set_sndbuf(c->io, l/RECORD_BUFFER_FRAGMENTS*2);
- assert(!c->source_output);
- c->source_output = pa_source_output_new(source, name, &ss, -1);
- assert(c->source_output);
-
c->source_output->owner = c->protocol->module;
c->source_output->client = c->client;
c->source_output->push = source_output_push_cb;
@@ -829,8 +841,8 @@ static int do_read(struct connection *c) {
pa_log(__FILE__": read() failed: %s\n", r == 0 ? "EOF" : strerror(errno));
return -1;
}
-
-/* pa_log(__FILE__": read %u\n", r); */
+
+/* pa_log(__FILE__": read %u\n", r); */
chunk.memblock = c->playback.current_memblock;
chunk.index = c->playback.memblock_index;
@@ -880,7 +892,7 @@ static int do_write(struct connection *c) {
pa_log(__FILE__": write(): %s\n", strerror(errno));
return -1;
}
-
+
pa_memblockq_drop(c->output_memblockq, &chunk, r);
pa_memblock_unref(chunk.memblock);
}
@@ -894,18 +906,21 @@ static void do_work(struct connection *c) {
assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable);
c->protocol->core->mainloop->defer_enable(c->defer_event, 0);
-/* pa_log("DOWORK\n"); */
-
- if (c->dead || !c->io)
- return;
+/* pa_log("DOWORK %i\n", pa_iochannel_is_hungup(c->io)); */
- if (pa_iochannel_is_readable(c->io))
+ if (!c->dead && pa_iochannel_is_readable(c->io))
if (do_read(c) < 0)
goto fail;
-
- if (pa_iochannel_is_writable(c->io))
+
+ if (!c->dead && pa_iochannel_is_writable(c->io))
if (do_write(c) < 0)
goto fail;
+
+ /* In case the line was hungup, make sure to rerun this function
+ as soon as possible, until all data has been read. */
+
+ if (!c->dead && pa_iochannel_is_hungup(c->io))
+ c->protocol->core->mainloop->defer_enable(c->defer_event, 1);
return;