mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-12-19 08:57:00 -05:00
* 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
This commit is contained in:
parent
eef235d879
commit
8641af3c6d
11 changed files with 240 additions and 145 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue