* Ed Schouten <[EMAIL PROTECTED]> wrote: > Maybe this evening I'll take a look if it's possible to delay the > opening of the stream when the `ss' argument is NULL, so I can call > pa_simple_new() to already instantiate the connection to the daemon > before the chroot() call.
Done. I did fix it in another way though. I split up the pa_simple_new() routine in two separate routines. The first one only opens the connection to the server and the latter creates the actual stream. So far it works quite good, with one nasty side-effect: it cannot unlink the shared memory at shutdown. I'm still thinking of a nice way to work around this. Anyway, here's a first version of the patch, which also makes the mmap() calls work on FreeBSD. Yours, -- Ed Schouten <[EMAIL PROTECTED]> WWW: http://g-rave.nl/
--- src/pulse/simple.c Fri Aug 18 23:29:25 2006
+++ src/pulse/simple.c Tue Jun 5 17:44:38 2007
@@ -136,27 +136,16 @@
pa_simple* pa_simple_new(
const char *server,
const char *name,
- pa_stream_direction_t dir,
- const char *dev,
- const char *stream_name,
- const pa_sample_spec *ss,
- const pa_channel_map *map,
- const pa_buffer_attr *attr,
int *rerror) {
pa_simple *p;
- int error = PA_ERR_INTERNAL, r;
+ int error = PA_ERR_INTERNAL;
CHECK_VALIDITY_RETURN_ANY(rerror, !server || *server, PA_ERR_INVALID, NULL);
- CHECK_VALIDITY_RETURN_ANY(rerror, dir == PA_STREAM_PLAYBACK || dir == PA_STREAM_RECORD, PA_ERR_INVALID, NULL);
- CHECK_VALIDITY_RETURN_ANY(rerror, !dev || *dev, PA_ERR_INVALID, NULL);
- CHECK_VALIDITY_RETURN_ANY(rerror, ss && pa_sample_spec_valid(ss), PA_ERR_INVALID, NULL);
- CHECK_VALIDITY_RETURN_ANY(rerror, !map || (pa_channel_map_valid(map) && map->channels == ss->channels), PA_ERR_INVALID, NULL)
p = pa_xnew(pa_simple, 1);
p->context = NULL;
p->stream = NULL;
- p->direction = dir;
p->read_data = NULL;
p->read_index = p->read_length = 0;
@@ -186,47 +175,84 @@
goto unlock_and_fail;
}
- if (!(p->stream = pa_stream_new(p->context, stream_name, ss, map))) {
- error = pa_context_errno(p->context);
+ pa_threaded_mainloop_unlock(p->mainloop);
+
+ return p;
+
+unlock_and_fail:
+ pa_threaded_mainloop_unlock(p->mainloop);
+
+fail:
+ if (rerror)
+ *rerror = error;
+ pa_simple_free(p);
+ return NULL;
+}
+
+int pa_simple_configure(
+ pa_simple *s,
+ pa_stream_direction_t dir,
+ const char *dev,
+ const char *stream_name,
+ const pa_sample_spec *ss,
+ const pa_channel_map *map,
+ const pa_buffer_attr *attr,
+ int *rerror) {
+
+ int error = PA_ERR_INTERNAL, r;
+
+ CHECK_VALIDITY_RETURN_ANY(rerror, dir == PA_STREAM_PLAYBACK || dir == PA_STREAM_RECORD, PA_ERR_INVALID, -1);
+ CHECK_VALIDITY_RETURN_ANY(rerror, !dev || *dev, PA_ERR_INVALID, -1);
+ CHECK_VALIDITY_RETURN_ANY(rerror, ss && pa_sample_spec_valid(ss), PA_ERR_INVALID, -1);
+ CHECK_VALIDITY_RETURN_ANY(rerror, !map || (pa_channel_map_valid(map) && map->channels == ss->channels), PA_ERR_INVALID, -1);
+
+ s->direction = dir;
+
+ pa_threaded_mainloop_lock(s->mainloop);
+
+ /* Close the original stream */
+ if (s->stream)
+ pa_stream_unref(s->stream);
+ if (!(s->stream = pa_stream_new(s->context, stream_name, ss, map))) {
+ error = pa_context_errno(s->context);
goto unlock_and_fail;
}
- pa_stream_set_state_callback(p->stream, stream_state_cb, p);
- pa_stream_set_read_callback(p->stream, stream_request_cb, p);
- pa_stream_set_write_callback(p->stream, stream_request_cb, p);
- pa_stream_set_latency_update_callback(p->stream, stream_latency_update_cb, p);
+ pa_stream_set_state_callback(s->stream, stream_state_cb, s);
+ pa_stream_set_read_callback(s->stream, stream_request_cb, s);
+ pa_stream_set_write_callback(s->stream, stream_request_cb, s);
+ pa_stream_set_latency_update_callback(s->stream, stream_latency_update_cb, s);
if (dir == PA_STREAM_PLAYBACK)
- r = pa_stream_connect_playback(p->stream, dev, attr, PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL);
+ r = pa_stream_connect_playback(s->stream, dev, attr, PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL);
else
- r = pa_stream_connect_record(p->stream, dev, attr, PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE);
+ r = pa_stream_connect_record(s->stream, dev, attr, PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE);
if (r < 0) {
- error = pa_context_errno(p->context);
+ error = pa_context_errno(s->context);
goto unlock_and_fail;
}
/* Wait until the stream is ready */
- pa_threaded_mainloop_wait(p->mainloop);
+ pa_threaded_mainloop_wait(s->mainloop);
/* Wait until the stream is ready */
- if (pa_stream_get_state(p->stream) != PA_STREAM_READY) {
- error = pa_context_errno(p->context);
+ if (pa_stream_get_state(s->stream) != PA_STREAM_READY) {
+ error = pa_context_errno(s->context);
goto unlock_and_fail;
}
- pa_threaded_mainloop_unlock(p->mainloop);
-
- return p;
+ pa_threaded_mainloop_unlock(s->mainloop);
+
+ return 0;
unlock_and_fail:
- pa_threaded_mainloop_unlock(p->mainloop);
+ pa_threaded_mainloop_unlock(s->mainloop);
fail:
if (rerror)
*rerror = error;
- pa_simple_free(p);
- return NULL;
+ return -1;
}
void pa_simple_free(pa_simple *s) {
--- src/pulse/simple.h Tue Jun 20 01:53:23 2006
+++ src/pulse/simple.h Tue Jun 5 17:39:11 2007
@@ -114,6 +114,12 @@
pa_simple* pa_simple_new(
const char *server, /**< Server name, or NULL for default */
const char *name, /**< A descriptive name for this client (application name, ...) */
+ int *error /**< A pointer where the error code is stored when the routine returns NULL. It is OK to pass NULL here. */
+ );
+
+/** Configure a connection to the server */
+int pa_simple_configure(
+ pa_simple *s, /**< Connection to the server */
pa_stream_direction_t dir, /**< Open this stream for recording or playback? */
const char *dev, /**< Sink (resp. source) name, or NULL for default */
const char *stream_name, /**< A descriptive name for this client (application name, song title, ...) */
--- src/pulsecore/shm.c Fri Aug 25 01:56:34 2006
+++ src/pulsecore/shm.c Tue Jun 5 19:24:35 2007
@@ -67,8 +67,8 @@
m->id = 0;
m->size = size;
-#ifdef MAP_ANONYMOUS
- if ((m->ptr = mmap(NULL, m->size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
+#ifdef MAP_ANON
+ if ((m->ptr = mmap(NULL, m->size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
pa_log("mmap() failed: %s", pa_cstrerror(errno));
goto fail;
}
@@ -140,7 +140,7 @@
#endif
if (!m->shared) {
-#ifdef MAP_ANONYMOUS
+#ifdef MAP_ANON
if (munmap(m->ptr, m->size) < 0)
pa_log("munmap() failed: %s", pa_cstrerror(errno));
#elif defined(HAVE_POSIX_MEMALIGN)
@@ -158,7 +158,7 @@
segment_name(fn, sizeof(fn), m->id);
- if (shm_unlink(fn) < 0)
+ if (shm_unlink(fn) < 0 && errno != ENOENT)
pa_log(__FILE__":shm_unlink(%s) failed: %s", fn, pa_cstrerror(errno));
}
#else
@@ -251,7 +251,7 @@
goto fail;
}
- m->do_unlink = 0;
+ m->do_unlink = 1;
m->shared = 1;
close(fd);
--- src/tests/pacat-simple.c Fri Aug 18 23:29:26 2006
+++ src/tests/pacat-simple.c Tue Jun 5 17:54:19 2007
@@ -66,8 +66,12 @@
}
/* Create a new playback stream */
- if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, NULL, &error))) {
+ if (!(s = pa_simple_new(NULL, argv[0], &error))) {
fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
+ goto finish;
+ }
+ if (pa_simple_configure(s, PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, NULL, &error) != 0) {
+ fprintf(stderr, __FILE__": pa_simple_configure() failed: %s\n", pa_strerror(error));
goto finish;
}
--- src/tests/parec-simple.c Fri Aug 18 23:29:26 2006
+++ src/tests/parec-simple.c Tue Jun 5 17:52:47 2007
@@ -67,8 +67,12 @@
int error;
/* Create the recording stream */
- if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error))) {
+ if (!(s = pa_simple_new(NULL, argv[0], &error))) {
fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
+ goto finish;
+ }
+ if (pa_simple_configure(s, PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error) != 0) {
+ fprintf(stderr, __FILE__": pa_simple_configure() failed: %s\n", pa_strerror(error));
goto finish;
}
pgpB4APaY5Oq2.pgp
Description: PGP signature
_______________________________________________ pulseaudio-discuss mailing list [email protected] https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss
