-- cgit From 00da37f2c448096cdd54481b072db47b2f253141 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 11 Jun 2007 12:08:37 +0000 Subject: Merge HUGE set of changes temporarily into a branch, to allow me to move them from one machine to another (lock-free and stuff) git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1469 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 118 ++++--- src/modules/module-alsa-sink.c | 12 +- src/modules/module-alsa-source.c | 10 +- src/modules/module-esound-sink.c | 11 +- src/modules/module-jack-sink.c | 5 +- src/modules/module-jack-source.c | 7 +- src/modules/module-null-sink.c | 194 ++++++++--- src/modules/module-oss-mmap.c | 4 +- src/modules/module-oss.c | 22 +- src/modules/module-pipe-sink.c | 289 +++++++++++------ src/modules/module-pipe-source.c | 13 +- src/modules/module-sine.c | 12 +- src/modules/rtp/rtp.c | 18 +- src/pulse/internal.h | 1 + src/pulse/stream.c | 18 +- src/pulse/xmalloc.h | 9 + src/pulsecore/asyncmsgq.c | 235 ++++++++++++++ src/pulsecore/asyncmsgq.h | 73 +++++ src/pulsecore/asyncq.c | 271 ++++++++++++++++ src/pulsecore/asyncq.h | 56 ++++ src/pulsecore/atomic.h | 20 +- src/pulsecore/cli-command.c | 63 +++- src/pulsecore/cli-text.c | 64 +++- src/pulsecore/core-def.h | 5 +- src/pulsecore/core.c | 64 +++- src/pulsecore/core.h | 16 +- src/pulsecore/flist.c | 41 ++- src/pulsecore/flist.h | 20 ++ src/pulsecore/hashmap.h | 4 +- src/pulsecore/idxset.c | 1 + src/pulsecore/idxset.h | 5 - src/pulsecore/macro.h | 80 +++++ src/pulsecore/mcalign.c | 10 +- src/pulsecore/memblock.c | 427 ++++++++++++++++++++----- src/pulsecore/memblock.h | 61 ++-- src/pulsecore/memblockq.c | 10 +- src/pulsecore/memchunk.c | 15 +- src/pulsecore/msgobject.c | 40 +++ src/pulsecore/msgobject.h | 52 +++ src/pulsecore/mutex-posix.c | 2 - src/pulsecore/object.c | 61 ++++ src/pulsecore/object.h | 72 +++++ src/pulsecore/once-posix.c | 74 +++-- src/pulsecore/once.h | 12 +- src/pulsecore/play-memblockq.c | 2 - src/pulsecore/play-memchunk.c | 4 +- src/pulsecore/protocol-esound.c | 35 +- src/pulsecore/protocol-native.c | 14 +- src/pulsecore/protocol-simple.c | 306 +++++++++++++----- src/pulsecore/pstream.c | 158 ++++----- src/pulsecore/refcnt.h | 10 +- src/pulsecore/resampler.c | 239 +++++++------- src/pulsecore/sample-util.c | 116 +++++-- src/pulsecore/sample-util.h | 3 +- src/pulsecore/semaphore-posix.c | 69 ++++ src/pulsecore/semaphore.h | 35 ++ src/pulsecore/sink-input.c | 657 +++++++++++++++++++++----------------- src/pulsecore/sink-input.h | 83 +++-- src/pulsecore/sink.c | 484 +++++++++++++++++----------- src/pulsecore/sink.h | 114 ++++--- src/pulsecore/sound-file-stream.c | 8 +- src/pulsecore/sound-file.c | 15 +- src/pulsecore/source-output.c | 324 ++++++++++--------- src/pulsecore/source-output.h | 59 +++- src/pulsecore/source.c | 377 +++++++++++++--------- src/pulsecore/source.h | 106 ++++-- src/pulsecore/thread-posix.c | 61 ++-- src/tests/asyncmsgq-test.c | 110 +++++++ src/tests/asyncq-test.c | 87 +++++ src/tests/mcalign-test.c | 17 +- src/tests/memblock-test.c | 20 +- src/tests/memblockq-test.c | 4 +- 72 files changed, 4368 insertions(+), 1746 deletions(-) create mode 100644 src/pulsecore/asyncmsgq.c create mode 100644 src/pulsecore/asyncmsgq.h create mode 100644 src/pulsecore/asyncq.c create mode 100644 src/pulsecore/asyncq.h create mode 100644 src/pulsecore/macro.h create mode 100644 src/pulsecore/msgobject.c create mode 100644 src/pulsecore/msgobject.h create mode 100644 src/pulsecore/object.c create mode 100644 src/pulsecore/object.h create mode 100644 src/pulsecore/semaphore-posix.c create mode 100644 src/pulsecore/semaphore.h create mode 100644 src/tests/asyncmsgq-test.c create mode 100644 src/tests/asyncq-test.c diff --git a/src/Makefile.am b/src/Makefile.am index d90361f3..eab465c8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -78,13 +78,15 @@ if OS_IS_WIN32 PA_THREAD_OBJS = \ pulsecore/once-win32.c pulsecore/once.h \ pulsecore/mutex-win32.c pulsecore/mutex.h \ - pulsecore/thread-win32.c pulsecore/thread.h + pulsecore/thread-win32.c pulsecore/thread.h \ + pulsecore/semaphore-win32.c pulsecore/semaphore.h else PA_THREAD_OBJS = \ pulsecore/atomic.h \ pulsecore/once-posix.c pulsecore/once.h \ pulsecore/mutex-posix.c pulsecore/mutex.h \ - pulsecore/thread-posix.c pulsecore/thread.h + pulsecore/thread-posix.c pulsecore/thread.h \ + pulsecore/semaphore-posix.c pulsecore/semaphore.h endif ################################### @@ -219,7 +221,9 @@ noinst_PROGRAMS = \ hook-list-test \ memblock-test \ thread-test \ - flist-test + flist-test \ + asyncq-test \ + asyncmsgq-test if HAVE_SIGXCPU noinst_PROGRAMS += \ @@ -274,13 +278,21 @@ thread_test_CFLAGS = $(AM_CFLAGS) thread_test_LDADD = $(AM_LDADD) libpulsecore.la thread_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) -flist_test_SOURCES = tests/flist-test.c \ - pulsecore/atomic.h \ - pulsecore/flist.c pulsecore/flist.h +flist_test_SOURCES = tests/flist-test.c flist_test_CFLAGS = $(AM_CFLAGS) flist_test_LDADD = $(AM_LDADD) libpulsecore.la flist_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) +asyncq_test_SOURCES = tests/asyncq-test.c pulsecore/thread-posix.c pulsecore/thread.h pulsecore/asyncq.c pulsecore/asyncq.h pulsecore/core-util.c pulsecore/core-util.h pulse/xmalloc.c pulse/xmalloc.h pulsecore/log.h pulsecore/log.c pulsecore/core-error.h pulsecore/core-error.c pulsecore/once-posix.c pulsecore/once.h pulsecore/mutex-posix.c pulsecore/mutex.h pulse/utf8.c pulse/utf8.h pulse/util.h pulse/util.c +asyncq_test_CFLAGS = $(AM_CFLAGS) +asyncq_test_LDADD = $(AM_LDADD) #libpulsecore.la +asyncq_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + +asyncmsgq_test_SOURCES = tests/asyncmsgq-test.c pulsecore/thread-posix.c pulsecore/thread.h pulsecore/asyncq.c pulsecore/asyncq.h pulsecore/asyncmsgq.c pulsecore/asyncmsgq.h pulsecore/core-util.c pulsecore/core-util.h pulse/xmalloc.c pulse/xmalloc.h pulsecore/log.h pulsecore/log.c pulsecore/core-error.h pulsecore/core-error.c pulsecore/once-posix.c pulsecore/once.h pulsecore/mutex-posix.c pulsecore/mutex.h pulse/utf8.c pulse/utf8.h pulse/util.h pulse/util.c pulsecore/semaphore.h pulsecore/semaphore-posix.c pulsecore/flist.h pulsecore/flist.c +asyncmsgq_test_CFLAGS = $(AM_CFLAGS) +asyncmsgq_test_LDADD = $(AM_LDADD) #libpulsecore.la +asyncmsgq_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + mcalign_test_SOURCES = tests/mcalign-test.c mcalign_test_CFLAGS = $(AM_CFLAGS) mcalign_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecore.la @@ -455,6 +467,9 @@ libpulse_la_SOURCES += \ pulsecore/core-error.c pulsecore/core-error.h \ pulsecore/winsock.h pulsecore/creds.h \ pulsecore/shm.c pulsecore/shm.h \ + pulsecore/flist.c pulsecore/flist.h \ + pulsecore/object.c pulsecore/object.h \ + pulsecore/msgobject.c pulsecore/msgobject.h \ $(PA_THREAD_OBJS) if OS_IS_WIN32 @@ -567,6 +582,7 @@ pulsecoreinclude_HEADERS = \ pulsecore/refcnt.h \ pulsecore/mutex.h \ pulsecore/thread.h \ + pulsecore/semaphore.h \ pulsecore/once.h lib_LTLIBRARIES += libpulsecore.la @@ -636,6 +652,8 @@ libpulsecore_la_SOURCES += \ pulsecore/core-error.c pulsecore/core-error.h \ pulsecore/hook-list.c pulsecore/hook-list.h \ pulsecore/shm.c pulsecore/shm.h \ + pulsecore/flist.c pulsecore/flist.h \ + pulsecore/anotify.c pulsecore/anotify.h \ $(PA_THREAD_OBJS) if OS_IS_WIN32 @@ -851,34 +869,34 @@ modlibexec_LTLIBRARIES += \ module-cli.la \ module-cli-protocol-tcp.la \ module-simple-protocol-tcp.la \ - module-esound-protocol-tcp.la \ - module-native-protocol-tcp.la \ - module-native-protocol-fd.la \ - module-sine.la \ - module-combine.la \ - module-tunnel-sink.la \ - module-tunnel-source.la \ - module-null-sink.la \ - module-esound-sink.la \ - module-http-protocol-tcp.la \ - module-detect.la \ - module-volume-restore.la \ - module-rescue-streams.la + module-null-sink.la +# module-esound-protocol-tcp.la \ +# module-native-protocol-tcp.la \ +# module-native-protocol-fd.la \ +# module-sine.la \ +# module-combine.la \ +# module-tunnel-sink.la \ +# module-tunnel-source.la \ +# module-esound-sink.la \ +# module-http-protocol-tcp.la \ +# module-detect.la \ +# module-volume-restore.la \ +# module-rescue-streams.la # See comment at librtp.la above -if !OS_IS_WIN32 -modlibexec_LTLIBRARIES += \ - module-rtp-send.la \ - module-rtp-recv.la -endif +#if !OS_IS_WIN32 +#modlibexec_LTLIBRARIES += \ +# module-rtp-send.la \ +# module-rtp-recv.la +#endif if HAVE_AF_UNIX modlibexec_LTLIBRARIES += \ module-cli-protocol-unix.la \ - module-simple-protocol-unix.la \ - module-esound-protocol-unix.la \ - module-native-protocol-unix.la \ - module-http-protocol-unix.la + module-simple-protocol-unix.la +# module-esound-protocol-unix.la \ +# module-native-protocol-unix.la \ +# module-http-protocol-unix.la endif if HAVE_MKFIFO @@ -887,11 +905,11 @@ modlibexec_LTLIBRARIES += \ module-pipe-source.la endif -if !OS_IS_WIN32 -modlibexec_LTLIBRARIES += \ - module-esound-compat-spawnfd.la \ - module-esound-compat-spawnpid.la -endif +#if !OS_IS_WIN32 +#modlibexec_LTLIBRARIES += \ +# module-esound-compat-spawnfd.la \ +# module-esound-compat-spawnpid.la +#endif if HAVE_REGEX modlibexec_LTLIBRARIES += \ @@ -904,19 +922,19 @@ modlibexec_LTLIBRARIES += \ module-x11-publish.la endif -if HAVE_OSS -modlibexec_LTLIBRARIES += \ - liboss-util.la \ - module-oss.la \ - module-oss-mmap.la -endif +#if HAVE_OSS +#modlibexec_LTLIBRARIES += \ +# liboss-util.la \ +# module-oss.la \ +# module-oss-mmap.la +#endif -if HAVE_ALSA -modlibexec_LTLIBRARIES += \ - libalsa-util.la \ - module-alsa-sink.la \ - module-alsa-source.la -endif +#if HAVE_ALSA +#modlibexec_LTLIBRARIES += \ +# libalsa-util.la \ +# module-alsa-sink.la \ +# module-alsa-source.la +#endif if HAVE_SOLARIS modlibexec_LTLIBRARIES += \ @@ -938,11 +956,11 @@ modlibexec_LTLIBRARIES += \ module-mmkbd-evdev.la endif -if HAVE_JACK -modlibexec_LTLIBRARIES += \ - module-jack-sink.la \ - module-jack-source.la -endif +#if HAVE_JACK +#modlibexec_LTLIBRARIES += \ +# module-jack-sink.la \ +# module-jack-source.la +#endif if HAVE_GCONF modlibexec_LTLIBRARIES += \ diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 3d9f7577..f9c4efd4 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -174,6 +174,7 @@ static void do_write(struct userdata *u) { update_usage(u); for (;;) { + void *p; pa_memchunk *memchunk = NULL; snd_pcm_sframes_t frames; @@ -185,14 +186,15 @@ static void do_write(struct userdata *u) { else memchunk = &u->memchunk; } - assert(memchunk->memblock); - assert(memchunk->memblock->data); assert(memchunk->length); - assert(memchunk->memblock->length); assert((memchunk->length % u->frame_size) == 0); - if ((frames = snd_pcm_writei(u->pcm_handle, (uint8_t*) memchunk->memblock->data + memchunk->index, memchunk->length / u->frame_size)) < 0) { + p = pa_memblock_acquire(memchunk->memblock); + + if ((frames = snd_pcm_writei(u->pcm_handle, (uint8_t*) p + memchunk->index, memchunk->length / u->frame_size)) < 0) { + pa_memblock_release(memchunk->memblock); + if (frames == -EAGAIN) return; @@ -217,6 +219,8 @@ static void do_write(struct userdata *u) { return; } + pa_memblock_release(memchunk->memblock); + if (memchunk == &u->memchunk) { size_t l = frames * u->frame_size; memchunk->index += l; diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 4061d668..6d7e09e6 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -180,6 +180,7 @@ static void do_read(struct userdata *u) { pa_memchunk post_memchunk; snd_pcm_sframes_t frames; size_t l; + void *p; if (!u->memchunk.memblock) { u->memchunk.memblock = pa_memblock_new(u->source->core->mempool, u->memchunk.length = u->fragment_size); @@ -188,11 +189,13 @@ static void do_read(struct userdata *u) { assert(u->memchunk.memblock); assert(u->memchunk.length); - assert(u->memchunk.memblock->data); - assert(u->memchunk.memblock->length); assert(u->memchunk.length % u->frame_size == 0); - if ((frames = snd_pcm_readi(u->pcm_handle, (uint8_t*) u->memchunk.memblock->data + u->memchunk.index, u->memchunk.length / u->frame_size)) < 0) { + p = pa_memblock_acquire(u->memchunk.memblock); + + if ((frames = snd_pcm_readi(u->pcm_handle, (uint8_t*) p + u->memchunk.index, u->memchunk.length / u->frame_size)) < 0) { + pa_memblock_release(u->memchunk.memblock); + if (frames == -EAGAIN) return; @@ -216,6 +219,7 @@ static void do_read(struct userdata *u) { pa_module_unload_request(u->module); return; } + pa_memblock_release(u->memchunk.memblock); l = frames * u->frame_size; diff --git a/src/modules/module-esound-sink.c b/src/modules/module-esound-sink.c index 26638d9d..39886d04 100644 --- a/src/modules/module-esound-sink.c +++ b/src/modules/module-esound-sink.c @@ -144,18 +144,25 @@ static int do_write(struct userdata *u) { u->write_index = u->write_length = 0; } } else if (u->state == STATE_RUNNING) { + void *p; + pa_module_set_used(u->module, pa_sink_used_by(u->sink)); if (!u->memchunk.length) if (pa_sink_render(u->sink, 8192, &u->memchunk) < 0) return 0; - assert(u->memchunk.memblock && u->memchunk.length); + assert(u->memchunk.memblock); + assert(u->memchunk.length); + + p = pa_memblock_acquire(u->memchunk.memblock); - if ((r = pa_iochannel_write(u->io, (uint8_t*) u->memchunk.memblock->data + u->memchunk.index, u->memchunk.length)) < 0) { + if ((r = pa_iochannel_write(u->io, (uint8_t*) p + u->memchunk.index, u->memchunk.length)) < 0) { + pa_memblock_release(u->memchunk.memblock); pa_log("write() failed: %s", pa_cstrerror(errno)); return -1; } + pa_memblock_release(u->memchunk.memblock); u->memchunk.index += r; u->memchunk.length -= r; diff --git a/src/modules/module-jack-sink.c b/src/modules/module-jack-sink.c index c6a7e33f..1092aed8 100644 --- a/src/modules/module-jack-sink.c +++ b/src/modules/module-jack-sink.c @@ -137,22 +137,25 @@ static void io_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event_ unsigned fs; jack_nframes_t frame_idx; pa_memchunk chunk; + void *p; fs = pa_frame_size(&u->sink->sample_spec); pa_sink_render_full(u->sink, u->frames_requested * fs, &chunk); + p = pa_memblock_acquire(chunk.memblock); for (frame_idx = 0; frame_idx < u->frames_requested; frame_idx ++) { unsigned c; for (c = 0; c < u->channels; c++) { - float *s = ((float*) ((uint8_t*) chunk.memblock->data + chunk.index)) + (frame_idx * u->channels) + c; + float *s = ((float*) ((uint8_t*) p + chunk.index)) + (frame_idx * u->channels) + c; float *d = ((float*) u->buffer[c]) + frame_idx; *d = *s; } } + pa_memblock_release(chunk.memblock); pa_memblock_unref(chunk.memblock); u->frames_requested = 0; diff --git a/src/modules/module-jack-source.c b/src/modules/module-jack-source.c index 8ca24035..e19b2181 100644 --- a/src/modules/module-jack-source.c +++ b/src/modules/module-jack-source.c @@ -136,23 +136,28 @@ static void io_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event_ unsigned fs; jack_nframes_t frame_idx; pa_memchunk chunk; + void *p; fs = pa_frame_size(&u->source->sample_spec); chunk.memblock = pa_memblock_new(u->core->mempool, chunk.length = u->frames_posted * fs); chunk.index = 0; + p = pa_memblock_acquire(chunk.memblock); + for (frame_idx = 0; frame_idx < u->frames_posted; frame_idx ++) { unsigned c; for (c = 0; c < u->channels; c++) { float *s = ((float*) u->buffer[c]) + frame_idx; - float *d = ((float*) ((uint8_t*) chunk.memblock->data + chunk.index)) + (frame_idx * u->channels) + c; + float *d = ((float*) ((uint8_t*) p + chunk.index)) + (frame_idx * u->channels) + c; *d = *s; } } + pa_memblock_release(chunk.memblock); + pa_source_post(u->source, &chunk); pa_memblock_unref(chunk.memblock); diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index 54a8e890..8cf961b9 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -38,6 +37,7 @@ #include #include +#include #include #include #include @@ -64,11 +64,9 @@ struct userdata { pa_core *core; pa_module *module; pa_sink *sink; - pa_time_event *time_event; + pa_thread *thread; size_t block_size; - - uint64_t n_bytes; - struct timeval start_time; + struct timeval timestamp; }; static const char* const valid_modargs[] = { @@ -81,35 +79,131 @@ static const char* const valid_modargs[] = { NULL }; -static void time_callback(pa_mainloop_api *m, pa_time_event*e, const struct timeval *tv, void *userdata) { +static void thread_func(void *userdata) { struct userdata *u = userdata; - pa_memchunk chunk; - struct timeval ntv = *tv; - size_t l; - - assert(u); - - if (pa_sink_render(u->sink, u->block_size, &chunk) >= 0) { - l = chunk.length; - pa_memblock_unref(chunk.memblock); - } else - l = u->block_size; - - pa_timeval_add(&ntv, pa_bytes_to_usec(l, &u->sink->sample_spec)); - m->time_restart(e, &ntv); - - u->n_bytes += l; -} - -static pa_usec_t get_latency(pa_sink *s) { - struct userdata *u = s->userdata; - pa_usec_t a, b; - struct timeval now; + int quit = 0; + struct pollfd pollfd; + int running = 1; + + pa_assert(u); + + pa_log_debug("Thread starting up"); + + memset(&pollfd, 0, sizeof(pollfd)); + pollfd.fd = pa_asyncmsgq_get_fd(u->sink->asyncmsgq, PA_ASYNCQ_POP); + pollfd.events = POLLIN; + + pa_gettimeofday(u->timestamp); + + for (;;) { + int code; + void *data, *object; + int r, timeout; + struct timeval now; + + /* Check whether there is a message for us to process */ + if (pa_asyncmsgq_get(u->sink->asyncmsgq, &object, &code, &data) == 0) { + + + /* Now process these messages our own way */ + if (!object) { + + switch (code) { + case PA_MESSAGE_SHUTDOWN: + goto finish; + + default: + pa_sink_process_msg(u->sink->asyncmsgq, object, code, data); + + } + + } else if (object == u->sink) { + + switch (code) { + case PA_SINK_MESSAGE_STOP: + pa_assert(running); + running = 0; + break; + + case PA_SINK_MESSAGE_START: + pa_assert(!running); + running = 1; + + pa_gettimeofday(u->timestamp); + break; + + case PA_SINK_MESSAGE_GET_LATENCY: + + if (pa_timeval_cmp(&u->timestamp, &now) > 0) + *((pa_usec_t*) data) = 0; + else + *((pa_usec_t*) data) = pa_timeval_diff(&u->timestamp, &now); + break; + + /* ... */ + + default: + pa_sink_process_msg(u->sink->asyncmsgq, object, code, data); + } + } + + pa_asyncmsgq_done(u->sink->asyncmsgq); + continue; + } + + /* Render some data and drop it immediately */ + + if (running) { + pa_gettimeofday(&now); + + if (pa_timeval_cmp(u->timestamp, &now) <= 0) { + pa_memchunk chunk; + size_t l; + + if (pa_sink_render(u->sink, u->block_size, &chunk) >= 0) { + l = chunk.length; + pa_memblock_unref(chunk.memblock); + } else + l = u->block_size; + + pa_timeval_add(&u->timestamp, pa_bytes_to_usec(l, &u->sink->sample_spec)); + continue; + } + + timeout = pa_timeval_diff(&u->timestamp, &now)/1000; + + if (timeout < 1) + timeout = 1; + } else + timeout = -1; + + /* Hmm, nothing to do. Let's sleep */ + + if (pa_asyncmsgq_before_poll(u->sink->asyncmsgq) < 0) + continue; + + r = poll(&pollfd, 1, timeout); + pa_asyncmsgq_after_poll(u->sink->asyncmsgq); + + if (r < 0) { + if (errno == EINTR) + continue; + + pa_log("poll() failed: %s", pa_cstrerror(errno)); + goto fail; + } + + pa_assert(r == 0 || pollfd.revents == POLLIN); + } - a = pa_timeval_diff(pa_gettimeofday(&now), &u->start_time); - b = pa_bytes_to_usec(u->n_bytes, &s->sample_spec); +fail: + /* We have to continue processing messages until we receive the + * SHUTDOWN message */ + pa_asyncmsgq_post(u->core->asyncmsgq, u->core, PA_CORE_MESSAGE_UNLOAD_MODULE, pa_module_ref(u->module), NULL, pa_module_unref); + pa_asyncmsgq_wait_for(PA_MESSAGE_SHUTDOWN); - return b > a ? b - a : 0; +finish: + pa_log_debug("Thread shutting down"); } int pa__init(pa_core *c, pa_module*m) { @@ -118,17 +212,17 @@ int pa__init(pa_core *c, pa_module*m) { pa_channel_map map; pa_modargs *ma = NULL; - assert(c); - assert(m); + pa_assert(c); + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { - pa_log("failed to parse module arguments."); + pa_log("Failed to parse module arguments."); goto fail; } ss = c->default_sample_spec; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) { - pa_log("invalid sample format specification or channel map."); + pa_log("Invalid sample format specification or channel map"); goto fail; } @@ -138,22 +232,24 @@ int pa__init(pa_core *c, pa_module*m) { m->userdata = u; if (!(u->sink = pa_sink_new(c, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map))) { - pa_log("failed to create sink."); + pa_log("Failed to create sink."); goto fail; } - u->sink->get_latency = get_latency; u->sink->userdata = u; pa_sink_set_owner(u->sink, m); pa_sink_set_description(u->sink, pa_modargs_get_value(ma, "description", "NULL sink")); - u->n_bytes = 0; - pa_gettimeofday(&u->start_time); - - u->time_event = c->mainloop->time_new(c->mainloop, &u->start_time, time_callback, u); - - u->block_size = pa_bytes_per_second(&ss) / 10; + u->block_size = pa_bytes_per_second(&ss) / 20; /* 50 ms */ + + if (u->block_size <= 0) + u->block_size = pa_frame_size(&ss); + if (!(u->thread = pa_thread_new(thread_func, u))) { + pa_log("Failed to create thread."); + goto fail; + } + pa_modargs_free(ma); return 0; @@ -169,15 +265,21 @@ fail: void pa__done(pa_core *c, pa_module*m) { struct userdata *u; - assert(c && m); + + pa_assert(c); + pa_assert(m); if (!(u = m->userdata)) return; pa_sink_disconnect(u->sink); - pa_sink_unref(u->sink); - u->core->mainloop->time_free(u->time_event); + if (u->thread) { + pa_asyncmsgq_send(u->sink->asyncmsgq, PA_SINK_MESSAGE_SHUTDOWN, NULL); + pa_thread_free(u->thread); + } + + pa_sink_unref(u->sink); pa_xfree(u); } diff --git a/src/modules/module-oss-mmap.c b/src/modules/module-oss-mmap.c index 16c9b311..567230e0 100644 --- a/src/modules/module-oss-mmap.c +++ b/src/modules/module-oss-mmap.c @@ -173,7 +173,7 @@ static void out_fill_memblocks(struct userdata *u, unsigned n) { u->out_fragment_size, 1); assert(chunk.memblock); - chunk.length = chunk.memblock->length; + chunk.length = pa_memblock_get_length(chunk.memblock); chunk.index = 0; pa_sink_render_into_full(u->sink, &chunk); @@ -217,7 +217,7 @@ static void in_post_memblocks(struct userdata *u, unsigned n) { if (!u->in_memblocks[u->in_current]) { chunk.memblock = u->in_memblocks[u->in_current] = pa_memblock_new_fixed(u->core->mempool, (uint8_t*) u->in_mmap+u->in_fragment_size*u->in_current, u->in_fragment_size, 1); - chunk.length = chunk.memblock->length; + chunk.length = pa_memblock_get_length(chunk.memblock); chunk.index = 0; pa_source_post(u->source, &chunk); diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 9d4d0eac..9061e110 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -158,6 +158,7 @@ static void do_write(struct userdata *u) { } do { + void *p; memchunk = &u->memchunk; if (!memchunk->length) @@ -165,10 +166,11 @@ static void do_write(struct userdata *u) { memchunk = &u->silence; assert(memchunk->memblock); - assert(memchunk->memblock->data); assert(memchunk->length); - if ((r = pa_iochannel_write(u->io, (uint8_t*) memchunk->memblock->data + memchunk->index, memchunk->length)) < 0) { + p = pa_memblock_acquire(memchunk->memblock); + if ((r = pa_iochannel_write(u->io, (uint8_t*) p + memchunk->index, memchunk->length)) < 0) { + pa_memblock_release(memchunk->memblock); if (errno != EAGAIN) { pa_log("write() failed: %s", pa_cstrerror(errno)); @@ -180,6 +182,8 @@ static void do_write(struct userdata *u) { break; } + pa_memblock_release(memchunk->memblock); + if (memchunk == &u->silence) assert(r % u->sample_size == 0); else { @@ -224,9 +228,13 @@ static void do_read(struct userdata *u) { } do { + void *p; memchunk.memblock = pa_memblock_new(u->core->mempool, l); - assert(memchunk.memblock); - if ((r = pa_iochannel_read(u->io, memchunk.memblock->data, memchunk.memblock->length)) < 0) { + + p = pa_memblock_acquire(memchunk.memblock); + + if ((r = pa_iochannel_read(u->io, p, pa_memblock_get_length(memchunk.memblock))) < 0) { + pa_memblock_release(memchunk.memblock); pa_memblock_unref(memchunk.memblock); if (errno != EAGAIN) { @@ -239,8 +247,10 @@ static void do_read(struct userdata *u) { break; } - assert(r <= (ssize_t) memchunk.memblock->length); - memchunk.length = memchunk.memblock->length = r; + pa_memblock_release(memchunk.memblock); + + assert(r <= (ssize_t) pa_memblock_get_length(memchunk.memblock)); + memchunk.length = r; memchunk.index = 0; pa_source_post(u->source, &memchunk); diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index 170b046e..61672ede 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -58,20 +58,16 @@ PA_MODULE_USAGE( "rate=" "channel_map=") -#define DEFAULT_FIFO_NAME "/tmp/music.output" +#define DEFAULT_FILE_NAME "/tmp/music.output" #define DEFAULT_SINK_NAME "fifo_output" struct userdata { pa_core *core; - - char *filename; - - pa_sink *sink; - pa_iochannel *io; - pa_defer_event *defer_event; - - pa_memchunk memchunk; pa_module *module; + pa_sink *sink; + char *filename; + int fd; + pa_thread *thread; }; static const char* const valid_modargs[] = { @@ -84,97 +80,203 @@ static const char* const valid_modargs[] = { NULL }; -static void do_write(struct userdata *u) { - ssize_t r; - assert(u); +enum { + POLLFD_ASYNCQ, + POLLFD_FIFO, + POLLFD_MAX, +}; - u->core->mainloop->defer_enable(u->defer_event, 0); +static void thread_func(void *userdata) { + struct userdata *u = userdata; + int quit = 0; + struct pollfd pollfd[POLLFD_MAX]; + int running = 1, underrun = 0; + pa_memchunk memchunk; - if (!pa_iochannel_is_writable(u->io)) - return; + pa_assert(u); - pa_module_set_used(u->module, pa_sink_used_by(u->sink)); + pa_log_debug("Thread starting up"); + + memset(&pollfd, 0, sizeof(pollfd)); + pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->sink->asyncmsgq, PA_ASYNCQ_POP); + pollfd[POLLFD_ASYNCQ].events = POLLIN; - if (!u->memchunk.length) - if (pa_sink_render(u->sink, PIPE_BUF, &u->memchunk) < 0) - return; + pollfd[POLLFD_FIFO].fd = u->fd; - assert(u->memchunk.memblock && u->memchunk.length); + memset(&memchunk, 0, sizeof(memchunk)); + + for (;;) { + int code; + void *object, *data; + int r; + struct timeval now; - if ((r = pa_iochannel_write(u->io, (uint8_t*) u->memchunk.memblock->data + u->memchunk.index, u->memchunk.length)) < 0) { - pa_log("write(): %s", pa_cstrerror(errno)); - return; - } + /* Check whether there is a message for us to process */ + if (pa_asyncmsgq_get(u->sink->asyncmsgq, &object, &code, &data) == 0) { - u->memchunk.index += r; - u->memchunk.length -= r; - if (u->memchunk.length <= 0) { - pa_memblock_unref(u->memchunk.memblock); - u->memchunk.memblock = NULL; + /* Now process these messages our own way */ + if (!object) { + switch (code) { + case PA_SINK_MESSAGE_SHUTDOWN: + goto finish; + + default: + pa_sink_process_msg(u->sink->asyncmsgq, object, code, data); + } + + } else if (object == u->sink) { + + case PA_SINK_MESSAGE_STOP: + pa_assert(running); + running = 0; + break; + + case PA_SINK_MESSAGE_START: + pa_assert(!running); + running = 1; + break; + + case PA_SINK_MESSAGE_GET_LATENCY: { + size_t n = 0; + int l; + + if (ioctl(u->fd, TIOCINQ, &l) >= 0 && l > 0) + n = (size_t) l; + + n += memchunk.length; + + *((pa_usec_t*) data) pa_bytes_to_usec(n, &u->sink->sample_spec); + break; + } + + /* ... */ + + default: + pa_sink_process_msg(u->sink->asyncmsgq, object, code, data); + } + + pa_asyncmsgq_done(u->sink->asyncmsgq); + continue; + } + + /* Render some data and write it to the fifo */ + + if (running && (pollfd[POLLFD_FIFO].revents || underrun)) { + + if (chunk.length <= 0) + pa_sink_render(u->fd, PIPE_BUF, &chunk); + + underrun = chunk.length <= 0; + + if (!underrun) { + ssize_t l; + + p = pa_memblock_acquire(u->memchunk.memblock); + l = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length); + pa_memblock_release(p); + + if (l < 0) { + + if (errno != EINTR && errno != EAGAIN) { + pa_log("Failed to write data to FIFO: %s", pa_cstrerror(errno)); + goto fail; + } + + } else { + + u->memchunk.index += l; + u->memchunk.length -= l; + + if (u->memchunk.length <= 0) { + pa_memblock_unref(u->memchunk.memblock); + u->memchunk.memblock = NULL; + } + } + + pollfd[POLLFD_FIFO].revents = 0; + continue; + } + } + + pollfd[POLLFD_FIFO].events = running && !underrun ? POLLOUT : 0; + + /* Hmm, nothing to do. Let's sleep */ + + if (pa_asyncmsgq_before_poll(u->sink->asyncmsgq) < 0) + continue; + + r = poll(&pollfd, 1, 0); + pa_asyncmsgq_after_poll(u->sink->asyncmsgq); + + if (r < 0) { + if (errno == EINTR) + continue; + + pa_log("poll() failed: %s", pa_cstrerror(errno)); + goto fail; + } + + if (pollfd[POLLFD_FIFO].revents & ~POLLIN) { + pa_log("FIFO shutdown."); + goto fail; + } + + pa_assert(pollfd[POLLFD_ASYNCQ].revents & ~POLLIN == 0); } -} - -static void notify_cb(pa_sink*s) { - struct userdata *u = s->userdata; - assert(s && u); - - if (pa_iochannel_is_writable(u->io)) - u->core->mainloop->defer_enable(u->defer_event, 1); -} - -static pa_usec_t get_latency_cb(pa_sink *s) { - struct userdata *u = s->userdata; - assert(s && u); - - return u->memchunk.memblock ? pa_bytes_to_usec(u->memchunk.length, &s->sample_spec) : 0; -} - -static void defer_callback(PA_GCC_UNUSED pa_mainloop_api *m, PA_GCC_UNUSED pa_defer_event*e, void *userdata) { - struct userdata *u = userdata; - assert(u); - do_write(u); -} + +fail: + /* We have to continue processing messages until we receive the + * SHUTDOWN message */ + pa_asyncmsgq_post(u->core->asyncmsgq, u->core, PA_CORE_MESSAGE_UNLOAD_MODULE, pa_module_ref(u->module), pa_module_unref); + pa_asyncmsgq_wait_for(PA_SINK_MESSAGE_SHUTDOWN); -static void io_callback(PA_GCC_UNUSED pa_iochannel *io, void*userdata) { - struct userdata *u = userdata; - assert(u); - do_write(u); +finish: + pa_log_debug("Thread shutting down"); } int pa__init(pa_core *c, pa_module*m) { struct userdata *u = NULL; struct stat st; - const char *p; - int fd = -1; pa_sample_spec ss; pa_channel_map map; pa_modargs *ma = NULL; char *t; - assert(c && m); + pa_assert(c); + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { - pa_log("failed to parse module arguments"); + pa_log("Failed to parse module arguments."); goto fail; } ss = c->default_sample_spec; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) { - pa_log("invalid sample format specification"); + pa_log("Invalid sample format specification"); goto fail; } - mkfifo(p = pa_modargs_get_value(ma, "file", DEFAULT_FIFO_NAME), 0777); - - if ((fd = open(p, O_RDWR)) < 0) { + u = pa_xnew0(struct userdata, 1); + u->core = c; + u->module = m; + u->filename = pa_xstrdup(pa_modargs_get_value(ma, "file", DEFAULT_FIFO_NAME)); + u->fd = fd; + u->memchunk.memblock = NULL; + u->memchunk.length = 0; + m->userdata = u; + + mkfifo(u->filename, 0666); + + if ((u->fd = open(u->filename, O_RDWR)) < 0) { pa_log("open('%s'): %s", p, pa_cstrerror(errno)); goto fail; } - pa_fd_set_cloexec(fd, 1); + pa_fd_set_cloexec(u->fd, 1); + pa_make_nonblock_fd(u->fd); - if (fstat(fd, &st) < 0) { + if (fstat(u->fd, &st) < 0) { pa_log("fstat('%s'): %s", p, pa_cstrerror(errno)); goto fail; } @@ -184,34 +286,21 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - u = pa_xmalloc0(sizeof(struct userdata)); - u->filename = pa_xstrdup(p); - u->core = c; - u->module = m; - m->userdata = u; - if (!(u->sink = pa_sink_new(c, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map))) { - pa_log("failed to create sink."); + pa_log("Failed to create sink."); goto fail; } - u->sink->notify = notify_cb; - u->sink->get_latency = get_latency_cb; + u->sink->userdata = u; pa_sink_set_owner(u->sink, m); pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Unix FIFO sink '%s'", p)); pa_xfree(t); - u->io = pa_iochannel_new(c->mainloop, -1, fd); - assert(u->io); - pa_iochannel_set_callback(u->io, io_callback, u); - - u->memchunk.memblock = NULL; - u->memchunk.length = 0; - - u->defer_event = c->mainloop->defer_new(c->mainloop, defer_callback, u); - assert(u->defer_event); - c->mainloop->defer_enable(u->defer_event, 0); - + if (!(u->thread = pa_thread_new(thread_func, u))) { + pa_log("Failed to create thread."); + goto fail; + } + pa_modargs_free(ma); return 0; @@ -220,9 +309,6 @@ fail: if (ma) pa_modargs_free(ma); - if (fd >= 0) - close(fd); - pa__done(c, m); return -1; @@ -230,22 +316,31 @@ fail: void pa__done(pa_core *c, pa_module*m) { struct userdata *u; - assert(c && m); + pa_assert(c); + pa_assert(m); if (!(u = m->userdata)) return; - if (u->memchunk.memblock) - pa_memblock_unref(u->memchunk.memblock); - pa_sink_disconnect(u->sink); + + if (u->thread) { + pa_asyncmsgq_send(u->sink->asyncmsgq, PA_SINK_MESSAGE_SHUTDOWN, NULL); + pa_thread_free(u->thread); + } + pa_sink_unref(u->sink); - pa_iochannel_free(u->io); - u->core->mainloop->defer_free(u->defer_event); - assert(u->filename); - unlink(u->filename); - pa_xfree(u->filename); + if (u->memchunk.memblock) + pa_memblock_unref(u->memchunk.memblock); + + if (u->filename) { + unlink(u->filename); + pa_xfree(u->filename); + } + + if (u->fd >= 0) + close(u->fd); pa_xfree(u); } diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index 56c721b0..f275c5d4 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -84,7 +84,9 @@ static const char* const valid_modargs[] = { static void do_read(struct userdata *u) { ssize_t r; + void *p; pa_memchunk chunk; + assert(u); if (!pa_iochannel_is_readable(u->io)) @@ -97,17 +99,22 @@ static void do_read(struct userdata *u) { u->chunk.index = chunk.length = 0; } - assert(u->chunk.memblock && u->chunk.memblock->length > u->chunk.index); - if ((r = pa_iochannel_read(u->io, (uint8_t*) u->chunk.memblock->data + u->chunk.index, u->chunk.memblock->length - u->chunk.index)) <= 0) { + assert(u->chunk.memblock); + assert(pa_memblock_get_length(u->chunk.memblock) > u->chunk.index); + + p = pa_memblock_acquire(u->chunk.memblock); + if ((r = pa_iochannel_read(u->io, (uint8_t*) p + u->chunk.index, pa_memblock_get_length(u->chunk.memblock) - u->chunk.index)) <= 0) { + pa_memblock_release(u->chunk.memblock); pa_log("read(): %s", pa_cstrerror(errno)); return; } + pa_memblock_release(u->chunk.memblock); u->chunk.length = r; pa_source_post(u->source, &u->chunk); u->chunk.index += r; - if (u->chunk.index >= u->chunk.memblock->length) { + if (u->chunk.index >= pa_memblock_get_length(u->chunk.memblock)) { u->chunk.index = u->chunk.length = 0; pa_memblock_unref(u->chunk.memblock); u->chunk.memblock = NULL; diff --git a/src/modules/module-sine.c b/src/modules/module-sine.c index 661455b3..baf37346 100644 --- a/src/modules/module-sine.c +++ b/src/modules/module-sine.c @@ -65,7 +65,7 @@ static int sink_input_peek(pa_sink_input *i, pa_memchunk *chunk) { chunk->memblock = pa_memblock_ref(u->memblock); chunk->index = u->peek_index; - chunk->length = u->memblock->length - u->peek_index; + chunk->length = pa_memblock_get_length(u->memblock) - u->peek_index; return 0; } @@ -74,11 +74,12 @@ static void sink_input_drop(pa_sink_input *i, const pa_memchunk *chunk, size_t l assert(i && chunk && length && i->userdata); u = i->userdata; - assert(chunk->memblock == u->memblock && length <= u->memblock->length-u->peek_index); + assert(chunk->memblock == u->memblock); + assert(length <= pa_memblock_get_length(u->memblock)-u->peek_index); u->peek_index += length; - if (u->peek_index >= u->memblock->length) + if (u->peek_index >= pa_memblock_get_length(u->memblock)) u->peek_index = 0; } @@ -111,6 +112,7 @@ int pa__init(pa_core *c, pa_module*m) { pa_sample_spec ss; uint32_t frequency; char t[256]; + void *p; pa_sink_input_new_data data; if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { @@ -142,7 +144,9 @@ int pa__init(pa_core *c, pa_module*m) { } u->memblock = pa_memblock_new(c->mempool, pa_bytes_per_second(&ss)); - calc_sine(u->memblock->data, u->memblock->length, frequency); + p = pa_memblock_acquire(u->memblock); + calc_sine(p, pa_memblock_get_length(u->memblock), frequency); + pa_memblock_release(u->memblock); snprintf(t, sizeof(t), "Sine Generator at %u Hz", frequency); diff --git a/src/modules/rtp/rtp.c b/src/modules/rtp/rtp.c index 03a01412..f0ab7d8a 100644 --- a/src/modules/rtp/rtp.c +++ b/src/modules/rtp/rtp.c @@ -81,7 +81,7 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) { size_t k = n + chunk.length > size ? size - n : chunk.length; if (chunk.memblock) { - iov[iov_idx].iov_base = (void*)((uint8_t*) chunk.memblock->data + chunk.index); + iov[iov_idx].iov_base = (void*)((uint8_t*) pa_memblock_acquire(chunk.memblock) + chunk.index); iov[iov_idx].iov_len = k; mb[iov_idx] = chunk.memblock; iov_idx ++; @@ -116,8 +116,10 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) { k = sendmsg(c->fd, &m, MSG_DONTWAIT); - for (i = 1; i < iov_idx; i++) + for (i = 1; i < iov_idx; i++) { + pa_memblock_release(mb[i]); pa_memblock_unref(mb[i]); + } c->sequence++; } else @@ -174,7 +176,7 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) { chunk->memblock = pa_memblock_new(pool, size); - iov.iov_base = chunk->memblock->data; + iov.iov_base = pa_memblock_acquire(chunk->memblock); iov.iov_len = size; m.msg_name = NULL; @@ -195,9 +197,9 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) { goto fail; } - memcpy(&header, chunk->memblock->data, sizeof(uint32_t)); - memcpy(&c->timestamp, (uint8_t*) chunk->memblock->data + 4, sizeof(uint32_t)); - memcpy(&c->ssrc, (uint8_t*) chunk->memblock->data + 8, sizeof(uint32_t)); + memcpy(&header, iov.iov_base, sizeof(uint32_t)); + memcpy(&c->timestamp, (uint8_t*) iov.iov_base + 4, sizeof(uint32_t)); + memcpy(&c->ssrc, (uint8_t*) iov.iov_base + 8, sizeof(uint32_t)); header = ntohl(header); c->timestamp = ntohl(c->timestamp); @@ -238,8 +240,10 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) { return 0; fail: - if (chunk->memblock) + if (chunk->memblock) { + pa_memblock_release(chunk->memblock); pa_memblock_unref(chunk->memblock); + } return -1; } diff --git a/src/pulse/internal.h b/src/pulse/internal.h index 52354fdc..e5c9ef12 100644 --- a/src/pulse/internal.h +++ b/src/pulse/internal.h @@ -116,6 +116,7 @@ struct pa_stream { uint32_t requested_bytes; pa_memchunk peek_memchunk; + void *peek_data; pa_memblockq *record_memblockq; int corked; diff --git a/src/pulse/stream.c b/src/pulse/stream.c index f20c17ae..44fce52f 100644 --- a/src/pulse/stream.c +++ b/src/pulse/stream.c @@ -91,6 +91,7 @@ pa_stream *pa_stream_new(pa_context *c, const char *name, const pa_sample_spec * s->peek_memchunk.index = 0; s->peek_memchunk.length = 0; s->peek_memchunk.memblock = NULL; + s->peek_data = NULL; s->record_memblockq = NULL; @@ -125,8 +126,11 @@ static void stream_free(pa_stream *s) { s->mainloop->time_free(s->auto_timing_update_event); } - if (s->peek_memchunk.memblock) + if (s->peek_memchunk.memblock) { + if (s->peek_data) + pa_memblock_release(s->peek_memchunk.memblock); pa_memblock_unref(s->peek_memchunk.memblock); + } if (s->record_memblockq) pa_memblockq_free(s->record_memblockq); @@ -608,8 +612,11 @@ int pa_stream_write( if (free_cb) chunk.memblock = pa_memblock_new_user(s->context->mempool, (void*) data, length, free_cb, 1); else { + void *tdata; chunk.memblock = pa_memblock_new(s->context->mempool, length); - memcpy(chunk.memblock->data, data, length); + tdata = pa_memblock_acquire(chunk.memblock); + memcpy(tdata, data, length); + pa_memblock_release(chunk.memblock); } chunk.index = 0; @@ -675,9 +682,12 @@ int pa_stream_peek(pa_stream *s, const void **data, size_t *length) { *length = 0; return 0; } + + s->peek_data = pa_memblock_acquire(s->peek_memchunk.memblock); } - *data = (const char*) s->peek_memchunk.memblock->data + s->peek_memchunk.index; + assert(s->peek_data); + *data = (uint8_t*) s->peek_data + s->peek_memchunk.index; *length = s->peek_memchunk.length; return 0; } @@ -696,6 +706,8 @@ int pa_stream_drop(pa_stream *s) { if (s->timing_info_valid && !s->timing_info.read_index_corrupt) s->timing_info.read_index += s->peek_memchunk.length; + assert(s->peek_data); + pa_memblock_release(s->peek_memchunk.memblock); pa_memblock_unref(s->peek_memchunk.memblock); s->peek_memchunk.length = 0; s->peek_memchunk.index = 0; diff --git a/src/pulse/xmalloc.h b/src/pulse/xmalloc.h index 2f6399c5..62a450dc 100644 --- a/src/pulse/xmalloc.h +++ b/src/pulse/xmalloc.h @@ -75,6 +75,15 @@ static inline void* pa_xnew0_internal(unsigned n, size_t k) { /** Same as pa_xnew() but set the memory to zero */ #define pa_xnew0(type, n) ((type*) pa_xnew0_internal((n), sizeof(type))) +/** Internal helper for pa_xnew0() */ +static inline void* pa_xnewdup_internal(const void *p, unsigned n, size_t k) { + assert(n < INT_MAX/k); + return pa_xmemdup(p, n*k); +} + +/** Same as pa_xnew() but set the memory to zero */ +#define pa_xnewdup(type, p, n) ((type*) pa_xnewdup_internal((p), (n), sizeof(type))) + PA_C_DECL_END #endif diff --git a/src/pulsecore/asyncmsgq.c b/src/pulsecore/asyncmsgq.c new file mode 100644 index 00000000..31e27e7d --- /dev/null +++ b/src/pulsecore/asyncmsgq.c @@ -0,0 +1,235 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "asyncmsgq.h" + +PA_STATIC_FLIST_DECLARE(asyncmsgq, 0); + +struct asyncmsgq_item { + int code; + pa_msgobject *object; + void *userdata; + pa_free_cb_t free_cb; + pa_memchunk memchunk; + pa_semaphore *semaphore; +}; + +struct pa_asyncmsgq { + pa_asyncq *asyncq; + pa_mutex *mutex; /* only for the writer side */ + + struct asyncmsgq_item *current; +}; + +pa_asyncmsgq *pa_asyncmsgq_new(unsigned size) { + pa_asyncmsgq *a; + + a = pa_xnew(pa_asyncmsgq, 1); + + pa_assert_se(a->asyncq = pa_asyncq_new(size)); + pa_assert_se(a->mutex = pa_mutex_new(0)); + a->current = NULL; + + return a; +} + +void pa_asyncmsgq_free(pa_asyncmsgq *a) { + struct asyncmsgq_item *i; + pa_assert(a); + + while ((i = pa_asyncq_pop(a->asyncq, 0))) { + + pa_assert(!i->semaphore); + + if (i->object) + pa_msgobject_unref(i->object); + + if (i->memchunk.memblock) + pa_memblock_unref(i->object); + + if (i->userdata_free_cb) + i->userdata_free_cb(i->userdata); + + if (pa_flist_push(PA_STATIC_FLIST_GET(asyncmsgq), i) < 0) + pa_xfree(i); + } + + pa_asyncq_free(a->asyncq, NULL); + pa_mutex_free(a->mutex); + pa_xfree(a); +} + +void pa_asyncmsgq_post(pa_asyncmsgq *a, pa_msgobject *object, int code, const void *userdata, const pa_memchunk *chunk, pa_free_cb_t free_cb) { + struct asyncmsgq_item *i; + pa_assert(a); + + if (!(i = pa_flist_pop(PA_STATIC_FLIST_GET(asyncmsgq)))) + i = pa_xnew(struct asyncmsgq_item, 1); + + i->code = code; + i->object = pa_msgobject_ref(object); + i->userdata = (void*) userdata; + i->free_cb = free_cb; + if (chunk) { + pa_assert(chunk->memblock); + i->memchunk = *chunk; + pa_memblock_ref(i->memchunk.memblock); + } else + pa_memchunk_reset(&i->memchunk); + i->semaphore = NULL; + + /* Thus mutex makes the queue multiple-writer safe. This lock is only used on the writing side */ + pa_mutex_lock(a->mutex); + pa_assert_se(pa_asyncq_push(a->asyncq, i, 1) == 0); + pa_mutex_unlock(a->mutex); +} + +int pa_asyncmsgq_send(pa_asyncmsgq *a, pa_msgobject *object, int code, const void *userdata, const pa_memchunk *chunk) { + struct asyncmsgq_item i; + pa_assert(a); + + i.code = code; + i.object = object; + i.userdata = (void*) userdata; + i.free_cb = NULL; + i.ret = -1; + if (chunk) { + pa_assert(chunk->memblock); + i->memchunk = *chunk; + } else + pa_memchunk_reset(&i->memchunk); + pa_assert_se(i.semaphore = pa_semaphore_new(0)); + + /* Thus mutex makes the queue multiple-writer safe. This lock is only used on the writing side */ + pa_mutex_lock(a->mutex); + pa_assert_se(pa_asyncq_push(a->asyncq, &i, 1) == 0); + pa_mutex_unlock(a->mutex); + + pa_semaphore_wait(i.semaphore); + pa_semaphore_free(i.semaphore); + + return i.ret; +} + +int pa_asyncmsgq_get(pa_asyncmsgq *a, pa_msgobject **object, int *code, void **userdata, pa_memchunk *chunk, int wait) { + pa_assert(a); + pa_assert(code); + pa_assert(!a->current); + + if (!(a->current = pa_asyncq_pop(a->asyncq, wait))) + return -1; + + *code = a->current->code; + if (userdata) + *userdata = a->current->userdata; + if (object) + *object = a->current->object; + if (chunk) + *chunk = a->chunk; + + return 0; +} + +void pa_asyncmsgq_done(pa_asyncmsgq *a, int ret) { + pa_assert(a); + pa_assert(a->current); + + if (a->current->semaphore) { + a->current->ret = ret; + pa_semaphore_post(a->current->semaphore); + } else { + + if (a->current->free_cb) + a->current->free_cb(a->current->userdata); + + if (a->current->object) + pa_msgobject_unref(a->current->object); + + if (a->current->memchunk.memblock) + pa_memblock_unref(a->current->memchunk.memblock); + + if (pa_flist_push(PA_STATIC_FLIST_GET(asyncmsgq), a->current) < 0) + pa_xfree(a->current); + } + + a->current = NULL; +} + +int pa_asyncmsgq_wait_for(pa_asyncmsgq *a, int code) { + int c; + pa_assert(a); + + do { + + if (pa_asyncmsgq_get(a, NULL, &c, NULL, 1) < 0) + return -1; + + pa_asyncmsgq_done(a); + + } while (c != code); + + return 0; +} + +int pa_asyncmsgq_get_fd(pa_asyncmsgq *a) { + pa_assert(a); + + return pa_asyncq_get_fd(a->asyncq); +} + +int pa_asyncmsgq_before_poll(pa_asyncmsgq *a) { + pa_assert(a); + + return pa_asyncq_before_poll(a->asyncq); +} + +void pa_asyncmsgq_after_poll(pa_asyncmsgq *a) { + pa_assert(a); + + pa_asyncq_after_poll(a->asyncq); +} + +int pa_asyncmsgq_dispatch(pa_msgobject *object, int code, void *userdata, pa_memchunk *memchunk) { + pa_assert(q); + + if (object) + return object->msg_process(object, code, userdata, memchunk); + + return 0; +} diff --git a/src/pulsecore/asyncmsgq.h b/src/pulsecore/asyncmsgq.h new file mode 100644 index 00000000..17b37e4b --- /dev/null +++ b/src/pulsecore/asyncmsgq.h @@ -0,0 +1,73 @@ +#ifndef foopulseasyncmsgqhfoo +#define foopulseasyncmsgqhfoo + +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include + +#include +#include +#include + +/* A simple asynchronous message queue, based on pa_asyncq. In + * contrast to pa_asyncq this one is multiple-writer safe, though + * still not multiple-reader safe. This queue is intended to be used + * for controlling real-time threads from normal-priority + * threads. Multiple-writer-safety is accomplished by using a mutex on + * the writer side. This queue is thus not useful for communication + * between several real-time threads. + * + * The queue takes messages consisting of: + * "Object" for which this messages is intended (may be NULL) + * A numeric message code + * Arbitrary userdata pointer (may be NULL) + * A memchunk (may be NULL) + * + * There are two functions for submitting messages: _post and + * _send. The fromer just enqueues the message asynchronously, the + * latter waits for completion, synchronously. */ + +enum { + PA_MESSAGE_SHUTDOWN /* A generic message to inform the handler of this queue to quit */ +}; + +typedef struct pa_asyncmsgq pa_asyncmsgq; + +pa_asyncmsgq* pa_asyncmsgq_new(size_t size); +void pa_asyncmsgq_free(pa_asyncmsgq* q); + +void pa_asyncmsgq_post(pa_asyncmsgq *q, pa_msgobject *object, int code, const void *userdata, const pa_memchunk *memchunk, pa_free_cb_t userdata_free_cb); +int pa_asyncmsgq_send(pa_asyncmsgq *q, pa_msgobject *object, int code, const void *userdata, const pa_memchunk *memchunk); + +int pa_asyncmsgq_get(pa_asyncmsgq *q, pa_msgobject **object, int *code, void **userdata, pa_memchunk *memchunk, int wait); +int pa_asyncmsgq_dispatch(pa_msgobject *object, int code, void *userdata, pa_memchunk *memchunk); +void pa_asyncmsgq_done(pa_asyncmsgq *q, int ret); +int pa_asyncmsgq_wait_for(pa_asyncmsgq *a, int code); + +/* Just for the reading side */ +int pa_asyncmsgq_get_fd(pa_asyncmsgq *q); +int pa_asyncmsgq_before_poll(pa_asyncmsgq *a); +void pa_asyncmsgq_after_poll(pa_asyncmsgq *a); + +#endif diff --git a/src/pulsecore/asyncq.c b/src/pulsecore/asyncq.c new file mode 100644 index 00000000..779cd479 --- /dev/null +++ b/src/pulsecore/asyncq.c @@ -0,0 +1,271 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "asyncq.h" + +#define ASYNCQ_SIZE 128 + +/* For debugging purposes we can define _Y to put and extra thread + * yield between each operation. */ + +#ifdef PROFILE +#define _Y pa_thread_yield() +#else +#define _Y do { } while(0) +#endif + +struct pa_asyncq { + unsigned size; + unsigned read_idx; + unsigned write_idx; + pa_atomic_int_t read_waiting; + pa_atomic_int_t write_waiting; + int read_fds[2], write_fds[2]; +}; + +#define PA_ASYNCQ_CELLS(x) ((pa_atomic_ptr_t*) ((uint8_t*) (x) + PA_ALIGN(sizeof(struct pa_asyncq)))) + +static int is_power_of_two(unsigned size) { + return !(size & (size - 1)); +} + +static int reduce(pa_asyncq *l, int value) { + return value & (unsigned) (l->size - 1); +} + +pa_asyncq *pa_asyncq_new(unsigned size) { + pa_asyncq *l; + + if (!size) + size = ASYNCQ_SIZE; + + pa_assert(is_power_of_two(size)); + + l = pa_xmalloc0(PA_ALIGN(sizeof(pa_asyncq)) + (sizeof(pa_atomic_ptr_t) * size)); + + l->size = size; + pa_atomic_store(&l->read_waiting, 0); + pa_atomic_store(&l->write_waiting, 0); + + if (pipe(l->read_fds) < 0) { + pa_xfree(l); + return NULL; + } + + if (pipe(l->write_fds) < 0) { + pa_close(l->read_fds[0]); + pa_close(l->read_fds[1]); + pa_xfree(l); + return NULL; + } + + pa_make_nonblock_fd(l->read_fds[1]); + pa_make_nonblock_fd(l->write_fds[1]); + + return l; +} + +void pa_asyncq_free(pa_asyncq *l, pa_free_cb_t free_cb) { + pa_assert(l); + + if (free_cb) { + void *p; + + while ((p = pa_asyncq_pop(l, 0))) + free_cb(p); + } + + pa_close(l->read_fds[0]); + pa_close(l->read_fds[1]); + pa_close(l->write_fds[0]); + pa_close(l->write_fds[1]); + + pa_xfree(l); +} + +int pa_asyncq_push(pa_asyncq*l, void *p, int wait) { + int idx; + pa_atomic_ptr_t *cells; + + pa_assert(l); + pa_assert(p); + + cells = PA_ASYNCQ_CELLS(l); + + _Y; + idx = reduce(l, l->write_idx); + + if (!pa_atomic_ptr_cmpxchg(&cells[idx], NULL, p)) { + + /* First try failed. Let's wait for changes. */ + + if (!wait) + return -1; + + _Y; + + pa_atomic_inc(&l->write_waiting); + + for (;;) { + char x[20]; + + _Y; + + if (pa_atomic_ptr_cmpxchg(&cells[idx], NULL, p)) + break; + + _Y; + + if (read(l->write_fds[0], x, sizeof(x)) < 0 && errno != EINTR) { + pa_atomic_dec(&l->write_waiting); + return -1; + } + } + + _Y; + + pa_atomic_dec(&l->write_waiting); + } + + _Y; + l->write_idx++; + + if (pa_atomic_load(&l->read_waiting)) { + char x = 'x'; + _Y; + write(l->read_fds[1], &x, sizeof(x)); + } + + return 0; +} + +void* pa_asyncq_pop(pa_asyncq*l, int wait) { + int idx; + void *ret; + pa_atomic_ptr_t *cells; + + pa_assert(l); + + cells = PA_ASYNCQ_CELLS(l); + + _Y; + idx = reduce(l, l->read_idx); + + if (!(ret = pa_atomic_ptr_load(&cells[idx]))) { + + /* First try failed. Let's wait for changes. */ + + if (!wait) + return NULL; + + _Y; + + pa_atomic_inc(&l->read_waiting); + + for (;;) { + char x[20]; + + _Y; + + if ((ret = pa_atomic_ptr_load(&cells[idx]))) + break; + + _Y; + + if (read(l->read_fds[0], x, sizeof(x)) < 0 && errno != EINTR) { + pa_atomic_dec(&l->read_waiting); + return NULL; + } + } + + _Y; + + pa_atomic_dec(&l->read_waiting); + } + + /* Guaranteed if we only have a single reader */ + pa_assert_se(pa_atomic_ptr_cmpxchg(&cells[idx], ret, NULL)); + + _Y; + l->read_idx++; + + if (pa_atomic_load(&l->write_waiting)) { + char x = 'x'; + _Y; + write(l->write_fds[1], &x, sizeof(x)); + } + + return ret; +} + +int pa_asyncq_get_fd(pa_asyncq *q) { + pa_assert(q); + + return q->read_fds[0]; +} + +int pa_asyncq_before_poll(pa_asyncq *l) { + int idx; + pa_atomic_ptr_t *cells; + + pa_assert(l); + + cells = PA_ASYNCQ_CELLS(l); + + _Y; + idx = reduce(l, l->read_idx); + + if (pa_atomic_ptr_load(&cells[idx])) + return -1; + + pa_atomic_inc(&l->read_waiting); + + if (pa_atomic_ptr_load(&cells[idx])) { + pa_atomic_dec(&l->read_waiting); + return -1; + } + + return 0; +} + +int pa_asyncq_after_poll(pa_asyncq *l) { + pa_assert(l); + + pa_assert(pa_atomic_load(&l->read_waiting) > 0); + + pa_atomic_dec(&l->read_waiting); +} diff --git a/src/pulsecore/asyncq.h b/src/pulsecore/asyncq.h new file mode 100644 index 00000000..aac45b1d --- /dev/null +++ b/src/pulsecore/asyncq.h @@ -0,0 +1,56 @@ +#ifndef foopulseasyncqhfoo +#define foopulseasyncqhfoo + +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include +#include + +/* A simple, asynchronous, lock-free (if requested also wait-free) + * queue. Not multiple-reader/multiple-writer safe. If that is + * required both sides can be protected by a mutex each. --- Which is + * not a bad thing in most cases, since this queue is intended for + * communication between a normal thread and a single real-time + * thread. Only the real-time side needs to be lock-free/wait-free. + * + * If the queue is full and another entry shall be pushed, or when the + * queue is empty and another entry shall be popped and the "wait" + * argument is non-zero, the queue will block on a UNIX FIFO object -- + * that will probably require locking on the kernel side -- which + * however is probably not problematic, because we do it only on + * starvation or overload in which case we have to block anyway. */ + +typedef struct pa_asyncq pa_asyncq; + +pa_asyncq* pa_asyncq_new(size_t size); +void pa_asyncq_free(pa_asyncq* q, pa_free_cb_t free_cb); + +void* pa_asyncq_pop(pa_asyncq *q, int wait); +int pa_asyncq_push(pa_asyncq *q, void *p, int wait); + +int pa_asyncq_get_fd(pa_asyncq *q); +int pa_asyncq_before_poll(pa_asyncq *a); +int pa_asyncq_after_poll(pa_asyncq *a); + +#endif diff --git a/src/pulsecore/atomic.h b/src/pulsecore/atomic.h index 013e8c20..9a024f91 100644 --- a/src/pulsecore/atomic.h +++ b/src/pulsecore/atomic.h @@ -31,9 +31,9 @@ * It is not guaranteed however, that sizeof(AO_t) == sizeof(size_t). * however very likely. */ -typedef struct pa_atomic_int { +typedef struct pa_atomic { volatile AO_t value; -} pa_atomic_int_t; +} pa_atomic_t; #define PA_ATOMIC_INIT(v) { .value = (v) } @@ -41,31 +41,31 @@ typedef struct pa_atomic_int { * to support more elaborate memory barriers, in which case we will add * suffixes to the function names */ -static inline int pa_atomic_load(const pa_atomic_int_t *a) { +static inline int pa_atomic_load(const pa_atomic_t *a) { return (int) AO_load_full((AO_t*) &a->value); } -static inline void pa_atomic_store(pa_atomic_int_t *a, int i) { +static inline void pa_atomic_store(pa_atomic_t *a, int i) { AO_store_full(&a->value, (AO_t) i); } -static inline int pa_atomic_add(pa_atomic_int_t *a, int i) { +static inline int pa_atomic_add(pa_atomic_t *a, int i) { return AO_fetch_and_add_full(&a->value, (AO_t) i); } -static inline int pa_atomic_sub(pa_atomic_int_t *a, int i) { +static inline int pa_atomic_sub(pa_atomic_t *a, int i) { return AO_fetch_and_add_full(&a->value, (AO_t) -i); } -static inline int pa_atomic_inc(pa_atomic_int_t *a) { +static inline int pa_atomic_inc(pa_atomic_t *a) { return AO_fetch_and_add1_full(&a->value); } -static inline int pa_atomic_dec(pa_atomic_int_t *a) { +static inline int pa_atomic_dec(pa_atomic_t *a) { return AO_fetch_and_sub1_full(&a->value); } -static inline int pa_atomic_cmpxchg(pa_atomic_int_t *a, int old_i, int new_i) { +static inline int pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) { return AO_compare_and_swap_full(&a->value, old_i, new_i); } @@ -73,6 +73,8 @@ typedef struct pa_atomic_ptr { volatile AO_t value; } pa_atomic_ptr_t; +#define PA_ATOMIC_PTR_INIT(v) { .value = (AO_t) (v) } + static inline void* pa_atomic_ptr_load(const pa_atomic_ptr_t *a) { return (void*) AO_load_full((AO_t*) &a->value); } diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c index 6989069d..36c85d60 100644 --- a/src/pulsecore/cli-command.c +++ b/src/pulsecore/cli-command.c @@ -95,6 +95,7 @@ static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strb static int pa_cli_command_source_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); static int pa_cli_command_sink_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); static int pa_cli_command_source_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); +static int pa_cli_command_sink_input_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); static int pa_cli_command_sink_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); static int pa_cli_command_source_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); static int pa_cli_command_kill_client(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); @@ -130,12 +131,13 @@ static const struct command commands[] = { { "info", pa_cli_command_info, "Show comprehensive status", 1 }, { "ls", pa_cli_command_info, NULL, 1 }, { "list", pa_cli_command_info, NULL, 1 }, - { "load-module", pa_cli_command_load, "Load a module (args: name, arguments)", 3}, - { "unload-module", pa_cli_command_unload, "Unload a module (args: index)", 2}, - { "set-sink-volume", pa_cli_command_sink_volume, "Set the volume of a sink (args: index|name, volume)", 3}, + { "load-module", pa_cli_command_load, "Load a module (args: name, arguments)", 3}, + { "unload-module", pa_cli_command_unload, "Unload a module (args: index)", 2}, + { "set-sink-volume", pa_cli_command_sink_volume, "Set the volume of a sink (args: index|name, volume)", 3}, { "set-sink-input-volume", pa_cli_command_sink_input_volume, "Set the volume of a sink input (args: index|name, volume)", 3}, { "set-source-volume", pa_cli_command_source_volume, "Set the volume of a source (args: index|name, volume)", 3}, { "set-sink-mute", pa_cli_command_sink_mute, "Set the mute switch of a sink (args: index|name, mute)", 3}, + { "set-sink-input-mute", pa_cli_command_sink_input_mute, "Set the mute switch of a sink input (args: index|name, mute)", 3}, { "set-source-mute", pa_cli_command_source_mute, "Set the mute switch of a source (args: index|name, mute)", 3}, { "set-default-sink", pa_cli_command_sink_default, "Set the default sink (args: index|name)", 2}, { "set-default-source", pa_cli_command_source_default, "Set the default source (args: index|name)", 2}, @@ -392,7 +394,7 @@ static int pa_cli_command_sink_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *bu } pa_cvolume_set(&cvolume, sink->sample_spec.channels, volume); - pa_sink_set_volume(sink, PA_MIXER_HARDWARE, &cvolume); + pa_sink_set_volume(sink, &cvolume); return 0; } @@ -460,7 +462,7 @@ static int pa_cli_command_source_volume(pa_core *c, pa_tokenizer *t, pa_strbuf * } pa_cvolume_set(&cvolume, source->sample_spec.channels, volume); - pa_source_set_volume(source, PA_MIXER_HARDWARE, &cvolume); + pa_source_set_volume(source, &cvolume); return 0; } @@ -489,7 +491,7 @@ static int pa_cli_command_sink_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, return -1; } - pa_sink_set_mute(sink, PA_MIXER_HARDWARE, mute); + pa_sink_set_mute(sink, mute); return 0; } @@ -518,7 +520,42 @@ static int pa_cli_command_source_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *bu return -1; } - pa_source_set_mute(source, PA_MIXER_HARDWARE, mute); + pa_source_set_mute(source, mute); + return 0; +} + +static int pa_cli_command_sink_input_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { + const char *n, *v; + pa_sink_input *si; + uint32_t idx; + int mute; + + if (!(n = pa_tokenizer_get(t, 1))) { + pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n"); + return -1; + } + + if ((idx = parse_index(n)) == PA_IDXSET_INVALID) { + pa_strbuf_puts(buf, "Failed to parse index.\n"); + return -1; + } + + if (!(v = pa_tokenizer_get(t, 2))) { + pa_strbuf_puts(buf, "You need to specify a volume >= 0. (0 is muted, 0x100 is normal volume)\n"); + return -1; + } + + if (pa_atoi(v, &mute) < 0) { + pa_strbuf_puts(buf, "Failed to parse mute switch.\n"); + return -1; + } + + if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) { + pa_strbuf_puts(buf, "No sink input found with this index.\n"); + return -1; + } + + pa_sink_input_set_mute(si, mute); return 0; } @@ -900,7 +937,7 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_G nl = 0; for (sink = pa_idxset_first(c->sinks, &idx); sink; sink = pa_idxset_next(c->sinks, &idx)) { - if (sink->owner && sink->owner->auto_unload) + if (sink->module && sink->module->auto_unload) continue; if (!nl) { @@ -908,12 +945,12 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_G nl = 1; } - pa_strbuf_printf(buf, "set-sink-volume %s 0x%03x\n", sink->name, pa_cvolume_avg(pa_sink_get_volume(sink, PA_MIXER_HARDWARE))); - pa_strbuf_printf(buf, "set-sink-mute %s %d\n", sink->name, pa_sink_get_mute(sink, PA_MIXER_HARDWARE)); + pa_strbuf_printf(buf, "set-sink-volume %s 0x%03x\n", sink->name, pa_cvolume_avg(pa_sink_get_volume(sink))); + pa_strbuf_printf(buf, "set-sink-mute %s %d\n", sink->name, pa_sink_get_mute(sink)); } for (source = pa_idxset_first(c->sources, &idx); source; source = pa_idxset_next(c->sources, &idx)) { - if (source->owner && source->owner->auto_unload) + if (source->module && source->module->auto_unload) continue; if (!nl) { @@ -921,8 +958,8 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_G nl = 1; } - pa_strbuf_printf(buf, "set-source-volume %s 0x%03x\n", source->name, pa_cvolume_avg(pa_source_get_volume(source, PA_MIXER_HARDWARE))); - pa_strbuf_printf(buf, "set-source-mute %s %d\n", source->name, pa_source_get_mute(source, PA_MIXER_HARDWARE)); + pa_strbuf_printf(buf, "set-source-volume %s 0x%03x\n", source->name, pa_cvolume_avg(pa_source_get_volume(source))); + pa_strbuf_printf(buf, "set-source-mute %s %d\n", source->name, pa_source_get_mute(source)); } diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c index 413f9334..05d681e3 100644 --- a/src/pulsecore/cli-text.c +++ b/src/pulsecore/cli-text.c @@ -93,6 +93,12 @@ char *pa_sink_list_to_string(pa_core *c) { pa_strbuf *s; pa_sink *sink; uint32_t idx = PA_IDXSET_INVALID; + static const char* const state_table[] = { + [PA_SINK_RUNNING] = "RUNNING", + [PA_SINK_SUSPENDED] = "SUSPENDED", + [PA_SINK_IDLE] = "IDLE", + [PA_SINK_DISCONNECTED] = "DISCONNECTED" + }; assert(c); s = pa_strbuf_new(); @@ -108,22 +114,29 @@ char *pa_sink_list_to_string(pa_core *c) { " %c index: %u\n" "\tname: <%s>\n" "\tdriver: <%s>\n" + "\tis_hardware: <%i>\n" + "\tstate: %s\n" "\tvolume: <%s>\n" + "\tmute: <%i>\n" "\tlatency: <%0.0f usec>\n" "\tmonitor_source: <%u>\n" "\tsample spec: <%s>\n" "\tchannel map: <%s>\n", c->default_sink_name && !strcmp(sink->name, c->default_sink_name) ? '*' : ' ', - sink->index, sink->name, + sink->index, + sink->name, sink->driver, - pa_cvolume_snprint(cv, sizeof(cv), pa_sink_get_volume(sink, PA_MIXER_HARDWARE)), + !!sink->is_hardware, + state_table[pa_sink_get_state(sink)], + pa_cvolume_snprint(cv, sizeof(cv), pa_sink_get_volume(sink)), + !!pa_sink_get_mute(sink), (double) pa_sink_get_latency(sink), sink->monitor_source ? sink->monitor_source->index : PA_INVALID_INDEX, pa_sample_spec_snprint(ss, sizeof(ss), &sink->sample_spec), pa_channel_map_snprint(cm, sizeof(cm), &sink->channel_map)); - if (sink->owner) - pa_strbuf_printf(s, "\towner module: <%u>\n", sink->owner->index); + if (sink->module) + pa_strbuf_printf(s, "\tmodule: <%u>\n", sink->module->index); if (sink->description) pa_strbuf_printf(s, "\tdescription: <%s>\n", sink->description); } @@ -135,6 +148,12 @@ char *pa_source_list_to_string(pa_core *c) { pa_strbuf *s; pa_source *source; uint32_t idx = PA_IDXSET_INVALID; + static const char* const state_table[] = { + [PA_SOURCE_RUNNING] = "RUNNING", + [PA_SOURCE_SUSPENDED] = "SUSPENDED", + [PA_SOURCE_IDLE] = "IDLE", + [PA_SOURCE_DISCONNECTED] = "DISCONNECTED" + }; assert(c); s = pa_strbuf_new(); @@ -143,7 +162,7 @@ char *pa_source_list_to_string(pa_core *c) { pa_strbuf_printf(s, "%u source(s) available.\n", pa_idxset_size(c->sources)); for (source = pa_idxset_first(c->sources, &idx); source; source = pa_idxset_next(c->sources, &idx)) { - char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX]; + char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX]; pa_strbuf_printf( @@ -151,6 +170,10 @@ char *pa_source_list_to_string(pa_core *c) { " %c index: %u\n" "\tname: <%s>\n" "\tdriver: <%s>\n" + "\tis_hardware: <%i>\n" + "\tstate: %s\n" + "\tvolume: <%s>\n" + "\tmute: <%u>\n" "\tlatency: <%0.0f usec>\n" "\tsample spec: <%s>\n" "\tchannel map: <%s>\n", @@ -158,14 +181,18 @@ char *pa_source_list_to_string(pa_core *c) { source->index, source->name, source->driver, + !!source->is_hardware, + state_table[pa_source_get_state(source)], + pa_cvolume_snprint(cv, sizeof(cv), pa_source_get_volume(source)), + !!pa_source_get_mute(source), (double) pa_source_get_latency(source), pa_sample_spec_snprint(ss, sizeof(ss), &source->sample_spec), pa_channel_map_snprint(cm, sizeof(cm), &source->channel_map)); if (source->monitor_of) pa_strbuf_printf(s, "\tmonitor_of: <%u>\n", source->monitor_of->index); - if (source->owner) - pa_strbuf_printf(s, "\towner module: <%u>\n", source->owner->index); + if (source->module) + pa_strbuf_printf(s, "\tmodule: <%u>\n", source->module->index); if (source->description) pa_strbuf_printf(s, "\tdescription: <%s>\n", source->description); } @@ -179,9 +206,9 @@ char *pa_source_output_list_to_string(pa_core *c) { pa_source_output *o; uint32_t idx = PA_IDXSET_INVALID; static const char* const state_table[] = { - "RUNNING", - "CORKED", - "DISCONNECTED" + [PA_SOURCE_OUTPUT_RUNNING] = "RUNNING", + [PA_SOURCE_OUTPUT_CORKED] = "CORKED", + [PA_SOURCE_OUTPUT_DISCONNECTED] = "DISCONNECTED" }; assert(c); @@ -202,14 +229,16 @@ char *pa_source_output_list_to_string(pa_core *c) { "\tdriver: <%s>\n" "\tstate: %s\n" "\tsource: <%u> '%s'\n" + "\tlatency: <%0.0f usec>\n" "\tsample spec: <%s>\n" "\tchannel map: <%s>\n" "\tresample method: %s\n", o->index, o->name, o->driver, - state_table[o->state], + state_table[pa_source_output_get_state(o)], o->source->index, o->source->name, + (double) pa_source_output_get_latency(o), pa_sample_spec_snprint(ss, sizeof(ss), &o->sample_spec), pa_channel_map_snprint(cm, sizeof(cm), &o->channel_map), pa_resample_method_to_string(pa_source_output_get_resample_method(o))); @@ -227,9 +256,10 @@ char *pa_sink_input_list_to_string(pa_core *c) { pa_sink_input *i; uint32_t idx = PA_IDXSET_INVALID; static const char* const state_table[] = { - "RUNNING", - "CORKED", - "DISCONNECTED" + [PA_SINK_INPUT_RUNNING] = "RUNNING", + [PA_SINK_INPUT_DRAINED] = "DRAINED", + [PA_SINK_INPUT_CORKED] = "CORKED", + [PA_SINK_INPUT_DISCONNECTED] = "DISCONNECTED" }; assert(c); @@ -251,6 +281,7 @@ char *pa_sink_input_list_to_string(pa_core *c) { "\tstate: %s\n" "\tsink: <%u> '%s'\n" "\tvolume: <%s>\n" + "\tmute: <%i>\n" "\tlatency: <%0.0f usec>\n" "\tsample spec: <%s>\n" "\tchannel map: <%s>\n" @@ -258,16 +289,17 @@ char *pa_sink_input_list_to_string(pa_core *c) { i->index, i->name, i->driver, - state_table[i->state], + state_table[pa_sink_input_get_state(i)], i->sink->index, i->sink->name, pa_cvolume_snprint(cv, sizeof(cv), pa_sink_input_get_volume(i)), + !!pa_sink_input_get_mute(i), (double) pa_sink_input_get_latency(i), pa_sample_spec_snprint(ss, sizeof(ss), &i->sample_spec), pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map), pa_resample_method_to_string(pa_sink_input_get_resample_method(i))); if (i->module) - pa_strbuf_printf(s, "\towner module: <%u>\n", i->module->index); + pa_strbuf_printf(s, "\tmodule: <%u>\n", i->module->index); if (i->client) pa_strbuf_printf(s, "\tclient: <%u> '%s'\n", i->client->index, i->client->name); } diff --git a/src/pulsecore/core-def.h b/src/pulsecore/core-def.h index 10a3be42..4bc05137 100644 --- a/src/pulsecore/core-def.h +++ b/src/pulsecore/core-def.h @@ -24,9 +24,6 @@ USA. ***/ -typedef enum pa_mixer { - PA_MIXER_SOFTWARE, - PA_MIXER_HARDWARE -} pa_mixer_t; +/* FIXME: Remove this shit */ #endif diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c index 31b6c188..c80caf14 100644 --- a/src/pulsecore/core.c +++ b/src/pulsecore/core.c @@ -45,13 +45,59 @@ #include #include #include +#include #include "core.h" +static int core_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk) { + pa_core *c = PA_CORE(o); + + pa_core_assert_ref(c); + + switch (code) { + + case PA_CORE_MESSAGE_UNLOAD_MODULE: + pa_module_unload(c, userdata); + return 0; + + default: + return -1; + } +} + +static void asyncmsgq_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) { + pa_core *c = userdata; + + pa_assert(pa_asyncmsgq_get_fd(c->asyncmsgq) == fd); + pa_assert(events == PA_IO_EVENT_INPUT); + + pa_asyncmsgq_after_poll(c->asyncmsgq); + + for (;;) { + pa_msgobject *object; + int code; + void *data; + pa_memchunk chunk; + + /* Check whether there is a message for us to process */ + while (pa_asyncmsgq_get(c->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { + pa_asyncmsgq_dispatch(object, code, data, &chunk); + pa_asyncmsgq_done(c->asyncmsgq, 0); + } + + if (pa_asyncmsgq_before_poll(c->asyncmsgq) == 0) + break; + } +} + +static void core_free(pa_object *o); + pa_core* pa_core_new(pa_mainloop_api *m, int shared) { pa_core* c; pa_mempool *pool; + pa_assert(m); + if (shared) { if (!(pool = pa_mempool_new(shared))) { pa_log_warn("failed to allocate shared memory pool. Falling back to a normal memory pool."); @@ -66,7 +112,9 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { } } - c = pa_xnew(pa_core, 1); + c = pa_msgobject_new(pa_core); + c->parent.parent.free = core_free; + c->parent.process_msg = core_process_msg; c->mainloop = m; c->clients = pa_idxset_new(NULL, NULL); @@ -123,11 +171,17 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { #ifdef SIGPIPE pa_check_signal_is_blocked(SIGPIPE); #endif + + pa_assert_se(c->asyncmsgq = pa_asyncmsgq_new(0)); + pa_assert_se(pa_asyncmsgq_before_poll(c->asyncmsgq) == 0); + pa_assert_se(c->asyncmsgq_event = c->mainloop->io_new(c->mainloop, pa_asyncmsgq_get_fd(c->asyncmsgq), PA_IO_EVENT_INPUT, asyncmsgq_cb, c)); + return c; } -void pa_core_free(pa_core *c) { - assert(c); +static void core_free(pa_object *o) { + pa_core *c = PA_CORE(o); + pa_core_assert_ref(c); pa_module_unload_all(c); assert(!c->modules); @@ -162,6 +216,10 @@ void pa_core_free(pa_core *c) { pa_property_cleanup(c); + c->mainloop->io_free(c->asyncmsgq_event); + pa_asyncmsgq_after_poll(c->asyncmsgq); + pa_asyncmsgq_free(c->asyncmsgq); + pa_hook_free(&c->hook_sink_input_new); pa_hook_free(&c->hook_sink_disconnect); pa_hook_free(&c->hook_source_output_new); diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index 51a18b62..dc2ebb48 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -34,17 +34,21 @@ #include #include #include +#include typedef struct pa_core pa_core; #include #include +#include /* The core structure of PulseAudio. Every PulseAudio daemon contains * exactly one of these. It is used for storing kind of global * variables for the daemon. */ struct pa_core { + pa_msgobject parent; + /* A random value which may be used to identify this instance of * PulseAudio. Not cryptographically secure in any way. */ uint32_t cookie; @@ -88,10 +92,20 @@ struct pa_core { hook_sink_disconnect, hook_source_output_new, hook_source_disconnect; + + pa_asyncmsgq *asyncmsgq; + pa_io_event *asyncmsgq_event; +}; + +PA_DECLARE_CLASS(pa_core); +#define PA_CORE(o) ((pa_core*) o) + +enum { + PA_CORE_MESSAGE_UNLOAD_MODULE, + PA_CORE_MESSAGE_MAX }; pa_core* pa_core_new(pa_mainloop_api *m, int shared); -void pa_core_free(pa_core*c); /* Check whether noone is connected to this core */ void pa_core_check_quit(pa_core *c); diff --git a/src/pulsecore/flist.c b/src/pulsecore/flist.c index 00567ab3..3805e1d1 100644 --- a/src/pulsecore/flist.c +++ b/src/pulsecore/flist.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "flist.h" @@ -90,18 +91,19 @@ enum { }; struct cell { - pa_atomic_int_t state; + pa_atomic_t state; void *data; }; struct pa_flist { - struct cell *cells; unsigned size; - pa_atomic_int_t length; - pa_atomic_int_t read_idx; - pa_atomic_int_t write_idx; + pa_atomic_t length; + pa_atomic_t read_idx; + pa_atomic_t write_idx; }; +#define PA_FLIST_CELLS(x) ((struct cell*) ((uint8_t*) (x) + PA_ALIGN(sizeof(struct pa_flist)))) + static int is_power_of_two(unsigned size) { return !(size & (size - 1)); } @@ -114,10 +116,9 @@ pa_flist *pa_flist_new(unsigned size) { assert(is_power_of_two(size)); - l = pa_xnew(pa_flist, 1); + l = pa_xmalloc0(PA_ALIGN(sizeof(pa_flist)) + (sizeof(struct cell) * size)); l->size = size; - l->cells = pa_xnew0(struct cell, size); pa_atomic_store(&l->read_idx, 0); pa_atomic_store(&l->write_idx, 0); @@ -134,30 +135,35 @@ void pa_flist_free(pa_flist *l, pa_free_cb_t free_cb) { assert(l); if (free_cb) { + struct cell *cells; int len, idx; + cells = PA_FLIST_CELLS(l); + idx = reduce(l, pa_atomic_load(&l->read_idx)); len = pa_atomic_load(&l->length); for (; len > 0; len--) { - if (pa_atomic_load(&l->cells[idx].state) == STATE_USED) - free_cb(l->cells[idx].data); + if (pa_atomic_load(&cells[idx].state) == STATE_USED) + free_cb(cells[idx].data); idx = reduce(l, idx + 1); } } - pa_xfree(l->cells); pa_xfree(l); } int pa_flist_push(pa_flist*l, void *p) { int idx, len, n; + struct cell *cells; assert(l); assert(p); + cells = PA_FLIST_CELLS(l); + n = len = (int) l->size - pa_atomic_load(&l->length) + N_EXTRA_SCAN; _Y; idx = reduce(l, pa_atomic_load(&l->write_idx)); @@ -165,13 +171,13 @@ int pa_flist_push(pa_flist*l, void *p) { for (; n > 0 ; n--) { _Y; - if (pa_atomic_cmpxchg(&l->cells[idx].state, STATE_UNUSED, STATE_BUSY)) { + if (pa_atomic_cmpxchg(&cells[idx].state, STATE_UNUSED, STATE_BUSY)) { _Y; pa_atomic_inc(&l->write_idx); _Y; - l->cells[idx].data = p; + cells[idx].data = p; _Y; - pa_atomic_store(&l->cells[idx].state, STATE_USED); + pa_atomic_store(&cells[idx].state, STATE_USED); _Y; pa_atomic_inc(&l->length); return 0; @@ -191,9 +197,12 @@ int pa_flist_push(pa_flist*l, void *p) { void* pa_flist_pop(pa_flist*l) { int idx, len, n; + struct cell *cells; assert(l); + cells = PA_FLIST_CELLS(l); + n = len = pa_atomic_load(&l->length) + N_EXTRA_SCAN; _Y; idx = reduce(l, pa_atomic_load(&l->read_idx)); @@ -201,14 +210,14 @@ void* pa_flist_pop(pa_flist*l) { for (; n > 0 ; n--) { _Y; - if (pa_atomic_cmpxchg(&l->cells[idx].state, STATE_USED, STATE_BUSY)) { + if (pa_atomic_cmpxchg(&cells[idx].state, STATE_USED, STATE_BUSY)) { void *p; _Y; pa_atomic_inc(&l->read_idx); _Y; - p = l->cells[idx].data; + p = cells[idx].data; _Y; - pa_atomic_store(&l->cells[idx].state, STATE_UNUSED); + pa_atomic_store(&cells[idx].state, STATE_UNUSED); _Y; pa_atomic_dec(&l->length); diff --git a/src/pulsecore/flist.h b/src/pulsecore/flist.h index bf702bf3..80fd86c1 100644 --- a/src/pulsecore/flist.h +++ b/src/pulsecore/flist.h @@ -26,6 +26,8 @@ #include +#include + /* A multiple-reader multipler-write lock-free free list implementation */ typedef struct pa_flist pa_flist; @@ -38,4 +40,22 @@ void pa_flist_free(pa_flist *l, pa_free_cb_t free_cb); int pa_flist_push(pa_flist*l, void *p); void* pa_flist_pop(pa_flist*l); +#define PA_STATIC_FLIST_DECLARE(name, size) \ + struct { \ + pa_flist *flist; \ + pa_once_t once; \ + } name##_static_flist = { NULL, PA_ONCE_INIT }; \ + \ + static void name##_init(void) { \ + name##_static_flist.flist = pa_flist_new(size); \ + } \ + \ + static inline pa_flist* name##_get(void) { \ + pa_once(&name##_static_flist.once, name##_init); \ + return name##_static_flist.flist; \ + } \ + struct __stupid_useless_struct_to_allow_trailing_semicolon + +#define PA_STATIC_FLIST_GET(name) (name##_get()) + #endif diff --git a/src/pulsecore/hashmap.h b/src/pulsecore/hashmap.h index 3ca2a479..98df4502 100644 --- a/src/pulsecore/hashmap.h +++ b/src/pulsecore/hashmap.h @@ -32,11 +32,13 @@ typedef struct pa_hashmap pa_hashmap; +typedef void (*pa_free2_cb_t)(void *p, void *userdata); + /* Create a new hashmap. Use the specified functions for hashing and comparing objects in the map */ pa_hashmap *pa_hashmap_new(pa_hash_func_t hash_func, pa_compare_func_t compare_func); /* Free the hash table. Calls the specified function for every value in the table. The function may be NULL */ -void pa_hashmap_free(pa_hashmap*, void (*free_func)(void *p, void *userdata), void *userdata); +void pa_hashmap_free(pa_hashmap*, pa_free2_cb_t free_cb, void *userdata); /* Returns non-zero when the entry already exists */ int pa_hashmap_put(pa_hashmap *h, const void *key, void *value); diff --git a/src/pulsecore/idxset.c b/src/pulsecore/idxset.c index 70ef7ba7..e683eada 100644 --- a/src/pulsecore/idxset.c +++ b/src/pulsecore/idxset.c @@ -32,6 +32,7 @@ #include #include +#include #include "idxset.h" diff --git a/src/pulsecore/idxset.h b/src/pulsecore/idxset.h index 17a70f4f..5b55cec2 100644 --- a/src/pulsecore/idxset.h +++ b/src/pulsecore/idxset.h @@ -44,11 +44,6 @@ int pa_idxset_trivial_compare_func(const void *a, const void *b); unsigned pa_idxset_string_hash_func(const void *p); int pa_idxset_string_compare_func(const void *a, const void *b); -#define PA_PTR_TO_UINT(p) ((unsigned int) (unsigned long) (p)) -#define PA_UINT_TO_PTR(u) ((void*) (unsigned long) (u)) -#define PA_PTR_TO_UINT32(p) ((uint32_t) PA_PTR_TO_UINT(p)) -#define PA_UINT32_TO_PTR(u) PA_UINT_TO_PTR(u) - typedef unsigned (*pa_hash_func_t)(const void *p); typedef int (*pa_compare_func_t)(const void *a, const void *b); diff --git a/src/pulsecore/macro.h b/src/pulsecore/macro.h new file mode 100644 index 00000000..215c5c02 --- /dev/null +++ b/src/pulsecore/macro.h @@ -0,0 +1,80 @@ +#ifndef foopulsemacrohfoo +#define foopulsemacrohfoo + +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include +#include + +static inline size_t pa_align(size_t l) { + return (((l + sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*)); +} + +#define PA_ALIGN(x) (pa_align(x)) + +#define PA_ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0])) + +#define SA_MAX(a, b) ((a) > (b) ? (a) : (b)) +#define SA_MIN(a, b) ((a) < (b) ? (a) : (b)) + +#ifdef __GNUC__ +#define PA_PRETTY_FUNCTION __PRETTY_FUNCTION__ +#else +#define PA_PRETTY_FUNCTION "" +#endif + +#define pa_return_if_fail(expr) \ + do { \ + if (!(expr)) { \ + pa_log_debug("%s: Assertion <%s> failed.\n", PA_PRETTY_FUNCTION, #expr ); \ + return; \ + } \ + } while(0) + +#define pa_return_val_if_fail(expr, val) \ + do { \ + if (!(expr)) { \ + pa_log_debug("%s: Assertion <%s> failed.\n", PA_PRETTY_FUNCTION, #expr ); \ + return (val); \ + } \ + } while(0) + +#define pa_return_null_if_fail(expr) pa_return_val_if_fail(expr, NULL) + +#define pa_assert assert + +#define pa_assert_not_reached() pa_assert(!"Should not be reached.") + +/* An assert which guarantees side effects of x */ +#define pa_assert_se(x) do { \ + int _r = !!(x); \ + pa_assert(_r); \ + } while(0) + +#define PA_PTR_TO_UINT(p) ((unsigned int) (unsigned long) (p)) +#define PA_UINT_TO_PTR(u) ((void*) (unsigned long) (u)) +#define PA_PTR_TO_UINT32(p) ((uint32_t) PA_PTR_TO_UINT(p)) +#define PA_UINT32_TO_PTR(u) PA_UINT_TO_PTR(u) + +#endif diff --git a/src/pulsecore/mcalign.c b/src/pulsecore/mcalign.c index dd1d71f3..97616437 100644 --- a/src/pulsecore/mcalign.c +++ b/src/pulsecore/mcalign.c @@ -91,6 +91,7 @@ void pa_mcalign_push(pa_mcalign *m, const pa_memchunk *c) { } else { size_t l; + void *lo_data, *m_data; /* We have to copy */ assert(m->leftover.length < m->base); @@ -102,10 +103,15 @@ void pa_mcalign_push(pa_mcalign *m, const pa_memchunk *c) { /* Can we use the current block? */ pa_memchunk_make_writable(&m->leftover, m->base); - memcpy((uint8_t*) m->leftover.memblock->data + m->leftover.index + m->leftover.length, (uint8_t*) c->memblock->data + c->index, l); + lo_data = pa_memblock_acquire(m->leftover.memblock); + m_data = pa_memblock_acquire(c->memblock); + memcpy((uint8_t*) lo_data + m->leftover.index + m->leftover.length, (uint8_t*) m_data + c->index, l); + pa_memblock_release(m->leftover.memblock); + pa_memblock_release(c->memblock); m->leftover.length += l; - assert(m->leftover.length <= m->base && m->leftover.length <= m->leftover.memblock->length); + assert(m->leftover.length <= m->base); + assert(m->leftover.length <= pa_memblock_get_length(m->leftover.memblock)); if (c->length > l) { /* Save the remainder of the memory block */ diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index 6f09a906..71b576ac 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -33,10 +33,14 @@ #include #include +#include #include #include #include +#include +#include +#include #include "memblock.h" @@ -48,6 +52,32 @@ #define PA_MEMIMPORT_SLOTS_MAX 128 #define PA_MEMIMPORT_SEGMENTS_MAX 16 +struct pa_memblock { + PA_REFCNT_DECLARE; /* the reference counter */ + pa_mempool *pool; + + pa_memblock_type_t type; + int read_only; /* boolean */ + + pa_atomic_ptr_t data; + size_t length; + + pa_atomic_t n_acquired; + pa_atomic_t please_signal; + + union { + struct { + /* If type == PA_MEMBLOCK_USER this points to a function for freeing this memory block */ + pa_free_cb_t free_cb; + } user; + + struct { + uint32_t id; + pa_memimport_segment *segment; + } imported; + } per_type; +}; + struct pa_memimport_segment { pa_memimport *import; pa_shm memory; @@ -55,6 +85,8 @@ struct pa_memimport_segment { }; struct pa_memimport { + pa_mutex *mutex; + pa_mempool *pool; pa_hashmap *segments; pa_hashmap *blocks; @@ -73,9 +105,11 @@ struct memexport_slot { }; struct pa_memexport { + pa_mutex *mutex; pa_mempool *pool; struct memexport_slot slots[PA_MEMEXPORT_SLOTS_MAX]; + PA_LLIST_HEAD(struct memexport_slot, free_slots); PA_LLIST_HEAD(struct memexport_slot, used_slots); unsigned n_init; @@ -95,21 +129,27 @@ struct mempool_slot { }; struct pa_mempool { + pa_semaphore *semaphore; + pa_mutex *mutex; + pa_shm memory; size_t block_size; - unsigned n_blocks, n_init; + unsigned n_blocks; + + pa_atomic_t n_init; PA_LLIST_HEAD(pa_memimport, imports); PA_LLIST_HEAD(pa_memexport, exports); /* A list of free slots that may be reused */ - PA_LLIST_HEAD(struct mempool_slot, free_slots); + pa_flist *free_slots; pa_mempool_stat stat; }; static void segment_detach(pa_memimport_segment *seg); +/* No lock necessary */ static void stat_add(pa_memblock*b) { assert(b); assert(b->pool); @@ -129,6 +169,7 @@ static void stat_add(pa_memblock*b) { pa_atomic_inc(&b->pool->stat.n_accumulated_by_type[b->type]); } +/* No lock necessary */ static void stat_remove(pa_memblock *b) { assert(b); assert(b->pool); @@ -152,6 +193,7 @@ static void stat_remove(pa_memblock *b) { static pa_memblock *memblock_new_appended(pa_mempool *p, size_t length); +/* No lock necessary */ pa_memblock *pa_memblock_new(pa_mempool *p, size_t length) { pa_memblock *b; @@ -164,56 +206,70 @@ pa_memblock *pa_memblock_new(pa_mempool *p, size_t length) { return b; } +/* No lock necessary */ static pa_memblock *memblock_new_appended(pa_mempool *p, size_t length) { pa_memblock *b; assert(p); assert(length > 0); - b = pa_xmalloc(sizeof(pa_memblock) + length); + b = pa_xmalloc(PA_ALIGN(sizeof(pa_memblock)) + length); + PA_REFCNT_INIT(b); + b->pool = p; b->type = PA_MEMBLOCK_APPENDED; b->read_only = 0; - PA_REFCNT_INIT(b); + pa_atomic_ptr_store(&b->data, (uint8_t*) b + PA_ALIGN(sizeof(pa_memblock))); b->length = length; - b->data = (uint8_t*) b + sizeof(pa_memblock); - b->pool = p; + pa_atomic_store(&b->n_acquired, 0); + pa_atomic_store(&b->please_signal, 0); stat_add(b); return b; } +/* No lock necessary */ static struct mempool_slot* mempool_allocate_slot(pa_mempool *p) { struct mempool_slot *slot; assert(p); - if (p->free_slots) { - slot = p->free_slots; - PA_LLIST_REMOVE(struct mempool_slot, p->free_slots, slot); - } else if (p->n_init < p->n_blocks) - slot = (struct mempool_slot*) ((uint8_t*) p->memory.ptr + (p->block_size * p->n_init++)); - else { - pa_log_debug("Pool full"); - pa_atomic_inc(&p->stat.n_pool_full); - return NULL; + if (!(slot = pa_flist_pop(p->free_slots))) { + int idx; + + /* The free list was empty, we have to allocate a new entry */ + + if ((unsigned) (idx = pa_atomic_inc(&p->n_init)) >= p->n_blocks) + pa_atomic_dec(&p->n_init); + else + slot = (struct mempool_slot*) ((uint8_t*) p->memory.ptr + (p->block_size * idx)); + + if (!slot) { + pa_log_debug("Pool full"); + pa_atomic_inc(&p->stat.n_pool_full); + return NULL; + } } return slot; } +/* No lock necessary */ static void* mempool_slot_data(struct mempool_slot *slot) { assert(slot); return (uint8_t*) slot + sizeof(struct mempool_slot); } +/* No lock necessary */ static unsigned mempool_slot_idx(pa_mempool *p, void *ptr) { assert(p); + assert((uint8_t*) ptr >= (uint8_t*) p->memory.ptr); assert((uint8_t*) ptr < (uint8_t*) p->memory.ptr + p->memory.size); return ((uint8_t*) ptr - (uint8_t*) p->memory.ptr) / p->block_size; } +/* No lock necessary */ static struct mempool_slot* mempool_slot_by_ptr(pa_mempool *p, void *ptr) { unsigned idx; @@ -223,6 +279,7 @@ static struct mempool_slot* mempool_slot_by_ptr(pa_mempool *p, void *ptr) { return (struct mempool_slot*) ((uint8_t*) p->memory.ptr + (idx * p->block_size)); } +/* No lock necessary */ pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) { pa_memblock *b = NULL; struct mempool_slot *slot; @@ -237,7 +294,7 @@ pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) { b = mempool_slot_data(slot); b->type = PA_MEMBLOCK_POOL; - b->data = (uint8_t*) b + sizeof(pa_memblock); + pa_atomic_ptr_store(&b->data, (uint8_t*) b + sizeof(pa_memblock)); } else if (p->block_size - sizeof(struct mempool_slot) >= length) { @@ -246,22 +303,26 @@ pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) { b = pa_xnew(pa_memblock, 1); b->type = PA_MEMBLOCK_POOL_EXTERNAL; - b->data = mempool_slot_data(slot); + pa_atomic_ptr_store(&b->data, mempool_slot_data(slot)); + } else { pa_log_debug("Memory block too large for pool: %u > %u", length, p->block_size - sizeof(struct mempool_slot)); pa_atomic_inc(&p->stat.n_too_large_for_pool); return NULL; } - b->length = length; - b->read_only = 0; PA_REFCNT_INIT(b); b->pool = p; + b->read_only = 0; + b->length = length; + pa_atomic_store(&b->n_acquired, 0); + pa_atomic_store(&b->please_signal, 0); stat_add(b); return b; } +/* No lock necessary */ pa_memblock *pa_memblock_new_fixed(pa_mempool *p, void *d, size_t length, int read_only) { pa_memblock *b; @@ -270,17 +331,20 @@ pa_memblock *pa_memblock_new_fixed(pa_mempool *p, void *d, size_t length, int re assert(length > 0); b = pa_xnew(pa_memblock, 1); + PA_REFCNT_INIT(b); + b->pool = p; b->type = PA_MEMBLOCK_FIXED; b->read_only = read_only; - PA_REFCNT_INIT(b); + pa_atomic_ptr_store(&b->data, d); b->length = length; - b->data = d; - b->pool = p; + pa_atomic_store(&b->n_acquired, 0); + pa_atomic_store(&b->please_signal, 0); stat_add(b); return b; } +/* No lock necessary */ pa_memblock *pa_memblock_new_user(pa_mempool *p, void *d, size_t length, void (*free_cb)(void *p), int read_only) { pa_memblock *b; @@ -290,18 +354,68 @@ pa_memblock *pa_memblock_new_user(pa_mempool *p, void *d, size_t length, void (* assert(free_cb); b = pa_xnew(pa_memblock, 1); + PA_REFCNT_INIT(b); + b->pool = p; b->type = PA_MEMBLOCK_USER; b->read_only = read_only; - PA_REFCNT_INIT(b); + pa_atomic_ptr_store(&b->data, d); b->length = length; - b->data = d; + pa_atomic_store(&b->n_acquired, 0); + pa_atomic_store(&b->please_signal, 0); + b->per_type.user.free_cb = free_cb; - b->pool = p; stat_add(b); return b; } +/* No lock necessary */ +int pa_memblock_is_read_only(pa_memblock *b) { + assert(b); + assert(PA_REFCNT_VALUE(b) > 0); + + return b->read_only && PA_REFCNT_VALUE(b) == 1; +} + +/* No lock necessary */ +void* pa_memblock_acquire(pa_memblock *b) { + assert(b); + assert(PA_REFCNT_VALUE(b) > 0); + + pa_atomic_inc(&b->n_acquired); + + return pa_atomic_ptr_load(&b->data); +} + +/* No lock necessary, in corner cases locks by its own */ +void pa_memblock_release(pa_memblock *b) { + int r; + assert(b); + assert(PA_REFCNT_VALUE(b) > 0); + + r = pa_atomic_dec(&b->n_acquired); + assert(r >= 1); + + /* Signal a waiting thread that this memblock is no longer used */ + if (r == 1 && pa_atomic_load(&b->please_signal)) + pa_semaphore_post(b->pool->semaphore); +} + +size_t pa_memblock_get_length(pa_memblock *b) { + assert(b); + assert(PA_REFCNT_VALUE(b) > 0); + + return b->length; +} + +pa_mempool* pa_memblock_get_pool(pa_memblock *b) { + assert(b); + assert(PA_REFCNT_VALUE(b) > 0); + + return b->pool; +} + +/* No lock necessary */ pa_memblock* pa_memblock_ref(pa_memblock*b) { assert(b); assert(PA_REFCNT_VALUE(b) > 0); @@ -310,19 +424,17 @@ pa_memblock* pa_memblock_ref(pa_memblock*b) { return b; } -void pa_memblock_unref(pa_memblock*b) { +static void memblock_free(pa_memblock *b) { assert(b); - assert(PA_REFCNT_VALUE(b) > 0); - if (PA_REFCNT_DEC(b) > 0) - return; + assert(pa_atomic_load(&b->n_acquired) == 0); stat_remove(b); switch (b->type) { case PA_MEMBLOCK_USER : assert(b->per_type.user.free_cb); - b->per_type.user.free_cb(b->data); + b->per_type.user.free_cb(pa_atomic_ptr_load(&b->data)); /* Fall through */ @@ -333,17 +445,24 @@ void pa_memblock_unref(pa_memblock*b) { case PA_MEMBLOCK_IMPORTED : { pa_memimport_segment *segment; + pa_memimport *import; + + /* FIXME! This should be implemented lock-free */ segment = b->per_type.imported.segment; assert(segment); - assert(segment->import); - - pa_hashmap_remove(segment->import->blocks, PA_UINT32_TO_PTR(b->per_type.imported.id)); - segment->import->release_cb(segment->import, b->per_type.imported.id, segment->import->userdata); + import = segment->import; + assert(import); + pa_mutex_lock(import->mutex); + pa_hashmap_remove(import->blocks, PA_UINT32_TO_PTR(b->per_type.imported.id)); if (-- segment->n_blocks <= 0) segment_detach(segment); + pa_mutex_unlock(import->mutex); + + import->release_cb(import, b->per_type.imported.id, import->userdata); + pa_xfree(b); break; } @@ -351,13 +470,20 @@ void pa_memblock_unref(pa_memblock*b) { case PA_MEMBLOCK_POOL_EXTERNAL: case PA_MEMBLOCK_POOL: { struct mempool_slot *slot; + int call_free; - slot = mempool_slot_by_ptr(b->pool, b->data); + slot = mempool_slot_by_ptr(b->pool, pa_atomic_ptr_load(&b->data)); assert(slot); - PA_LLIST_PREPEND(struct mempool_slot, b->pool->free_slots, slot); + call_free = b->type == PA_MEMBLOCK_POOL_EXTERNAL; - if (b->type == PA_MEMBLOCK_POOL_EXTERNAL) + /* The free list dimensions should easily allow all slots + * to fit in, hence try harder if pushing this slot into + * the free list fails */ + while (pa_flist_push(b->pool->free_slots, slot) < 0) + ; + + if (call_free) pa_xfree(b); break; @@ -369,6 +495,36 @@ void pa_memblock_unref(pa_memblock*b) { } } +/* No lock necessary */ +void pa_memblock_unref(pa_memblock*b) { + assert(b); + assert(PA_REFCNT_VALUE(b) > 0); + + if (PA_REFCNT_DEC(b) > 0) + return; + + memblock_free(b); +} + +/* Self locked */ +static void memblock_wait(pa_memblock *b) { + assert(b); + + if (pa_atomic_load(&b->n_acquired) > 0) { + /* We need to wait until all threads gave up access to the + * memory block before we can go on. Unfortunately this means + * that we have to lock and wait here. Sniff! */ + + pa_atomic_inc(&b->please_signal); + + while (pa_atomic_load(&b->n_acquired) > 0) + pa_semaphore_wait(b->pool->semaphore); + + pa_atomic_dec(&b->please_signal); + } +} + +/* No lock necessary. This function is not multiple caller safe! */ static void memblock_make_local(pa_memblock *b) { assert(b); @@ -381,38 +537,43 @@ static void memblock_make_local(pa_memblock *b) { void *new_data; /* We can move it into a local pool, perfect! */ + new_data = mempool_slot_data(slot); + memcpy(new_data, pa_atomic_ptr_load(&b->data), b->length); + pa_atomic_ptr_store(&b->data, new_data); + b->type = PA_MEMBLOCK_POOL_EXTERNAL; b->read_only = 0; - new_data = mempool_slot_data(slot); - memcpy(new_data, b->data, b->length); - b->data = new_data; goto finish; } } /* Humm, not enough space in the pool, so lets allocate the memory with malloc() */ - b->type = PA_MEMBLOCK_USER; b->per_type.user.free_cb = pa_xfree; + pa_atomic_ptr_store(&b->data, pa_xmemdup(pa_atomic_ptr_load(&b->data), b->length)); + + b->type = PA_MEMBLOCK_USER; b->read_only = 0; - b->data = pa_xmemdup(b->data, b->length); finish: pa_atomic_inc(&b->pool->stat.n_allocated_by_type[b->type]); pa_atomic_inc(&b->pool->stat.n_accumulated_by_type[b->type]); + memblock_wait(b); } +/* No lock necessary. This function is not multiple caller safe*/ void pa_memblock_unref_fixed(pa_memblock *b) { assert(b); assert(PA_REFCNT_VALUE(b) > 0); assert(b->type == PA_MEMBLOCK_FIXED); - if (PA_REFCNT_VALUE(b) > 1) + if (PA_REFCNT_DEC(b) > 0) memblock_make_local(b); - - pa_memblock_unref(b); + else + memblock_free(b); } +/* Self-locked. This function is not multiple-caller safe */ static void memblock_replace_import(pa_memblock *b) { pa_memimport_segment *seg; @@ -428,6 +589,8 @@ static void memblock_replace_import(pa_memblock *b) { assert(seg); assert(seg->import); + pa_mutex_lock(seg->import->mutex); + pa_hashmap_remove( seg->import->blocks, PA_UINT32_TO_PTR(b->per_type.imported.id)); @@ -436,6 +599,8 @@ static void memblock_replace_import(pa_memblock *b) { if (-- seg->n_blocks <= 0) segment_detach(seg); + + pa_mutex_unlock(seg->import->mutex); } pa_mempool* pa_mempool_new(int shared) { @@ -444,12 +609,15 @@ pa_mempool* pa_mempool_new(int shared) { p = pa_xnew(pa_mempool, 1); + p->mutex = pa_mutex_new(1); + p->semaphore = pa_semaphore_new(0); + #ifdef HAVE_SYSCONF ps = (size_t) sysconf(_SC_PAGESIZE); #elif defined(PAGE_SIZE) - ps = (size_t) PAGE_SIZE; + ps = (size_t) PAGE_SIZE; #else - ps = 4096; /* Let's hope it's like x86. */ + ps = 4096; /* Let's hope it's like x86. */ #endif p->block_size = (PA_MEMPOOL_SLOT_SIZE/ps)*ps; @@ -466,13 +634,13 @@ pa_mempool* pa_mempool_new(int shared) { return NULL; } - p->n_init = 0; + memset(&p->stat, 0, sizeof(p->stat)); + pa_atomic_store(&p->n_init, 0); PA_LLIST_HEAD_INIT(pa_memimport, p->imports); PA_LLIST_HEAD_INIT(pa_memexport, p->exports); - PA_LLIST_HEAD_INIT(struct mempool_slot, p->free_slots); - memset(&p->stat, 0, sizeof(p->stat)); + p->free_slots = pa_flist_new(p->n_blocks*2); return p; } @@ -480,34 +648,61 @@ pa_mempool* pa_mempool_new(int shared) { void pa_mempool_free(pa_mempool *p) { assert(p); + pa_mutex_lock(p->mutex); + while (p->imports) pa_memimport_free(p->imports); while (p->exports) pa_memexport_free(p->exports); + pa_mutex_unlock(p->mutex); + if (pa_atomic_load(&p->stat.n_allocated) > 0) pa_log_warn("WARNING! Memory pool destroyed but not all memory blocks freed!"); + pa_flist_free(p->free_slots, NULL); pa_shm_free(&p->memory); + + pa_mutex_free(p->mutex); + pa_semaphore_free(p->semaphore); + pa_xfree(p); } +/* No lock necessary */ const pa_mempool_stat* pa_mempool_get_stat(pa_mempool *p) { assert(p); return &p->stat; } +/* No lock necessary */ void pa_mempool_vacuum(pa_mempool *p) { struct mempool_slot *slot; + pa_flist *list; assert(p); - for (slot = p->free_slots; slot; slot = slot->next) - pa_shm_punch(&p->memory, (uint8_t*) slot + sizeof(struct mempool_slot) - (uint8_t*) p->memory.ptr, p->block_size - sizeof(struct mempool_slot)); + list = pa_flist_new(p->n_blocks*2); + + while ((slot = pa_flist_pop(p->free_slots))) + while (pa_flist_push(list, slot) < 0) + ; + + while ((slot = pa_flist_pop(list))) { + pa_shm_punch(&p->memory, + (uint8_t*) slot - (uint8_t*) p->memory.ptr + sizeof(struct mempool_slot), + p->block_size - sizeof(struct mempool_slot)); + + while (pa_flist_push(p->free_slots, slot)) + ; + } + + pa_flist_free(list, NULL); } +/* No lock necessary */ int pa_mempool_get_shm_id(pa_mempool *p, uint32_t *id) { assert(p); @@ -519,6 +714,7 @@ int pa_mempool_get_shm_id(pa_mempool *p, uint32_t *id) { return 0; } +/* No lock necessary */ int pa_mempool_is_shared(pa_mempool *p) { assert(p); @@ -533,18 +729,23 @@ pa_memimport* pa_memimport_new(pa_mempool *p, pa_memimport_release_cb_t cb, void assert(cb); i = pa_xnew(pa_memimport, 1); + i->mutex = pa_mutex_new(0); i->pool = p; i->segments = pa_hashmap_new(NULL, NULL); i->blocks = pa_hashmap_new(NULL, NULL); i->release_cb = cb; i->userdata = userdata; + pa_mutex_lock(p->mutex); PA_LLIST_PREPEND(pa_memimport, p->imports, i); + pa_mutex_unlock(p->mutex); + return i; } static void memexport_revoke_blocks(pa_memexport *e, pa_memimport *i); +/* Should be called locked */ static pa_memimport_segment* segment_attach(pa_memimport *i, uint32_t shm_id) { pa_memimport_segment* seg; @@ -565,6 +766,7 @@ static pa_memimport_segment* segment_attach(pa_memimport *i, uint32_t shm_id) { return seg; } +/* Should be called locked */ static void segment_detach(pa_memimport_segment *seg) { assert(seg); @@ -573,51 +775,68 @@ static void segment_detach(pa_memimport_segment *seg) { pa_xfree(seg); } +/* Self-locked. Not multiple-caller safe */ void pa_memimport_free(pa_memimport *i) { pa_memexport *e; pa_memblock *b; assert(i); - /* If we've exported this block further we need to revoke that export */ - for (e = i->pool->exports; e; e = e->next) - memexport_revoke_blocks(e, i); + pa_mutex_lock(i->mutex); while ((b = pa_hashmap_get_first(i->blocks))) memblock_replace_import(b); assert(pa_hashmap_size(i->segments) == 0); + pa_mutex_unlock(i->mutex); + + pa_mutex_lock(i->pool->mutex); + + /* If we've exported this block further we need to revoke that export */ + for (e = i->pool->exports; e; e = e->next) + memexport_revoke_blocks(e, i); + + PA_LLIST_REMOVE(pa_memimport, i->pool->imports, i); + + pa_mutex_unlock(i->pool->mutex); + pa_hashmap_free(i->blocks, NULL, NULL); pa_hashmap_free(i->segments, NULL, NULL); - PA_LLIST_REMOVE(pa_memimport, i->pool->imports, i); + pa_mutex_free(i->mutex); + pa_xfree(i); } +/* Self-locked */ pa_memblock* pa_memimport_get(pa_memimport *i, uint32_t block_id, uint32_t shm_id, size_t offset, size_t size) { - pa_memblock *b; + pa_memblock *b = NULL; pa_memimport_segment *seg; assert(i); + pa_mutex_lock(i->mutex); + if (pa_hashmap_size(i->blocks) >= PA_MEMIMPORT_SLOTS_MAX) - return NULL; + goto finish; if (!(seg = pa_hashmap_get(i->segments, PA_UINT32_TO_PTR(shm_id)))) if (!(seg = segment_attach(i, shm_id))) - return NULL; + goto finish; if (offset+size > seg->memory.size) - return NULL; + goto finish; b = pa_xnew(pa_memblock, 1); + PA_REFCNT_INIT(b); + b->pool = i->pool; b->type = PA_MEMBLOCK_IMPORTED; b->read_only = 1; - PA_REFCNT_INIT(b); + pa_atomic_ptr_store(&b->data, (uint8_t*) seg->memory.ptr + offset); b->length = size; - b->data = (uint8_t*) seg->memory.ptr + offset; - b->pool = i->pool; + pa_atomic_store(&b->n_acquired, 0); + pa_atomic_store(&b->please_signal, 0); b->per_type.imported.id = block_id; b->per_type.imported.segment = seg; @@ -625,6 +844,10 @@ pa_memblock* pa_memimport_get(pa_memimport *i, uint32_t block_id, uint32_t shm_i seg->n_blocks++; +finish: + pa_mutex_unlock(i->mutex); + + if (b) stat_add(b); return b; @@ -634,10 +857,15 @@ int pa_memimport_process_revoke(pa_memimport *i, uint32_t id) { pa_memblock *b; assert(i); + pa_mutex_lock(i->mutex); + if (!(b = pa_hashmap_get(i->blocks, PA_UINT32_TO_PTR(id)))) return -1; memblock_replace_import(b); + + pa_mutex_unlock(i->mutex); + return 0; } @@ -652,6 +880,7 @@ pa_memexport* pa_memexport_new(pa_mempool *p, pa_memexport_revoke_cb_t cb, void return NULL; e = pa_xnew(pa_memexport, 1); + e->mutex = pa_mutex_new(1); e->pool = p; PA_LLIST_HEAD_INIT(struct memexport_slot, e->free_slots); PA_LLIST_HEAD_INIT(struct memexport_slot, e->used_slots); @@ -659,51 +888,75 @@ pa_memexport* pa_memexport_new(pa_mempool *p, pa_memexport_revoke_cb_t cb, void e->revoke_cb = cb; e->userdata = userdata; + pa_mutex_lock(p->mutex); PA_LLIST_PREPEND(pa_memexport, p->exports, e); + pa_mutex_unlock(p->mutex); return e; } void pa_memexport_free(pa_memexport *e) { assert(e); + pa_mutex_lock(e->mutex); while (e->used_slots) pa_memexport_process_release(e, e->used_slots - e->slots); + pa_mutex_unlock(e->mutex); + pa_mutex_lock(e->pool->mutex); PA_LLIST_REMOVE(pa_memexport, e->pool->exports, e); + pa_mutex_unlock(e->pool->mutex); + pa_xfree(e); } +/* Self-locked */ int pa_memexport_process_release(pa_memexport *e, uint32_t id) { + pa_memblock *b; + assert(e); + pa_mutex_lock(e->mutex); + if (id >= e->n_init) - return -1; + goto fail; if (!e->slots[id].block) - return -1; + goto fail; + + b = e->slots[id].block; + e->slots[id].block = NULL; + + PA_LLIST_REMOVE(struct memexport_slot, e->used_slots, &e->slots[id]); + PA_LLIST_PREPEND(struct memexport_slot, e->free_slots, &e->slots[id]); + + pa_mutex_unlock(e->mutex); /* pa_log("Processing release for %u", id); */ assert(pa_atomic_load(&e->pool->stat.n_exported) > 0); - assert(pa_atomic_load(&e->pool->stat.exported_size) >= (int) e->slots[id].block->length); + assert(pa_atomic_load(&e->pool->stat.exported_size) >= (int) b->length); pa_atomic_dec(&e->pool->stat.n_exported); - pa_atomic_sub(&e->pool->stat.exported_size, e->slots[id].block->length); - - pa_memblock_unref(e->slots[id].block); - e->slots[id].block = NULL; + pa_atomic_sub(&e->pool->stat.exported_size, b->length); - PA_LLIST_REMOVE(struct memexport_slot, e->used_slots, &e->slots[id]); - PA_LLIST_PREPEND(struct memexport_slot, e->free_slots, &e->slots[id]); + pa_memblock_unref(b); return 0; + +fail: + pa_mutex_unlock(e->mutex); + + return -1; } +/* Self-locked */ static void memexport_revoke_blocks(pa_memexport *e, pa_memimport *i) { struct memexport_slot *slot, *next; assert(e); assert(i); + pa_mutex_lock(e->mutex); + for (slot = e->used_slots; slot; slot = next) { uint32_t idx; next = slot->next; @@ -716,8 +969,11 @@ static void memexport_revoke_blocks(pa_memexport *e, pa_memimport *i) { e->revoke_cb(e, idx, e->userdata); pa_memexport_process_release(e, idx); } + + pa_mutex_unlock(e->mutex); } +/* No lock necessary */ static pa_memblock *memblock_shared_copy(pa_mempool *p, pa_memblock *b) { pa_memblock *n; @@ -734,13 +990,16 @@ static pa_memblock *memblock_shared_copy(pa_mempool *p, pa_memblock *b) { if (!(n = pa_memblock_new_pool(p, b->length))) return NULL; - memcpy(n->data, b->data, b->length); + memcpy(pa_atomic_ptr_load(&n->data), pa_atomic_ptr_load(&b->data), b->length); return n; } +/* Self-locked */ int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32_t *shm_id, size_t *offset, size_t * size) { pa_shm *memory; struct memexport_slot *slot; + void *data; + size_t length; assert(e); assert(b); @@ -753,12 +1012,15 @@ int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32 if (!(b = memblock_shared_copy(e->pool, b))) return -1; + pa_mutex_lock(e->mutex); + if (e->free_slots) { slot = e->free_slots; PA_LLIST_REMOVE(struct memexport_slot, e->free_slots, slot); - } else if (e->n_init < PA_MEMEXPORT_SLOTS_MAX) { + } else if (e->n_init < PA_MEMEXPORT_SLOTS_MAX) slot = &e->slots[e->n_init++]; - } else { + else { + pa_mutex_unlock(e->mutex); pa_memblock_unref(b); return -1; } @@ -767,8 +1029,11 @@ int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32 slot->block = b; *block_id = slot - e->slots; + pa_mutex_unlock(e->mutex); /* pa_log("Got block id %u", *block_id); */ + data = pa_memblock_acquire(b); + if (b->type == PA_MEMBLOCK_IMPORTED) { assert(b->per_type.imported.segment); memory = &b->per_type.imported.segment->memory; @@ -778,15 +1043,17 @@ int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32 memory = &b->pool->memory; } - assert(b->data >= memory->ptr); - assert((uint8_t*) b->data + b->length <= (uint8_t*) memory->ptr + memory->size); + assert(data >= memory->ptr); + assert((uint8_t*) data + length <= (uint8_t*) memory->ptr + memory->size); *shm_id = memory->id; - *offset = (uint8_t*) b->data - (uint8_t*) memory->ptr; - *size = b->length; + *offset = (uint8_t*) data - (uint8_t*) memory->ptr; + *size = length; + + pa_memblock_release(b); pa_atomic_inc(&e->pool->stat.n_exported); - pa_atomic_add(&e->pool->stat.exported_size, b->length); + pa_atomic_add(&e->pool->stat.exported_size, length); return 0; } diff --git a/src/pulsecore/memblock.h b/src/pulsecore/memblock.h index fe4773d4..6f8bbef3 100644 --- a/src/pulsecore/memblock.h +++ b/src/pulsecore/memblock.h @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -58,45 +59,25 @@ typedef struct pa_memexport pa_memexport; typedef void (*pa_memimport_release_cb_t)(pa_memimport *i, uint32_t block_id, void *userdata); typedef void (*pa_memexport_revoke_cb_t)(pa_memexport *e, uint32_t block_id, void *userdata); -struct pa_memblock { - pa_memblock_type_t type; - int read_only; /* boolean */ - PA_REFCNT_DECLARE; /* the reference counter */ - size_t length; - void *data; - pa_mempool *pool; - - union { - struct { - void (*free_cb)(void *p); /* If type == PA_MEMBLOCK_USER this points to a function for freeing this memory block */ - } user; - - struct { - uint32_t id; - pa_memimport_segment *segment; - } imported; - } per_type; -}; - /* Please note that updates to this structure are not locked, * i.e. n_allocated might be updated at a point in time where * n_accumulated is not yet. Take these values with a grain of salt, - * threy are here for purely statistical reasons.*/ + * they are here for purely statistical reasons.*/ struct pa_mempool_stat { - pa_atomic_int_t n_allocated; - pa_atomic_int_t n_accumulated; - pa_atomic_int_t n_imported; - pa_atomic_int_t n_exported; - pa_atomic_int_t allocated_size; - pa_atomic_int_t accumulated_size; - pa_atomic_int_t imported_size; - pa_atomic_int_t exported_size; - - pa_atomic_int_t n_too_large_for_pool; - pa_atomic_int_t n_pool_full; - - pa_atomic_int_t n_allocated_by_type[PA_MEMBLOCK_TYPE_MAX]; - pa_atomic_int_t n_accumulated_by_type[PA_MEMBLOCK_TYPE_MAX]; + pa_atomic_t n_allocated; + pa_atomic_t n_accumulated; + pa_atomic_t n_imported; + pa_atomic_t n_exported; + pa_atomic_t allocated_size; + pa_atomic_t accumulated_size; + pa_atomic_t imported_size; + pa_atomic_t exported_size; + + pa_atomic_t n_too_large_for_pool; + pa_atomic_t n_pool_full; + + pa_atomic_t n_allocated_by_type[PA_MEMBLOCK_TYPE_MAX]; + pa_atomic_t n_accumulated_by_type[PA_MEMBLOCK_TYPE_MAX]; }; /* Allocate a new memory block of type PA_MEMBLOCK_MEMPOOL or PA_MEMBLOCK_APPENDED, depending on the size */ @@ -120,9 +101,17 @@ pa_memblock* pa_memblock_ref(pa_memblock*b); /* This special unref function has to be called by the owner of the memory of a static memory block when he wants to release all references to the memory. This causes the memory to be copied and -converted into a PA_MEMBLOCK_DYNAMIC type memory block */ +converted into a pool or malloc'ed memory block. Please note that this +function is not multiple caller safe, i.e. needs to be locked +manually if called from more than one thread at the same time. */ void pa_memblock_unref_fixed(pa_memblock*b); +int pa_memblock_is_read_only(pa_memblock *b); +void* pa_memblock_acquire(pa_memblock *b); +void pa_memblock_release(pa_memblock *b); +size_t pa_memblock_get_length(pa_memblock *b); +pa_mempool * pa_memblock_get_pool(pa_memblock *b); + /* The memory block manager */ pa_mempool* pa_mempool_new(int shared); void pa_mempool_free(pa_mempool *p); diff --git a/src/pulsecore/memblockq.c b/src/pulsecore/memblockq.c index e31fb6df..a80df338 100644 --- a/src/pulsecore/memblockq.c +++ b/src/pulsecore/memblockq.c @@ -178,7 +178,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { assert(uchunk); assert(uchunk->memblock); assert(uchunk->length > 0); - assert(uchunk->index + uchunk->length <= uchunk->memblock->length); + assert(uchunk->index + uchunk->length <= pa_memblock_get_length(uchunk->memblock)); if (uchunk->length % bq->base) return -1; @@ -362,8 +362,8 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) { if (bq->silence) { chunk->memblock = pa_memblock_ref(bq->silence); - if (!length || length > chunk->memblock->length) - length = chunk->memblock->length; + if (!length || length > pa_memblock_get_length(chunk->memblock)) + length = pa_memblock_get_length(chunk->memblock); chunk->length = length; } else { @@ -415,8 +415,8 @@ void pa_memblockq_drop(pa_memblockq *bq, const pa_memchunk *chunk, size_t length if (bq->silence) { - if (!l || l > bq->silence->length) - l = bq->silence->length; + if (!l || l > pa_memblock_get_length(bq->silence)) + l = pa_memblock_get_length(bq->silence); } diff --git a/src/pulsecore/memchunk.c b/src/pulsecore/memchunk.c index 7111e1ec..f00cc9e7 100644 --- a/src/pulsecore/memchunk.c +++ b/src/pulsecore/memchunk.c @@ -37,22 +37,25 @@ void pa_memchunk_make_writable(pa_memchunk *c, size_t min) { pa_memblock *n; size_t l; + void *tdata, *sdata; assert(c); assert(c->memblock); - assert(PA_REFCNT_VALUE(c->memblock) > 0); - if (PA_REFCNT_VALUE(c->memblock) == 1 && - !c->memblock->read_only && - c->memblock->length >= c->index+min) + if (pa_memblock_is_read_only(c->memblock) && + pa_memblock_get_length(c->memblock) >= c->index+min) return; l = c->length; if (l < min) l = min; - n = pa_memblock_new(c->memblock->pool, l); - memcpy(n->data, (uint8_t*) c->memblock->data + c->index, c->length); + n = pa_memblock_new(pa_memblock_get_pool(c->memblock), l); + tdata = pa_memblock_acquire(n); + sdata = pa_memblock_acquire(c->memblock); + memcpy(tdata, (uint8_t*) sdata + c->index, c->length); + pa_memblock_release(n); + pa_memblock_release(c->memblock); pa_memblock_unref(c->memblock); c->memblock = n; c->index = 0; diff --git a/src/pulsecore/msgobject.c b/src/pulsecore/msgobject.c new file mode 100644 index 00000000..ea404ccf --- /dev/null +++ b/src/pulsecore/msgobject.c @@ -0,0 +1,40 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "msgobject.h" + +pa_msgobject *pa_msgobject_new_internal(size_t size, const char *type_name) { + pa_msgobject *o; + + pa_assert(size > sizeof(pa_msgobject)); + pa_assert(type_name); + + o = PA_MSGOBJECT(pa_object_new_internal(size, type_name)); + o->process_msg = NULL; + return o; +} diff --git a/src/pulsecore/msgobject.h b/src/pulsecore/msgobject.h new file mode 100644 index 00000000..317ebd20 --- /dev/null +++ b/src/pulsecore/msgobject.h @@ -0,0 +1,52 @@ +#ifndef foopulsemsgobjecthfoo +#define foopulsemsgobjecthfoo + +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include + +#include +#include +#include +#include +#include + +typedef struct pa_msgobject pa_msgobject; + +struct pa_msgobject { + pa_object parent; + int (*process_msg)(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk); +}; + +pa_msgobject *pa_msgobject_new_internal(size_t size, const char *type_name); + +#define pa_msgobject_new(type) ((type*) pa_msgobject_new_internal(sizeof(type), #type)) +#define pa_msgobject_free ((void (*) (pa_msgobject* o)) pa_object_free) + +#define PA_MSGOBJECT(o) ((pa_msgobject*) (o)) + +PA_DECLARE_CLASS(pa_msgobject); + +#endif diff --git a/src/pulsecore/mutex-posix.c b/src/pulsecore/mutex-posix.c index 52e731b3..a66950eb 100644 --- a/src/pulsecore/mutex-posix.c +++ b/src/pulsecore/mutex-posix.c @@ -28,8 +28,6 @@ #include #include -#include - #include #include "mutex.h" diff --git a/src/pulsecore/object.c b/src/pulsecore/object.c new file mode 100644 index 00000000..de7d5ad5 --- /dev/null +++ b/src/pulsecore/object.c @@ -0,0 +1,61 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "object.h" + +pa_object *pa_object_new_internal(size_t size, const char *type_name) { + pa_object *o; + + pa_assert(size > sizeof(pa_object)); + pa_assert(type_name); + + o = pa_xmalloc(size); + PA_REFCNT_INIT(o); + o->type_name = type_name; + o->free = pa_object_free; + + return o; +} + +pa_object *pa_object_ref(pa_object *o) { + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); + + PA_REFCNT_INC(o); + return o; +} + +void pa_object_unref(pa_object *o) { + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); + + if (PA_REFCNT_DEC(o) <= 0) { + pa_assert(o->free); + o->free(o); + } +} diff --git a/src/pulsecore/object.h b/src/pulsecore/object.h new file mode 100644 index 00000000..8fccf191 --- /dev/null +++ b/src/pulsecore/object.h @@ -0,0 +1,72 @@ +#ifndef foopulseobjecthfoo +#define foopulseobjecthfoo + +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include +#include +#include +#include + +typedef struct pa_object pa_object; + +struct pa_object { + PA_REFCNT_DECLARE; + const char *type_name; + void (*free)(pa_object *o); +}; + +pa_object *pa_object_new_internal(size_t size, const char *type_name); +#define pa_object_new(type) ((type*) pa_object_new_internal(sizeof(type), #type)) + +#define pa_object_free ((void (*) (pa_object* o)) pa_xfree) + +pa_object *pa_object_ref(pa_object *o); +void pa_object_unref(pa_object *o); + +static inline int pa_object_refcnt(pa_object *o) { + return o ? PA_REFCNT_VALUE(o) : 0; +} + +#define pa_object_assert_ref(o) pa_assert(pa_object_refcnt(o)) + +#define PA_OBJECT(o) ((pa_object*) (o)) + +#define PA_DECLARE_CLASS(c) \ + static inline c* c##_ref(c *o) { \ + return (c*) pa_object_ref(PA_OBJECT(o)); \ + } \ + static inline void c##_unref(c* o) { \ + pa_object_unref(PA_OBJECT(o)); \ + } \ + static inline int c##_refcnt(c* o) { \ + return pa_object_refcnt(PA_OBJECT(o)); \ + } \ + static inline void c##_assert_ref(c *o) { \ + pa_object_assert_ref(PA_OBJECT(o)); \ + } \ + struct __stupid_useless_struct_to_allow_trailing_semicolon + +#endif diff --git a/src/pulsecore/once-posix.c b/src/pulsecore/once-posix.c index 4af7b36e..7ccd08ed 100644 --- a/src/pulsecore/once-posix.c +++ b/src/pulsecore/once-posix.c @@ -26,44 +26,56 @@ #endif #include -#include +#include #include #include "once.h" -#define ASSERT_SUCCESS(x) do { \ - int _r = (x); \ - assert(_r == 0); \ -} while(0) - -static pa_mutex *global_mutex; -static pthread_once_t global_mutex_once = PTHREAD_ONCE_INIT; - -static void global_mutex_once_func(void) { - global_mutex = pa_mutex_new(0); -} - +/* Not reentrant -- how could it be? */ void pa_once(pa_once_t *control, pa_once_func_t func) { - assert(control); - assert(func); - - /* Create the global mutex */ - ASSERT_SUCCESS(pthread_once(&global_mutex_once, global_mutex_once_func)); - - /* Create the local mutex */ - pa_mutex_lock(global_mutex); - if (!control->mutex) - control->mutex = pa_mutex_new(1); - pa_mutex_unlock(global_mutex); - - /* Execute function */ - pa_mutex_lock(control->mutex); - if (!control->once_value) { - control->once_value = 1; - func(); + pa_mutex *m; + + pa_assert(control); + pa_assert(func); + + if (pa_atomic_load(&control->done)) + return; + + pa_atomic_inc(&control->ref); + + for (;;) { + + if ((m = pa_atomic_ptr_load(&control->mutex))) { + + /* The mutex is stored in locked state, hence let's just + * wait until it is unlocked */ + pa_mutex_lock(m); + pa_mutex_unlock(m); + break; + } + + pa_assert_se(m = pa_mutex_new(0)); + pa_mutex_lock(m); + + if (pa_atomic_ptr_cmpxchg(&control->mutex, NULL, m)) { + func(); + pa_atomic_store(&control->done, 1); + pa_mutex_unlock(m); + + break; + } + + pa_mutex_unlock(m); + pa_mutex_free(m); + } + + pa_assert(pa_atomic_load(&control->done)); + + if (pa_atomic_dec(&control->ref) <= 1) { + pa_assert(pa_atomic_ptr_cmpxchg(&control->mutex, m, NULL)); + pa_mutex_free(m); } - pa_mutex_unlock(control->mutex); /* Caveat: We have to make sure that the once func has completed * before returning, even if the once func is not actually diff --git a/src/pulsecore/once.h b/src/pulsecore/once.h index c20fc0b4..b2602121 100644 --- a/src/pulsecore/once.h +++ b/src/pulsecore/once.h @@ -25,13 +25,19 @@ ***/ #include +#include typedef struct pa_once { - unsigned int once_value; - pa_mutex *mutex; + pa_atomic_ptr_t mutex; + pa_atomic_t ref, done; } pa_once_t; -#define PA_ONCE_INIT { .once_value = 0, .mutex = NULL } +#define PA_ONCE_INIT \ + { \ + .mutex = PA_ATOMIC_PTR_INIT(NULL), \ + .ref = PA_ATOMIC_INIT(0), \ + .done = PA_ATOMIC_INIT(0) \ + } typedef void (*pa_once_func_t) (void); diff --git a/src/pulsecore/play-memblockq.c b/src/pulsecore/play-memblockq.c index 76edd27a..9c5945af 100644 --- a/src/pulsecore/play-memblockq.c +++ b/src/pulsecore/play-memblockq.c @@ -122,7 +122,5 @@ int pa_play_memblockq( si->userdata = q; - pa_sink_notify(si->sink); - return 0; } diff --git a/src/pulsecore/play-memchunk.c b/src/pulsecore/play-memchunk.c index 9132e294..65b6e825 100644 --- a/src/pulsecore/play-memchunk.c +++ b/src/pulsecore/play-memchunk.c @@ -57,7 +57,7 @@ static int sink_input_peek(pa_sink_input *i, pa_memchunk *chunk) { if (c->length <= 0) return -1; - assert(c->memblock && c->memblock->length); + assert(c->memblock); *chunk = *c; pa_memblock_ref(c->memblock); @@ -122,7 +122,5 @@ int pa_play_memchunk( pa_memblock_ref(chunk->memblock); - pa_sink_notify(si->sink); - return 0; } diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c index 49a78d41..6a5c6127 100644 --- a/src/pulsecore/protocol-esound.c +++ b/src/pulsecore/protocol-esound.c @@ -894,14 +894,22 @@ static int do_read(struct connection *c) { } } else if (c->state == ESD_CACHING_SAMPLE) { ssize_t r; + void *p; - assert(c->scache.memchunk.memblock && c->scache.name && c->scache.memchunk.index < c->scache.memchunk.length); + assert(c->scache.memchunk.memblock); + assert(c->scache.name); + assert(c->scache.memchunk.index < c->scache.memchunk.length); - if ((r = pa_iochannel_read(c->io, (uint8_t*) c->scache.memchunk.memblock->data+c->scache.memchunk.index, c->scache.memchunk.length-c->scache.memchunk.index)) <= 0) { + p = pa_memblock_acquire(c->scache.memchunk.memblock); + + if ((r = pa_iochannel_read(c->io, (uint8_t*) p+c->scache.memchunk.index, c->scache.memchunk.length-c->scache.memchunk.index)) <= 0) { + pa_memblock_release(c->scache.memchunk.memblock); pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); return -1; } + pa_memblock_release(c->scache.memchunk.memblock); + c->scache.memchunk.index += r; assert(c->scache.memchunk.index <= c->scache.memchunk.length); @@ -928,6 +936,7 @@ static int do_read(struct connection *c) { pa_memchunk chunk; ssize_t r; size_t l; + void *p; assert(c->input_memblockq); @@ -940,7 +949,7 @@ static int do_read(struct connection *c) { l = c->playback.fragment_size; if (c->playback.current_memblock) - if (c->playback.current_memblock->length - c->playback.memblock_index < l) { + if (pa_memblock_get_length(c->playback.current_memblock) - c->playback.memblock_index < l) { pa_memblock_unref(c->playback.current_memblock); c->playback.current_memblock = NULL; c->playback.memblock_index = 0; @@ -948,14 +957,19 @@ static int do_read(struct connection *c) { if (!c->playback.current_memblock) { c->playback.current_memblock = pa_memblock_new(c->protocol->core->mempool, c->playback.fragment_size*2); - assert(c->playback.current_memblock && c->playback.current_memblock->length >= l); + assert(c->playback.current_memblock); + assert(pa_memblock_get_length(c->playback.current_memblock) >= l); c->playback.memblock_index = 0; } - if ((r = pa_iochannel_read(c->io, (uint8_t*) c->playback.current_memblock->data+c->playback.memblock_index, l)) <= 0) { + p = pa_memblock_acquire(c->playback.current_memblock); + + if ((r = pa_iochannel_read(c->io, (uint8_t*) p+c->playback.memblock_index, l)) <= 0) { + pa_memblock_release(c->playback.current_memblock); pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); return -1; } + pa_memblock_release(c->playback.current_memblock); chunk.memblock = c->playback.current_memblock; chunk.index = c->playback.memblock_index; @@ -993,19 +1007,26 @@ static int do_write(struct connection *c) { } else if (c->state == ESD_STREAMING_DATA && c->source_output) { pa_memchunk chunk; ssize_t r; + void *p; assert(c->output_memblockq); if (pa_memblockq_peek(c->output_memblockq, &chunk) < 0) return 0; - assert(chunk.memblock && chunk.length); + assert(chunk.memblock); + assert(chunk.length); + + p = pa_memblock_acquire(chunk.memblock); - if ((r = pa_iochannel_write(c->io, (uint8_t*) chunk.memblock->data+chunk.index, chunk.length)) < 0) { + if ((r = pa_iochannel_write(c->io, (uint8_t*) p+chunk.index, chunk.length)) < 0) { + pa_memblock_release(chunk.memblock); pa_memblock_unref(chunk.memblock); pa_log("write(): %s", pa_cstrerror(errno)); return -1; } + pa_memblock_release(chunk.memblock); + pa_memblockq_drop(c->output_memblockq, &chunk, r); pa_memblock_unref(chunk.memblock); diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index dd41b3d5..86455693 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -2278,6 +2278,7 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o } else { struct upload_stream *u = (struct upload_stream*) stream; size_t l; + assert(u->type == UPLOAD_STREAM); if (!u->memchunk.memblock) { @@ -2297,9 +2298,18 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o if (l > chunk->length) l = chunk->length; + if (l > 0) { - memcpy((uint8_t*) u->memchunk.memblock->data + u->memchunk.index + u->memchunk.length, - (uint8_t*) chunk->memblock->data+chunk->index, l); + void *src, *dst; + dst = pa_memblock_acquire(u->memchunk.memblock); + src = pa_memblock_acquire(chunk->memblock); + + memcpy((uint8_t*) dst + u->memchunk.index + u->memchunk.length, + (uint8_t*) src+chunk->index, l); + + pa_memblock_release(u->memchunk.memblock); + pa_memblock_release(chunk->memblock); + u->memchunk.length += l; u->length -= l; } diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index 31ad6ddd..288cf87a 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -25,7 +25,6 @@ #include #endif -#include #include #include #include @@ -54,13 +53,13 @@ struct connection { pa_source_output *source_output; pa_client *client; pa_memblockq *input_memblockq, *output_memblockq; - pa_defer_event *defer_event; int dead; struct { pa_memblock *current_memblock; size_t memblock_index, fragment_size; + pa_atomic_int missing; } playback; }; @@ -69,35 +68,52 @@ struct pa_protocol_simple { pa_core *core; pa_socket_server*server; pa_idxset *connections; + + pa_asyncmsgq *asyncmsgq; + enum { RECORD = 1, PLAYBACK = 2, DUPLEX = 3 } mode; + pa_sample_spec sample_spec; char *source_name, *sink_name; }; +enum { + SINK_INPUT_MESSAGE_POST_DATA = PA_SINK_INPUT_MESSAGE_MAX, /* data from main loop to sink input */ +}; + +enum { + MESSAGE_REQUEST_DATA, /* data from source output to main loop */ + MESSAGE_POST_DATA /* data from source output to main loop */ +}; + + #define PLAYBACK_BUFFER_SECONDS (.5) #define PLAYBACK_BUFFER_FRAGMENTS (10) #define RECORD_BUFFER_SECONDS (5) #define RECORD_BUFFER_FRAGMENTS (100) static void connection_free(struct connection *c) { - assert(c); + pa_assert(c); pa_idxset_remove_by_data(c->protocol->connections, c, NULL); - if (c->playback.current_memblock) - pa_memblock_unref(c->playback.current_memblock); if (c->sink_input) { pa_sink_input_disconnect(c->sink_input); pa_sink_input_unref(c->sink_input); } + if (c->source_output) { pa_source_output_disconnect(c->source_output); pa_source_output_unref(c->source_output); } + + if (c->playback.current_memblock) + pa_memblock_unref(c->playback.current_memblock); + if (c->client) pa_client_free(c->client); if (c->io) @@ -106,8 +122,7 @@ static void connection_free(struct connection *c) { pa_memblockq_free(c->input_memblockq); if (c->output_memblockq) pa_memblockq_free(c->output_memblockq); - if (c->defer_event) - c->protocol->core->mainloop->defer_free(c->defer_event); + pa_xfree(c); } @@ -115,27 +130,37 @@ static int do_read(struct connection *c) { pa_memchunk chunk; ssize_t r; size_t l; + void *p; - if (!c->sink_input || !(l = pa_memblockq_missing(c->input_memblockq))) + pa_assert(c); + + if (!c->sink_input || !(l = pa_atomic_load(&c->playback.missing))) return 0; if (l > c->playback.fragment_size) l = c->playback.fragment_size; if (c->playback.current_memblock) - if (c->playback.current_memblock->length - c->playback.memblock_index < l) { + if (pa_memblock_get_length(c->playback.current_memblock) - c->playback.memblock_index < l) { pa_memblock_unref(c->playback.current_memblock); c->playback.current_memblock = NULL; c->playback.memblock_index = 0; } if (!c->playback.current_memblock) { - c->playback.current_memblock = pa_memblock_new(c->protocol->core->mempool, c->playback.fragment_size*2); - assert(c->playback.current_memblock && c->playback.current_memblock->length >= l); + pa_assert_se(c->playback.current_memblock = pa_memblock_new(c->protocol->core->mempool, l)); c->playback.memblock_index = 0; } - if ((r = pa_iochannel_read(c->io, (uint8_t*) c->playback.current_memblock->data+c->playback.memblock_index, l)) <= 0) { + p = pa_memblock_acquire(c->playback.current_memblock); + r = pa_iochannel_read(c->io, (uint8_t*) p + c->playback.memblock_index, l); + pa_memblock_release(c->playback.current_memblock); + + if (r <= 0) { + + if (errno == EINTR || errno == EAGAIN) + return 0; + pa_log_debug("read(): %s", r == 0 ? "EOF" : pa_cstrerror(errno)); return -1; } @@ -143,14 +168,10 @@ static int do_read(struct connection *c) { chunk.memblock = c->playback.current_memblock; chunk.index = c->playback.memblock_index; chunk.length = r; - assert(chunk.memblock); c->playback.memblock_index += r; - assert(c->input_memblockq); - pa_memblockq_push_align(c->input_memblockq, &chunk); - assert(c->sink_input); - pa_sink_notify(c->sink_input->sink); + pa_asyncmsgq_post(c->protocol->asyncmsgq, c, MESSAGE_POST_DATA, NULL, &chunk, NULL, NULL); return 0; } @@ -158,35 +179,41 @@ static int do_read(struct connection *c) { static int do_write(struct connection *c) { pa_memchunk chunk; ssize_t r; + void *p; + + p_assert(c); if (!c->source_output) return 0; - assert(c->output_memblockq); if (pa_memblockq_peek(c->output_memblockq, &chunk) < 0) return 0; - assert(chunk.memblock && chunk.length); + pa_assert(chunk.memblock); + pa_assert(chunk.length); + + p = pa_memblock_acquire(chunk.memblock); + r = pa_iochannel_write(c->io, (uint8_t*) p+chunk.index, chunk.length); + pa_memblock_release(chunk.memblock); + + pa_memblock_unref(chunk.memblock); + + if (r < 0) { + + if (errno == EINTR || errno == EAGAIN) + return 0; - if ((r = pa_iochannel_write(c->io, (uint8_t*) chunk.memblock->data+chunk.index, chunk.length)) < 0) { - pa_memblock_unref(chunk.memblock); pa_log("write(): %s", pa_cstrerror(errno)); return -1; } pa_memblockq_drop(c->output_memblockq, &chunk, r); - pa_memblock_unref(chunk.memblock); - - pa_source_notify(c->source_output->source); - + return 0; } static void do_work(struct connection *c) { - assert(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_assert(c); if (c->dead) return; @@ -207,103 +234,148 @@ static void do_work(struct connection *c) { fail: if (c->sink_input) { + + /* If there is a sink input, we first drain what we already have read before shutting down the connection */ c->dead = 1; pa_iochannel_free(c->io); c->io = NULL; pa_memblockq_prebuf_disable(c->input_memblockq); - pa_sink_notify(c->sink_input->sink); } else connection_free(c); } /*** sink_input callbacks ***/ -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { +/* Called from thread context */ +static int sink_input_process_msg(pa_sink_input *i, int code, void *userdata, const pa_memchunk *chunk) { struct connection*c; - assert(i && i->userdata && chunk); + + pa_assert(i); c = i->userdata; + pa_assert(c); - if (pa_memblockq_peek(c->input_memblockq, chunk) < 0) { + switch (code) { - if (c->dead) - connection_free(c); + case SINK_INPUT_MESSAGE_POST_DATA: { + pa_assert(chunk); - return -1; + /* New data from the main loop */ + pa_memblockq_push_align(c->input_memblockq, chunk); + return 0; + } + + case PA_SINK_INPUT_MESSAGE_GET_LATENCY: { + pa_usec_t *r = userdata; + + *r = pa_bytes_to_usec(pa_memblockq_get_length(c->input_memblockq), &c->sink_input->sample_spec); + + /* Fall through, the default handler will add in the extra + * latency added by the resampler */ + } + + default: + return pa_sink_input_process_msg(i, code, userdata); } +} - return 0; +/* Called from thread context */ +static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { + struct connection*c; + + pa_assert(i); + c = i->userdata; + pa_assert(c); + pa_assert(chunk); + + r = pa_memblockq_peek(c->input_memblockq, chunk); + + if (c->dead && r < 0) + connection_free(c); + + return r; } +/* Called from thread context */ static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_t length) { struct connection*c = i->userdata; - assert(i && c && length); + size_t old, new; + + pa_assert(i); + pa_assert(c); + pa_assert(length); + old = pa_memblockq_missing(c->input_memblockq); pa_memblockq_drop(c->input_memblockq, chunk, length); + new = pa_memblockq_missing(c->input_memblockq); - /* do something */ - 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, 1); + pa_atomic_store(&c->playback.missing, &new); + + if (new > old) + pa_asyncmsgq_post(c->protocol->asyncmsgq, c, MESSAGE_REQUEST_DATA, NULL, NULL, NULL, NULL); } +/* Called from main context */ static void sink_input_kill_cb(pa_sink_input *i) { - assert(i && i->userdata); + pa_assert(i); + pa_assert(i->userdata); + connection_free((struct connection *) i->userdata); } - -static pa_usec_t sink_input_get_latency_cb(pa_sink_input *i) { - struct connection*c = i->userdata; - assert(i && c); - return pa_bytes_to_usec(pa_memblockq_get_length(c->input_memblockq), &c->sink_input->sample_spec); -} - /*** source_output callbacks ***/ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) { - struct connection *c = o->userdata; - assert(o && c && chunk); - - pa_memblockq_push(c->output_memblockq, chunk); + struct connection *c; + + pa_assert(o); + c = o->userdata; + pa_assert(c); + pa_assert(chunk); - /* do something */ - 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, 1); + pa_asyncmsgq_post(c->protocol->asyncmsgq, c, MESSAGE_REQUEST_DATA, NULL, chunk, NULL, NULL); } static void source_output_kill_cb(pa_source_output *o) { - assert(o && o->userdata); - connection_free((struct connection *) o->userdata); + struct connection*c; + + pa_assert(o); + c = o->userdata; + pa_assert(c); + + connection_free(c); } static pa_usec_t source_output_get_latency_cb(pa_source_output *o) { - struct connection*c = o->userdata; - assert(o && c); + struct connection*c; + + pa_assert(o); + c = o->userdata; + pa_assert(c); + return pa_bytes_to_usec(pa_memblockq_get_length(c->output_memblockq), &c->source_output->sample_spec); } /*** client callbacks ***/ -static void client_kill_cb(pa_client *c) { - assert(c && c->userdata); - connection_free((struct connection *) c->userdata); +static void client_kill_cb(pa_client *client) { + struct connection*c; + + pa_assert(client); + c = client->userdata; + pa_assert(c); + + connection_free(client); } /*** pa_iochannel callbacks ***/ static void io_callback(pa_iochannel*io, void *userdata) { struct connection *c = userdata; - assert(io && c && c->io == io); - - do_work(c); -} -/*** fixed callback ***/ - -static void defer_callback(pa_mainloop_api*a, pa_defer_event *e, void *userdata) { - struct connection *c = userdata; - assert(a && c && c->defer_event == e); + pa_assert(io); + pa_assert(c); do_work(c); } @@ -314,7 +386,10 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) pa_protocol_simple *p = userdata; struct connection *c = NULL; char cname[256]; - assert(s && io && p); + + pa_assert(s); + pa_assert(io); + pa_assert(p); if (pa_idxset_size(p->connections)+1 > MAX_CONNECTIONS) { pa_log("Warning! Too many connections (%u), dropping incoming connection.", MAX_CONNECTIONS); @@ -322,25 +397,25 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) return; } - c = pa_xmalloc(sizeof(struct connection)); + c = pa_xnew(struct connection, 1); c->io = io; c->sink_input = NULL; c->source_output = NULL; - c->defer_event = NULL; c->input_memblockq = c->output_memblockq = NULL; c->protocol = p; c->playback.current_memblock = NULL; c->playback.memblock_index = 0; c->playback.fragment_size = 0; c->dead = 0; + pa_atomic_store(&c->playback.missing, 0); pa_iochannel_socket_peer_to_string(io, cname, sizeof(cname)); - c->client = pa_client_new(p->core, __FILE__, cname); - assert(c->client); + pa_assert_se(c->client = pa_client_new(p->core, __FILE__, cname)); c->client->owner = p->module; c->client->kill = client_kill_cb; c->client->userdata = c; + if (p->mode & PLAYBACK) { pa_sink_input_new_data data; size_t l; @@ -372,11 +447,13 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) (size_t) -1, l/PLAYBACK_BUFFER_FRAGMENTS, NULL); - assert(c->input_memblockq); + pa_assert(c->input_memblockq); pa_iochannel_socket_set_rcvbuf(io, l/PLAYBACK_BUFFER_FRAGMENTS*5); c->playback.fragment_size = l/10; - pa_sink_notify(c->sink_input->sink); + pa_atomic_store(&c->playback.missing, pa_memblockq_missing(c->input_memblockq)); + + pa_sink_input_put(c->sink_input); } if (p->mode & RECORD) { @@ -409,16 +486,14 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) 0, NULL); pa_iochannel_socket_set_sndbuf(io, l/RECORD_BUFFER_FRAGMENTS*2); - pa_source_notify(c->source_output->source); + + pa_source_output_put(c->source_output); } + pa_iochannel_set_callback(c->io, io_callback, c); pa_idxset_put(p->connections, c, NULL); - - c->defer_event = p->core->mainloop->defer_new(p->core->mainloop, defer_callback, c); - assert(c->defer_event); - p->core->mainloop->defer_enable(c->defer_event, 0); - + return; fail: @@ -426,16 +501,60 @@ fail: connection_free(c); } +static void asyncmsgq_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) { + pa_protocol_simple *p = userdata; + int do_some_work = 0; + + pa_assert(pa_asyncmsgq_get_fd(p->asyncmsgq) == fd); + pa_assert(events == PA_IO_EVENT_INPUT); + + pa_asyncmsgq_after_poll(p->asyncmsgq); + + for (;;) { + int code; + void *object, *data; + + /* Check whether there is a message for us to process */ + while (pa_asyncmsgq_get(p->asyncmsgq, &object, &code, &data) == 0) { + + connection *c = object; + + pa_assert(c); + + switch (code) { + + case MESSAGE_REQUEST_DATA: + do_work(c); + break; + + case MESSAGE_POST_DATA: + pa_memblockq_push(c->output_memblockq, chunk); + do_work(c); + break; + } + + pa_asyncmsgq_done(p->asyncmsgq); + } + + if (pa_asyncmsgq_before_poll(p->asyncmsgq) == 0) + break; + } +} + pa_protocol_simple* pa_protocol_simple_new(pa_core *core, pa_socket_server *server, pa_module *m, pa_modargs *ma) { pa_protocol_simple* p = NULL; int enable; - assert(core && server && ma); + + pa_assert(core); + pa_assert(server); + pa_assert(ma); - p = pa_xmalloc0(sizeof(pa_protocol_simple)); + p = pa_xnew0(pa_protocol_simple, 1); p->module = m; p->core = core; p->server = server; p->connections = pa_idxset_new(NULL, NULL); + pa_assert_se(p->asyncmsgq = pa_asyncmsgq_new(0)); p->sample_spec = core->default_sample_spec; if (pa_modargs_get_sample_spec(ma, &p->sample_spec) < 0) { @@ -467,18 +586,22 @@ pa_protocol_simple* pa_protocol_simple_new(pa_core *core, pa_socket_server *serv pa_socket_server_set_callback(p->server, on_connection, p); + pa_assert_se(pa_asyncmsgq_before_poll(p->asyncmsgq) == 0); + pa_assert_se(p->asyncmsgq_event = core->mainloop->io_event_new(core->mainloop, pa_asyncmsgq_get_fd(p->asyncmsgq), PA_IO_EVENT_INPUT, p)); + return p; fail: if (p) pa_protocol_simple_free(p); + return NULL; } void pa_protocol_simple_free(pa_protocol_simple *p) { struct connection *c; - assert(p); + pa_assert(p); if (p->connections) { while((c = pa_idxset_first(p->connections, NULL))) @@ -489,6 +612,13 @@ void pa_protocol_simple_free(pa_protocol_simple *p) { if (p->server) pa_socket_server_unref(p->server); + + if (p->asyncmsgq) { + c->mainloop->io_event_free(c->asyncmsgq_event); + pa_asyncmsgq_after_poll(c->asyncmsgq); + pa_asyncmsgq_free(p->asyncmsgq); + } + pa_xfree(p); } diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c index fdb1a66a..f4aab1c2 100644 --- a/src/pulsecore/pstream.c +++ b/src/pulsecore/pstream.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include "pstream.h" @@ -118,8 +117,8 @@ struct pa_pstream { pa_mainloop_api *mainloop; pa_defer_event *defer_event; pa_iochannel *io; + pa_queue *send_queue; - pa_mutex *mutex; int dead; @@ -129,6 +128,7 @@ struct pa_pstream { uint32_t shm_info[PA_PSTREAM_SHM_MAX]; void *data; size_t index; + pa_memchunk memchunk; } write; struct { @@ -173,8 +173,6 @@ static void do_something(pa_pstream *p) { pa_pstream_ref(p); - pa_mutex_lock(p->mutex); - p->mainloop->defer_enable(p->defer_event, 0); if (!p->dead && pa_iochannel_is_readable(p->io)) { @@ -188,8 +186,6 @@ static void do_something(pa_pstream *p) { goto fail; } - pa_mutex_unlock(p->mutex); - pa_pstream_unref(p); return; @@ -200,8 +196,6 @@ fail: if (p->die_callback) p->die_callback(p, p->die_callback_userdata); - pa_mutex_unlock(p->mutex); - pa_pstream_unref(p); } @@ -214,16 +208,6 @@ static void io_callback(pa_iochannel*io, void *userdata) { do_something(p); } -static void defer_callback(pa_mainloop_api *m, pa_defer_event *e, void*userdata) { - pa_pstream *p = userdata; - - assert(p); - assert(p->defer_event == e); - assert(p->mainloop == m); - - do_something(p); -} - static void memimport_release_cb(pa_memimport *i, uint32_t block_id, void *userdata); pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_mempool *pool) { @@ -239,17 +223,14 @@ pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_mempool *poo pa_iochannel_set_callback(io, io_callback, p); p->dead = 0; - p->mutex = pa_mutex_new(1); - p->mainloop = m; - p->defer_event = m->defer_new(m, defer_callback, p); - m->defer_enable(p->defer_event, 0); p->send_queue = pa_queue_new(); assert(p->send_queue); p->write.current = NULL; p->write.index = 0; + pa_memchunk_reset(&p->write.memchunk); p->read.memblock = NULL; p->read.packet = NULL; p->read.index = 0; @@ -312,8 +293,8 @@ static void pstream_free(pa_pstream *p) { if (p->read.packet) pa_packet_unref(p->read.packet); - if (p->mutex) - pa_mutex_free(p->mutex); + if (p->write.memchunk.memblock) + pa_memblock_unref(p->write.memchunk.memblock); pa_xfree(p); } @@ -325,10 +306,8 @@ void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const pa_creds *cre assert(PA_REFCNT_VALUE(p) > 0); assert(packet); - pa_mutex_lock(p->mutex); - if (p->dead) - goto finish; + return; i = pa_xnew(struct item_info, 1); i->type = PA_PSTREAM_ITEM_PACKET; @@ -340,11 +319,6 @@ void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const pa_creds *cre #endif pa_queue_push(p->send_queue, i); - p->mainloop->defer_enable(p->defer_event, 1); - -finish: - - pa_mutex_unlock(p->mutex); } void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa_seek_mode_t seek_mode, const pa_memchunk *chunk) { @@ -355,12 +329,9 @@ void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa assert(channel != (uint32_t) -1); assert(chunk); - pa_mutex_lock(p->mutex); - if (p->dead) - goto finish; + return; - length = chunk->length; idx = 0; while (length > 0) { @@ -389,10 +360,6 @@ void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa } p->mainloop->defer_enable(p->defer_event, 1); - -finish: - - pa_mutex_unlock(p->mutex); } static void memimport_release_cb(pa_memimport *i, uint32_t block_id, void *userdata) { @@ -402,10 +369,8 @@ static void memimport_release_cb(pa_memimport *i, uint32_t block_id, void *userd assert(p); assert(PA_REFCNT_VALUE(p) > 0); - pa_mutex_lock(p->mutex); - if (p->dead) - goto finish; + return; /* pa_log("Releasing block %u", block_id); */ @@ -417,11 +382,6 @@ static void memimport_release_cb(pa_memimport *i, uint32_t block_id, void *userd #endif pa_queue_push(p->send_queue, item); - p->mainloop->defer_enable(p->defer_event, 1); - -finish: - - pa_mutex_unlock(p->mutex); } static void memexport_revoke_cb(pa_memexport *e, uint32_t block_id, void *userdata) { @@ -431,11 +391,8 @@ static void memexport_revoke_cb(pa_memexport *e, uint32_t block_id, void *userda assert(p); assert(PA_REFCNT_VALUE(p) > 0); - pa_mutex_lock(p->mutex); - if (p->dead) - goto finish; - + return; /* pa_log("Revoking block %u", block_id); */ item = pa_xnew(struct item_info, 1); @@ -446,22 +403,20 @@ static void memexport_revoke_cb(pa_memexport *e, uint32_t block_id, void *userda #endif pa_queue_push(p->send_queue, item); - p->mainloop->defer_enable(p->defer_event, 1); - -finish: - - pa_mutex_unlock(p->mutex); } static void prepare_next_write_item(pa_pstream *p) { assert(p); assert(PA_REFCNT_VALUE(p) > 0); - if (!(p->write.current = pa_queue_pop(p->send_queue))) + p->write.current = pa_queue_pop(p->send_queue); + + if (!p->write.current) return; p->write.index = 0; p->write.data = NULL; + pa_memchunk_reset(&p->write.memchunk); p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = 0; p->write.descriptor[PA_PSTREAM_DESCRIPTOR_CHANNEL] = htonl((uint32_t) -1); @@ -528,7 +483,9 @@ static void prepare_next_write_item(pa_pstream *p) { if (send_payload) { p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl(p->write.current->chunk.length); - p->write.data = (uint8_t*) p->write.current->chunk.memblock->data + p->write.current->chunk.index; + p->write.memchunk = p->write.current->chunk; + pa_memblock_ref(p->write.memchunk.memblock); + p->write.data = NULL; } p->write.descriptor[PA_PSTREAM_DESCRIPTOR_FLAGS] = htonl(flags); @@ -544,6 +501,7 @@ static int do_write(pa_pstream *p) { void *d; size_t l; ssize_t r; + pa_memblock *release_memblock = NULL; assert(p); assert(PA_REFCNT_VALUE(p) > 0); @@ -558,9 +516,16 @@ static int do_write(pa_pstream *p) { d = (uint8_t*) p->write.descriptor + p->write.index; l = PA_PSTREAM_DESCRIPTOR_SIZE - p->write.index; } else { - assert(p->write.data); + assert(p->write.data || p->write.memchunk.memblock); + + if (p->write.data) + d = p->write.data; + else { + d = (uint8_t*) pa_memblock_acquire(p->write.memchunk.memblock) + p->write.memchunk.index; + release_memblock = p->write.memchunk.memblock; + } - d = (uint8_t*) p->write.data + p->write.index - PA_PSTREAM_DESCRIPTOR_SIZE; + d = (uint8_t*) d + p->write.index - PA_PSTREAM_DESCRIPTOR_SIZE; l = ntohl(p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]) - (p->write.index - PA_PSTREAM_DESCRIPTOR_SIZE); } @@ -570,14 +535,17 @@ static int do_write(pa_pstream *p) { if (p->send_creds_now) { if ((r = pa_iochannel_write_with_creds(p->io, d, l, &p->write_creds)) < 0) - return -1; + goto fail; p->send_creds_now = 0; } else #endif if ((r = pa_iochannel_write(p->io, d, l)) < 0) - return -1; + goto fail; + + if (release_memblock) + pa_memblock_release(release_memblock); p->write.index += r; @@ -591,13 +559,20 @@ static int do_write(pa_pstream *p) { } return 0; + +fail: + + if (release_memblock) + pa_memblock_release(release_memblock); + + return -1; } static int do_read(pa_pstream *p) { void *d; size_t l; ssize_t r; - + pa_memblock *release_memblock = NULL; assert(p); assert(PA_REFCNT_VALUE(p) > 0); @@ -605,8 +580,16 @@ static int do_read(pa_pstream *p) { d = (uint8_t*) p->read.descriptor + p->read.index; l = PA_PSTREAM_DESCRIPTOR_SIZE - p->read.index; } else { - assert(p->read.data); - d = (uint8_t*) p->read.data + p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE; + assert(p->read.data || p->read.memblock); + + if (p->read.data) + d = p->read.data; + else { + d = pa_memblock_acquire(p->read.memblock); + release_memblock = p->read.memblock; + } + + d = (uint8_t*) d + p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE; l = ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]) - (p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE); } @@ -615,15 +598,18 @@ static int do_read(pa_pstream *p) { int b = 0; if ((r = pa_iochannel_read_with_creds(p->io, d, l, &p->read_creds, &b)) <= 0) - return -1; + goto fail; p->read_creds_valid = p->read_creds_valid || b; } #else if ((r = pa_iochannel_read(p->io, d, l)) <= 0) - return -1; + goto fail; #endif + if (release_memblock) + pa_memblock_release(release_memblock); + p->read.index += r; if (p->read.index == PA_PSTREAM_DESCRIPTOR_SIZE) { @@ -704,7 +690,7 @@ static int do_read(pa_pstream *p) { /* Frame is a memblock frame */ p->read.memblock = pa_memblock_new(p->mempool, length); - p->read.data = p->read.memblock->data; + p->read.data = NULL; } else { pa_log_warn("Recieved memblock frame with invalid flags value."); @@ -791,7 +777,7 @@ static int do_read(pa_pstream *p) { chunk.memblock = b; chunk.index = 0; - chunk.length = b->length; + chunk.length = pa_memblock_get_length(b); offset = (int64_t) ( (((uint64_t) ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI])) << 32) | @@ -819,52 +805,51 @@ frame_done: p->read.memblock = NULL; p->read.packet = NULL; p->read.index = 0; + p->read.data = NULL; #ifdef HAVE_CREDS p->read_creds_valid = 0; #endif return 0; + +fail: + if (release_memblock) + pa_memblock_release(release_memblock); + + return -1; } void pa_pstream_set_die_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata) { assert(p); assert(PA_REFCNT_VALUE(p) > 0); - pa_mutex_lock(p->mutex); p->die_callback = cb; p->die_callback_userdata = userdata; - pa_mutex_unlock(p->mutex); } void pa_pstream_set_drain_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata) { assert(p); assert(PA_REFCNT_VALUE(p) > 0); - pa_mutex_lock(p->mutex); p->drain_callback = cb; p->drain_callback_userdata = userdata; - pa_mutex_unlock(p->mutex); } void pa_pstream_set_recieve_packet_callback(pa_pstream *p, pa_pstream_packet_cb_t cb, void *userdata) { assert(p); assert(PA_REFCNT_VALUE(p) > 0); - pa_mutex_lock(p->mutex); p->recieve_packet_callback = cb; p->recieve_packet_callback_userdata = userdata; - pa_mutex_unlock(p->mutex); } void pa_pstream_set_recieve_memblock_callback(pa_pstream *p, pa_pstream_memblock_cb_t cb, void *userdata) { assert(p); assert(PA_REFCNT_VALUE(p) > 0); - pa_mutex_lock(p->mutex); p->recieve_memblock_callback = cb; p->recieve_memblock_callback_userdata = userdata; - pa_mutex_unlock(p->mutex); } int pa_pstream_is_pending(pa_pstream *p) { @@ -873,15 +858,11 @@ int pa_pstream_is_pending(pa_pstream *p) { assert(p); assert(PA_REFCNT_VALUE(p) > 0); - pa_mutex_lock(p->mutex); - if (p->dead) b = 0; else b = p->write.current || !pa_queue_is_empty(p->send_queue); - pa_mutex_unlock(p->mutex); - return b; } @@ -904,8 +885,6 @@ pa_pstream* pa_pstream_ref(pa_pstream*p) { void pa_pstream_close(pa_pstream *p) { assert(p); - pa_mutex_lock(p->mutex); - p->dead = 1; if (p->import) { @@ -923,25 +902,16 @@ void pa_pstream_close(pa_pstream *p) { p->io = NULL; } - if (p->defer_event) { - p->mainloop->defer_free(p->defer_event); - p->defer_event = NULL; - } - p->die_callback = NULL; p->drain_callback = NULL; p->recieve_packet_callback = NULL; p->recieve_memblock_callback = NULL; - - pa_mutex_unlock(p->mutex); } void pa_pstream_use_shm(pa_pstream *p, int enable) { assert(p); assert(PA_REFCNT_VALUE(p) > 0); - pa_mutex_lock(p->mutex); - p->use_shm = enable; if (enable) { @@ -956,6 +926,4 @@ void pa_pstream_use_shm(pa_pstream *p, int enable) { p->export = NULL; } } - - pa_mutex_unlock(p->mutex); } diff --git a/src/pulsecore/refcnt.h b/src/pulsecore/refcnt.h index 43433ff8..64271ab2 100644 --- a/src/pulsecore/refcnt.h +++ b/src/pulsecore/refcnt.h @@ -27,18 +27,18 @@ #include #define PA_REFCNT_DECLARE \ - pa_atomic_int_t _ref + pa_atomic_t _ref #define PA_REFCNT_INIT(p) \ - pa_atomic_store(&p->_ref, 1) + pa_atomic_store(&(p)->_ref, 1) #define PA_REFCNT_INC(p) \ - pa_atomic_inc(&p->_ref) + pa_atomic_inc(&(p)->_ref) #define PA_REFCNT_DEC(p) \ - (pa_atomic_dec(&p->_ref)-1) + (pa_atomic_dec(&(p)->_ref)-1) #define PA_REFCNT_VALUE(p) \ - pa_atomic_load(&p->_ref) + pa_atomic_load(&(p)->_ref) #endif diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index 3827ff94..248d7337 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -53,8 +53,7 @@ struct pa_resampler { }; struct impl_libsamplerate { - pa_memblock *buf1_block, *buf2_block, *buf3_block, *buf4_block; - float* buf1, *buf2, *buf3, *buf4; + pa_memchunk buf1, buf2, buf3, buf4; unsigned buf1_samples, buf2_samples, buf3_samples, buf4_samples; pa_convert_to_float32ne_func_t to_float32ne_func; @@ -226,14 +225,14 @@ static void libsamplerate_free(pa_resampler *r) { if (u->src_state) src_delete(u->src_state); - if (u->buf1_block) - pa_memblock_unref(u->buf1_block); - if (u->buf2_block) - pa_memblock_unref(u->buf2_block); - if (u->buf3_block) - pa_memblock_unref(u->buf3_block); - if (u->buf4_block) - pa_memblock_unref(u->buf4_block); + if (u->buf1.memblock) + pa_memblock_unref(u->buf1.memblock); + if (u->buf2.memblock) + pa_memblock_unref(u->buf2.memblock); + if (u->buf3.memblock) + pa_memblock_unref(u->buf3.memblock); + if (u->buf4.memblock) + pa_memblock_unref(u->buf4.memblock); pa_xfree(u); } @@ -272,64 +271,80 @@ static void calc_map_table(pa_resampler *r) { } } -static float * convert_to_float(pa_resampler *r, void *input, unsigned n_frames) { +static pa_memchunk* convert_to_float(pa_resampler *r, pa_memchunk *input) { struct impl_libsamplerate *u; unsigned n_samples; + void *src, *dst; assert(r); assert(input); + assert(input->memblock); + assert(r->impl_data); u = r->impl_data; /* Convert the incoming sample into floats and place them in buf1 */ - if (!u->to_float32ne_func) + if (!u->to_float32ne_func || !input->length) return input; - n_samples = n_frames * r->i_ss.channels; + n_samples = (input->length / r->i_fz) * r->i_ss.channels; - if (u->buf1_samples < n_samples) { - if (u->buf1_block) - pa_memblock_unref(u->buf1_block); + if (!u->buf1.memblock || u->buf1_samples < n_samples) { + if (u->buf1.memblock) + pa_memblock_unref(u->buf1.memblock); u->buf1_samples = n_samples; - u->buf1_block = pa_memblock_new(r->mempool, sizeof(float) * n_samples); - u->buf1 = u->buf1_block->data; + u->buf1.memblock = pa_memblock_new(r->mempool, u->buf1.length = sizeof(float) * n_samples); + u->buf1.index = 0; } - u->to_float32ne_func(n_samples, input, u->buf1); + src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index; + dst = (uint8_t*) pa_memblock_acquire(u->buf1.memblock); + u->to_float32ne_func(n_samples, src, dst); + pa_memblock_release(input->memblock); + pa_memblock_release(u->buf1.memblock); + + u->buf1.length = sizeof(float) * n_samples; - return u->buf1; + return &u->buf1; } -static float *remap_channels(pa_resampler *r, float *input, unsigned n_frames) { +static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) { struct impl_libsamplerate *u; - unsigned n_samples; + unsigned n_samples, n_frames; int i_skip, o_skip; unsigned oc; + float *src, *dst; assert(r); assert(input); + assert(input->memblock); + assert(r->impl_data); u = r->impl_data; /* Remap channels and place the result int buf2 */ - if (!u->map_required) + if (!u->map_required || !input->length) return input; - n_samples = n_frames * r->o_ss.channels; + n_samples = input->length / sizeof(float); + n_frames = n_samples / r->o_ss.channels; - if (u->buf2_samples < n_samples) { - if (u->buf2_block) - pa_memblock_unref(u->buf2_block); + if (!u->buf2.memblock || u->buf2_samples < n_samples) { + if (u->buf2.memblock) + pa_memblock_unref(u->buf2.memblock); u->buf2_samples = n_samples; - u->buf2_block = pa_memblock_new(r->mempool, sizeof(float) * n_samples); - u->buf2 = u->buf2_block->data; + u->buf2.memblock = pa_memblock_new(r->mempool, u->buf2.length = sizeof(float) * n_samples); + u->buf2.index = 0; } - memset(u->buf2, 0, n_samples * sizeof(float)); + src = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); + dst = (float*) pa_memblock_acquire(u->buf2.memblock); + + memset(dst, 0, n_samples * sizeof(float)); o_skip = sizeof(float) * r->o_ss.channels; i_skip = sizeof(float) * r->i_ss.channels; @@ -340,49 +355,57 @@ static float *remap_channels(pa_resampler *r, float *input, unsigned n_frames) { for (i = 0; i < PA_CHANNELS_MAX && u->map_table[oc][i] >= 0; i++) oil_vectoradd_f32( - u->buf2 + oc, o_skip, - u->buf2 + oc, o_skip, - input + u->map_table[oc][i], i_skip, + dst + oc, o_skip, + dst + oc, o_skip, + src + u->map_table[oc][i], i_skip, n_frames, &one, &one); } - return u->buf2; + pa_memblock_release(input->memblock); + pa_memblock_release(u->buf2.memblock); + + u->buf2.length = n_frames * sizeof(float) * r->o_ss.channels; + + return &u->buf2; } -static float *resample(pa_resampler *r, float *input, unsigned *n_frames) { +static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) { struct impl_libsamplerate *u; SRC_DATA data; + unsigned in_n_frames, in_n_samples; unsigned out_n_frames, out_n_samples; int ret; assert(r); assert(input); - assert(n_frames); assert(r->impl_data); u = r->impl_data; /* Resample the data and place the result in buf3 */ - if (!u->src_state) + if (!u->src_state || !input->length) return input; - out_n_frames = (*n_frames*r->o_ss.rate/r->i_ss.rate)+1024; + in_n_samples = input->length / sizeof(float); + in_n_frames = in_n_samples * r->o_ss.channels; + + out_n_frames = (in_n_frames*r->o_ss.rate/r->i_ss.rate)+1024; out_n_samples = out_n_frames * r->o_ss.channels; - if (u->buf3_samples < out_n_samples) { - if (u->buf3_block) - pa_memblock_unref(u->buf3_block); + if (!u->buf3.memblock || u->buf3_samples < out_n_samples) { + if (u->buf3.memblock) + pa_memblock_unref(u->buf3.memblock); u->buf3_samples = out_n_samples; - u->buf3_block = pa_memblock_new(r->mempool, sizeof(float) * out_n_samples); - u->buf3 = u->buf3_block->data; + u->buf3.memblock = pa_memblock_new(r->mempool, u->buf3.length = sizeof(float) * out_n_samples); + u->buf3.index = 0; } - data.data_in = input; - data.input_frames = *n_frames; + data.data_in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); + data.input_frames = in_n_frames; - data.data_out = u->buf3; + data.data_out = (float*) pa_memblock_acquire(u->buf3.memblock); data.output_frames = out_n_frames; data.src_ratio = (double) r->o_ss.rate / r->i_ss.rate; @@ -390,16 +413,20 @@ static float *resample(pa_resampler *r, float *input, unsigned *n_frames) { ret = src_process(u->src_state, &data); assert(ret == 0); - assert((unsigned) data.input_frames_used == *n_frames); + assert((unsigned) data.input_frames_used == in_n_frames); - *n_frames = data.output_frames_gen; + pa_memblock_release(input->memblock); + pa_memblock_release(u->buf3.memblock); - return u->buf3; + u->buf3.length = data.output_frames_gen * sizeof(float) * r->o_ss.channels; + + return &u->buf3; } -static void *convert_from_float(pa_resampler *r, float *input, unsigned n_frames) { +static pa_memchunk *convert_from_float(pa_resampler *r, pa_memchunk *input) { struct impl_libsamplerate *u; - unsigned n_samples; + unsigned n_samples, n_frames; + void *src, *dst; assert(r); assert(input); @@ -408,30 +435,35 @@ static void *convert_from_float(pa_resampler *r, float *input, unsigned n_frames /* Convert the data into the correct sample type and place the result in buf4 */ - if (!u->from_float32ne_func) + if (!u->from_float32ne_func || !input->length) return input; + n_frames = input->length / sizeof(float) / r->o_ss.channels; n_samples = n_frames * r->o_ss.channels; if (u->buf4_samples < n_samples) { - if (u->buf4_block) - pa_memblock_unref(u->buf4_block); + if (u->buf4.memblock) + pa_memblock_unref(u->buf4.memblock); u->buf4_samples = n_samples; - u->buf4_block = pa_memblock_new(r->mempool, sizeof(float) * n_samples); - u->buf4 = u->buf4_block->data; + u->buf4.memblock = pa_memblock_new(r->mempool, u->buf4.length = r->o_fz * n_frames); + u->buf4.index = 0; } - u->from_float32ne_func(n_samples, input, u->buf4); + src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->length; + dst = pa_memblock_acquire(u->buf4.memblock); + u->from_float32ne_func(n_samples, src, dst); + pa_memblock_release(input->memblock); + pa_memblock_release(u->buf4.memblock); - return u->buf4; + u->buf4.length = r->o_fz * n_frames; + + return &u->buf4; } static void libsamplerate_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) { struct impl_libsamplerate *u; - float *buf; - void *input, *output; - unsigned n_frames; + pa_memchunk *buf; assert(r); assert(in); @@ -443,55 +475,23 @@ static void libsamplerate_run(pa_resampler *r, const pa_memchunk *in, pa_memchun u = r->impl_data; - input = ((uint8_t*) in->memblock->data + in->index); - n_frames = in->length / r->i_fz; - assert(n_frames > 0); - - buf = convert_to_float(r, input, n_frames); - buf = remap_channels(r, buf, n_frames); - buf = resample(r, buf, &n_frames); - - if (n_frames) { - output = convert_from_float(r, buf, n_frames); - - if (output == input) { - /* Mm, no adjustment has been necessary, so let's return the original block */ - out->memblock = pa_memblock_ref(in->memblock); - out->index = in->index; - out->length = in->length; - } else { - out->length = n_frames * r->o_fz; - out->index = 0; - out->memblock = NULL; - - if (output == u->buf1) { - u->buf1 = NULL; - u->buf1_samples = 0; - out->memblock = u->buf1_block; - u->buf1_block = NULL; - } else if (output == u->buf2) { - u->buf2 = NULL; - u->buf2_samples = 0; - out->memblock = u->buf2_block; - u->buf2_block = NULL; - } else if (output == u->buf3) { - u->buf3 = NULL; - u->buf3_samples = 0; - out->memblock = u->buf3_block; - u->buf3_block = NULL; - } else if (output == u->buf4) { - u->buf4 = NULL; - u->buf4_samples = 0; - out->memblock = u->buf4_block; - u->buf4_block = NULL; - } - - assert(out->memblock); - } - } else { - out->memblock = NULL; - out->index = out->length = 0; - } + buf = convert_to_float(r, (pa_memchunk*) in); + buf = remap_channels(r, buf); + buf = resample(r, buf); + + if (buf->length) { + buf = convert_from_float(r, buf); + *out = *buf; + + if (buf == in) + pa_memblock_ref(buf->memblock); + else + pa_memchunk_reset(buf); + } else + pa_memchunk_reset(out); + + pa_memblock_release(in->memblock); + } static void libsamplerate_update_input_rate(pa_resampler *r, uint32_t rate) { @@ -518,8 +518,10 @@ static int libsamplerate_init(pa_resampler *r) { r->impl_data = u = pa_xnew(struct impl_libsamplerate, 1); - u->buf1 = u->buf2 = u->buf3 = u->buf4 = NULL; - u->buf1_block = u->buf2_block = u->buf3_block = u->buf4_block = NULL; + pa_memchunk_reset(&u->buf1); + pa_memchunk_reset(&u->buf2); + pa_memchunk_reset(&u->buf3); + pa_memchunk_reset(&u->buf4); u->buf1_samples = u->buf2_samples = u->buf3_samples = u->buf4_samples = 0; if (r->i_ss.format == PA_SAMPLE_FLOAT32NE) @@ -580,6 +582,7 @@ static void trivial_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out /* Do real resampling */ size_t l; unsigned o_index; + void *src, *dst; /* The length of the new memory block rounded up */ l = ((((n_frames+1) * r->o_ss.rate) / r->i_ss.rate) + 1) * fz; @@ -587,6 +590,9 @@ static void trivial_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out out->index = 0; out->memblock = pa_memblock_new(r->mempool, l); + src = (uint8_t*) pa_memblock_acquire(in->memblock) + in->index; + dst = pa_memblock_acquire(out->memblock); + for (o_index = 0;; o_index++, u->o_counter++) { unsigned j; @@ -596,13 +602,16 @@ static void trivial_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out if (j >= n_frames) break; - assert(o_index*fz < out->memblock->length); + assert(o_index*fz < pa_memblock_get_length(out->memblock)); - memcpy((uint8_t*) out->memblock->data + fz*o_index, - (uint8_t*) in->memblock->data + in->index + fz*j, fz); + memcpy((uint8_t*) dst + fz*o_index, + (uint8_t*) src + fz*j, fz); } + pa_memblock_release(in->memblock); + pa_memblock_release(out->memblock); + out->length = o_index*fz; } diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c index a9971408..2e514279 100644 --- a/src/pulsecore/sample-util.c +++ b/src/pulsecore/sample-util.c @@ -61,15 +61,27 @@ pa_memblock *pa_silence_memblock_new(pa_mempool *pool, const pa_sample_spec *spe } pa_memblock *pa_silence_memblock(pa_memblock* b, const pa_sample_spec *spec) { - assert(b && b->data && spec); - pa_silence_memory(b->data, b->length, spec); + void *data; + + assert(b); + assert(spec); + + data = pa_memblock_acquire(b); + pa_silence_memory(data, pa_memblock_get_length(b), spec); + pa_memblock_release(b); return b; } void pa_silence_memchunk(pa_memchunk *c, const pa_sample_spec *spec) { - assert(c && c->memblock && c->memblock->data && spec && c->length); + void *data; - pa_silence_memory((uint8_t*) c->memblock->data+c->index, c->length, spec); + assert(c); + assert(c->memblock); + assert(spec); + + data = pa_memblock_acquire(c->memblock); + pa_silence_memory((uint8_t*) data+c->index, c->length, spec); + pa_memblock_release(c->memblock); } void pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) { @@ -98,26 +110,38 @@ void pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) { } size_t pa_mix( - const pa_mix_info streams[], - unsigned nstreams, - void *data, - size_t length, - const pa_sample_spec *spec, - const pa_cvolume *volume, - int mute) { + pa_mix_info streams[], + unsigned nstreams, + void *data, + size_t length, + const pa_sample_spec *spec, + const pa_cvolume *volume, + int mute) { + + pa_cvolume full_volume; + size_t d = 0; + unsigned k; + + assert(streams); + assert(data); + assert(length); + assert(spec); - assert(streams && data && length && spec); + if (!volume) + volume = pa_cvolume_reset(&full_volume, spec->channels); + + for (k = 0; k < nstreams; k++) + streams[k].internal = pa_memblock_acquire(streams[k].chunk.memblock); switch (spec->format) { case PA_SAMPLE_S16NE:{ - size_t d; unsigned channel = 0; for (d = 0;; d += sizeof(int16_t)) { int32_t sum = 0; if (d >= length) - return d; + goto finish; if (!mute && volume->values[channel] != PA_VOLUME_MUTED) { unsigned i; @@ -127,12 +151,12 @@ size_t pa_mix( pa_volume_t cvolume = streams[i].volume.values[channel]; if (d >= streams[i].chunk.length) - return d; + goto finish; if (cvolume == PA_VOLUME_MUTED) v = 0; else { - v = *((int16_t*) ((uint8_t*) streams[i].chunk.memblock->data + streams[i].chunk.index + d)); + v = *((int16_t*) ((uint8_t*) streams[i].internal + streams[i].chunk.index + d)); if (cvolume != PA_VOLUME_NORM) v = (int32_t) (v * pa_sw_volume_to_linear(cvolume)); @@ -155,17 +179,18 @@ size_t pa_mix( if (++channel >= spec->channels) channel = 0; } + + break; } case PA_SAMPLE_S16RE:{ - size_t d; unsigned channel = 0; for (d = 0;; d += sizeof(int16_t)) { int32_t sum = 0; if (d >= length) - return d; + goto finish; if (!mute && volume->values[channel] != PA_VOLUME_MUTED) { unsigned i; @@ -175,12 +200,12 @@ size_t pa_mix( pa_volume_t cvolume = streams[i].volume.values[channel]; if (d >= streams[i].chunk.length) - return d; + goto finish; if (cvolume == PA_VOLUME_MUTED) v = 0; else { - v = INT16_SWAP(*((int16_t*) ((uint8_t*) streams[i].chunk.memblock->data + streams[i].chunk.index + d))); + v = INT16_SWAP(*((int16_t*) ((uint8_t*) streams[i].internal + streams[i].chunk.index + d))); if (cvolume != PA_VOLUME_NORM) v = (int32_t) (v * pa_sw_volume_to_linear(cvolume)); @@ -203,17 +228,18 @@ size_t pa_mix( if (++channel >= spec->channels) channel = 0; } + + break; } case PA_SAMPLE_U8: { - size_t d; unsigned channel = 0; for (d = 0;; d ++) { int32_t sum = 0; if (d >= length) - return d; + goto finish; if (!mute && volume->values[channel] != PA_VOLUME_MUTED) { unsigned i; @@ -223,12 +249,12 @@ size_t pa_mix( pa_volume_t cvolume = streams[i].volume.values[channel]; if (d >= streams[i].chunk.length) - return d; + goto finish; if (cvolume == PA_VOLUME_MUTED) v = 0; else { - v = (int32_t) *((uint8_t*) streams[i].chunk.memblock->data + streams[i].chunk.index + d) - 0x80; + v = (int32_t) *((uint8_t*) streams[i].internal + streams[i].chunk.index + d) - 0x80; if (cvolume != PA_VOLUME_NORM) v = (int32_t) (v * pa_sw_volume_to_linear(cvolume)); @@ -251,17 +277,18 @@ size_t pa_mix( if (++channel >= spec->channels) channel = 0; } + + break; } case PA_SAMPLE_FLOAT32NE: { - size_t d; unsigned channel = 0; for (d = 0;; d += sizeof(float)) { float sum = 0; if (d >= length) - return d; + goto finish; if (!mute && volume->values[channel] != PA_VOLUME_MUTED) { unsigned i; @@ -271,12 +298,12 @@ size_t pa_mix( pa_volume_t cvolume = streams[i].volume.values[channel]; if (d >= streams[i].chunk.length) - return d; + goto finish; if (cvolume == PA_VOLUME_MUTED) v = 0; else { - v = *((float*) ((uint8_t*) streams[i].chunk.memblock->data + streams[i].chunk.index + d)); + v = *((float*) ((uint8_t*) streams[i].internal + streams[i].chunk.index + d)); if (cvolume != PA_VOLUME_NORM) v *= pa_sw_volume_to_linear(cvolume); @@ -295,17 +322,34 @@ size_t pa_mix( if (++channel >= spec->channels) channel = 0; } + + break; } default: pa_log_error("ERROR: Unable to mix audio data of format %s.", pa_sample_format_to_string(spec->format)); abort(); } + +finish: + + for (k = 0; k < nstreams; k++) + pa_memblock_release(streams[k].chunk.memblock); + + return d; } -void pa_volume_memchunk(pa_memchunk*c, const pa_sample_spec *spec, const pa_cvolume *volume) { - assert(c && spec && (c->length % pa_frame_size(spec) == 0)); +void pa_volume_memchunk( + pa_memchunk*c, + const pa_sample_spec *spec, + const pa_cvolume *volume) { + + void *ptr; + + assert(c); + assert(spec); + assert(c->length % pa_frame_size(spec) == 0); assert(volume); if (pa_cvolume_channels_equal_to(volume, PA_VOLUME_NORM)) @@ -316,6 +360,8 @@ void pa_volume_memchunk(pa_memchunk*c, const pa_sample_spec *spec, const pa_cvol return; } + ptr = pa_memblock_acquire(c->memblock); + switch (spec->format) { case PA_SAMPLE_S16NE: { int16_t *d; @@ -326,7 +372,7 @@ void pa_volume_memchunk(pa_memchunk*c, const pa_sample_spec *spec, const pa_cvol for (channel = 0; channel < spec->channels; channel++) linear[channel] = pa_sw_volume_to_linear(volume->values[channel]); - for (channel = 0, d = (int16_t*) ((uint8_t*) c->memblock->data+c->index), n = c->length/sizeof(int16_t); n > 0; d++, n--) { + for (channel = 0, d = (int16_t*) ((uint8_t*) ptr + c->index), n = c->length/sizeof(int16_t); n > 0; d++, n--) { int32_t t = (int32_t)(*d); t = (int32_t) (t * linear[channel]); @@ -351,7 +397,7 @@ void pa_volume_memchunk(pa_memchunk*c, const pa_sample_spec *spec, const pa_cvol for (channel = 0; channel < spec->channels; channel++) linear[channel] = pa_sw_volume_to_linear(volume->values[channel]); - for (channel = 0, d = (int16_t*) ((uint8_t*) c->memblock->data+c->index), n = c->length/sizeof(int16_t); n > 0; d++, n--) { + for (channel = 0, d = (int16_t*) ((uint8_t*) ptr + c->index), n = c->length/sizeof(int16_t); n > 0; d++, n--) { int32_t t = (int32_t)(INT16_SWAP(*d)); t = (int32_t) (t * linear[channel]); @@ -373,7 +419,7 @@ void pa_volume_memchunk(pa_memchunk*c, const pa_sample_spec *spec, const pa_cvol size_t n; unsigned channel = 0; - for (d = (uint8_t*) c->memblock->data + c->index, n = c->length; n > 0; d++, n--) { + for (d = (uint8_t*) ptr + c->index, n = c->length; n > 0; d++, n--) { int32_t t = (int32_t) *d - 0x80; t = (int32_t) (t * pa_sw_volume_to_linear(volume->values[channel])); @@ -395,7 +441,7 @@ void pa_volume_memchunk(pa_memchunk*c, const pa_sample_spec *spec, const pa_cvol unsigned n; unsigned channel; - d = (float*) ((uint8_t*) c->memblock->data + c->index); + d = (float*) ((uint8_t*) ptr + c->index); skip = spec->channels * sizeof(float); n = c->length/sizeof(float)/spec->channels; @@ -418,5 +464,7 @@ void pa_volume_memchunk(pa_memchunk*c, const pa_sample_spec *spec, const pa_cvol pa_sample_format_to_string(spec->format)); abort(); } + + pa_memblock_release(c->memblock); } diff --git a/src/pulsecore/sample-util.h b/src/pulsecore/sample-util.h index 3ff065ab..2b11ad3c 100644 --- a/src/pulsecore/sample-util.h +++ b/src/pulsecore/sample-util.h @@ -39,10 +39,11 @@ typedef struct pa_mix_info { pa_memchunk chunk; pa_cvolume volume; void *userdata; + void *internal; /* Used internally by pa_mix(), should not be initialised when calling pa_mix() */ } pa_mix_info; size_t pa_mix( - const pa_mix_info channels[], + pa_mix_info channels[], unsigned nchannels, void *data, size_t length, diff --git a/src/pulsecore/semaphore-posix.c b/src/pulsecore/semaphore-posix.c new file mode 100644 index 00000000..71ec57a2 --- /dev/null +++ b/src/pulsecore/semaphore-posix.c @@ -0,0 +1,69 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include + +#include "semaphore.h" + +struct pa_semaphore { + sem_t sem; +}; + +pa_semaphore* pa_semaphore_new(unsigned value) { + pa_semaphore *s; + + s = pa_xnew(pa_semaphore, 1); + pa_assert_se(sem_init(&s->sem, 0, value) == 0); + return s; +} + +void pa_semaphore_free(pa_semaphore *s) { + pa_assert(s); + pa_assert_se(sem_destroy(&s->sem) == 0); + pa_xfree(s); +} + +void pa_semaphore_post(pa_semaphore *s) { + pa_assert(s); + pa_assert_se(sem_post(&s->sem) == 0); +} + +void pa_semaphore_wait(pa_semaphore *s) { + int ret; + pa_assert(s); + + do { + ret = sem_wait(&s->sem); + } while (ret < 0 && errno == EINTR); + + pa_assert(ret == 0); +} diff --git a/src/pulsecore/semaphore.h b/src/pulsecore/semaphore.h new file mode 100644 index 00000000..c394e0f2 --- /dev/null +++ b/src/pulsecore/semaphore.h @@ -0,0 +1,35 @@ +#ifndef foopulsesemaphorehfoo +#define foopulsesemaphorehfoo + +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +typedef struct pa_semaphore pa_semaphore; + +pa_semaphore* pa_semaphore_new(unsigned value); +void pa_semaphore_free(pa_semaphore *m); + +void pa_semaphore_post(pa_semaphore *m); +void pa_semaphore_wait(pa_semaphore *m); + +#endif diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 3ddd7435..da7b58b7 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -27,7 +27,6 @@ #endif #include -#include #include #include @@ -46,41 +45,45 @@ #define MOVE_BUFFER_LENGTH (1024*1024) #define SILENCE_BUFFER_LENGTH (64*1024) -#define CHECK_VALIDITY_RETURN_NULL(condition) \ -do {\ -if (!(condition)) \ - return NULL; \ -} while (0) +static void sink_input_free(pa_msgobject *o); pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data) { - assert(data); + pa_assert(data); memset(data, 0, sizeof(*data)); data->resample_method = PA_RESAMPLER_INVALID; + return data; } void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const pa_channel_map *map) { - assert(data); + pa_assert(data); if ((data->channel_map_is_set = !!map)) data->channel_map = *map; } void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume) { - assert(data); + pa_assert(data); if ((data->volume_is_set = !!volume)) data->volume = *volume; } void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const pa_sample_spec *spec) { - assert(data); + pa_assert(data); if ((data->sample_spec_is_set = !!spec)) data->sample_spec = *spec; } +void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, int mute) { + pa_assert(data); + + data->muted_is_set = 1; + data->muted = !!mute; +} + pa_sink_input* pa_sink_input_new( pa_core *core, pa_sink_input_new_data *data, @@ -88,46 +91,52 @@ pa_sink_input* pa_sink_input_new( pa_sink_input *i; pa_resampler *resampler = NULL; - int r; char st[PA_SAMPLE_SPEC_SNPRINT_MAX]; - assert(core); - assert(data); + pa_assert(core); + pa_assert(data); if (!(flags & PA_SINK_INPUT_NO_HOOKS)) if (pa_hook_fire(&core->hook_sink_input_new, data) < 0) return NULL; - CHECK_VALIDITY_RETURN_NULL(!data->driver || pa_utf8_valid(data->driver)); - CHECK_VALIDITY_RETURN_NULL(!data->name || pa_utf8_valid(data->name)); + pa_return_null_if_fail(!data->driver || pa_utf8_valid(data->driver)); + pa_return_null_if_fail(!data->name || pa_utf8_valid(data->name)); if (!data->sink) data->sink = pa_namereg_get(core, NULL, PA_NAMEREG_SINK, 1); - CHECK_VALIDITY_RETURN_NULL(data->sink); - CHECK_VALIDITY_RETURN_NULL(data->sink->state == PA_SINK_RUNNING); + pa_return_null_if_fail(data->sink); + pa_return_null_if_fail(pa_sink_get_state(data->sink) != PA_SINK_DISCONNECTED); if (!data->sample_spec_is_set) data->sample_spec = data->sink->sample_spec; - CHECK_VALIDITY_RETURN_NULL(pa_sample_spec_valid(&data->sample_spec)); + pa_return_null_if_fail(pa_sample_spec_valid(&data->sample_spec)); - if (!data->channel_map_is_set) - pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT); + if (!data->channel_map_is_set) { + if (data->sink->channel_map.channels == data->sample_spec.channels) + data->channel_map = data->sink->channel_map; + else + pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT); + } - CHECK_VALIDITY_RETURN_NULL(pa_channel_map_valid(&data->channel_map)); - CHECK_VALIDITY_RETURN_NULL(data->channel_map.channels == data->sample_spec.channels); + pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map)); + pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels); if (!data->volume_is_set) pa_cvolume_reset(&data->volume, data->sample_spec.channels); - CHECK_VALIDITY_RETURN_NULL(pa_cvolume_valid(&data->volume)); - CHECK_VALIDITY_RETURN_NULL(data->volume.channels == data->sample_spec.channels); + pa_return_null_if_fail(pa_cvolume_valid(&data->volume)); + pa_return_null_if_fail(data->volume.channels == data->sample_spec.channels); + if (!data->muted_is_set) + data->muted = 0; + if (data->resample_method == PA_RESAMPLER_INVALID) data->resample_method = core->resample_method; - CHECK_VALIDITY_RETURN_NULL(data->resample_method < PA_RESAMPLER_MAX); + pa_return_null_if_fail(data->resample_method < PA_RESAMPLER_MAX); if (pa_idxset_size(data->sink->inputs) >= PA_MAX_INPUTS_PER_SINK) { pa_log_warn("Failed to create sink input: too many inputs per sink."); @@ -136,7 +145,7 @@ pa_sink_input* pa_sink_input_new( if ((flags & PA_SINK_INPUT_VARIABLE_RATE) || !pa_sample_spec_equal(&data->sample_spec, &data->sink->sample_spec) || - !pa_channel_map_equal(&data->channel_map, &data->sink->channel_map)) + !pa_channel_map_equal(&data->channel_map, &data->sink->channel_map)) { if (!(resampler = pa_resampler_new( core->mempool, @@ -147,20 +156,31 @@ pa_sink_input* pa_sink_input_new( return NULL; } - i = pa_xnew(pa_sink_input, 1); - i->ref = 1; - i->state = PA_SINK_INPUT_DRAINED; + data->resample_method = pa_resampler_get_method(resampler); + } + + i = pa_msgobject_new(pa_sink_input); + + i->parent.parent.free = sink_input_free; + i->parent.process_msg = pa_sink_input_process_msg; + + i->core = core; + pa_atomic_load(&i->state, PA_SINK_INPUT_DRAINED); i->flags = flags; i->name = pa_xstrdup(data->name); i->driver = pa_xstrdup(data->driver); i->module = data->module; i->sink = data->sink; i->client = data->client; - + + i->resample_method = data->resample_method; i->sample_spec = data->sample_spec; i->channel_map = data->channel_map; - i->volume = data->volume; + i->volume = data->volume; + i->muted = data->muted; + + i->process_msg = NULL; i->peek = NULL; i->drop = NULL; i->kill = NULL; @@ -168,94 +188,87 @@ pa_sink_input* pa_sink_input_new( i->underrun = NULL; i->userdata = NULL; - i->move_silence = 0; - - pa_memchunk_reset(&i->resampled_chunk); - i->resampler = resampler; - i->resample_method = data->resample_method; - i->silence_memblock = NULL; + i->thread_info.silence_memblock = NULL; + i->thread_info.move_silence = 0; + pa_memchunk_reset(&i->thread_info.resampled_chunk); + i->thread_info.resampler = resampler; + i->thread_info.soft_volume = i->volume; + i->thread_info.soft_muted = i->muted; - r = pa_idxset_put(core->sink_inputs, i, &i->index); - assert(r == 0); - r = pa_idxset_put(i->sink->inputs, i, NULL); - assert(r == 0); + pa_assert_se(pa_idxset_put(core->sink_inputs, i, &i->index) == 0); + pa_assert_se(pa_idxset_put(i->sink->inputs, i, NULL) == 0); - pa_log_info("created %u \"%s\" on %s with sample spec %s", + pa_log_info("Created input %u \"%s\" on %s with sample spec %s", i->index, i->name, i->sink->name, pa_sample_spec_snprint(st, sizeof(st), &i->sample_spec)); - pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index); - - /* We do not call pa_sink_notify() here, because the virtual - * functions have not yet been initialized */ + /* Don't forget to call pa_sink_input_put! */ return i; } void pa_sink_input_disconnect(pa_sink_input *i) { - assert(i); - assert(i->state != PA_SINK_INPUT_DISCONNECTED); - assert(i->sink); - assert(i->sink->core); + pa_assert(i); + pa_return_if_fail(pa_sink_input_get_state(i) != PA_SINK_INPUT_DISCONNECTED); + pa_asyncmsgq_send(i->sink->asyncmsgq, i->sink, PA_SINK_MESSAGE_REMOVE_INPUT, i, NULL); + pa_idxset_remove_by_data(i->sink->core->sink_inputs, i, NULL); pa_idxset_remove_by_data(i->sink->inputs, i, NULL); pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE, i->index); i->sink = NULL; + i->process_msg = NULL; i->peek = NULL; i->drop = NULL; i->kill = NULL; i->get_latency = NULL; i->underrun = NULL; - i->state = PA_SINK_INPUT_DISCONNECTED; + pa_atomic_load(&i->state, PA_SINK_INPUT_DISCONNECTED); } -static void sink_input_free(pa_sink_input* i) { - assert(i); +static void sink_input_free(pa_msgobject *o) { + pa_sink_input* i = PA_SINK_INPUT(o); - if (i->state != PA_SINK_INPUT_DISCONNECTED) - pa_sink_input_disconnect(i); + pa_assert(i); + pa_assert(pa_sink_input_refcnt(i) == 0); + + pa_sink_input_disconnect(i); - pa_log_info("freed %u \"%s\"", i->index, i->name); + pa_log_info("Freeing output %u \"%s\"", i->index, i->name); if (i->resampled_chunk.memblock) pa_memblock_unref(i->resampled_chunk.memblock); - if (i->resampler) - pa_resampler_free(i->resampler); + if (i->thread_info.resampler) + pa_resampler_free(i->thread_info.resampler); - if (i->silence_memblock) - pa_memblock_unref(i->silence_memblock); + if (i->thread_info.silence_memblock) + pa_memblock_unref(i->thread_info.silence_memblock); pa_xfree(i->name); pa_xfree(i->driver); pa_xfree(i); } -void pa_sink_input_unref(pa_sink_input *i) { - assert(i); - assert(i->ref >= 1); +void pa_sink_input_put(pa_sink_input *i) { + pa_sink_input_assert_ref(i); - if (!(--i->ref)) - sink_input_free(i); -} + i->thread_info.volume = i->volume; + i->thread_info.muted = i->muted; -pa_sink_input* pa_sink_input_ref(pa_sink_input *i) { - assert(i); - assert(i->ref >= 1); + pa_asyncmsgq_post(i->sink->asyncmsgq, i->sink, PA_SINK_MESSAGE_ADD_INPUT, i, NULL, pa_sink_unref, pa_sink_input_unref); + pa_sink_update_status(i->sink); - i->ref++; - return i; + pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index); } void pa_sink_input_kill(pa_sink_input*i) { - assert(i); - assert(i->ref >= 1); + pa_sink_input_assert_ref(i); if (i->kill) i->kill(i); @@ -264,18 +277,14 @@ void pa_sink_input_kill(pa_sink_input*i) { pa_usec_t pa_sink_input_get_latency(pa_sink_input *i) { pa_usec_t r = 0; - assert(i); - assert(i->ref >= 1); + pa_sink_input_assert_ref(i); + if (pa_asyncmsgq_send(i->sink->asyncmsgq, i->sink, PA_SINK_INPUT_MESSAGE_GET_LATENCY, &r, NULL) < 0) + r = 0; + if (i->get_latency) r += i->get_latency(i); - if (i->resampled_chunk.memblock) - r += pa_bytes_to_usec(i->resampled_chunk.length, &i->sink->sample_spec); - - if (i->move_silence) - r += pa_bytes_to_usec(i->move_silence, &i->sink->sample_spec); - return r; } @@ -283,35 +292,40 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) int ret = -1; int do_volume_adj_here; int volume_is_norm; + pa_sink_input_state_t state; + + pa_sink_input_assert_ref(i); + pa_assert(chunk); + pa_assert(volume); - assert(i); - assert(i->ref >= 1); - assert(chunk); - assert(volume); + state = pa_sink_input_get_state(i); - pa_sink_input_ref(i); + if (state == PA_SINK_INPUT_DISCONNECTED) + return -1; - if (!i->peek || !i->drop || i->state == PA_SINK_INPUT_CORKED) + if (!i->peek || !i->drop || state == PA_SINK_INPUT_CORKED) goto finish; - assert(i->state == PA_SINK_INPUT_RUNNING || i->state == PA_SINK_INPUT_DRAINED); + pa_assert(state == PA_SINK_INPUT_RUNNING || state == PA_SINK_INPUT_DRAINED); - if (i->move_silence > 0) { +/* if (i->thread_info.move_silence > 0) { */ +/* size_t l; */ - /* We have just been moved and shall play some silence for a - * while until the old sink has drained its playback buffer */ +/* /\* We have just been moved and shall play some silence for a */ +/* * while until the old sink has drained its playback buffer *\/ */ - if (!i->silence_memblock) - i->silence_memblock = pa_silence_memblock_new(i->sink->core->mempool, &i->sink->sample_spec, SILENCE_BUFFER_LENGTH); +/* if (!i->thread_info.silence_memblock) */ +/* i->thread_info.silence_memblock = pa_silence_memblock_new(i->sink->core->mempool, &i->sink->sample_spec, SILENCE_BUFFER_LENGTH); */ - chunk->memblock = pa_memblock_ref(i->silence_memblock); - chunk->index = 0; - chunk->length = i->move_silence < chunk->memblock->length ? i->move_silence : chunk->memblock->length; +/* chunk->memblock = pa_memblock_ref(i->thread_info.silence_memblock); */ +/* chunk->index = 0; */ +/* l = pa_memblock_get_length(chunk->memblock); */ +/* chunk->length = i->move_silence < l ? i->move_silence : l; */ - ret = 0; - do_volume_adj_here = 1; - goto finish; - } +/* ret = 0; */ +/* do_volume_adj_here = 1; */ +/* goto finish; */ +/* } */ if (!i->resampler) { do_volume_adj_here = 0; @@ -320,16 +334,16 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) } do_volume_adj_here = !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map); - volume_is_norm = pa_cvolume_is_norm(&i->volume); + volume_is_norm = pa_cvolume_is_norm(&i->thread_info.soft_volume) && !i->thread_info.soft_muted; - while (!i->resampled_chunk.memblock) { + while (!i->thread_info.resampled_chunk.memblock) { pa_memchunk tchunk; size_t l; if ((ret = i->peek(i, &tchunk)) < 0) goto finish; - assert(tchunk.length); + pa_assert(tchunk.length); l = pa_resampler_request(i->resampler, CONVERT_BUFFER_LENGTH); @@ -342,30 +356,30 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) /* It might be necessary to adjust the volume here */ if (do_volume_adj_here && !volume_is_norm) { pa_memchunk_make_writable(&tchunk, 0); - pa_volume_memchunk(&tchunk, &i->sample_spec, &i->volume); + pa_volume_memchunk(&tchunk, &i->sample_spec, &i->thread_info.soft_volume); } - pa_resampler_run(i->resampler, &tchunk, &i->resampled_chunk); + pa_resampler_run(i->resampler, &tchunk, &i->thread_info.resampled_chunk); pa_memblock_unref(tchunk.memblock); } - assert(i->resampled_chunk.memblock); - assert(i->resampled_chunk.length); + pa_assert(i->thread_info.resampled_chunk.memblock); + pa_assert(i->thread_info.resampled_chunk.length); - *chunk = i->resampled_chunk; - pa_memblock_ref(i->resampled_chunk.memblock); + *chunk = i->thread_info.resampled_chunk; + pa_memblock_ref(i->thread_info.resampled_chunk.memblock); ret = 0; finish: - if (ret < 0 && i->state == PA_SINK_INPUT_RUNNING && i->underrun) + if (ret < 0 && state == PA_SINK_INPUT_RUNNING && i->underrun) i->underrun(i); if (ret >= 0) - i->state = PA_SINK_INPUT_RUNNING; + pa_atomic_cmpxchg(&i->state, state, PA_SINK_INPUT_RUNNING); else if (ret < 0 && i->state == PA_SINK_INPUT_RUNNING) - i->state = PA_SINK_INPUT_DRAINED; + pa_atomic_cmpxchg(&i->state, state, PA_SINK_INPUT_DRAINED); if (ret >= 0) { /* Let's see if we had to apply the volume adjustment @@ -376,42 +390,42 @@ finish: pa_cvolume_reset(volume, i->sink->sample_spec.channels); else /* We've both the same channel map, so let's have the sink do the adjustment for us*/ - *volume = i->volume; + *volume = i->thread_info.volume; } - pa_sink_input_unref(i); - return ret; } void pa_sink_input_drop(pa_sink_input *i, const pa_memchunk *chunk, size_t length) { - assert(i); - assert(i->ref >= 1); - assert(length > 0); + pa_sink_input_assert_ref(i); + pa_assert(length > 0); - if (i->move_silence > 0) { +/* if (i->move_silence > 0) { */ - if (chunk) { +/* if (chunk) { */ +/* size_t l; */ - if (chunk->memblock != i->silence_memblock || - chunk->index != 0 || - (chunk->memblock && (chunk->length != (i->silence_memblock->length < i->move_silence ? i->silence_memblock->length : i->move_silence)))) - return; +/* l = pa_memblock_get_length(i->silence_memblock); */ - } +/* if (chunk->memblock != i->silence_memblock || */ +/* chunk->index != 0 || */ +/* (chunk->memblock && (chunk->length != (l < i->move_silence ? l : i->move_silence)))) */ +/* return; */ - assert(i->move_silence >= length); +/* } */ - i->move_silence -= length; +/* pa_assert(i->move_silence >= length); */ - if (i->move_silence <= 0) { - assert(i->silence_memblock); - pa_memblock_unref(i->silence_memblock); - i->silence_memblock = NULL; - } +/* i->move_silence -= length; */ - return; - } +/* if (i->move_silence <= 0) { */ +/* pa_assert(i->silence_memblock); */ +/* pa_memblock_unref(i->silence_memblock); */ +/* i->silence_memblock = NULL; */ +/* } */ + +/* return; */ +/* } */ if (!i->resampler) { if (i->drop) @@ -419,75 +433,88 @@ void pa_sink_input_drop(pa_sink_input *i, const pa_memchunk *chunk, size_t lengt return; } - assert(i->resampled_chunk.memblock); - assert(i->resampled_chunk.length >= length); + pa_assert(i->thread_info.resampled_chunk.memblock); + pa_assert(i->thread_info.resampled_chunk.length >= length); - i->resampled_chunk.index += length; - i->resampled_chunk.length -= length; + i->thread_info.resampled_chunk.index += length; + i->thread_info.resampled_chunk.length -= length; - if (i->resampled_chunk.length <= 0) { - pa_memblock_unref(i->resampled_chunk.memblock); - i->resampled_chunk.memblock = NULL; - i->resampled_chunk.index = i->resampled_chunk.length = 0; + if (i->thread_info.resampled_chunk.length <= 0) { + pa_memblock_unref(i->thread_info.resampled_chunk.memblock); + i->thread_info.resampled_chunk.memblock = NULL; + i->thread_info.resampled_chunk.index = i->thread_info.resampled_chunk.length = 0; } } void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume) { - assert(i); - assert(i->ref >= 1); - assert(i->sink); - assert(i->sink->core); + pa_sink_input_assert_ref(i); if (pa_cvolume_equal(&i->volume, volume)) return; i->volume = *volume; + + pa_asyncmsgq_post(s->asyncmsgq, pa_sink_input_ref(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME, pa_xnewdup(struct pa_cvolume, volume, 1), pa_sink_input_unref, pa_xfree); pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); } -const pa_cvolume * pa_sink_input_get_volume(pa_sink_input *i) { - assert(i); - assert(i->ref >= 1); +const pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i) { + pa_sink_input_assert_ref(i); return &i->volume; } -void pa_sink_input_cork(pa_sink_input *i, int b) { - int n; +void pa_sink_input_set_mute(pa_sink_input *i, int mute) { + pa_assert(i); + pa_sink_input_assert_ref(i); - assert(i); - assert(i->ref >= 1); + if (!i->muted == !mute) + return; - assert(i->state != PA_SINK_INPUT_DISCONNECTED); + i->muted = mute; - n = i->state == PA_SINK_INPUT_CORKED && !b; + pa_asyncmsgq_post(s->asyncmsgq, pa_sink_input_ref(i), PA_SINK_INPUT_MESSAGE_SET_MUTE, PA_UINT_TO_PTR(mute), pa_sink_input_unref, NULL); + pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); +} - if (b) - i->state = PA_SINK_INPUT_CORKED; - else if (i->state == PA_SINK_INPUT_CORKED) - i->state = PA_SINK_INPUT_DRAINED; +int pa_sink_input_get_mute(pa_sink_input *i) { + pa_sink_input_assert_ref(i); - if (n) - pa_sink_notify(i->sink); + return !!i->mute; } -void pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) { - assert(i); - assert(i->resampler); - assert(i->ref >= 1); +void pa_sink_input_cork(pa_sink_input *i, int b) { + int n; + pa_sink_input_state_t state; + + pa_sink_input_assert_ref(i); + + state = pa_sink_input_get_state(i); + pa_assert(state != PA_SINK_INPUT_DISCONNECTED); + + if (b && state != PA_SINK_INPUT_CORKED) + pa_atomic_store(i->state, PA_SINK_INPUT_CORKED); + else if (!b && state == PA_SINK_INPUT_CORKED) + pa_atomic_cmpxchg(i->state, state, PA_SINK_INPUT_DRAINED); +} + +int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) { + pa_sink_input_assert_ref(i); + pa_return_val_if_fail(u->thread_info.resampler, -1); if (i->sample_spec.rate == rate) - return; + return 0; i->sample_spec.rate = rate; - pa_resampler_set_input_rate(i->resampler, rate); + pa_asyncmsgq_post(s->asyncmsgq, pa_sink_input_ref(i), PA_SINK_INPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), NULL, pa_sink_input_unref, NULL); + pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); + return 0 } void pa_sink_input_set_name(pa_sink_input *i, const char *name) { - assert(i); - assert(i->ref >= 1); + pa_sink_input_assert_ref(i); if (!i->name && !name) return; @@ -502,13 +529,9 @@ void pa_sink_input_set_name(pa_sink_input *i, const char *name) { } pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i) { - assert(i); - assert(i->ref >= 1); - - if (!i->resampler) - return i->resample_method; + pa_sink_input_assert_ref(i); - return pa_resampler_get_method(i->resampler); + return i->resample_method; } int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { @@ -516,156 +539,196 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { pa_memblockq *buffer = NULL; pa_sink *origin; - assert(i); - assert(dest); + pa_sink_input_assert_ref(i); + pa_sink_assert_ref(dest); - origin = i->sink; + return -1; + +/* origin = i->sink; */ - if (dest == origin) - return 0; +/* if (dest == origin) */ +/* return 0; */ - if (pa_idxset_size(dest->inputs) >= PA_MAX_INPUTS_PER_SINK) { - pa_log_warn("Failed to move sink input: too many inputs per sink."); - return -1; - } +/* if (pa_idxset_size(dest->inputs) >= PA_MAX_INPUTS_PER_SINK) { */ +/* pa_log_warn("Failed to move sink input: too many inputs per sink."); */ +/* return -1; */ +/* } */ - if (i->resampler && - pa_sample_spec_equal(&origin->sample_spec, &dest->sample_spec) && - pa_channel_map_equal(&origin->channel_map, &dest->channel_map)) +/* if (i->resampler && */ +/* pa_sample_spec_equal(&origin->sample_spec, &dest->sample_spec) && */ +/* pa_channel_map_equal(&origin->channel_map, &dest->channel_map)) */ - /* Try to reuse the old resampler if possible */ - new_resampler = i->resampler; +/* /\* Try to reuse the old resampler if possible *\/ */ +/* new_resampler = i->resampler; */ - else if ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) || - !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec) || - !pa_channel_map_equal(&i->channel_map, &dest->channel_map)) { +/* else if ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) || */ +/* !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec) || */ +/* !pa_channel_map_equal(&i->channel_map, &dest->channel_map)) { */ - /* Okey, we need a new resampler for the new sink */ +/* /\* Okey, we need a new resampler for the new sink *\/ */ - if (!(new_resampler = pa_resampler_new( - dest->core->mempool, - &i->sample_spec, &i->channel_map, - &dest->sample_spec, &dest->channel_map, - i->resample_method))) { - pa_log_warn("Unsupported resampling operation."); - return -1; - } - } - - if (!immediately) { - pa_usec_t old_latency, new_latency; - pa_usec_t silence_usec = 0; - - buffer = pa_memblockq_new(0, MOVE_BUFFER_LENGTH, 0, pa_frame_size(&origin->sample_spec), 0, 0, NULL); +/* if (!(new_resampler = pa_resampler_new( */ +/* dest->core->mempool, */ +/* &i->sample_spec, &i->channel_map, */ +/* &dest->sample_spec, &dest->channel_map, */ +/* i->resample_method))) { */ +/* pa_log_warn("Unsupported resampling operation."); */ +/* return -1; */ +/* } */ +/* } */ - /* Let's do a little bit of Voodoo for compensating latency - * differences */ +/* if (!immediately) { */ +/* pa_usec_t old_latency, new_latency; */ +/* pa_usec_t silence_usec = 0; */ - old_latency = pa_sink_get_latency(origin); - new_latency = pa_sink_get_latency(dest); +/* buffer = pa_memblockq_new(0, MOVE_BUFFER_LENGTH, 0, pa_frame_size(&origin->sample_spec), 0, 0, NULL); */ + +/* /\* Let's do a little bit of Voodoo for compensating latency */ +/* * differences *\/ */ + +/* old_latency = pa_sink_get_latency(origin); */ +/* new_latency = pa_sink_get_latency(dest); */ - /* The already resampled data should go to the old sink */ +/* /\* The already resampled data should go to the old sink *\/ */ + +/* if (old_latency >= new_latency) { */ - if (old_latency >= new_latency) { +/* /\* The latency of the old sink is larger than the latency */ +/* * of the new sink. Therefore to compensate for the */ +/* * difference we to play silence on the new one for a */ +/* * while *\/ */ - /* The latency of the old sink is larger than the latency - * of the new sink. Therefore to compensate for the - * difference we to play silence on the new one for a - * while */ +/* silence_usec = old_latency - new_latency; */ - silence_usec = old_latency - new_latency; +/* } else { */ +/* size_t l; */ +/* int volume_is_norm; */ - } else { - size_t l; - int volume_is_norm; +/* /\* The latency of new sink is larger than the latency of */ +/* * the old sink. Therefore we have to precompute a little */ +/* * and make sure that this is still played on the old */ +/* * sink, until we can play the first sample on the new */ +/* * sink.*\/ */ - /* The latency of new sink is larger than the latency of - * the old sink. Therefore we have to precompute a little - * and make sure that this is still played on the old - * sink, until we can play the first sample on the new - * sink.*/ +/* l = pa_usec_to_bytes(new_latency - old_latency, &origin->sample_spec); */ - l = pa_usec_to_bytes(new_latency - old_latency, &origin->sample_spec); +/* volume_is_norm = pa_cvolume_is_norm(&i->volume); */ - volume_is_norm = pa_cvolume_is_norm(&i->volume); +/* while (l > 0) { */ +/* pa_memchunk chunk; */ +/* pa_cvolume volume; */ +/* size_t n; */ - while (l > 0) { - pa_memchunk chunk; - pa_cvolume volume; - size_t n; +/* if (pa_sink_input_peek(i, &chunk, &volume) < 0) */ +/* break; */ - if (pa_sink_input_peek(i, &chunk, &volume) < 0) - break; +/* n = chunk.length > l ? l : chunk.length; */ +/* pa_sink_input_drop(i, &chunk, n); */ +/* chunk.length = n; */ - n = chunk.length > l ? l : chunk.length; - pa_sink_input_drop(i, &chunk, n); - chunk.length = n; +/* if (!volume_is_norm) { */ +/* pa_memchunk_make_writable(&chunk, 0); */ +/* pa_volume_memchunk(&chunk, &origin->sample_spec, &volume); */ +/* } */ - if (!volume_is_norm) { - pa_memchunk_make_writable(&chunk, 0); - pa_volume_memchunk(&chunk, &origin->sample_spec, &volume); - } +/* if (pa_memblockq_push(buffer, &chunk) < 0) { */ +/* pa_memblock_unref(chunk.memblock); */ +/* break; */ +/* } */ - if (pa_memblockq_push(buffer, &chunk) < 0) { - pa_memblock_unref(chunk.memblock); - break; - } +/* pa_memblock_unref(chunk.memblock); */ +/* l -= n; */ +/* } */ +/* } */ + +/* if (i->resampled_chunk.memblock) { */ + +/* /\* There is still some data left in the already resampled */ +/* * memory block. Hence, let's output it on the old sink */ +/* * and sleep so long on the new sink *\/ */ + +/* pa_memblockq_push(buffer, &i->resampled_chunk); */ +/* silence_usec += pa_bytes_to_usec(i->resampled_chunk.length, &origin->sample_spec); */ +/* } */ + +/* /\* Calculate the new sleeping time *\/ */ +/* i->move_silence = pa_usec_to_bytes( */ +/* pa_bytes_to_usec(i->move_silence, &i->sample_spec) + */ +/* silence_usec, */ +/* &i->sample_spec); */ +/* } */ + +/* /\* Okey, let's move it *\/ */ +/* pa_idxset_remove_by_data(origin->inputs, i, NULL); */ +/* pa_idxset_put(dest->inputs, i, NULL); */ +/* i->sink = dest; */ + +/* /\* Replace resampler *\/ */ +/* if (new_resampler != i->resampler) { */ +/* if (i->resampler) */ +/* pa_resampler_free(i->resampler); */ +/* i->resampler = new_resampler; */ + +/* /\* if the resampler changed, the silence memblock is */ +/* * probably invalid now, too *\/ */ +/* if (i->silence_memblock) { */ +/* pa_memblock_unref(i->silence_memblock); */ +/* i->silence_memblock = NULL; */ +/* } */ +/* } */ - pa_memblock_unref(chunk.memblock); - l -= n; - } - } - - if (i->resampled_chunk.memblock) { - - /* There is still some data left in the already resampled - * memory block. Hence, let's output it on the old sink - * and sleep so long on the new sink */ +/* /\* Dump already resampled data *\/ */ +/* if (i->resampled_chunk.memblock) { */ +/* pa_memblock_unref(i->resampled_chunk.memblock); */ +/* i->resampled_chunk.memblock = NULL; */ +/* i->resampled_chunk.index = i->resampled_chunk.length = 0; */ +/* } */ + +/* /\* Notify everyone *\/ */ +/* pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); */ +/* pa_sink_notify(i->sink); */ + +/* /\* Ok, now let's feed the precomputed buffer to the old sink *\/ */ +/* if (buffer) */ +/* pa_play_memblockq(origin, "Ghost Stream", &origin->sample_spec, &origin->channel_map, buffer, NULL); */ + +/* return 0; */ +} - pa_memblockq_push(buffer, &i->resampled_chunk); - silence_usec += pa_bytes_to_usec(i->resampled_chunk.length, &origin->sample_spec); +int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk) { + pa_sink_input *i = PA_SINK_INPUT(o); + + pa_sink_input_assert_ref(i); + + switch (code) { + case PA_SINK_INPUT_MESSAGE_SET_VOLUME: + s->thread_info.soft_volume = *((pa_cvolume*) userdata); + return 0; + + case PA_SINK_INPUT_MESSAGE_SET_MUTE: + s->thread_info.soft_muted = PA_PTR_TO_UINT(userdata); + return 0; + + case PA_SINK_INPUT_MESSAGE_GET_LATENCY: { + pa_usec_t *r = userdata; + + if (i->thread_info.resampled_chunk.memblock) + *r += pa_bytes_to_usec(i->resampled_chunk.length, &i->sink->sample_spec); + +/* if (i->move_silence) */ +/* r += pa_bytes_to_usec(i->move_silence, &i->sink->sample_spec); */ + + return 0; } + + case PA_SINK_INPUT_MESSAGE_SET_RATE: { + + i->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata); + pa_resampler_set_input_rate(i->resampler, PA_PTR_TO_UINT(userdata)); - /* Calculate the new sleeping time */ - i->move_silence = pa_usec_to_bytes( - pa_bytes_to_usec(i->move_silence, &i->sample_spec) + - silence_usec, - &i->sample_spec); - } - - /* Okey, let's move it */ - pa_idxset_remove_by_data(origin->inputs, i, NULL); - pa_idxset_put(dest->inputs, i, NULL); - i->sink = dest; - - /* Replace resampler */ - if (new_resampler != i->resampler) { - if (i->resampler) - pa_resampler_free(i->resampler); - i->resampler = new_resampler; - - /* if the resampler changed, the silence memblock is - * probably invalid now, too */ - if (i->silence_memblock) { - pa_memblock_unref(i->silence_memblock); - i->silence_memblock = NULL; + return 0; } } - /* Dump already resampled data */ - if (i->resampled_chunk.memblock) { - pa_memblock_unref(i->resampled_chunk.memblock); - i->resampled_chunk.memblock = NULL; - i->resampled_chunk.index = i->resampled_chunk.length = 0; - } - - /* Notify everyone */ - pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); - pa_sink_notify(i->sink); - - /* Ok, no let's feed the precomputed buffer to the old sink */ - if (buffer) - pa_play_memblockq(origin, "Ghost Stream", &origin->sample_spec, &origin->channel_map, buffer, NULL); - - return 0; + return -1; } diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index 51d9ec78..64a7a73f 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -1,5 +1,5 @@ -#ifndef foosinkinputhfoo -#define foosinkinputhfoo +#ifndef foopulsesinkinputhfoo +#define foopulsesinkinputhfoo /* $Id$ */ @@ -51,9 +51,11 @@ typedef enum pa_sink_input_flags { } pa_sink_input_flags_t; struct pa_sink_input { - int ref; + pa_msgobject parent; + uint32_t index; - pa_sink_input_state_t state; + pa_core *core; + pa_atomic_t state; pa_sink_input_flags_t flags; char *name, *driver; /* may be NULL */ @@ -64,27 +66,47 @@ struct pa_sink_input { pa_sample_spec sample_spec; pa_channel_map channel_map; + pa_cvolume volume; + int muted; - /* Some silence to play before the actual data. This is used to - * compensate for latency differences when moving a sink input - * "hot" between sinks. */ - size_t move_silence; - + int (*process_msg)(pa_sink_input *i, int code, void *userdata); int (*peek) (pa_sink_input *i, pa_memchunk *chunk); void (*drop) (pa_sink_input *i, const pa_memchunk *chunk, size_t length); void (*kill) (pa_sink_input *i); /* may be NULL */ pa_usec_t (*get_latency) (pa_sink_input *i); /* may be NULL */ void (*underrun) (pa_sink_input *i); /* may be NULL */ - void *userdata; + pa_resample_method_t resample_method; - pa_memchunk resampled_chunk; - pa_resampler *resampler; /* may be NULL */ + struct { + pa_sample_spec sample_spec; + + pa_memchunk resampled_chunk; + pa_resampler *resampler; /* may be NULL */ + + /* Some silence to play before the actual data. This is used to + * compensate for latency differences when moving a sink input + * "hot" between sinks. */ + /* size_t move_silence; */ + pa_memblock *silence_memblock; /* may be NULL */ + + pa_cvolume volume; + int muted; + } thread_info; + + void *userdata; +}; - pa_resample_method_t resample_method; +PA_DECLARE_CLASS(pa_sink_input); +#define PA_SINK_INPUT(o) ((pa_sink_input*) (o)) - pa_memblock *silence_memblock; /* may be NULL */ +enum { + PA_SINK_INPUT_MESSAGE_SET_VOLUME, + PA_SINK_INPUT_MESSAGE_SET_MUTE, + PA_SINK_INPUT_MESSAGE_GET_LATENCY, + PA_SINK_INPUT_MESSAGE_SET_RATE, + PA_SINK_INPUT_MESSAGE_MAX }; typedef struct pa_sink_input_new_data { @@ -100,6 +122,8 @@ typedef struct pa_sink_input_new_data { int channel_map_is_set; pa_cvolume volume; int volume_is_set; + int muted; + int muted_is_set; pa_resample_method_t resample_method; } pa_sink_input_new_data; @@ -108,37 +132,46 @@ pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const pa_sample_spec *spec); void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const pa_channel_map *map); void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume); +void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, int mute); + +/* To be called by the implementing module only */ pa_sink_input* pa_sink_input_new( pa_core *core, pa_sink_input_new_data *data, pa_sink_input_flags_t flags); -void pa_sink_input_unref(pa_sink_input* i); -pa_sink_input* pa_sink_input_ref(pa_sink_input* i); - -/* To be called by the implementing module only */ +void pa_sink_input_put(pa_sink_input *i); void pa_sink_input_disconnect(pa_sink_input* i); -/* External code may request disconnection with this funcion */ +void pa_sink_input_set_name(pa_sink_input *i, const char *name); + +/* Callable by everyone */ + +/* External code may request disconnection with this function */ void pa_sink_input_kill(pa_sink_input*i); pa_usec_t pa_sink_input_get_latency(pa_sink_input *i); -int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume); -void pa_sink_input_drop(pa_sink_input *i, const pa_memchunk *chunk, size_t length); - void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume); -const pa_cvolume * pa_sink_input_get_volume(pa_sink_input *i); +const pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i); +void pa_sink_input_set_mute(pa_sink_input *i, int mute); +int pa_sink_input_get_mute(pa_sink_input *i); void pa_sink_input_cork(pa_sink_input *i, int b); void pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate); -void pa_sink_input_set_name(pa_sink_input *i, const char *name); - pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i); int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately); +#define pa_sink_input_get_state(i) ((pa_sink_input_state_t) pa_atomic_load(&i->state)) + +/* To be used exclusively by the sink driver thread */ + +int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume); +void pa_sink_input_drop(pa_sink_input *i, const pa_memchunk *chunk, size_t length); +int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk); + #endif diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 9588c2c3..36205597 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -41,16 +41,13 @@ #include #include #include +#include #include "sink.h" #define MAX_MIX_CHANNELS 32 -#define CHECK_VALIDITY_RETURN_NULL(condition) \ -do {\ -if (!(condition)) \ - return NULL; \ -} while (0) +static void sink_free(pa_object *s); pa_sink* pa_sink_new( pa_core *core, @@ -66,60 +63,64 @@ pa_sink* pa_sink_new( int r; pa_channel_map tmap; - assert(core); - assert(name); - assert(spec); + pa_assert(core); + pa_assert(name); + pa_assert(spec); - CHECK_VALIDITY_RETURN_NULL(pa_sample_spec_valid(spec)); + pa_return_null_if_fail(pa_sample_spec_valid(spec)); if (!map) map = pa_channel_map_init_auto(&tmap, spec->channels, PA_CHANNEL_MAP_DEFAULT); - CHECK_VALIDITY_RETURN_NULL(map && pa_channel_map_valid(map)); - CHECK_VALIDITY_RETURN_NULL(map->channels == spec->channels); - CHECK_VALIDITY_RETURN_NULL(!driver || pa_utf8_valid(driver)); - CHECK_VALIDITY_RETURN_NULL(pa_utf8_valid(name) && *name); + pa_return_null_if_fail(map && pa_channel_map_valid(map)); + pa_return_null_if_fail(map->channels == spec->channels); + pa_return_null_if_fail(!driver || pa_utf8_valid(driver)); + pa_return_null_if_fail(name && pa_utf8_valid(name) && *name); - s = pa_xnew(pa_sink, 1); + s = pa_msgobject_new(pa_sink); if (!(name = pa_namereg_register(core, name, PA_NAMEREG_SINK, s, fail))) { pa_xfree(s); return NULL; } - s->ref = 1; + s->parent.parent.free = sink_free; + s->parent.process_msg = pa_sink_process_msg; + s->core = core; - s->state = PA_SINK_RUNNING; + pa_atomic_store(&s->state, PA_SINK_IDLE); s->name = pa_xstrdup(name); s->description = NULL; s->driver = pa_xstrdup(driver); - s->owner = NULL; + s->module = NULL; s->sample_spec = *spec; s->channel_map = *map; s->inputs = pa_idxset_new(NULL, NULL); - pa_cvolume_reset(&s->sw_volume, spec->channels); - pa_cvolume_reset(&s->hw_volume, spec->channels); - s->sw_muted = 0; - s->hw_muted = 0; + pa_cvolume_reset(&s->volume, spec->channels); + s->muted = 0; + s->refresh_volume = s->refresh_mute = 0; s->is_hardware = 0; s->get_latency = NULL; - s->notify = NULL; - s->set_hw_volume = NULL; - s->get_hw_volume = NULL; - s->set_hw_mute = NULL; - s->get_hw_mute = NULL; + s->set_volume = NULL; + s->get_volume = NULL; + s->set_mute = NULL; + s->get_mute = NULL; + s->start = NULL; + s->stop = NULL; s->userdata = NULL; + pa_assert_se(s->asyncmsgq = pa_asyncmsgq_new(0)); + r = pa_idxset_put(core->sinks, s, &s->index); - assert(s->index != PA_IDXSET_INVALID && r >= 0); + pa_assert(s->index != PA_IDXSET_INVALID && r >= 0); pa_sample_spec_snprint(st, sizeof(st), spec); - pa_log_info("created %u \"%s\" with sample spec \"%s\"", s->index, s->name, st); + pa_log_info("Created sink %u \"%s\" with sample spec \"%s\"", s->index, s->name, st); n = pa_sprintf_malloc("%s.monitor", name); @@ -135,24 +136,64 @@ pa_sink* pa_sink_new( pa_xfree(n); + s->thread_info.inputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + s->thread_info.soft_volume = s->volume; + s->thread_info.soft_muted = s->muted; + pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index); return s; } +static void sink_start(pa_sink *s) { + pa_sink_state_t state; + pa_assert(s); + + state = pa_sink_get_state(s); + pa_return_if_fail(state == PA_SINK_IDLE || state == PA_SINK_SUSPENDED); + + pa_atomic_store(&s->state, PA_SINK_RUNNING); + + if (s->start) + s->start(s); + else + pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_START, NULL, NULL, NULL); +} + +static void sink_stop(pa_sink *s) { + pa_sink_state_t state; + int stop; + + pa_assert(s); + state = pa_sink_get_state(s); + pa_return_if_fail(state == PA_SINK_RUNNING || state == PA_SINK_SUSPENDED); + + stop = state == PA_SINK_RUNNING; + pa_atomic_store(&s->state, PA_SINK_IDLE); + + if (stop) { + if (s->stop) + s->stop(s); + else + pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_STOP, NULL, NULL, NULL); + } +} + void pa_sink_disconnect(pa_sink* s) { pa_sink_input *i, *j = NULL; - assert(s); - assert(s->state == PA_SINK_RUNNING); + pa_assert(s); + pa_return_if_fail(pa_sink_get_state(s) != PA_SINK_DISCONNECTED); - s->state = PA_SINK_DISCONNECTED; + sink_stop(s); + + pa_atomic_store(&s->state, PA_SINK_DISCONNECTED); pa_namereg_unregister(s->core, s->name); pa_hook_fire(&s->core->hook_sink_disconnect, s); while ((i = pa_idxset_first(s->inputs, NULL))) { - assert(i != j); + pa_assert(i != j); pa_sink_input_kill(i); j = i; } @@ -163,23 +204,25 @@ void pa_sink_disconnect(pa_sink* s) { pa_idxset_remove_by_data(s->core->sinks, s, NULL); s->get_latency = NULL; - s->notify = NULL; - s->get_hw_volume = NULL; - s->set_hw_volume = NULL; - s->set_hw_mute = NULL; - s->get_hw_mute = NULL; + s->get_volume = NULL; + s->set_volume = NULL; + s->set_mute = NULL; + s->get_mute = NULL; + s->start = NULL; + s->stop = NULL; pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_REMOVE, s->index); } -static void sink_free(pa_sink *s) { - assert(s); - assert(!s->ref); +static void sink_free(pa_object *o) { + pa_sink *s = PA_SINK(o); + + pa_assert(s); + pa_assert(pa_sink_refcnt(s) == 0); - if (s->state != PA_SINK_DISCONNECTED) - pa_sink_disconnect(s); + pa_sink_disconnect(s); - pa_log_info("freed %u \"%s\"", s->index, s->name); + pa_log_info("Freeing sink %u \"%s\"", s->index, s->name); if (s->monitor_source) { pa_source_unref(s->monitor_source); @@ -187,47 +230,66 @@ static void sink_free(pa_sink *s) { } pa_idxset_free(s->inputs, NULL, NULL); + + pa_hashmap_free(s->thread_info.inputs, (pa_free2_cb_t) pa_sink_input_unref, NULL); + pa_asyncmsgq_free(s->asyncmsgq); + pa_xfree(s->name); pa_xfree(s->description); pa_xfree(s->driver); pa_xfree(s); } -void pa_sink_unref(pa_sink*s) { - assert(s); - assert(s->ref >= 1); +void pa_sink_update_status(pa_sink*s) { + pa_sink_assert_ref(s); - if (!(--s->ref)) - sink_free(s); + if (pa_sink_get_state(s) == PA_SINK_SUSPENDED) + return; + + if (pa_sink_used_by(s) > 0) + sink_start(s); + else + sink_stop(s); } -pa_sink* pa_sink_ref(pa_sink *s) { - assert(s); - assert(s->ref >= 1); +void pa_sink_suspend(pa_sink *s, int suspend) { + pa_sink_state_t state; - s->ref++; - return s; -} + pa_sink_assert_ref(s); -void pa_sink_notify(pa_sink*s) { - assert(s); - assert(s->ref >= 1); + state = pa_sink_get_state(s); + pa_return_if_fail(suspend && (state == PA_SINK_RUNNING || state == PA_SINK_IDLE)); + pa_return_if_fail(!suspend && (state == PA_SINK_SUSPENDED)); - if (s->notify) - s->notify(s); + + if (suspend) { + pa_atomic_store(&s->state, PA_SINK_SUSPENDED); + + if (s->stop) + s->stop(s); + else + pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_STOP, NULL, NULL, NULL); + + } else { + pa_atomic_store(&s->state, PA_SINK_RUNNING); + + if (s->start) + s->start(s); + else + pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_START, NULL, NULL, NULL); + } } static unsigned fill_mix_info(pa_sink *s, pa_mix_info *info, unsigned maxinfo) { - uint32_t idx = PA_IDXSET_INVALID; pa_sink_input *i; unsigned n = 0; + void *state = NULL; - assert(s); - assert(s->ref >= 1); - assert(info); + pa_sink_assert_ref(s); + pa_assert(info); - for (i = pa_idxset_first(s->inputs, &idx); maxinfo > 0 && i; i = pa_idxset_next(s->inputs, &idx)) { + while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL))) { /* Increase ref counter, to make sure that this input doesn't * vanish while we still need it */ pa_sink_input_ref(i); @@ -239,9 +301,8 @@ static unsigned fill_mix_info(pa_sink *s, pa_mix_info *info, unsigned maxinfo) { info->userdata = i; - assert(info->chunk.memblock); - assert(info->chunk.memblock->data); - assert(info->chunk.length); + pa_assert(info->chunk.memblock); + pa_assert(info->chunk.length); info++; maxinfo--; @@ -252,15 +313,14 @@ static unsigned fill_mix_info(pa_sink *s, pa_mix_info *info, unsigned maxinfo) { } static void inputs_drop(pa_sink *s, pa_mix_info *info, unsigned maxinfo, size_t length) { - assert(s); - assert(s->ref >= 1); - assert(info); + pa_sink_assert_ref(s); + pa_assert(info); for (; maxinfo > 0; maxinfo--, info++) { pa_sink_input *i = info->userdata; - assert(i); - assert(info->chunk.memblock); + pa_assert(i); + pa_assert(info->chunk.memblock); /* Drop read data */ pa_sink_input_drop(i, &info->chunk, length); @@ -277,10 +337,9 @@ int pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) { unsigned n; int r = -1; - assert(s); - assert(s->ref >= 1); - assert(length); - assert(result); + pa_sink_assert_ref(s); + pa_assert(length); + pa_assert(result); pa_sink_ref(s); @@ -298,23 +357,23 @@ int pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) { if (result->length > length) result->length = length; - pa_sw_cvolume_multiply(&volume, &s->sw_volume, &info[0].volume); + pa_sw_cvolume_multiply(&volume, &s->thread_info.soft_volume, &info[0].volume); - if (s->sw_muted || !pa_cvolume_is_norm(&volume)) { + if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&volume)) { pa_memchunk_make_writable(result, 0); - if (s->sw_muted) + if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume)) pa_silence_memchunk(result, &s->sample_spec); else pa_volume_memchunk(result, &s->sample_spec, &volume); } } else { + void *ptr; result->memblock = pa_memblock_new(s->core->mempool, length); - assert(result->memblock); -/* pa_log("mixing %i", n); */ + ptr = pa_memblock_acquire(result->memblock); + result->length = pa_mix(info, n, ptr, length, &s->sample_spec, &s->thread_info.soft_volume, s->thread_info.soft_muted); + pa_memblock_release(result->memblock); - result->length = pa_mix(info, n, result->memblock->data, length, - &s->sample_spec, &s->sw_volume, s->sw_muted); result->index = 0; } @@ -336,12 +395,10 @@ int pa_sink_render_into(pa_sink*s, pa_memchunk *target) { unsigned n; int r = -1; - assert(s); - assert(s->ref >= 1); - assert(target); - assert(target->memblock); - assert(target->length); - assert(target->memblock->data); + pa_sink_assert_ref(s); + pa_assert(target); + pa_assert(target->memblock); + pa_assert(target->length); pa_sink_ref(s); @@ -350,30 +407,48 @@ int pa_sink_render_into(pa_sink*s, pa_memchunk *target) { if (n <= 0) goto finish; - if (n == 1) { - pa_cvolume volume; + if (n == 1) { if (target->length > info[0].chunk.length) target->length = info[0].chunk.length; - memcpy((uint8_t*) target->memblock->data + target->index, - (uint8_t*) info[0].chunk.memblock->data + info[0].chunk.index, - target->length); - - pa_sw_cvolume_multiply(&volume, &s->sw_volume, &info[0].volume); - - if (s->sw_muted) + if (s->thread_info.soft_muted) pa_silence_memchunk(target, &s->sample_spec); - else if (!pa_cvolume_is_norm(&volume)) - pa_volume_memchunk(target, &s->sample_spec, &volume); - } else + else { + void *src, *ptr; + pa_cvolume volume; + + ptr = pa_memblock_acquire(target->memblock); + src = pa_memblock_acquire(info[0].chunk.memblock); + + memcpy((uint8_t*) ptr + target->index, + (uint8_t*) src + info[0].chunk.index, + target->length); + + pa_memblock_release(target->memblock); + pa_memblock_release(info[0].chunk.memblock); + + pa_sw_cvolume_multiply(&volume, &s->thread_info.soft_volume, &info[0].volume); + + if (!pa_cvolume_is_norm(&volume)) + pa_volume_memchunk(target, &s->sample_spec, &volume); + } + + } else { + void *ptr; + + ptr = pa_memblock_acquire(target->memblock); + target->length = pa_mix(info, n, - (uint8_t*) target->memblock->data + target->index, + (uint8_t*) ptr + target->index, target->length, &s->sample_spec, - &s->sw_volume, - s->sw_muted); - + &s->thread_info.soft_volume, + s->thread_info.soft_muted); + + pa_memblock_release(target->memblock); + } + inputs_drop(s, info, n, target->length); if (s->monitor_source) @@ -391,12 +466,10 @@ void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) { pa_memchunk chunk; size_t l, d; - assert(s); - assert(s->ref >= 1); - assert(target); - assert(target->memblock); - assert(target->length); - assert(target->memblock->data); + pa_sink_assert_ref(s); + pa_assert(target); + pa_assert(target->memblock); + pa_assert(target->length); pa_sink_ref(s); @@ -425,10 +498,9 @@ void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) { } void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) { - assert(s); - assert(s->ref >= 1); - assert(length); - assert(result); + pa_sink_assert_ref(s); + pa_assert(length); + pa_assert(result); /*** This needs optimization ***/ @@ -439,108 +511,109 @@ void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) { } pa_usec_t pa_sink_get_latency(pa_sink *s) { - assert(s); - assert(s->ref >= 1); - - if (!s->get_latency) + pa_usec_t usec = 0; + + pa_sink_assert_ref(s); + + if (s->get_latency) + return s->get_latency(s); + + if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY, &usec, NULL) < 0) return 0; - return s->get_latency(s); + return usec; } -void pa_sink_set_owner(pa_sink *s, pa_module *m) { - assert(s); - assert(s->ref >= 1); +void pa_sink_set_volume(pa_sink *s, const pa_cvolume *volume) { + int changed; - if (s->owner == m) - return; + pa_sink_assert_ref(s); + pa_assert(volume); - s->owner = m; + changed = !pa_cvolume_equal(volume, &s->volume); + s->volume = *volume; + + if (s->set_volume && s->set_volume(s) < 0) + s->set_volume = NULL; - if (s->monitor_source) - pa_source_set_owner(s->monitor_source, m); + if (!s->set_volume) + pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, pa_xnewdup(struct pa_cvolume, volume, 1), NULL, pa_xfree); - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + if (changed) + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); } -void pa_sink_set_volume(pa_sink *s, pa_mixer_t m, const pa_cvolume *volume) { - pa_cvolume *v; - - assert(s); - assert(s->ref >= 1); - assert(volume); - - if (m == PA_MIXER_HARDWARE && s->set_hw_volume) - v = &s->hw_volume; - else - v = &s->sw_volume; +const pa_cvolume *pa_sink_get_volume(pa_sink *s) { + struct pa_cvolume old_volume; - if (pa_cvolume_equal(v, volume)) - return; + pa_sink_assert_ref(s); - *v = *volume; + old_volume = s->volume; + + if (s->get_volume && s->get_volume(s) < 0) + s->get_volume = NULL; - if (v == &s->hw_volume) - if (s->set_hw_volume(s) < 0) - s->sw_volume = *volume; + if (!s->get_volume && s->refresh_volume) + pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_VOLUME, &s->volume, NULL); - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + if (!pa_cvolume_equal(&old_volume, &s->volume)) + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + + return &s->volume; } -const pa_cvolume *pa_sink_get_volume(pa_sink *s, pa_mixer_t m) { - assert(s); - assert(s->ref >= 1); +void pa_sink_set_mute(pa_sink *s, int mute) { + int changed; + + pa_sink_assert_ref(s); - if (m == PA_MIXER_HARDWARE && s->set_hw_volume) { + changed = s->muted != mute; - if (s->get_hw_volume) - s->get_hw_volume(s); + if (s->set_mute && s->set_mute(s) < 0) + s->set_mute = NULL; - return &s->hw_volume; - } else - return &s->sw_volume; -} + if (!s->set_mute) + pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MUTE, PA_UINT_TO_PTR(mute), NULL, NULL); -void pa_sink_set_mute(pa_sink *s, pa_mixer_t m, int mute) { - int *t; - - assert(s); - assert(s->ref >= 1); - - if (m == PA_MIXER_HARDWARE && s->set_hw_mute) - t = &s->hw_muted; - else - t = &s->sw_muted; + if (changed) + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); +} - if (!!*t == !!mute) - return; +int pa_sink_get_mute(pa_sink *s) { + int old_muted; + + pa_sink_assert_ref(s); - *t = !!mute; + old_muted = s->muted; + + if (s->get_mute && s->get_mute(s) < 0) + s->get_mute = NULL; - if (t == &s->hw_muted) - if (s->set_hw_mute(s) < 0) - s->sw_muted = !!mute; + if (!s->get_mute && s->refresh_mute) + pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MUTE, &s->muted, NULL); - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + if (old_muted != s->muted) + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + + return s->muted; } -int pa_sink_get_mute(pa_sink *s, pa_mixer_t m) { - assert(s); - assert(s->ref >= 1); +void pa_sink_set_module(pa_sink *s, pa_module *m) { + pa_sink_assert_ref(s); - if (m == PA_MIXER_HARDWARE && s->set_hw_mute) { + if (s->module == m) + return; - if (s->get_hw_mute) - s->get_hw_mute(s); + s->module = m; - return s->hw_muted; - } else - return s->sw_muted; + if (s->monitor_source) + pa_source_set_module(s->monitor_source, m); + + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); } void pa_sink_set_description(pa_sink *s, const char *description) { - assert(s); - assert(s->ref >= 1); + pa_sink_assert_ref(s); if (!description && !s->description) return; @@ -565,8 +638,7 @@ void pa_sink_set_description(pa_sink *s, const char *description) { unsigned pa_sink_used_by(pa_sink *s) { unsigned ret; - assert(s); - assert(s->ref >= 1); + pa_sink_assert_ref(s); ret = pa_idxset_size(s->inputs); @@ -575,3 +647,41 @@ unsigned pa_sink_used_by(pa_sink *s) { return ret; } + +int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk) { + pa_sink *s = PA_SINK(o); + pa_sink_assert_ref(s); + + switch (code) { + case PA_SINK_MESSAGE_ADD_INPUT: { + pa_sink_input *i = userdata; + pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), pa_sink_input_ref(i)); + return 0; + } + + case PA_SINK_MESSAGE_REMOVE_INPUT: { + pa_sink_input *i = userdata; + pa_hashmap_remove(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index)); + return 0; + } + + case PA_SINK_MESSAGE_SET_VOLUME: + s->thread_info.soft_volume = *((pa_cvolume*) userdata); + return 0; + + case PA_SINK_MESSAGE_SET_MUTE: + s->thread_info.soft_muted = PA_PTR_TO_UINT(userdata); + return 0; + + case PA_SINK_MESSAGE_GET_VOLUME: + *((pa_cvolume*) userdata) = s->thread_info.soft_volume; + return 0; + + case PA_SINK_MESSAGE_GET_MUTE: + *((int*) userdata) = s->thread_info.soft_muted; + return 0; + + default: + return -1; + } +} diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index ef73f67d..2939cc47 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -1,5 +1,5 @@ -#ifndef foosinkhfoo -#define foosinkhfoo +#ifndef foopulsesinkhfoo +#define foopulsesinkhfoo /* $Id$ */ @@ -25,37 +25,43 @@ USA. ***/ -#include - typedef struct pa_sink pa_sink; +#include + #include #include #include + #include #include #include #include #include +#include +#include #define PA_MAX_INPUTS_PER_SINK 32 typedef enum pa_sink_state { PA_SINK_RUNNING, + PA_SINK_SUSPENDED, + PA_SINK_IDLE, PA_SINK_DISCONNECTED } pa_sink_state_t; struct pa_sink { - int ref; + pa_msgobject parent; + uint32_t index; pa_core *core; - pa_sink_state_t state; + pa_atomic_t state; char *name; char *description, *driver; /* may be NULL */ int is_hardware; - pa_module *owner; /* may be NULL */ + pa_module *module; /* may be NULL */ pa_sample_spec sample_spec; pa_channel_map channel_map; @@ -63,49 +69,85 @@ struct pa_sink { pa_idxset *inputs; pa_source *monitor_source; /* may be NULL */ - pa_cvolume hw_volume, sw_volume; - int hw_muted, sw_muted; - - void (*notify)(pa_sink*sink); /* may be NULL */ - pa_usec_t (*get_latency)(pa_sink *s); /* dito */ - int (*set_hw_volume)(pa_sink *s); /* dito */ - int (*get_hw_volume)(pa_sink *s); /* dito */ - int (*set_hw_mute)(pa_sink *s); /* dito */ - int (*get_hw_mute)(pa_sink *s); /* dito */ + pa_cvolume volume; + int muted; + int refresh_volume; + int refresh_mute; + + int (*start)(pa_sink *s); + int (*stop)(pa_sink *s); + int (*set_volume)(pa_sink *s); /* dito */ + int (*get_volume)(pa_sink *s); /* dito */ + int (*get_mute)(pa_sink *s); /* dito */ + int (*set_mute)(pa_sink *s); /* dito */ + pa_usec_t (*get_latency)(pa_sink *s); /* dito */ + + pa_asyncmsgq *asyncmsgq; + + /* Contains copies of the above data so that the real-time worker + * thread can work without access locking */ + struct { + pa_hashmap *inputs; + pa_cvolume soft_volume; + int soft_muted; + } thread_info; void *userdata; }; +PA_DECLARE_CLASS(pa_sink); +#define PA_SINK(s) ((pa_sink*) (s)) + +typedef enum pa_sink_message { + PA_SINK_MESSAGE_ADD_INPUT, + PA_SINK_MESSAGE_REMOVE_INPUT, + PA_SINK_MESSAGE_GET_VOLUME, + PA_SINK_MESSAGE_SET_VOLUME, + PA_SINK_MESSAGE_GET_MUTE, + PA_SINK_MESSAGE_SET_MUTE, + PA_SINK_MESSAGE_GET_LATENCY, + PA_SINK_MESSAGE_START, + PA_SINK_MESSAGE_STOP, + PA_SINK_MESSAGE_MAX +} pa_sink_message_t; + +/* To be used exclusively by the sink driver */ + pa_sink* pa_sink_new( - pa_core *core, - const char *driver, - const char *name, - int namereg_fail, - const pa_sample_spec *spec, - const pa_channel_map *map); + pa_core *core, + const char *driver, + const char *name, + int namereg_fail, + const pa_sample_spec *spec, + const pa_channel_map *map); void pa_sink_disconnect(pa_sink* s); -void pa_sink_unref(pa_sink*s); -pa_sink* pa_sink_ref(pa_sink *s); -int pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result); -void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result); -int pa_sink_render_into(pa_sink*s, pa_memchunk *target); -void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target); +void pa_sink_set_module(pa_sink *sink, pa_module *m); +void pa_sink_set_description(pa_sink *s, const char *description); + +/* Usable by everyone */ pa_usec_t pa_sink_get_latency(pa_sink *s); -void pa_sink_notify(pa_sink*s); +void pa_sink_update_status(pa_sink*s); +void pa_sink_suspend(pa_sink *s, int suspend); -void pa_sink_set_owner(pa_sink *sink, pa_module *m); +void pa_sink_set_volume(pa_sink *sink, const pa_cvolume *volume); +const pa_cvolume *pa_sink_get_volume(pa_sink *sink); +void pa_sink_set_mute(pa_sink *sink, int mute); +int pa_sink_get_mute(pa_sink *sink); -void pa_sink_set_volume(pa_sink *sink, pa_mixer_t m, const pa_cvolume *volume); -const pa_cvolume *pa_sink_get_volume(pa_sink *sink, pa_mixer_t m); -void pa_sink_set_mute(pa_sink *sink, pa_mixer_t m, int mute); -int pa_sink_get_mute(pa_sink *sink, pa_mixer_t m); +unsigned pa_sink_used_by(pa_sink *s); +#define pa_sink_get_state(s) ((pa_sink_state_t) pa_atomic_load(&(s)->state)) -void pa_sink_set_description(pa_sink *s, const char *description); +/* To be used exclusively by the sink driver thread */ -unsigned pa_sink_used_by(pa_sink *s); +int pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result); +void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result); +int pa_sink_render_into(pa_sink*s, pa_memchunk *target); +void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target); + +int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk); #endif diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index 7a43c743..a682ee6c 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -76,21 +76,25 @@ static int sink_input_peek(pa_sink_input *i, pa_memchunk *chunk) { if (!u->memchunk.memblock) { uint32_t fs = pa_frame_size(&i->sample_spec); sf_count_t n; + void *p; u->memchunk.memblock = pa_memblock_new(i->sink->core->mempool, BUF_SIZE); u->memchunk.index = 0; + p = pa_memblock_acquire(u->memchunk.memblock); + if (u->readf_function) { - if ((n = u->readf_function(u->sndfile, u->memchunk.memblock->data, BUF_SIZE/fs)) <= 0) + if ((n = u->readf_function(u->sndfile, p, BUF_SIZE/fs)) <= 0) n = 0; u->memchunk.length = n * fs; } else { - if ((n = sf_read_raw(u->sndfile, u->memchunk.memblock->data, BUF_SIZE)) <= 0) + if ((n = sf_read_raw(u->sndfile, p, BUF_SIZE)) <= 0) n = 0; u->memchunk.length = n; } + pa_memblock_release(u->memchunk.memblock); if (!u->memchunk.length) { free_userdata(u); diff --git a/src/pulsecore/sound-file.c b/src/pulsecore/sound-file.c index 69b543ab..6e93f8aa 100644 --- a/src/pulsecore/sound-file.c +++ b/src/pulsecore/sound-file.c @@ -42,7 +42,11 @@ int pa_sound_file_load(pa_mempool *pool, const char *fname, pa_sample_spec *ss, int ret = -1; size_t l; sf_count_t (*readf_function)(SNDFILE *sndfile, void *ptr, sf_count_t frames) = NULL; - assert(fname && ss && chunk); + void *ptr = NULL; + + assert(fname); + assert(ss); + assert(chunk); chunk->memblock = NULL; chunk->index = chunk->length = 0; @@ -99,8 +103,10 @@ int pa_sound_file_load(pa_mempool *pool, const char *fname, pa_sample_spec *ss, chunk->index = 0; chunk->length = l; - if ((readf_function && readf_function(sf, chunk->memblock->data, sfinfo.frames) != sfinfo.frames) || - (!readf_function && sf_read_raw(sf, chunk->memblock->data, l) != l)) { + ptr = pa_memblock_acquire(chunk->memblock); + + if ((readf_function && readf_function(sf, ptr, sfinfo.frames) != sfinfo.frames) || + (!readf_function && sf_read_raw(sf, ptr, l) != l)) { pa_log("Premature file end"); goto finish; } @@ -112,6 +118,9 @@ finish: if (sf) sf_close(sf); + if (ptr) + pa_memblock_release(chunk->memblock); + if (ret != 0 && chunk->memblock) pa_memblock_unref(chunk->memblock); diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index c7a9858c..c1aa3393 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -26,7 +26,6 @@ #endif #include -#include #include #include @@ -39,14 +38,8 @@ #include "source-output.h" -#define CHECK_VALIDITY_RETURN_NULL(condition) \ -do {\ -if (!(condition)) \ - return NULL; \ -} while (0) - pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data) { - assert(data); + pa_assert(data); memset(data, 0, sizeof(*data)); data->resample_method = PA_RESAMPLER_INVALID; @@ -54,14 +47,14 @@ pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_d } void pa_source_output_new_data_set_channel_map(pa_source_output_new_data *data, const pa_channel_map *map) { - assert(data); + pa_assert(data); if ((data->channel_map_is_set = !!map)) data->channel_map = *map; } void pa_source_output_new_data_set_sample_spec(pa_source_output_new_data *data, const pa_sample_spec *spec) { - assert(data); + pa_assert(data); if ((data->sample_spec_is_set = !!spec)) data->sample_spec = *spec; @@ -74,48 +67,53 @@ pa_source_output* pa_source_output_new( pa_source_output *o; pa_resampler *resampler = NULL; - int r; char st[PA_SAMPLE_SPEC_SNPRINT_MAX]; - assert(core); - assert(data); + pa_assert(core); + pa_assert(data); if (!(flags & PA_SOURCE_OUTPUT_NO_HOOKS)) if (pa_hook_fire(&core->hook_source_output_new, data) < 0) return NULL; - CHECK_VALIDITY_RETURN_NULL(!data->driver || pa_utf8_valid(data->driver)); - CHECK_VALIDITY_RETURN_NULL(!data->name || pa_utf8_valid(data->name)); + pa_return_null_if_fail(!data->driver || pa_utf8_valid(data->driver)); + pa_return_null_if_fail(!data->name || pa_utf8_valid(data->name)); if (!data->source) data->source = pa_namereg_get(core, NULL, PA_NAMEREG_SOURCE, 1); - CHECK_VALIDITY_RETURN_NULL(data->source); - CHECK_VALIDITY_RETURN_NULL(data->source->state == PA_SOURCE_RUNNING); + pa_return_null_if_fail(data->source); + pa_return_null_if_fail(pa_source_get_state(data->source) != PA_SOURCE_DISCONNECTED); if (!data->sample_spec_is_set) data->sample_spec = data->source->sample_spec; - CHECK_VALIDITY_RETURN_NULL(pa_sample_spec_valid(&data->sample_spec)); + pa_return_null_if_fail(pa_sample_spec_valid(&data->sample_spec)); - if (!data->channel_map_is_set) - pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT); + if (!data->channel_map_is_set) { + if (data->source->channel_map.channels == data->sample_spec.channels) + data->channel_map = data->source->channel_map; + else + pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT); + } - CHECK_VALIDITY_RETURN_NULL(pa_channel_map_valid(&data->channel_map)); - CHECK_VALIDITY_RETURN_NULL(data->channel_map.channels == data->sample_spec.channels); + pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map)); + pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels); if (data->resample_method == PA_RESAMPLER_INVALID) data->resample_method = core->resample_method; - CHECK_VALIDITY_RETURN_NULL(data->resample_method < PA_RESAMPLER_MAX); + pa_return_null_if_fail(data->resample_method < PA_RESAMPLER_MAX); if (pa_idxset_size(data->source->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) { pa_log("Failed to create source output: too many outputs per source."); return NULL; } - if (!pa_sample_spec_equal(&data->sample_spec, &data->source->sample_spec) || - !pa_channel_map_equal(&data->channel_map, &data->source->channel_map)) + if ((flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) || + !pa_sample_spec_equal(&data->sample_spec, &data->source->sample_spec) || + !pa_channel_map_equal(&data->channel_map, &data->source->channel_map)) { + if (!(resampler = pa_resampler_new( core->mempool, &data->source->sample_spec, &data->source->channel_map, @@ -125,115 +123,133 @@ pa_source_output* pa_source_output_new( return NULL; } - o = pa_xnew(pa_source_output, 1); - o->ref = 1; - o->state = PA_SOURCE_OUTPUT_RUNNING; + data->resample_method = pa_resampler_get_method(resampler); + } + + o = pa_source_output_new(pa_source_output); + + o->parent.parent.free = source_output_free; + o->parent.process_msg = pa_source_output_process_msg; + + o->core = core; + pa_atomic_load(&o->state, PA_SOURCE_OUTPUT_RUNNING); + o->flags = flags; o->name = pa_xstrdup(data->name); o->driver = pa_xstrdup(data->driver); o->module = data->module; o->source = data->source; o->client = data->client; + o->resample_method = data->resample_method; o->sample_spec = data->sample_spec; o->channel_map = data->channel_map; + o->process_msg = NULL; o->push = NULL; o->kill = NULL; o->get_latency = NULL; o->userdata = NULL; - o->resampler = resampler; - o->resample_method = data->resample_method; + o->thread_info.resampler = resampler; - r = pa_idxset_put(core->source_outputs, o, &o->index); - assert(r == 0); - r = pa_idxset_put(o->source->outputs, o, NULL); - assert(r == 0); + pa_assert_se(pa_idxset_put(core->source_outputs, o, &o->index) == 0); + pa_assert_se( pa_idxset_put(o->source->outputs, o, NULL) == 0); - pa_log_info("created %u \"%s\" on %s with sample spec %s", + pa_log_info("Created output %u \"%s\" on %s with sample spec %s", o->index, o->name, o->source->name, pa_sample_spec_snprint(st, sizeof(st), &o->sample_spec)); - pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW, o->index); - - /* We do not call pa_source_notify() here, because the virtual - * functions have not yet been initialized */ + /* Don't forget to call pa_source_output_put! */ return o; } void pa_source_output_disconnect(pa_source_output*o) { - assert(o); - assert(o->state != PA_SOURCE_OUTPUT_DISCONNECTED); - assert(o->source); - assert(o->source->core); + pa_assert(o); + pa_return_if_fail(pa_source_output_get_state(i) != PA_SOURCE_OUTPUT_DISCONNECTED); + pa_assert(o->source); + pa_assert(o->source->core); + pa_asyncmsgq_send(i->sink->asyncmsgq, i->sink, PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, NULL); + pa_idxset_remove_by_data(o->source->core->source_outputs, o, NULL); pa_idxset_remove_by_data(o->source->outputs, o, NULL); pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_REMOVE, o->index); o->source = NULL; + o->process_msg = NULL; o->push = NULL; o->kill = NULL; o->get_latency = NULL; - o->state = PA_SOURCE_OUTPUT_DISCONNECTED; + pa_atomic_load(&i->state, PA_SOURCE_OUTPUT_DISCONNECTED); } -static void source_output_free(pa_source_output* o) { - assert(o); +static void source_output_free(pa_msgobject* mo) { + pa_source_output *o = PA_SOURCE_OUTPUT(mo); + + pa_assert(pa_source_output_refcnt(o) == 0); - if (o->state != PA_SOURCE_OUTPUT_DISCONNECTED) - pa_source_output_disconnect(o); + pa_source_output_disconnect(o); - pa_log_info("freed %u \"%s\"", o->index, o->name); + pa_log_info("Freeing output %u \"%s\"", o->index, o->name); - if (o->resampler) - pa_resampler_free(o->resampler); + if (o->thread_info.resampler) + pa_resampler_free(o->thread_info.resampler); pa_xfree(o->name); pa_xfree(o->driver); pa_xfree(o); } -void pa_source_output_unref(pa_source_output* o) { - assert(o); - assert(o->ref >= 1); +void pa_source_output_put(pa_source_output *o) { + pa_source_output_assert_ref(o); + + pa_asyncmsgq_post(o->source->asyncmsgq, o->source, PA_SOURCE_MESSAGE_ADD_OUTPUT, o, NULL, pa_source_unref, pa_source_output_unref); + pa_source_update_status(o->source); - if (!(--o->ref)) - source_output_free(o); -} - -pa_source_output* pa_source_output_ref(pa_source_output *o) { - assert(o); - assert(o->ref >= 1); - - o->ref++; - return o; + pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW, o->index); } void pa_source_output_kill(pa_source_output*o) { - assert(o); - assert(o->ref >= 1); + pa_source_output_assert_ref(o); if (o->kill) o->kill(o); } +pa_usec_t pa_source_output_get_latency(pa_source_output *o) { + pa_usec_t r = 0; + + pa_source_output_assert_ref(o); + + if (pa_asyncmsgq_send(o->source->asyncmsgq, i->source, PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY, &r, NULL) < 0) + r = 0; + + if (o->get_latency) + r += o->get_latency(o); + + return r; +} + void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) { pa_memchunk rchunk; + pa_source_output_state_t state; - assert(o); - assert(chunk); - assert(chunk->length); - assert(o->push); + pa_source_output_assert_ref(o); + pa_assert(chunk); + pa_assert(chunk->length); - if (o->state == PA_SOURCE_OUTPUT_CORKED) + state = pa_source_output_get_state(o); + + if (!o->push || state == PA_SOURCE_OUTPUT_DISCONNECTED || state == PA_SOURCE_OUTPUT_CORKED) return; + pa_assert(state = PA_SOURCE_OUTPUT_RUNNING); + if (!o->resampler) { o->push(o, chunk); return; @@ -243,119 +259,137 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) { if (!rchunk.length) return; - assert(rchunk.memblock); + pa_assert(rchunk.memblock); o->push(o, &rchunk); pa_memblock_unref(rchunk.memblock); } -void pa_source_output_set_name(pa_source_output *o, const char *name) { - assert(o); - assert(o->ref >= 1); - - if (!o->name && !name) - return; +void pa_source_output_cork(pa_source_output *o, int b) { + int n; + pa_source_output_state_t state; - if (o->name && name && !strcmp(o->name, name)) - return; + pa_source_output_assert_ref(o); - pa_xfree(o->name); - o->name = pa_xstrdup(name); + state = pa_source_output_get_state(o); + pa_assert(state != PA_SOURCE_OUTPUT_DISCONNECTED); - pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); + if (b && state != PA_SOURCE_OUTPUT_CORKED) + pa_atomic_store(o->state, PA_SOURCE_OUTPUT_CORKED); + else if (!b && state == PA_SOURCE_OUTPUT_CORKED) + pa_atomic_cmpxchg(o->state, state, PA_SOURCE_OUTPUT_RUNNING); } -pa_usec_t pa_source_output_get_latency(pa_source_output *o) { - assert(o); - assert(o->ref >= 1); +int pa_source_output_set_rate(pa_source_output *o, uint32_t rate) { + pa_source_output_assert_ref(o); + pa_return_val_if_fail(o->thread_info.resampler, -1); - if (o->get_latency) - return o->get_latency(o); + if (i->sample_spec.rate == rate) + return 0; + + i->sample_spec.rate = rate; + pa_asyncmsgq_post(s->asyncmsgq, pa_source_output_ref(i), PA_SOURCE_OUTPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), NULL, pa_source_output_unref, NULL); + + pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT!|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); return 0; } -void pa_source_output_cork(pa_source_output *o, int b) { - int n; - - assert(o); - assert(o->ref >= 1); +void pa_source_output_set_name(pa_source_output *o, const char *name) { + pa_source_output_assert_ref(o); - if (o->state == PA_SOURCE_OUTPUT_DISCONNECTED) + if (!o->name && !name) return; - n = o->state == PA_SOURCE_OUTPUT_CORKED && !b; + if (o->name && name && !strcmp(o->name, name)) + return; - o->state = b ? PA_SOURCE_OUTPUT_CORKED : PA_SOURCE_OUTPUT_RUNNING; + pa_xfree(o->name); + o->name = pa_xstrdup(name); - if (n) - pa_source_notify(o->source); + pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); } pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o) { - assert(o); - assert(o->ref >= 1); + pa_source_output_assert_ref(o); - if (!o->resampler) - return o->resample_method; - - return pa_resampler_get_method(o->resampler); + return o->resample_method; } int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { pa_source *origin; pa_resampler *new_resampler = NULL; - assert(o); - assert(o->ref >= 1); - assert(dest); + pa_source_output_assert_ref(o); + pa_source_assert_ref(dest); - origin = o->source; + return -1; + +/* origin = o->source; */ - if (dest == origin) - return 0; +/* if (dest == origin) */ +/* return 0; */ - if (pa_idxset_size(dest->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) { - pa_log_warn("Failed to move source output: too many outputs per source."); - return -1; - } +/* if (pa_idxset_size(dest->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) { */ +/* pa_log_warn("Failed to move source output: too many outputs per source."); */ +/* return -1; */ +/* } */ - if (o->resampler && - pa_sample_spec_equal(&origin->sample_spec, &dest->sample_spec) && - pa_channel_map_equal(&origin->channel_map, &dest->channel_map)) +/* if (o->resampler && */ +/* pa_sample_spec_equal(&origin->sample_spec, &dest->sample_spec) && */ +/* pa_channel_map_equal(&origin->channel_map, &dest->channel_map)) */ - /* Try to reuse the old resampler if possible */ - new_resampler = o->resampler; +/* /\* Try to reuse the old resampler if possible *\/ */ +/* new_resampler = o->resampler; */ - else if (!pa_sample_spec_equal(&o->sample_spec, &dest->sample_spec) || - !pa_channel_map_equal(&o->channel_map, &dest->channel_map)) { +/* else if (!pa_sample_spec_equal(&o->sample_spec, &dest->sample_spec) || */ +/* !pa_channel_map_equal(&o->channel_map, &dest->channel_map)) { */ - /* Okey, we need a new resampler for the new sink */ +/* /\* Okey, we need a new resampler for the new sink *\/ */ - if (!(new_resampler = pa_resampler_new( - dest->core->mempool, - &dest->sample_spec, &dest->channel_map, - &o->sample_spec, &o->channel_map, - o->resample_method))) { - pa_log_warn("Unsupported resampling operation."); - return -1; - } - } +/* if (!(new_resampler = pa_resampler_new( */ +/* dest->core->mempool, */ +/* &dest->sample_spec, &dest->channel_map, */ +/* &o->sample_spec, &o->channel_map, */ +/* o->resample_method))) { */ +/* pa_log_warn("Unsupported resampling operation."); */ +/* return -1; */ +/* } */ +/* } */ - /* Okey, let's move it */ - pa_idxset_remove_by_data(origin->outputs, o, NULL); - pa_idxset_put(dest->outputs, o, NULL); - o->source = dest; +/* /\* Okey, let's move it *\/ */ +/* pa_idxset_remove_by_data(origin->outputs, o, NULL); */ +/* pa_idxset_put(dest->outputs, o, NULL); */ +/* o->source = dest; */ - /* Replace resampler */ - if (new_resampler != o->resampler) { - if (o->resampler) - pa_resampler_free(o->resampler); - o->resampler = new_resampler; - } +/* /\* Replace resampler *\/ */ +/* if (new_resampler != o->resampler) { */ +/* if (o->resampler) */ +/* pa_resampler_free(o->resampler); */ +/* o->resampler = new_resampler; */ +/* } */ - /* Notify everyone */ - pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); - pa_source_notify(o->source); +/* /\* Notify everyone *\/ */ +/* pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); */ +/* pa_source_notify(o->source); */ - return 0; +/* return 0; */ +} + +int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, pa_memchunk* chunk) { + pa_source_output *o = PA_SOURCE_OUTPUT(o); + + pa_source_output_assert_ref(i); + + switch (code) { + + case PA_SOURCE_OUTPUT_MESSAGE_SET_RATE: { + + i->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata); + pa_resampler_set_output_rate(i->resampler, PA_PTR_TO_UINT(userdata)); + + return 0; + } + } + + return -1; } diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h index 3da6caac..0f9c3bae 100644 --- a/src/pulsecore/source-output.h +++ b/src/pulsecore/source-output.h @@ -1,5 +1,5 @@ -#ifndef foosourceoutputhfoo -#define foosourceoutputhfoo +#ifndef foopulsesourceoutputhfoo +#define foopulsesourceoutputhfoo /* $Id$ */ @@ -35,40 +35,59 @@ typedef struct pa_source_output pa_source_output; #include #include -typedef enum { +typedef enum pa_source_output_state { PA_SOURCE_OUTPUT_RUNNING, PA_SOURCE_OUTPUT_CORKED, PA_SOURCE_OUTPUT_DISCONNECTED } pa_source_output_state_t; typedef enum pa_source_output_flags { - PA_SOURCE_OUTPUT_NO_HOOKS = 1 + PA_SOURCE_OUTPUT_NO_HOOKS = 1, + PA_SOURCE_OUTPUT_VARIABLE_RATE = 2 } pa_source_output_flags_t; struct pa_source_output { - int ref; + pa_msgobject parent; + uint32_t index; - pa_source_output_state_t state; + pa_core *core; + pa_atomic_t state; + pa_source_output_flags_t flags; char *name, *driver; /* may be NULL */ pa_module *module; /* may be NULL */ + pa_client *client; /* may be NULL */ pa_source *source; - pa_client *client; /* may be NULL */ pa_sample_spec sample_spec; pa_channel_map channel_map; + int (*process_msg)(pa_sink_input *i, int code, void *userdata); void (*push)(pa_source_output *o, const pa_memchunk *chunk); void (*kill)(pa_source_output* o); /* may be NULL */ pa_usec_t (*get_latency) (pa_source_output *o); /* may be NULL */ - pa_resampler* resampler; /* may be NULL */ pa_resample_method_t resample_method; + struct { + pa_sample_spec sample_spec; + + pa_resampler* resampler; /* may be NULL */ + } thread_info; + void *userdata; }; +PA_DECLARE_CLASS(pa_source_output); +#define PA_SOURCE_OUTPUT(o) ((pa_source_output*) (o)) + +enum { + PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY, + PA_SOURCE_OUTPUT_MESSAGE_SET_RATE, + PA_SOURCE_OUTPUT_MESSAGE_MAX +}; + typedef struct pa_source_output_new_data { const char *name, *driver; pa_module *module; @@ -89,30 +108,38 @@ void pa_source_output_new_data_set_sample_spec(pa_source_output_new_data *data, void pa_source_output_new_data_set_channel_map(pa_source_output_new_data *data, const pa_channel_map *map); void pa_source_output_new_data_set_volume(pa_source_output_new_data *data, const pa_cvolume *volume); +/* To be called by the implementing module only */ + pa_source_output* pa_source_output_new( pa_core *core, pa_source_output_new_data *data, pa_source_output_flags_t flags); -void pa_source_output_unref(pa_source_output* o); -pa_source_output* pa_source_output_ref(pa_source_output *o); - -/* To be called by the implementing module only */ +void pa_source_output_put(pa_source_output *o); void pa_source_output_disconnect(pa_source_output*o); -/* External code may request disconnection with this funcion */ -void pa_source_output_kill(pa_source_output*o); +void pa_source_output_set_name(pa_source_output *i, const char *name); -void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk); +/* Callable by everyone */ -void pa_source_output_set_name(pa_source_output *i, const char *name); +/* External code may request disconnection with this funcion */ +void pa_source_output_kill(pa_source_output*o); pa_usec_t pa_source_output_get_latency(pa_source_output *i); void pa_source_output_cork(pa_source_output *i, int b); +void pa_source_output_set_rate(pa_source_output *o, uint32_t rate); + pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o); int pa_source_output_move_to(pa_source_output *o, pa_source *dest); +#define pa_source_output_get_state(o) ((pa_source_output_state_t) pa_atomic_load(&o->state)) + +/* To be used exclusively by the source driver thread */ + +void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk); +int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, pa_memchunk *chunk); + #endif diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 9bb2d342..fd3c85d7 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -42,12 +42,6 @@ #include "source.h" -#define CHECK_VALIDITY_RETURN_NULL(condition) \ -do {\ -if (!(condition)) \ - return NULL; \ -} while (0) - pa_source* pa_source_new( pa_core *core, const char *driver, @@ -65,30 +59,32 @@ pa_source* pa_source_new( assert(name); assert(spec); - CHECK_VALIDITY_RETURN_NULL(pa_sample_spec_valid(spec)); + pa_return_null_if_fail(pa_sample_spec_valid(spec)); if (!map) map = pa_channel_map_init_auto(&tmap, spec->channels, PA_CHANNEL_MAP_DEFAULT); - CHECK_VALIDITY_RETURN_NULL(map && pa_channel_map_valid(map)); - CHECK_VALIDITY_RETURN_NULL(map->channels == spec->channels); - CHECK_VALIDITY_RETURN_NULL(!driver || pa_utf8_valid(driver)); - CHECK_VALIDITY_RETURN_NULL(pa_utf8_valid(name) && *name); + pa_return_null_if_fail(map && pa_channel_map_valid(map)); + pa_return_null_if_fail(map->channels == spec->channels); + pa_return_null_if_fail(!driver || pa_utf8_valid(driver)); + pa_return_null_if_fail(pa_utf8_valid(name) && *name); - s = pa_xnew(pa_source, 1); + s = pa_msgobject_new(pa_source); if (!(name = pa_namereg_register(core, name, PA_NAMEREG_SOURCE, s, fail))) { pa_xfree(s); return NULL; } - s->ref = 1; + s->parent.parent.free = source_free; + s->parent.process_msg = pa_source_process_msg; + s->core = core; - s->state = PA_SOURCE_RUNNING; + pa_atomic_store(&s->state, PA_SOURCE_IDLE); s->name = pa_xstrdup(name); s->description = NULL; s->driver = pa_xstrdup(driver); - s->owner = NULL; + s->module = NULL; s->sample_spec = *spec; s->channel_map = *map; @@ -96,45 +92,87 @@ pa_source* pa_source_new( s->outputs = pa_idxset_new(NULL, NULL); s->monitor_of = NULL; - pa_cvolume_reset(&s->sw_volume, spec->channels); - pa_cvolume_reset(&s->hw_volume, spec->channels); - s->sw_muted = 0; - s->hw_muted = 0; + pa_cvolume_reset(&s->volume, spec->channels); + s->muted = 0; + s->refresh_volume = s->refresh_mute = 0; s->is_hardware = 0; s->get_latency = NULL; - s->notify = NULL; - s->set_hw_volume = NULL; - s->get_hw_volume = NULL; - s->set_hw_mute = NULL; - s->get_hw_mute = NULL; + s->set_volume = NULL; + s->get_volume = NULL; + s->set_mute = NULL; + s->get_mute = NULL; + s->start = NULL; + s->stop = NULL; s->userdata = NULL; + pa_assert_se(s->asyncmsgq = pa_asyncmsgq_new(0)); + r = pa_idxset_put(core->sources, s, &s->index); assert(s->index != PA_IDXSET_INVALID && r >= 0); pa_sample_spec_snprint(st, sizeof(st), spec); - pa_log_info("created %u \"%s\" with sample spec \"%s\"", s->index, s->name, st); + pa_log_info("Created source %u \"%s\" with sample spec \"%s\"", s->index, s->name, st); + s->thread_info.outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + s->thread_info.soft_volume = s->volume; + s->thread_info.soft_muted = s->muted; + pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index); return s; } +static void source_start(pa_source *s) { + pa_source_state_t state; + pa_assert(s); + + state = pa_source_get_state(s); + pa_return_if_fail(state == PA_SOURCE_IDLE || state == PA_SOURCE_SUSPENDED); + + pa_atomic_store(&s->state, PA_SOURCE_RUNNING); + + if (s->start) + s->start(s); + else + pa_asyncmsgq_post(s->asyncmsgq, s, PA_SOURCE_MESSAGE_START, NULL, NULL, pa_source_unref, NULL); +} + +static void source_stop(pa_source *s) { + pa_source_state_t state; + int stop; + + pa_assert(s); + state = pa_source_get_state(s); + pa_return_if_fail(state == PA_SOURCE_RUNNING || state == PA_SOURCE_SUSPENDED); + + stop = state == PA_SOURCE_RUNNING; + pa_atomic_store(&s->state, PA_SOURCE_IDLE); + + if (stop) { + if (s->stop) + s->stop(s); + else + pa_asyncmsgq_post(s->asyncmsgq, s, PA_SOURCE_MESSAGE_STOP, NULL, NULL, pa_source_unref, NULL); + } +} + void pa_source_disconnect(pa_source *s) { pa_source_output *o, *j = NULL; - assert(s); - assert(s->state == PA_SOURCE_RUNNING); + pa_assert(s); + pa_return_if_fail(pa_sink_get_state(s) != PA_SINK_DISCONNECT); - s->state = PA_SOURCE_DISCONNECTED; + source_stop(s); + + pa_atomic_store(&s->state, PA_SOURCE_DISCONNECTED); pa_namereg_unregister(s->core, s->name); pa_hook_fire(&s->core->hook_source_disconnect, s); while ((o = pa_idxset_first(s->outputs, NULL))) { - assert(o != j); + pa_assert(o != j); pa_source_output_kill(o); j = o; } @@ -142,190 +180,206 @@ void pa_source_disconnect(pa_source *s) { pa_idxset_remove_by_data(s->core->sources, s, NULL); s->get_latency = NULL; - s->notify = NULL; - s->get_hw_volume = NULL; - s->set_hw_volume = NULL; - s->set_hw_mute = NULL; - s->get_hw_mute = NULL; + s->get_volume = NULL; + s->set_volume = NULL; + s->set_mute = NULL; + s->get_mute = NULL; + s->start = NULL; + s->stop = NULL; pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_REMOVE, s->index); } -static void source_free(pa_source *s) { - assert(s); - assert(!s->ref); +static void source_free(pa_msgobject *o) { + pa_source *s = PA_SOURCE(o); + + pa_assert(s); + pa_assert(pa_source_refcnt(s) == 0); - if (s->state != PA_SOURCE_DISCONNECTED) - pa_source_disconnect(s); + pa_source_disconnect(s); - pa_log_info("freed %u \"%s\"", s->index, s->name); + pa_log_info("Freeing source %u \"%s\"", s->index, s->name); pa_idxset_free(s->outputs, NULL, NULL); + pa_hashmap_free(s->thread_info.outputs, pa_sink_output_unref, NULL); + pa_asyncmsgq_free(s->asyncmsgq); + pa_xfree(s->name); pa_xfree(s->description); pa_xfree(s->driver); pa_xfree(s); } -void pa_source_unref(pa_source *s) { - assert(s); - assert(s->ref >= 1); +void pa_source_update_status(pa_source*s) { + pa_source_assert_ref(s); - if (!(--s->ref)) - source_free(s); + if (pa_source_get_state(s) == PA_SOURCE_STATE_SUSPENDED) + return; + + if (pa_source_used_by(s) > 0) + source_start(s); + else + source_stop(s); } -pa_source* pa_source_ref(pa_source *s) { - assert(s); - assert(s->ref >= 1); +void pa_source_suspend(pa_source *s, int suspend) { + pa_source_state_t state; - s->ref++; - return s; -} + pa_source_assert_ref(s); -void pa_source_notify(pa_source*s) { - assert(s); - assert(s->ref >= 1); + state = pa_source_get_state(s); + pa_return_if_fail(suspend && (s->state == PA_SOURCE_RUNNING || s->state == PA_SOURCE_IDLE)); + pa_return_if_fail(!suspend && (s->state == PA_SOURCE_SUSPENDED)); - if (s->notify) - s->notify(s); -} -static int do_post(void *p, PA_GCC_UNUSED uint32_t idx, PA_GCC_UNUSED int *del, void*userdata) { - pa_source_output *o = p; - const pa_memchunk *chunk = userdata; + if (suspend) { + pa_atomic_store(&s->state, PA_SOURCE_SUSPENDED); - assert(o); - assert(chunk); + if (s->stop) + s->stop(s); + else + pa_asyncmsgq_post(s->asyncmsgq, s, PA_SOURCE_MESSAGE_STOP, NULL, NULL, pa_source_unref, NULL); + + } else { + pa_atomic_store(&s->state, PA_SOURCE_RUNNING); - pa_source_output_push(o, chunk); - return 0; + if (s->start) + s->start(s); + else + pa_asyncmsgq_post(s->asyncmsgq, s, PA_SOURCE_MESSAGE_START, NULL, NULL, pa_source_unref, NULL); + } } void pa_source_post(pa_source*s, const pa_memchunk *chunk) { - assert(s); - assert(s->ref >= 1); - assert(chunk); - - pa_source_ref(s); + pa_source_output *o; + void *state = NULL; + + pa_source_assert_ref(s); + pa_assert(chunk); if (s->sw_muted || !pa_cvolume_is_norm(&s->sw_volume)) { pa_memchunk vchunk = *chunk; pa_memblock_ref(vchunk.memblock); pa_memchunk_make_writable(&vchunk, 0); - if (s->sw_muted) + + if (s->thread_info.muted || pa_cvolume_is_muted(s->thread_info.volume)) pa_silence_memchunk(&vchunk, &s->sample_spec); else - pa_volume_memchunk(&vchunk, &s->sample_spec, &s->sw_volume); - pa_idxset_foreach(s->outputs, do_post, &vchunk); + pa_volume_memchunk(&vchunk, &s->sample_spec, &s->thread_info.volume); + + while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) + pa_source_output_push(o, &vchunk); + pa_memblock_unref(vchunk.memblock); - } else - pa_idxset_foreach(s->outputs, do_post, (void*) chunk); + } else { + + while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) + pa_source_output_push(o, chunk); - pa_source_unref(s); + } } -void pa_source_set_owner(pa_source *s, pa_module *m) { - assert(s); - assert(s->ref >= 1); - - if (m == s->owner) - return; +pa_usec_t pa_source_get_latency(pa_source *s) { + pa_usec_t usec; - s->owner = m; - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); -} + pa_source_assert_ref(s); -pa_usec_t pa_source_get_latency(pa_source *s) { - assert(s); - assert(s->ref >= 1); + if (s->get_latency) + return s->get_latency(s); - if (!s->get_latency) + if (pa_asyncmsgq_send(s->asyncmsgq, s, PA_SOURCE_MESSAGE_GET_LATENCY, &usec, NULL) < 0) return 0; - return s->get_latency(s); + return usec; } -void pa_source_set_volume(pa_source *s, pa_mixer_t m, const pa_cvolume *volume) { +void pa_source_set_volume(pa_source *s, const pa_cvolume *volume) { pa_cvolume *v; - assert(s); - assert(s->ref >= 1); - assert(volume); - - if (m == PA_MIXER_HARDWARE && s->set_hw_volume) - v = &s->hw_volume; - else - v = &s->sw_volume; - - if (pa_cvolume_equal(v, volume)) - return; + pa_source_assert_ref(s); + pa_assert(volume); - *v = *volume; + changed = !pa_cvolume_equal(volume, s->volume); + s->volume = *volume; + + if (s->set_volume && s->set_volume(s) < 0) + s->set_volume = NULL; - if (v == &s->hw_volume) - if (s->set_hw_volume(s) < 0) - s->sw_volume = *volume; + if (!s->set_volume) + pa_asyncmsgq_post(s->asyncmsgq, pa_source_ref(s), PA_SOURCE_MESSAGE_SET_VOLUME, pa_xnewdup(struct pa_cvolume, volume, 1), pa_source_unref, pa_xfree); - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + if (changed) + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); } -const pa_cvolume *pa_source_get_volume(pa_source *s, pa_mixer_t m) { - assert(s); - assert(s->ref >= 1); +const pa_cvolume *pa_source_get_volume(pa_source *s) { + pa_source_assert_ref(s); - if (m == PA_MIXER_HARDWARE && s->set_hw_volume) { + old_volume = s->volume; + + if (s->get_volume && s->get_volume(s) < 0) + s->get_volume = NULL; - if (s->get_hw_volume) - s->get_hw_volume(s); + if (!s->get_volume && s->refresh_volume) + pa_asyncmsgq_send(s->asyncmsgq, s, PA_SOURCE_MESSAGE_GET_VOLUME, &s->volume); - return &s->hw_volume; - } else - return &s->sw_volume; + if (!pa_cvolume_equal(&old_volume, &s->volume)) + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + + return &s->volume; } void pa_source_set_mute(pa_source *s, pa_mixer_t m, int mute) { - int *t; + int changed; + + pa_source_assert_ref(s); - assert(s); - assert(s->ref >= 1); + changed = s->muted != mute; - if (m == PA_MIXER_HARDWARE && s->set_hw_mute) - t = &s->hw_muted; - else - t = &s->sw_muted; - - if (!!*t == !!mute) - return; + if (s->set_mute && s->set_mute(s) < 0) + s->set_mute = NULL; - *t = !!mute; + if (!s->set_mute) + pa_asyncmsgq_post(s->asyncmsgq, pa_source_ref(s), PA_SOURCE_MESSAGE_SET_MUTE, PA_UINT_TO_PTR(mute), pa_source_unref, NULL); - if (t == &s->hw_muted) - if (s->set_hw_mute(s) < 0) - s->sw_muted = !!mute; - - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + if (changed) + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); } int pa_source_get_mute(pa_source *s, pa_mixer_t m) { - assert(s); - assert(s->ref >= 1); + int old_muted; + + pa_source_assert_ref(s); + + old_muted = s->muted; + + if (s->get_mute && s->get_mute(s) < 0) + s->get_mute = NULL; + + if (!s->get_mute && s->refresh_mute) + pa_asyncmsgq_send(s->asyncmsgq, s, PA_SOURCE_MESSAGE_GET_MUTE, &s->muted); + + if (old_muted != s->muted) + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + + return s->muted; +} - if (m == PA_MIXER_HARDWARE && s->set_hw_mute) { +void pa_source_set_module(pa_source *s, pa_module *m) { + pa_source_assert_ref(s); - if (s->get_hw_mute) - s->get_hw_mute(s); + if (m == s->module) + return; - return s->hw_muted; - } else - return s->sw_muted; + s->module = m; + + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); } void pa_source_set_description(pa_source *s, const char *description) { - assert(s); - assert(s->ref >= 1); + pa_source_assert_ref(s); if (!description && !s->description) return; @@ -340,8 +394,45 @@ void pa_source_set_description(pa_source *s, const char *description) { } unsigned pa_source_used_by(pa_source *s) { - assert(s); - assert(s->ref >= 1); + pa_source_assert_ref(s); return pa_idxset_size(s->outputs); } + +int pa_source_process_msg(pa_msgobject *o, void *object, int code, pa_memchunk *chunk, void *userdata) { + pa_source *s = PA_SOURCE(o); + pa_source_assert_ref(s); + + switch (code) { + case PA_SOURCE_MESSAGE_ADD_OUTPUT: { + pa_source_output *i = userdata; + pa_hashmap_put(s->thread_info.outputs, PA_UINT32_TO_PTR(i->index), pa_source_output_ref(i)); + return 0; + } + + case PA_SOURCE_MESSAGE_REMOVE_INPUT: { + pa_source_input *i = userdata; + pa_hashmap_remove(s->thread_info.outputs, PA_UINT32_TO_PTR(i->index), pa_source_output_ref(i)); + return 0; + } + + case PA_SOURCE_MESSAGE_SET_VOLUME: + s->thread_info.soft_volume = *((pa_cvolume*) userdata); + return 0; + + case PA_SOURCE_MESSAGE_SET_MUTE: + s->thread_info.soft_muted = PA_PTR_TO_UINT(userdata); + return 0; + + case PA_SOURCE_MESSAGE_GET_VOLUME: + *((pa_cvolume*) userdata) = s->thread_info.soft_volume; + return 0; + + case PA_SOURCE_MESSAGE_GET_MUTE: + *((int*) userdata) = s->thread_info.soft_muted; + return 0; + + default: + return -1; + } +} diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index 5a28cf4b..1e20c6e1 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -1,5 +1,5 @@ -#ifndef foosourcehfoo -#define foosourcehfoo +#ifndef foopulsesourcehfoo +#define foopulsesourcehfoo /* $Id$ */ @@ -32,6 +32,7 @@ typedef struct pa_source pa_source; #include #include #include + #include #include #include @@ -39,24 +40,30 @@ typedef struct pa_source pa_source; #include #include #include +#include +#include -#define PA_MAX_OUTPUTS_PER_SOURCE 16 +#define PA_MAX_OUTPUTS_PER_SOURCE 32 typedef enum pa_source_state { PA_SOURCE_RUNNING, + PA_SOURCE_SUSPENDED, + PA_SOURCE_IDLE, PA_SOURCE_DISCONNECTED } pa_source_state_t; struct pa_source { - int ref; + pa_msgobject parent; + uint32_t index; pa_core *core; - pa_source_state_t state; + pa_atomic_t state; char *name; char *description, *driver; /* may be NULL */ + int is_hardware; - pa_module *owner; /* may be NULL */ + pa_module *module; /* may be NULL */ pa_sample_spec sample_spec; pa_channel_map channel_map; @@ -64,48 +71,79 @@ struct pa_source { pa_idxset *outputs; pa_sink *monitor_of; /* may be NULL */ - pa_cvolume hw_volume, sw_volume; - int hw_muted, sw_muted; - - int is_hardware; - - void (*notify)(pa_source*source); /* may be NULL */ + pa_cvolume volume; + int muted; + int refresh_volume; + int referesh_mute; + + void (*start)(pa_source*source); /* may be NULL */ + void (*stop)(pa_source*source); /* may be NULL */ + int (*set_volume)(pa_source *s); /* dito */ + int (*get_volume)(pa_source *s); /* dito */ + int (*set_mute)(pa_source *s); /* dito */ + int (*get_mute)(pa_source *s); /* dito */ pa_usec_t (*get_latency)(pa_source *s); /* dito */ - int (*set_hw_volume)(pa_source *s); /* dito */ - int (*get_hw_volume)(pa_source *s); /* dito */ - int (*set_hw_mute)(pa_source *s); /* dito */ - int (*get_hw_mute)(pa_source *s); /* dito */ + pa_asyncmsgq *asyncmsgq; + + struct { + pa_hashmap *outputs; + pa_cvolume soft_volume; + int soft_muted; + } thread_info; + void *userdata; }; +PA_DECLARE_CLASS(pa_source); +#define PA_SOURCE(s) ((pa_source*) (s)) + +typedef enum pa_source_message { + PA_SOURCE_MESSAGE_ADD_OUTPUT, + PA_SOURCE_MESSAGE_REMOVE_OUTPUT, + PA_SOURCE_MESSAGE_GET_VOLUME, + PA_SOURCE_MESSAGE_SET_VOLUME, + PA_SOURCE_MESSAGE_GET_MUTE, + PA_SOURCE_MESSAGE_SET_MUTE, + PA_SOURCE_MESSAGE_GET_LATENCY, + PA_SOURCE_MESSAGE_START, + PA_SOURCE_MESSAGE_STOP, + PA_SOURCE_MESSAGE_MAX +} pa_source_message_t; + +/* To be used exclusively by the source driver */ + pa_source* pa_source_new( - pa_core *core, - const char *driver, - const char *name, - int namereg_fail, - const pa_sample_spec *spec, - const pa_channel_map *map); + pa_core *core, + const char *driver, + const char *name, + int namereg_fail, + const pa_sample_spec *spec, + const pa_channel_map *map); void pa_source_disconnect(pa_source *s); -void pa_source_unref(pa_source *s); -pa_source* pa_source_ref(pa_source *c); -/* Pass a new memory block to all output streams */ -void pa_source_post(pa_source*s, const pa_memchunk *b); - -void pa_source_notify(pa_source *s); +void pa_source_set_module(pa_source *s, pa_module *m); +void pa_source_set_description(pa_source *s, const char *description); -void pa_source_set_owner(pa_source *s, pa_module *m); +/* Callable by everyone */ pa_usec_t pa_source_get_latency(pa_source *s); -void pa_source_set_volume(pa_source *source, pa_mixer_t m, const pa_cvolume *volume); -const pa_cvolume *pa_source_get_volume(pa_source *source, pa_mixer_t m); -void pa_source_set_mute(pa_source *source, pa_mixer_t m, int mute); -int pa_source_get_mute(pa_source *source, pa_mixer_t m); +void pa_source_update_status(pa_source*s); +void pa_source_suspend(pa_source *s); -void pa_source_set_description(pa_source *s, const char *description); +void pa_source_set_volume(pa_source *source, const pa_cvolume *volume); +const pa_cvolume *pa_source_get_volume(pa_source *source); +void pa_source_set_mute(pa_source *source, int mute); +int pa_source_get_mute(pa_source *source); unsigned pa_source_used_by(pa_source *s); +#define pa_source_get_state(s) ((pa_source_state_t) pa_atomic_load(&(s)->state)) + +/* To be used exclusively by the source driver thread */ + +void pa_source_post(pa_source*s, const pa_memchunk *b); +void pa_source_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk); + #endif diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index 4271fa42..6ad5ac4a 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -26,7 +26,6 @@ #include #endif -#include #include #include #include @@ -35,56 +34,50 @@ #include #include #include +#include #include "thread.h" -#define ASSERT_SUCCESS(x) do { \ - int _r = (x); \ - assert(_r == 0); \ -} while(0) - struct pa_thread { pthread_t id; pa_thread_func_t thread_func; void *userdata; - pa_atomic_int_t running; + pa_atomic_t running; }; struct pa_tls { pthread_key_t key; }; -static pa_tls *thread_tls; -static pa_once_t thread_tls_once = PA_ONCE_INIT; +static pthread_key_t thread_key; +static pthread_once_t thread_once = PTHREAD_ONCE_INIT; -static void tls_free_cb(void *p) { +static void thread_free_cb(void *p) { pa_thread *t = p; - assert(t); + pa_assert(t); if (!t->thread_func) /* This is a foreign thread, we need to free the struct */ pa_xfree(t); } -static void thread_tls_once_func(void) { - thread_tls = pa_tls_new(tls_free_cb); - assert(thread_tls); +static void thread_once_func(void) { + pa_assert_se(pthread_key_create(&thread_key, thread_free_cb) == 0); } static void* internal_thread_func(void *userdata) { pa_thread *t = userdata; - assert(t); + pa_assert(t); t->id = pthread_self(); - pa_once(&thread_tls_once, thread_tls_once_func); - - pa_tls_set(thread_tls, t); + pthread_once(&thread_once, thread_once_func); + pthread_setspecific(thread_key, t); pa_atomic_inc(&t->running); t->thread_func(t->userdata); - pa_atomic_add(&t->running, -2); + pa_atomic_sub(&t->running, 2); return NULL; } @@ -92,7 +85,7 @@ static void* internal_thread_func(void *userdata) { pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) { pa_thread *t; - assert(thread_func); + pa_assert(thread_func); t = pa_xnew(pa_thread, 1); t->thread_func = thread_func; @@ -110,26 +103,26 @@ pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) { } int pa_thread_is_running(pa_thread *t) { - assert(t); + pa_assert(t); /* Unfortunately there is no way to tell whether a "foreign" * thread is still running. See * http://udrepper.livejournal.com/16844.html for more * information */ - assert(t->thread_func); + pa_assert(t->thread_func); return pa_atomic_load(&t->running) > 0; } void pa_thread_free(pa_thread *t) { - assert(t); + pa_assert(t); pa_thread_join(t); pa_xfree(t); } int pa_thread_join(pa_thread *t) { - assert(t); + pa_assert(t); return pthread_join(t->id, NULL); } @@ -137,9 +130,9 @@ int pa_thread_join(pa_thread *t) { pa_thread* pa_thread_self(void) { pa_thread *t; - pa_once(&thread_tls_once, thread_tls_once_func); + pthread_once(&thread_once, thread_once_func); - if ((t = pa_tls_get(thread_tls))) + if ((t = pthread_getspecific(thread_key))) return t; /* This is a foreign thread, let's create a pthread structure to @@ -151,19 +144,19 @@ pa_thread* pa_thread_self(void) { t->userdata = NULL; pa_atomic_store(&t->running, 2); - pa_tls_set(thread_tls, t); + pthread_setspecific(thread_key, t); return t; } void* pa_thread_get_data(pa_thread *t) { - assert(t); + pa_assert(t); return t->userdata; } void pa_thread_set_data(pa_thread *t, void *userdata) { - assert(t); + pa_assert(t); t->userdata = userdata; } @@ -172,7 +165,7 @@ void pa_thread_yield(void) { #ifdef HAVE_PTHREAD_YIELD pthread_yield(); #else - ASSERT_SUCCESS(sched_yield()); + pa_assert_se(sched_yield() == 0); #endif } @@ -190,14 +183,14 @@ pa_tls* pa_tls_new(pa_free_cb_t free_cb) { } void pa_tls_free(pa_tls *t) { - assert(t); + pa_assert(t); - ASSERT_SUCCESS(pthread_key_delete(t->key)); + pa_assert_se(pthread_key_delete(t->key) == 0); pa_xfree(t); } void *pa_tls_get(pa_tls *t) { - assert(t); + pa_assert(t); return pthread_getspecific(t->key); } @@ -206,7 +199,7 @@ void *pa_tls_set(pa_tls *t, void *userdata) { void *r; r = pthread_getspecific(t->key); - ASSERT_SUCCESS(pthread_setspecific(t->key, userdata)); + pa_assert_se(pthread_setspecific(t->key, userdata) == 0); return r; } diff --git a/src/tests/asyncmsgq-test.c b/src/tests/asyncmsgq-test.c new file mode 100644 index 00000000..8a0f5a3f --- /dev/null +++ b/src/tests/asyncmsgq-test.c @@ -0,0 +1,110 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +enum { + OPERATION_A, + OPERATION_B, + OPERATION_C, + QUIT +}; + +static void the_thread(void *_q) { + pa_asyncmsgq *q = _q; + int quit = 0; + + do { + int code = 0; + + pa_assert_se(pa_asyncmsgq_get(q, NULL, &code, NULL, 1) == 0); + + switch (code) { + + case OPERATION_A: + printf("Operation A\n"); + break; + + case OPERATION_B: + printf("Operation B\n"); + break; + + case OPERATION_C: + printf("Operation C\n"); + break; + + case QUIT: + printf("quit\n"); + quit = 1; + break; + } + + pa_asyncmsgq_done(q); + + } while (!quit); +} + +int main(int argc, char *argv[]) { + pa_asyncmsgq *q; + pa_thread *t; + + pa_assert_se(q = pa_asyncmsgq_new(0)); + + pa_assert_se(t = pa_thread_new(the_thread, q)); + + printf("Operation A post\n"); + pa_asyncmsgq_post(q, NULL, OPERATION_A, NULL, NULL, NULL); + + pa_thread_yield(); + + printf("Operation B post\n"); + pa_asyncmsgq_post(q, NULL, OPERATION_B, NULL, NULL, NULL); + + pa_thread_yield(); + + printf("Operation C send\n"); + pa_asyncmsgq_send(q, NULL, OPERATION_C, NULL); + + pa_thread_yield(); + + printf("Quit post\n"); + pa_asyncmsgq_post(q, NULL, QUIT, NULL, NULL, NULL); + + pa_thread_free(t); + + pa_asyncmsgq_free(q); + + return 0; +} diff --git a/src/tests/asyncq-test.c b/src/tests/asyncq-test.c new file mode 100644 index 00000000..10566db1 --- /dev/null +++ b/src/tests/asyncq-test.c @@ -0,0 +1,87 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static void producer(void *_q) { + pa_asyncq *q = _q; + int i; + + for (i = 0; i < 1000; i++) { + pa_asyncq_push(q, (void*) (i+1), 1); + printf("pushed %i\n", i); + } + + pa_asyncq_push(q, (void*) -1, 1); + printf("pushed end\n"); +} + +static void consumer(void *_q) { + pa_asyncq *q = _q; + void *p; + int i; + + sleep(1); + + for (i = 0;; i++) { + p = pa_asyncq_pop(q, 1); + + if (p == (void*) -1) + break; + + pa_assert(p == (void *) (i+1)); + + printf("popped %i\n", i); + } + + printf("popped end\n"); +} + +int main(int argc, char *argv[]) { + pa_asyncq *q; + pa_thread *t1, *t2; + + pa_assert_se(q = pa_asyncq_new(0)); + + pa_assert_se(t1 = pa_thread_new(producer, q)); + pa_assert_se(t2 = pa_thread_new(consumer, q)); + + pa_thread_free(t1); + pa_thread_free(t2); + + pa_asyncq_free(q, NULL); + + return 0; +} diff --git a/src/tests/mcalign-test.c b/src/tests/mcalign-test.c index db76712b..d1013118 100644 --- a/src/tests/mcalign-test.c +++ b/src/tests/mcalign-test.c @@ -59,24 +59,29 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { c.index = c.length = 0; } - assert(c.index < c.memblock->length); + assert(c.index < pa_memblock_get_length(c.memblock)); - l = c.memblock->length - c.index; + l = pa_memblock_get_length(c.memblock) - c.index; l = l <= 1 ? l : rand() % (l-1) +1 ; - if ((r = read(STDIN_FILENO, (uint8_t*) c.memblock->data + c.index, l)) <= 0) { + p = pa_memblock_acquire(c.memblock); + + if ((r = read(STDIN_FILENO, (uint8_t*) p + c.index, l)) <= 0) { + pa_memblock_release(c.memblock); fprintf(stderr, "read() failed: %s\n", r < 0 ? strerror(errno) : "EOF"); break; } + pa_memblock_release(c.memblock); + c.length = r; pa_mcalign_push(a, &c); fprintf(stderr, "Read %ld bytes\n", (long)r); c.index += r; - if (c.index >= c.memblock->length) { + if (c.index >= pa_memblock_get_length(c.memblock)) { pa_memblock_unref(c.memblock); pa_memchunk_reset(&c); } @@ -87,7 +92,9 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { if (pa_mcalign_pop(a, &t) < 0) break; - pa_loop_write(STDOUT_FILENO, (uint8_t*) t.memblock->data + t.index, t.length, NULL); + p = pa_memblock_acquire(t.memblock); + pa_loop_write(STDOUT_FILENO, (uint8_t*) p + t.index, t.length, NULL); + pa_memblock_release(t.memblock); fprintf(stderr, "Wrote %lu bytes.\n", (unsigned long) t.length); pa_memblock_unref(t.memblock); diff --git a/src/tests/memblock-test.c b/src/tests/memblock-test.c index 8d25ba38..1f63499e 100644 --- a/src/tests/memblock-test.c +++ b/src/tests/memblock-test.c @@ -76,6 +76,7 @@ int main(int argc, char *argv[]) { pa_memblock* blocks[5]; uint32_t id, shm_id; size_t offset, size; + char *x; const char txt[] = "This is a test!"; @@ -90,10 +91,17 @@ int main(int argc, char *argv[]) { assert(pool_a && pool_b && pool_c); blocks[0] = pa_memblock_new_fixed(pool_a, (void*) txt, sizeof(txt), 1); + blocks[1] = pa_memblock_new(pool_a, sizeof(txt)); - snprintf(blocks[1]->data, blocks[1]->length, "%s", txt); + x = pa_memblock_acquire(blocks[1]); + snprintf(x, pa_memblock_get_length(blocks[1]), "%s", txt); + pa_memblock_release(blocks[1]); + blocks[2] = pa_memblock_new_pool(pool_a, sizeof(txt)); - snprintf(blocks[2]->data, blocks[2]->length, "%s", txt); + x = pa_memblock_acquire(blocks[2]); + snprintf(x, pa_memblock_get_length(blocks[2]), "%s", txt); + pa_memblock_release(blocks[1]); + blocks[3] = pa_memblock_new_malloced(pool_a, pa_xstrdup(txt), sizeof(txt)); blocks[4] = NULL; @@ -130,14 +138,18 @@ int main(int argc, char *argv[]) { mb_c = pa_memimport_get(import_c, id, shm_id, offset, size); assert(mb_c); - printf("1 data=%s\n", (char*) mb_c->data); + x = pa_memblock_acquire(mb_c); + printf("1 data=%s\n", x); + pa_memblock_release(mb_c); print_stats(pool_a, "A"); print_stats(pool_b, "B"); print_stats(pool_c, "C"); pa_memexport_free(export_b); - printf("2 data=%s\n", (char*) mb_c->data); + x = pa_memblock_acquire(mb_c); + printf("2 data=%s\n", x); + pa_memblock_release(mb_c); pa_memblock_unref(mb_c); pa_memimport_free(import_b); diff --git a/src/tests/memblockq-test.c b/src/tests/memblockq-test.c index 1c0b7fed..7ad3b2f3 100644 --- a/src/tests/memblockq-test.c +++ b/src/tests/memblockq-test.c @@ -131,8 +131,10 @@ int main(int argc, char *argv[]) { if (pa_memblockq_peek(bq, &out) < 0) break; - for (e = (char*) out.memblock->data + out.index, n = 0; n < out.length; n++) + p = pa_memblock_acquire(out.memblock); + for (e = (char*) p + out.index, n = 0; n < out.length; n++) printf("%c", *e); + pa_memblock_release(out.memblock); pa_memblock_unref(out.memblock); pa_memblockq_drop(bq, &out, out.length); -- cgit From a4fed0fbb568dc57762906fb7e48fc945925d2ca Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 11 Jun 2007 12:17:40 +0000 Subject: make eolspace git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1470 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-null-sink.c | 36 +++++++++++------------ src/modules/module-pipe-sink.c | 30 +++++++++---------- src/pulsecore/asyncmsgq.c | 16 +++++------ src/pulsecore/asyncq.c | 26 ++++++++--------- src/pulsecore/core.c | 12 ++++---- src/pulsecore/core.h | 2 +- src/pulsecore/flist.c | 2 +- src/pulsecore/msgobject.c | 2 +- src/pulsecore/object.c | 2 +- src/pulsecore/object.h | 2 +- src/pulsecore/once-posix.c | 12 ++++---- src/pulsecore/protocol-simple.c | 64 ++++++++++++++++++++--------------------- src/pulsecore/semaphore-posix.c | 2 +- src/pulsecore/sink-input.c | 38 ++++++++++++------------ src/pulsecore/sink-input.h | 12 ++++---- src/pulsecore/sink.c | 64 ++++++++++++++++++++--------------------- src/pulsecore/source-output.c | 28 +++++++++--------- src/pulsecore/source-output.h | 6 ++-- src/pulsecore/source.c | 54 +++++++++++++++++----------------- src/pulsecore/source.h | 4 +-- src/tests/asyncmsgq-test.c | 8 +++--- src/tests/asyncq-test.c | 8 +++--- 22 files changed, 215 insertions(+), 215 deletions(-) diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index 8cf961b9..ce3b29b0 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -94,7 +94,7 @@ static void thread_func(void *userdata) { pollfd.events = POLLIN; pa_gettimeofday(u->timestamp); - + for (;;) { int code; void *data, *object; @@ -116,7 +116,7 @@ static void thread_func(void *userdata) { pa_sink_process_msg(u->sink->asyncmsgq, object, code, data); } - + } else if (object == u->sink) { switch (code) { @@ -124,29 +124,29 @@ static void thread_func(void *userdata) { pa_assert(running); running = 0; break; - + case PA_SINK_MESSAGE_START: pa_assert(!running); running = 1; - + pa_gettimeofday(u->timestamp); break; - + case PA_SINK_MESSAGE_GET_LATENCY: - + if (pa_timeval_cmp(&u->timestamp, &now) > 0) *((pa_usec_t*) data) = 0; else *((pa_usec_t*) data) = pa_timeval_diff(&u->timestamp, &now); break; - + /* ... */ default: pa_sink_process_msg(u->sink->asyncmsgq, object, code, data); } } - + pa_asyncmsgq_done(u->sink->asyncmsgq); continue; } @@ -155,30 +155,30 @@ static void thread_func(void *userdata) { if (running) { pa_gettimeofday(&now); - + if (pa_timeval_cmp(u->timestamp, &now) <= 0) { pa_memchunk chunk; size_t l; - + if (pa_sink_render(u->sink, u->block_size, &chunk) >= 0) { l = chunk.length; pa_memblock_unref(chunk.memblock); } else l = u->block_size; - + pa_timeval_add(&u->timestamp, pa_bytes_to_usec(l, &u->sink->sample_spec)); continue; } timeout = pa_timeval_diff(&u->timestamp, &now)/1000; - + if (timeout < 1) timeout = 1; } else timeout = -1; /* Hmm, nothing to do. Let's sleep */ - + if (pa_asyncmsgq_before_poll(u->sink->asyncmsgq) < 0) continue; @@ -192,7 +192,7 @@ static void thread_func(void *userdata) { pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; } - + pa_assert(r == 0 || pollfd.revents == POLLIN); } @@ -241,7 +241,7 @@ int pa__init(pa_core *c, pa_module*m) { pa_sink_set_description(u->sink, pa_modargs_get_value(ma, "description", "NULL sink")); u->block_size = pa_bytes_per_second(&ss) / 20; /* 50 ms */ - + if (u->block_size <= 0) u->block_size = pa_frame_size(&ss); @@ -249,7 +249,7 @@ int pa__init(pa_core *c, pa_module*m) { pa_log("Failed to create thread."); goto fail; } - + pa_modargs_free(ma); return 0; @@ -265,7 +265,7 @@ fail: void pa__done(pa_core *c, pa_module*m) { struct userdata *u; - + pa_assert(c); pa_assert(m); @@ -278,7 +278,7 @@ void pa__done(pa_core *c, pa_module*m) { pa_asyncmsgq_send(u->sink->asyncmsgq, PA_SINK_MESSAGE_SHUTDOWN, NULL); pa_thread_free(u->thread); } - + pa_sink_unref(u->sink); pa_xfree(u); diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index 61672ede..e4735f61 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -124,9 +124,9 @@ static void thread_func(void *userdata) { default: pa_sink_process_msg(u->sink->asyncmsgq, object, code, data); } - + } else if (object == u->sink) { - + case PA_SINK_MESSAGE_STOP: pa_assert(running); running = 0; @@ -155,7 +155,7 @@ static void thread_func(void *userdata) { default: pa_sink_process_msg(u->sink->asyncmsgq, object, code, data); } - + pa_asyncmsgq_done(u->sink->asyncmsgq); continue; } @@ -171,20 +171,20 @@ static void thread_func(void *userdata) { if (!underrun) { ssize_t l; - + p = pa_memblock_acquire(u->memchunk.memblock); l = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length); pa_memblock_release(p); - + if (l < 0) { if (errno != EINTR && errno != EAGAIN) { pa_log("Failed to write data to FIFO: %s", pa_cstrerror(errno)); goto fail; } - + } else { - + u->memchunk.index += l; u->memchunk.length -= l; @@ -202,7 +202,7 @@ static void thread_func(void *userdata) { pollfd[POLLFD_FIFO].events = running && !underrun ? POLLOUT : 0; /* Hmm, nothing to do. Let's sleep */ - + if (pa_asyncmsgq_before_poll(u->sink->asyncmsgq) < 0) continue; @@ -221,10 +221,10 @@ static void thread_func(void *userdata) { pa_log("FIFO shutdown."); goto fail; } - + pa_assert(pollfd[POLLFD_ASYNCQ].revents & ~POLLIN == 0); } - + fail: /* We have to continue processing messages until we receive the * SHUTDOWN message */ @@ -265,9 +265,9 @@ int pa__init(pa_core *c, pa_module*m) { u->memchunk.memblock = NULL; u->memchunk.length = 0; m->userdata = u; - + mkfifo(u->filename, 0666); - + if ((u->fd = open(u->filename, O_RDWR)) < 0) { pa_log("open('%s'): %s", p, pa_cstrerror(errno)); goto fail; @@ -290,7 +290,7 @@ int pa__init(pa_core *c, pa_module*m) { pa_log("Failed to create sink."); goto fail; } - + u->sink->userdata = u; pa_sink_set_owner(u->sink, m); pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Unix FIFO sink '%s'", p)); @@ -300,7 +300,7 @@ int pa__init(pa_core *c, pa_module*m) { pa_log("Failed to create thread."); goto fail; } - + pa_modargs_free(ma); return 0; @@ -328,7 +328,7 @@ void pa__done(pa_core *c, pa_module*m) { pa_asyncmsgq_send(u->sink->asyncmsgq, PA_SINK_MESSAGE_SHUTDOWN, NULL); pa_thread_free(u->thread); } - + pa_sink_unref(u->sink); if (u->memchunk.memblock) diff --git a/src/pulsecore/asyncmsgq.c b/src/pulsecore/asyncmsgq.c index 31e27e7d..de5b2f9d 100644 --- a/src/pulsecore/asyncmsgq.c +++ b/src/pulsecore/asyncmsgq.c @@ -65,7 +65,7 @@ pa_asyncmsgq *pa_asyncmsgq_new(unsigned size) { pa_assert_se(a->asyncq = pa_asyncq_new(size)); pa_assert_se(a->mutex = pa_mutex_new(0)); a->current = NULL; - + return a; } @@ -82,10 +82,10 @@ void pa_asyncmsgq_free(pa_asyncmsgq *a) { if (i->memchunk.memblock) pa_memblock_unref(i->object); - + if (i->userdata_free_cb) i->userdata_free_cb(i->userdata); - + if (pa_flist_push(PA_STATIC_FLIST_GET(asyncmsgq), i) < 0) pa_xfree(i); } @@ -162,7 +162,7 @@ int pa_asyncmsgq_get(pa_asyncmsgq *a, pa_msgobject **object, int *code, void **u *object = a->current->object; if (chunk) *chunk = a->chunk; - + return 0; } @@ -183,7 +183,7 @@ void pa_asyncmsgq_done(pa_asyncmsgq *a, int ret) { if (a->current->memchunk.memblock) pa_memblock_unref(a->current->memchunk.memblock); - + if (pa_flist_push(PA_STATIC_FLIST_GET(asyncmsgq), a->current) < 0) pa_xfree(a->current); } @@ -194,14 +194,14 @@ void pa_asyncmsgq_done(pa_asyncmsgq *a, int ret) { int pa_asyncmsgq_wait_for(pa_asyncmsgq *a, int code) { int c; pa_assert(a); - + do { - + if (pa_asyncmsgq_get(a, NULL, &c, NULL, 1) < 0) return -1; pa_asyncmsgq_done(a); - + } while (c != code); return 0; diff --git a/src/pulsecore/asyncq.c b/src/pulsecore/asyncq.c index 779cd479..54d36dc0 100644 --- a/src/pulsecore/asyncq.c +++ b/src/pulsecore/asyncq.c @@ -85,7 +85,7 @@ pa_asyncq *pa_asyncq_new(unsigned size) { pa_xfree(l); return NULL; } - + if (pipe(l->write_fds) < 0) { pa_close(l->read_fds[0]); pa_close(l->read_fds[1]); @@ -104,7 +104,7 @@ void pa_asyncq_free(pa_asyncq *l, pa_free_cb_t free_cb) { if (free_cb) { void *p; - + while ((p = pa_asyncq_pop(l, 0))) free_cb(p); } @@ -113,7 +113,7 @@ void pa_asyncq_free(pa_asyncq *l, pa_free_cb_t free_cb) { pa_close(l->read_fds[1]); pa_close(l->write_fds[0]); pa_close(l->write_fds[1]); - + pa_xfree(l); } @@ -125,12 +125,12 @@ int pa_asyncq_push(pa_asyncq*l, void *p, int wait) { pa_assert(p); cells = PA_ASYNCQ_CELLS(l); - + _Y; idx = reduce(l, l->write_idx); if (!pa_atomic_ptr_cmpxchg(&cells[idx], NULL, p)) { - + /* First try failed. Let's wait for changes. */ if (!wait) @@ -142,7 +142,7 @@ int pa_asyncq_push(pa_asyncq*l, void *p, int wait) { for (;;) { char x[20]; - + _Y; if (pa_atomic_ptr_cmpxchg(&cells[idx], NULL, p)) @@ -155,21 +155,21 @@ int pa_asyncq_push(pa_asyncq*l, void *p, int wait) { return -1; } } - + _Y; pa_atomic_dec(&l->write_waiting); } - + _Y; l->write_idx++; - + if (pa_atomic_load(&l->read_waiting)) { char x = 'x'; _Y; write(l->read_fds[1], &x, sizeof(x)); } - + return 0; } @@ -188,7 +188,7 @@ void* pa_asyncq_pop(pa_asyncq*l, int wait) { if (!(ret = pa_atomic_ptr_load(&cells[idx]))) { /* First try failed. Let's wait for changes. */ - + if (!wait) return NULL; @@ -228,7 +228,7 @@ void* pa_asyncq_pop(pa_asyncq*l, int wait) { _Y; write(l->write_fds[1], &x, sizeof(x)); } - + return ret; } @@ -253,7 +253,7 @@ int pa_asyncq_before_poll(pa_asyncq *l) { return -1; pa_atomic_inc(&l->read_waiting); - + if (pa_atomic_ptr_load(&cells[idx])) { pa_atomic_dec(&l->read_waiting); return -1; diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c index c80caf14..99ac74e1 100644 --- a/src/pulsecore/core.c +++ b/src/pulsecore/core.c @@ -53,9 +53,9 @@ static int core_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchu pa_core *c = PA_CORE(o); pa_core_assert_ref(c); - + switch (code) { - + case PA_CORE_MESSAGE_UNLOAD_MODULE: pa_module_unload(c, userdata); return 0; @@ -67,7 +67,7 @@ static int core_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchu static void asyncmsgq_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) { pa_core *c = userdata; - + pa_assert(pa_asyncmsgq_get_fd(c->asyncmsgq) == fd); pa_assert(events == PA_IO_EVENT_INPUT); @@ -84,7 +84,7 @@ static void asyncmsgq_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_even pa_asyncmsgq_dispatch(object, code, data, &chunk); pa_asyncmsgq_done(c->asyncmsgq, 0); } - + if (pa_asyncmsgq_before_poll(c->asyncmsgq) == 0) break; } @@ -97,7 +97,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { pa_mempool *pool; pa_assert(m); - + if (shared) { if (!(pool = pa_mempool_new(shared))) { pa_log_warn("failed to allocate shared memory pool. Falling back to a normal memory pool."); @@ -175,7 +175,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { pa_assert_se(c->asyncmsgq = pa_asyncmsgq_new(0)); pa_assert_se(pa_asyncmsgq_before_poll(c->asyncmsgq) == 0); pa_assert_se(c->asyncmsgq_event = c->mainloop->io_new(c->mainloop, pa_asyncmsgq_get_fd(c->asyncmsgq), PA_IO_EVENT_INPUT, asyncmsgq_cb, c)); - + return c; } diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index dc2ebb48..86660b7a 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -48,7 +48,7 @@ typedef struct pa_core pa_core; struct pa_core { pa_msgobject parent; - + /* A random value which may be used to identify this instance of * PulseAudio. Not cryptographically secure in any way. */ uint32_t cookie; diff --git a/src/pulsecore/flist.c b/src/pulsecore/flist.c index 3805e1d1..022010b3 100644 --- a/src/pulsecore/flist.c +++ b/src/pulsecore/flist.c @@ -163,7 +163,7 @@ int pa_flist_push(pa_flist*l, void *p) { assert(p); cells = PA_FLIST_CELLS(l); - + n = len = (int) l->size - pa_atomic_load(&l->length) + N_EXTRA_SCAN; _Y; idx = reduce(l, pa_atomic_load(&l->write_idx)); diff --git a/src/pulsecore/msgobject.c b/src/pulsecore/msgobject.c index ea404ccf..ce9f22f2 100644 --- a/src/pulsecore/msgobject.c +++ b/src/pulsecore/msgobject.c @@ -30,7 +30,7 @@ pa_msgobject *pa_msgobject_new_internal(size_t size, const char *type_name) { pa_msgobject *o; - + pa_assert(size > sizeof(pa_msgobject)); pa_assert(type_name); diff --git a/src/pulsecore/object.c b/src/pulsecore/object.c index de7d5ad5..e6ed53b2 100644 --- a/src/pulsecore/object.c +++ b/src/pulsecore/object.c @@ -30,7 +30,7 @@ pa_object *pa_object_new_internal(size_t size, const char *type_name) { pa_object *o; - + pa_assert(size > sizeof(pa_object)); pa_assert(type_name); diff --git a/src/pulsecore/object.h b/src/pulsecore/object.h index 8fccf191..e195a359 100644 --- a/src/pulsecore/object.h +++ b/src/pulsecore/object.h @@ -68,5 +68,5 @@ static inline int pa_object_refcnt(pa_object *o) { pa_object_assert_ref(PA_OBJECT(o)); \ } \ struct __stupid_useless_struct_to_allow_trailing_semicolon - + #endif diff --git a/src/pulsecore/once-posix.c b/src/pulsecore/once-posix.c index 7ccd08ed..25ccb035 100644 --- a/src/pulsecore/once-posix.c +++ b/src/pulsecore/once-posix.c @@ -35,17 +35,17 @@ /* Not reentrant -- how could it be? */ void pa_once(pa_once_t *control, pa_once_func_t func) { pa_mutex *m; - + pa_assert(control); pa_assert(func); if (pa_atomic_load(&control->done)) return; - + pa_atomic_inc(&control->ref); - + for (;;) { - + if ((m = pa_atomic_ptr_load(&control->mutex))) { /* The mutex is stored in locked state, hence let's just @@ -57,7 +57,7 @@ void pa_once(pa_once_t *control, pa_once_func_t func) { pa_assert_se(m = pa_mutex_new(0)); pa_mutex_lock(m); - + if (pa_atomic_ptr_cmpxchg(&control->mutex, NULL, m)) { func(); pa_atomic_store(&control->done, 1); @@ -71,7 +71,7 @@ void pa_once(pa_once_t *control, pa_once_func_t func) { } pa_assert(pa_atomic_load(&control->done)); - + if (pa_atomic_dec(&control->ref) <= 1) { pa_assert(pa_atomic_ptr_cmpxchg(&control->mutex, m, NULL)); pa_mutex_free(m); diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index 288cf87a..b7a4cc78 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -86,11 +86,11 @@ enum { }; enum { - MESSAGE_REQUEST_DATA, /* data from source output to main loop */ + MESSAGE_REQUEST_DATA, /* data from source output to main loop */ MESSAGE_POST_DATA /* data from source output to main loop */ }; - + #define PLAYBACK_BUFFER_SECONDS (.5) #define PLAYBACK_BUFFER_FRAGMENTS (10) #define RECORD_BUFFER_SECONDS (5) @@ -105,15 +105,15 @@ static void connection_free(struct connection *c) { pa_sink_input_disconnect(c->sink_input); pa_sink_input_unref(c->sink_input); } - + if (c->source_output) { pa_source_output_disconnect(c->source_output); pa_source_output_unref(c->source_output); } - + if (c->playback.current_memblock) pa_memblock_unref(c->playback.current_memblock); - + if (c->client) pa_client_free(c->client); if (c->io) @@ -122,7 +122,7 @@ static void connection_free(struct connection *c) { pa_memblockq_free(c->input_memblockq); if (c->output_memblockq) pa_memblockq_free(c->output_memblockq); - + pa_xfree(c); } @@ -133,7 +133,7 @@ static int do_read(struct connection *c) { void *p; pa_assert(c); - + if (!c->sink_input || !(l = pa_atomic_load(&c->playback.missing))) return 0; @@ -155,12 +155,12 @@ static int do_read(struct connection *c) { p = pa_memblock_acquire(c->playback.current_memblock); r = pa_iochannel_read(c->io, (uint8_t*) p + c->playback.memblock_index, l); pa_memblock_release(c->playback.current_memblock); - + if (r <= 0) { if (errno == EINTR || errno == EAGAIN) return 0; - + pa_log_debug("read(): %s", r == 0 ? "EOF" : pa_cstrerror(errno)); return -1; } @@ -195,7 +195,7 @@ static int do_write(struct connection *c) { p = pa_memblock_acquire(chunk.memblock); r = pa_iochannel_write(c->io, (uint8_t*) p+chunk.index, chunk.length); pa_memblock_release(chunk.memblock); - + pa_memblock_unref(chunk.memblock); if (r < 0) { @@ -208,7 +208,7 @@ static int do_write(struct connection *c) { } pa_memblockq_drop(c->output_memblockq, &chunk, r); - + return 0; } @@ -251,7 +251,7 @@ fail: /* Called from thread context */ static int sink_input_process_msg(pa_sink_input *i, int code, void *userdata, const pa_memchunk *chunk) { struct connection*c; - + pa_assert(i); c = i->userdata; pa_assert(c); @@ -265,10 +265,10 @@ static int sink_input_process_msg(pa_sink_input *i, int code, void *userdata, co pa_memblockq_push_align(c->input_memblockq, chunk); return 0; } - + case PA_SINK_INPUT_MESSAGE_GET_LATENCY: { pa_usec_t *r = userdata; - + *r = pa_bytes_to_usec(pa_memblockq_get_length(c->input_memblockq), &c->sink_input->sample_spec); /* Fall through, the default handler will add in the extra @@ -283,7 +283,7 @@ static int sink_input_process_msg(pa_sink_input *i, int code, void *userdata, co /* Called from thread context */ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { struct connection*c; - + pa_assert(i); c = i->userdata; pa_assert(c); @@ -301,7 +301,7 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_t length) { struct connection*c = i->userdata; size_t old, new; - + pa_assert(i); pa_assert(c); pa_assert(length); @@ -320,7 +320,7 @@ static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_ static void sink_input_kill_cb(pa_sink_input *i) { pa_assert(i); pa_assert(i->userdata); - + connection_free((struct connection *) i->userdata); } @@ -328,7 +328,7 @@ static void sink_input_kill_cb(pa_sink_input *i) { static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) { struct connection *c; - + pa_assert(o); c = o->userdata; pa_assert(c); @@ -343,17 +343,17 @@ static void source_output_kill_cb(pa_source_output *o) { pa_assert(o); c = o->userdata; pa_assert(c); - + connection_free(c); } static pa_usec_t source_output_get_latency_cb(pa_source_output *o) { struct connection*c; - + pa_assert(o); c = o->userdata; pa_assert(c); - + return pa_bytes_to_usec(pa_memblockq_get_length(c->output_memblockq), &c->source_output->sample_spec); } @@ -361,7 +361,7 @@ static pa_usec_t source_output_get_latency_cb(pa_source_output *o) { static void client_kill_cb(pa_client *client) { struct connection*c; - + pa_assert(client); c = client->userdata; pa_assert(c); @@ -386,7 +386,7 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) pa_protocol_simple *p = userdata; struct connection *c = NULL; char cname[256]; - + pa_assert(s); pa_assert(io); pa_assert(p); @@ -415,7 +415,7 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) c->client->kill = client_kill_cb; c->client->userdata = c; - + if (p->mode & PLAYBACK) { pa_sink_input_new_data data; size_t l; @@ -493,7 +493,7 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) pa_iochannel_set_callback(c->io, io_callback, c); pa_idxset_put(p->connections, c, NULL); - + return; fail: @@ -504,7 +504,7 @@ fail: static void asyncmsgq_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) { pa_protocol_simple *p = userdata; int do_some_work = 0; - + pa_assert(pa_asyncmsgq_get_fd(p->asyncmsgq) == fd); pa_assert(events == PA_IO_EVENT_INPUT); @@ -520,7 +520,7 @@ static void asyncmsgq_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_even connection *c = object; pa_assert(c); - + switch (code) { case MESSAGE_REQUEST_DATA: @@ -535,7 +535,7 @@ static void asyncmsgq_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_even pa_asyncmsgq_done(p->asyncmsgq); } - + if (pa_asyncmsgq_before_poll(p->asyncmsgq) == 0) break; } @@ -544,7 +544,7 @@ static void asyncmsgq_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_even pa_protocol_simple* pa_protocol_simple_new(pa_core *core, pa_socket_server *server, pa_module *m, pa_modargs *ma) { pa_protocol_simple* p = NULL; int enable; - + pa_assert(core); pa_assert(server); pa_assert(ma); @@ -588,13 +588,13 @@ pa_protocol_simple* pa_protocol_simple_new(pa_core *core, pa_socket_server *serv pa_assert_se(pa_asyncmsgq_before_poll(p->asyncmsgq) == 0); pa_assert_se(p->asyncmsgq_event = core->mainloop->io_event_new(core->mainloop, pa_asyncmsgq_get_fd(p->asyncmsgq), PA_IO_EVENT_INPUT, p)); - + return p; fail: if (p) pa_protocol_simple_free(p); - + return NULL; } @@ -618,7 +618,7 @@ void pa_protocol_simple_free(pa_protocol_simple *p) { pa_asyncmsgq_after_poll(c->asyncmsgq); pa_asyncmsgq_free(p->asyncmsgq); } - + pa_xfree(p); } diff --git a/src/pulsecore/semaphore-posix.c b/src/pulsecore/semaphore-posix.c index 71ec57a2..750c2afc 100644 --- a/src/pulsecore/semaphore-posix.c +++ b/src/pulsecore/semaphore-posix.c @@ -60,7 +60,7 @@ void pa_semaphore_post(pa_semaphore *s) { void pa_semaphore_wait(pa_semaphore *s) { int ret; pa_assert(s); - + do { ret = sem_wait(&s->sem); } while (ret < 0 && errno == EINTR); diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index da7b58b7..00b82d26 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -52,7 +52,7 @@ pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data memset(data, 0, sizeof(*data)); data->resample_method = PA_RESAMPLER_INVALID; - + return data; } @@ -117,7 +117,7 @@ pa_sink_input* pa_sink_input_new( if (!data->channel_map_is_set) { if (data->sink->channel_map.channels == data->sample_spec.channels) data->channel_map = data->sink->channel_map; - else + else pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT); } @@ -132,7 +132,7 @@ pa_sink_input* pa_sink_input_new( if (!data->muted_is_set) data->muted = 0; - + if (data->resample_method == PA_RESAMPLER_INVALID) data->resample_method = core->resample_method; @@ -163,7 +163,7 @@ pa_sink_input* pa_sink_input_new( i->parent.parent.free = sink_input_free; i->parent.process_msg = pa_sink_input_process_msg; - + i->core = core; pa_atomic_load(&i->state, PA_SINK_INPUT_DRAINED); i->flags = flags; @@ -172,14 +172,14 @@ pa_sink_input* pa_sink_input_new( i->module = data->module; i->sink = data->sink; i->client = data->client; - + i->resample_method = data->resample_method; i->sample_spec = data->sample_spec; i->channel_map = data->channel_map; i->volume = data->volume; i->muted = data->muted; - + i->process_msg = NULL; i->peek = NULL; i->drop = NULL; @@ -214,7 +214,7 @@ void pa_sink_input_disconnect(pa_sink_input *i) { pa_return_if_fail(pa_sink_input_get_state(i) != PA_SINK_INPUT_DISCONNECTED); pa_asyncmsgq_send(i->sink->asyncmsgq, i->sink, PA_SINK_MESSAGE_REMOVE_INPUT, i, NULL); - + pa_idxset_remove_by_data(i->sink->core->sink_inputs, i, NULL); pa_idxset_remove_by_data(i->sink->inputs, i, NULL); @@ -236,7 +236,7 @@ static void sink_input_free(pa_msgobject *o) { pa_assert(i); pa_assert(pa_sink_input_refcnt(i) == 0); - + pa_sink_input_disconnect(i); pa_log_info("Freeing output %u \"%s\"", i->index, i->name); @@ -281,7 +281,7 @@ pa_usec_t pa_sink_input_get_latency(pa_sink_input *i) { if (pa_asyncmsgq_send(i->sink->asyncmsgq, i->sink, PA_SINK_INPUT_MESSAGE_GET_LATENCY, &r, NULL) < 0) r = 0; - + if (i->get_latency) r += i->get_latency(i); @@ -293,7 +293,7 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) int do_volume_adj_here; int volume_is_norm; pa_sink_input_state_t state; - + pa_sink_input_assert_ref(i); pa_assert(chunk); pa_assert(volume); @@ -508,7 +508,7 @@ int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) { i->sample_spec.rate = rate; pa_asyncmsgq_post(s->asyncmsgq, pa_sink_input_ref(i), PA_SINK_INPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), NULL, pa_sink_input_unref, NULL); - + pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); return 0 } @@ -543,7 +543,7 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { pa_sink_assert_ref(dest); return -1; - + /* origin = i->sink; */ /* if (dest == origin) */ @@ -697,32 +697,32 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk) { pa_sink_input *i = PA_SINK_INPUT(o); - + pa_sink_input_assert_ref(i); switch (code) { case PA_SINK_INPUT_MESSAGE_SET_VOLUME: s->thread_info.soft_volume = *((pa_cvolume*) userdata); return 0; - + case PA_SINK_INPUT_MESSAGE_SET_MUTE: s->thread_info.soft_muted = PA_PTR_TO_UINT(userdata); return 0; - + case PA_SINK_INPUT_MESSAGE_GET_LATENCY: { pa_usec_t *r = userdata; - + if (i->thread_info.resampled_chunk.memblock) *r += pa_bytes_to_usec(i->resampled_chunk.length, &i->sink->sample_spec); /* if (i->move_silence) */ /* r += pa_bytes_to_usec(i->move_silence, &i->sink->sample_spec); */ - + return 0; } - + case PA_SINK_INPUT_MESSAGE_SET_RATE: { - + i->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata); pa_resampler_set_input_rate(i->resampler, PA_PTR_TO_UINT(userdata)); diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index 64a7a73f..338d6962 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -52,7 +52,7 @@ typedef enum pa_sink_input_flags { struct pa_sink_input { pa_msgobject parent; - + uint32_t index; pa_core *core; pa_atomic_t state; @@ -66,11 +66,11 @@ struct pa_sink_input { pa_sample_spec sample_spec; pa_channel_map channel_map; - + pa_cvolume volume; int muted; - int (*process_msg)(pa_sink_input *i, int code, void *userdata); + int (*process_msg)(pa_sink_input *i, int code, void *userdata); int (*peek) (pa_sink_input *i, pa_memchunk *chunk); void (*drop) (pa_sink_input *i, const pa_memchunk *chunk, size_t length); void (*kill) (pa_sink_input *i); /* may be NULL */ @@ -81,10 +81,10 @@ struct pa_sink_input { struct { pa_sample_spec sample_spec; - + pa_memchunk resampled_chunk; pa_resampler *resampler; /* may be NULL */ - + /* Some silence to play before the actual data. This is used to * compensate for latency differences when moving a sink input * "hot" between sinks. */ @@ -94,7 +94,7 @@ struct pa_sink_input { pa_cvolume volume; int muted; } thread_info; - + void *userdata; }; diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 36205597..0e022d92 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -86,7 +86,7 @@ pa_sink* pa_sink_new( s->parent.parent.free = sink_free; s->parent.process_msg = pa_sink_process_msg; - + s->core = core; pa_atomic_store(&s->state, PA_SINK_IDLE); s->name = pa_xstrdup(name); @@ -115,7 +115,7 @@ pa_sink* pa_sink_new( s->userdata = NULL; pa_assert_se(s->asyncmsgq = pa_asyncmsgq_new(0)); - + r = pa_idxset_put(core->sinks, s, &s->index); pa_assert(s->index != PA_IDXSET_INVALID && r >= 0); @@ -139,7 +139,7 @@ pa_sink* pa_sink_new( s->thread_info.inputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); s->thread_info.soft_volume = s->volume; s->thread_info.soft_muted = s->muted; - + pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index); return s; @@ -163,7 +163,7 @@ static void sink_start(pa_sink *s) { static void sink_stop(pa_sink *s) { pa_sink_state_t state; int stop; - + pa_assert(s); state = pa_sink_get_state(s); pa_return_if_fail(state == PA_SINK_RUNNING || state == PA_SINK_SUSPENDED); @@ -216,7 +216,7 @@ void pa_sink_disconnect(pa_sink* s) { static void sink_free(pa_object *o) { pa_sink *s = PA_SINK(o); - + pa_assert(s); pa_assert(pa_sink_refcnt(s) == 0); @@ -230,11 +230,11 @@ static void sink_free(pa_object *o) { } pa_idxset_free(s->inputs, NULL, NULL); - + pa_hashmap_free(s->thread_info.inputs, (pa_free2_cb_t) pa_sink_input_unref, NULL); pa_asyncmsgq_free(s->asyncmsgq); - + pa_xfree(s->name); pa_xfree(s->description); pa_xfree(s->driver); @@ -246,7 +246,7 @@ void pa_sink_update_status(pa_sink*s) { if (pa_sink_get_state(s) == PA_SINK_SUSPENDED) return; - + if (pa_sink_used_by(s) > 0) sink_start(s); else @@ -270,7 +270,7 @@ void pa_sink_suspend(pa_sink *s, int suspend) { s->stop(s); else pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_STOP, NULL, NULL, NULL); - + } else { pa_atomic_store(&s->state, PA_SINK_RUNNING); @@ -417,38 +417,38 @@ int pa_sink_render_into(pa_sink*s, pa_memchunk *target) { else { void *src, *ptr; pa_cvolume volume; - + ptr = pa_memblock_acquire(target->memblock); src = pa_memblock_acquire(info[0].chunk.memblock); - + memcpy((uint8_t*) ptr + target->index, (uint8_t*) src + info[0].chunk.index, target->length); - + pa_memblock_release(target->memblock); pa_memblock_release(info[0].chunk.memblock); - + pa_sw_cvolume_multiply(&volume, &s->thread_info.soft_volume, &info[0].volume); if (!pa_cvolume_is_norm(&volume)) pa_volume_memchunk(target, &s->sample_spec, &volume); } - + } else { void *ptr; ptr = pa_memblock_acquire(target->memblock); - + target->length = pa_mix(info, n, (uint8_t*) ptr + target->index, target->length, &s->sample_spec, &s->thread_info.soft_volume, s->thread_info.soft_muted); - + pa_memblock_release(target->memblock); } - + inputs_drop(s, info, n, target->length); if (s->monitor_source) @@ -512,12 +512,12 @@ void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) { pa_usec_t pa_sink_get_latency(pa_sink *s) { pa_usec_t usec = 0; - + pa_sink_assert_ref(s); if (s->get_latency) return s->get_latency(s); - + if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY, &usec, NULL) < 0) return 0; @@ -532,7 +532,7 @@ void pa_sink_set_volume(pa_sink *s, const pa_cvolume *volume) { changed = !pa_cvolume_equal(volume, &s->volume); s->volume = *volume; - + if (s->set_volume && s->set_volume(s) < 0) s->set_volume = NULL; @@ -549,7 +549,7 @@ const pa_cvolume *pa_sink_get_volume(pa_sink *s) { pa_sink_assert_ref(s); old_volume = s->volume; - + if (s->get_volume && s->get_volume(s) < 0) s->get_volume = NULL; @@ -558,13 +558,13 @@ const pa_cvolume *pa_sink_get_volume(pa_sink *s) { if (!pa_cvolume_equal(&old_volume, &s->volume)) pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); - + return &s->volume; } void pa_sink_set_mute(pa_sink *s, int mute) { int changed; - + pa_sink_assert_ref(s); changed = s->muted != mute; @@ -581,11 +581,11 @@ void pa_sink_set_mute(pa_sink *s, int mute) { int pa_sink_get_mute(pa_sink *s) { int old_muted; - + pa_sink_assert_ref(s); old_muted = s->muted; - + if (s->get_mute && s->get_mute(s) < 0) s->get_mute = NULL; @@ -594,7 +594,7 @@ int pa_sink_get_mute(pa_sink *s) { if (old_muted != s->muted) pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); - + return s->muted; } @@ -658,29 +658,29 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk * pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), pa_sink_input_ref(i)); return 0; } - + case PA_SINK_MESSAGE_REMOVE_INPUT: { pa_sink_input *i = userdata; pa_hashmap_remove(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index)); return 0; } - + case PA_SINK_MESSAGE_SET_VOLUME: s->thread_info.soft_volume = *((pa_cvolume*) userdata); return 0; - + case PA_SINK_MESSAGE_SET_MUTE: s->thread_info.soft_muted = PA_PTR_TO_UINT(userdata); return 0; - + case PA_SINK_MESSAGE_GET_VOLUME: *((pa_cvolume*) userdata) = s->thread_info.soft_volume; return 0; - + case PA_SINK_MESSAGE_GET_MUTE: *((int*) userdata) = s->thread_info.soft_muted; return 0; - + default: return -1; } diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index c1aa3393..517c033d 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -113,7 +113,7 @@ pa_source_output* pa_source_output_new( if ((flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) || !pa_sample_spec_equal(&data->sample_spec, &data->source->sample_spec) || !pa_channel_map_equal(&data->channel_map, &data->source->channel_map)) { - + if (!(resampler = pa_resampler_new( core->mempool, &data->source->sample_spec, &data->source->channel_map, @@ -127,10 +127,10 @@ pa_source_output* pa_source_output_new( } o = pa_source_output_new(pa_source_output); - + o->parent.parent.free = source_output_free; o->parent.process_msg = pa_source_output_process_msg; - + o->core = core; pa_atomic_load(&o->state, PA_SOURCE_OUTPUT_RUNNING); o->flags = flags; @@ -173,7 +173,7 @@ void pa_source_output_disconnect(pa_source_output*o) { pa_assert(o->source->core); pa_asyncmsgq_send(i->sink->asyncmsgq, i->sink, PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, NULL); - + pa_idxset_remove_by_data(o->source->core->source_outputs, o, NULL); pa_idxset_remove_by_data(o->source->outputs, o, NULL); @@ -190,7 +190,7 @@ void pa_source_output_disconnect(pa_source_output*o) { static void source_output_free(pa_msgobject* mo) { pa_source_output *o = PA_SOURCE_OUTPUT(mo); - + pa_assert(pa_source_output_refcnt(o) == 0); pa_source_output_disconnect(o); @@ -207,7 +207,7 @@ static void source_output_free(pa_msgobject* mo) { void pa_source_output_put(pa_source_output *o) { pa_source_output_assert_ref(o); - + pa_asyncmsgq_post(o->source->asyncmsgq, o->source, PA_SOURCE_MESSAGE_ADD_OUTPUT, o, NULL, pa_source_unref, pa_source_output_unref); pa_source_update_status(o->source); @@ -228,7 +228,7 @@ pa_usec_t pa_source_output_get_latency(pa_source_output *o) { if (pa_asyncmsgq_send(o->source->asyncmsgq, i->source, PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY, &r, NULL) < 0) r = 0; - + if (o->get_latency) r += o->get_latency(o); @@ -244,12 +244,12 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) { pa_assert(chunk->length); state = pa_source_output_get_state(o); - + if (!o->push || state == PA_SOURCE_OUTPUT_DISCONNECTED || state == PA_SOURCE_OUTPUT_CORKED) return; pa_assert(state = PA_SOURCE_OUTPUT_RUNNING); - + if (!o->resampler) { o->push(o, chunk); return; @@ -289,7 +289,7 @@ int pa_source_output_set_rate(pa_source_output *o, uint32_t rate) { i->sample_spec.rate = rate; pa_asyncmsgq_post(s->asyncmsgq, pa_source_output_ref(i), PA_SOURCE_OUTPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), NULL, pa_source_output_unref, NULL); - + pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT!|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); return 0; } @@ -312,7 +312,7 @@ void pa_source_output_set_name(pa_source_output *o, const char *name) { pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o) { pa_source_output_assert_ref(o); - return o->resample_method; + return o->resample_method; } int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { @@ -323,7 +323,7 @@ int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { pa_source_assert_ref(dest); return -1; - + /* origin = o->source; */ /* if (dest == origin) */ @@ -377,13 +377,13 @@ int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, pa_memchunk* chunk) { pa_source_output *o = PA_SOURCE_OUTPUT(o); - + pa_source_output_assert_ref(i); switch (code) { case PA_SOURCE_OUTPUT_MESSAGE_SET_RATE: { - + i->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata); pa_resampler_set_output_rate(i->resampler, PA_PTR_TO_UINT(userdata)); diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h index 0f9c3bae..e7c2c131 100644 --- a/src/pulsecore/source-output.h +++ b/src/pulsecore/source-output.h @@ -48,7 +48,7 @@ typedef enum pa_source_output_flags { struct pa_source_output { pa_msgobject parent; - + uint32_t index; pa_core *core; pa_atomic_t state; @@ -72,10 +72,10 @@ struct pa_source_output { struct { pa_sample_spec sample_spec; - + pa_resampler* resampler; /* may be NULL */ } thread_info; - + void *userdata; }; diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index fd3c85d7..7d013387 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -78,7 +78,7 @@ pa_source* pa_source_new( s->parent.parent.free = source_free; s->parent.process_msg = pa_source_process_msg; - + s->core = core; pa_atomic_store(&s->state, PA_SOURCE_IDLE); s->name = pa_xstrdup(name); @@ -108,7 +108,7 @@ pa_source* pa_source_new( s->userdata = NULL; pa_assert_se(s->asyncmsgq = pa_asyncmsgq_new(0)); - + r = pa_idxset_put(core->sources, s, &s->index); assert(s->index != PA_IDXSET_INVALID && r >= 0); @@ -118,7 +118,7 @@ pa_source* pa_source_new( s->thread_info.outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); s->thread_info.soft_volume = s->volume; s->thread_info.soft_muted = s->muted; - + pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index); return s; @@ -142,7 +142,7 @@ static void source_start(pa_source *s) { static void source_stop(pa_source *s) { pa_source_state_t state; int stop; - + pa_assert(s); state = pa_source_get_state(s); pa_return_if_fail(state == PA_SOURCE_RUNNING || state == PA_SOURCE_SUSPENDED); @@ -165,7 +165,7 @@ void pa_source_disconnect(pa_source *s) { pa_return_if_fail(pa_sink_get_state(s) != PA_SINK_DISCONNECT); source_stop(s); - + pa_atomic_store(&s->state, PA_SOURCE_DISCONNECTED); pa_namereg_unregister(s->core, s->name); @@ -192,7 +192,7 @@ void pa_source_disconnect(pa_source *s) { static void source_free(pa_msgobject *o) { pa_source *s = PA_SOURCE(o); - + pa_assert(s); pa_assert(pa_source_refcnt(s) == 0); @@ -204,7 +204,7 @@ static void source_free(pa_msgobject *o) { pa_hashmap_free(s->thread_info.outputs, pa_sink_output_unref, NULL); pa_asyncmsgq_free(s->asyncmsgq); - + pa_xfree(s->name); pa_xfree(s->description); pa_xfree(s->driver); @@ -216,7 +216,7 @@ void pa_source_update_status(pa_source*s) { if (pa_source_get_state(s) == PA_SOURCE_STATE_SUSPENDED) return; - + if (pa_source_used_by(s) > 0) source_start(s); else @@ -240,7 +240,7 @@ void pa_source_suspend(pa_source *s, int suspend) { s->stop(s); else pa_asyncmsgq_post(s->asyncmsgq, s, PA_SOURCE_MESSAGE_STOP, NULL, NULL, pa_source_unref, NULL); - + } else { pa_atomic_store(&s->state, PA_SOURCE_RUNNING); @@ -254,7 +254,7 @@ void pa_source_suspend(pa_source *s, int suspend) { void pa_source_post(pa_source*s, const pa_memchunk *chunk) { pa_source_output *o; void *state = NULL; - + pa_source_assert_ref(s); pa_assert(chunk); @@ -263,7 +263,7 @@ void pa_source_post(pa_source*s, const pa_memchunk *chunk) { pa_memblock_ref(vchunk.memblock); pa_memchunk_make_writable(&vchunk, 0); - + if (s->thread_info.muted || pa_cvolume_is_muted(s->thread_info.volume)) pa_silence_memchunk(&vchunk, &s->sample_spec); else @@ -271,10 +271,10 @@ void pa_source_post(pa_source*s, const pa_memchunk *chunk) { while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) pa_source_output_push(o, &vchunk); - + pa_memblock_unref(vchunk.memblock); } else { - + while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) pa_source_output_push(o, chunk); @@ -303,7 +303,7 @@ void pa_source_set_volume(pa_source *s, const pa_cvolume *volume) { changed = !pa_cvolume_equal(volume, s->volume); s->volume = *volume; - + if (s->set_volume && s->set_volume(s) < 0) s->set_volume = NULL; @@ -318,7 +318,7 @@ const pa_cvolume *pa_source_get_volume(pa_source *s) { pa_source_assert_ref(s); old_volume = s->volume; - + if (s->get_volume && s->get_volume(s) < 0) s->get_volume = NULL; @@ -327,13 +327,13 @@ const pa_cvolume *pa_source_get_volume(pa_source *s) { if (!pa_cvolume_equal(&old_volume, &s->volume)) pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); - + return &s->volume; } void pa_source_set_mute(pa_source *s, pa_mixer_t m, int mute) { int changed; - + pa_source_assert_ref(s); changed = s->muted != mute; @@ -350,11 +350,11 @@ void pa_source_set_mute(pa_source *s, pa_mixer_t m, int mute) { int pa_source_get_mute(pa_source *s, pa_mixer_t m) { int old_muted; - + pa_source_assert_ref(s); old_muted = s->muted; - + if (s->get_mute && s->get_mute(s) < 0) s->get_mute = NULL; @@ -363,7 +363,7 @@ int pa_source_get_mute(pa_source *s, pa_mixer_t m) { if (old_muted != s->muted) pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); - + return s->muted; } @@ -374,7 +374,7 @@ void pa_source_set_module(pa_source *s, pa_module *m) { return; s->module = m; - + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); } @@ -409,29 +409,29 @@ int pa_source_process_msg(pa_msgobject *o, void *object, int code, pa_memchunk * pa_hashmap_put(s->thread_info.outputs, PA_UINT32_TO_PTR(i->index), pa_source_output_ref(i)); return 0; } - + case PA_SOURCE_MESSAGE_REMOVE_INPUT: { pa_source_input *i = userdata; pa_hashmap_remove(s->thread_info.outputs, PA_UINT32_TO_PTR(i->index), pa_source_output_ref(i)); return 0; } - + case PA_SOURCE_MESSAGE_SET_VOLUME: s->thread_info.soft_volume = *((pa_cvolume*) userdata); return 0; - + case PA_SOURCE_MESSAGE_SET_MUTE: s->thread_info.soft_muted = PA_PTR_TO_UINT(userdata); return 0; - + case PA_SOURCE_MESSAGE_GET_VOLUME: *((pa_cvolume*) userdata) = s->thread_info.soft_volume; return 0; - + case PA_SOURCE_MESSAGE_GET_MUTE: *((int*) userdata) = s->thread_info.soft_muted; return 0; - + default: return -1; } diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index 1e20c6e1..b41b1bc3 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -54,7 +54,7 @@ typedef enum pa_source_state { struct pa_source { pa_msgobject parent; - + uint32_t index; pa_core *core; pa_atomic_t state; @@ -91,7 +91,7 @@ struct pa_source { pa_cvolume soft_volume; int soft_muted; } thread_info; - + void *userdata; }; diff --git a/src/tests/asyncmsgq-test.c b/src/tests/asyncmsgq-test.c index 8a0f5a3f..d10b512d 100644 --- a/src/tests/asyncmsgq-test.c +++ b/src/tests/asyncmsgq-test.c @@ -48,11 +48,11 @@ static void the_thread(void *_q) { do { int code = 0; - + pa_assert_se(pa_asyncmsgq_get(q, NULL, &code, NULL, 1) == 0); switch (code) { - + case OPERATION_A: printf("Operation A\n"); break; @@ -64,7 +64,7 @@ static void the_thread(void *_q) { case OPERATION_C: printf("Operation C\n"); break; - + case QUIT: printf("quit\n"); quit = 1; @@ -79,7 +79,7 @@ static void the_thread(void *_q) { int main(int argc, char *argv[]) { pa_asyncmsgq *q; pa_thread *t; - + pa_assert_se(q = pa_asyncmsgq_new(0)); pa_assert_se(t = pa_thread_new(the_thread, q)); diff --git a/src/tests/asyncq-test.c b/src/tests/asyncq-test.c index 10566db1..600d9d07 100644 --- a/src/tests/asyncq-test.c +++ b/src/tests/asyncq-test.c @@ -38,7 +38,7 @@ static void producer(void *_q) { pa_asyncq *q = _q; int i; - + for (i = 0; i < 1000; i++) { pa_asyncq_push(q, (void*) (i+1), 1); printf("pushed %i\n", i); @@ -54,7 +54,7 @@ static void consumer(void *_q) { int i; sleep(1); - + for (i = 0;; i++) { p = pa_asyncq_pop(q, 1); @@ -62,7 +62,7 @@ static void consumer(void *_q) { break; pa_assert(p == (void *) (i+1)); - + printf("popped %i\n", i); } @@ -72,7 +72,7 @@ static void consumer(void *_q) { int main(int argc, char *argv[]) { pa_asyncq *q; pa_thread *t1, *t2; - + pa_assert_se(q = pa_asyncq_new(0)); pa_assert_se(t1 = pa_thread_new(producer, q)); -- cgit From 590ae20d4de57d94ff276b62a0c726ec7b2f8154 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 11 Jun 2007 13:53:16 +0000 Subject: Add new untabify makefile target git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1471 fefdeb5f-60dc-0310-8127-8f9354f1896f --- Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile.am b/Makefile.am index abc3d776..0fd4ccc0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -48,4 +48,7 @@ doxygen: eolspace: find \( -name '*.c' -o -name '*.h' -o -name 'Makefile.am' \) -exec perl -i -pe 's/\s+\n$$/\1\n/;' \{\} \; +untabify: + find \( -name '*.c' -o -name '*.h' \) -exec perl -i -pe 's/\t/ /g;' \{\} \; + .PHONY: homepage distcleancheck doxygen -- cgit From 69115687ad1604ddfa9fa7cd86eb286e6bb5ea9a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 11 Jun 2007 13:53:31 +0000 Subject: make untabify git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1472 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/main.c | 2 +- src/modules/alsa-util.c | 2 +- src/modules/module-detect.c | 6 +- src/modules/oss-util.c | 4 +- src/pulse/utf8.c | 2 +- src/pulsecore/g711.c | 392 +++++++++++++++++++++--------------------- src/pulsecore/pipe.c | 16 +- src/pulsecore/shm.c | 32 ++-- src/pulsecore/socket-client.c | 6 +- src/pulsecore/socket-util.c | 2 +- src/utils/padsp.c | 20 +-- 11 files changed, 242 insertions(+), 242 deletions(-) diff --git a/src/daemon/main.c b/src/daemon/main.c index 91cc3a2f..2424efa7 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -568,7 +568,7 @@ int main(int argc, char *argv[]) { assert(mainloop); if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm))) { - pa_log("pa_core_new() failed."); + pa_log("pa_core_new() failed."); goto finish; } diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c index 40be5311..0a518025 100644 --- a/src/modules/alsa-util.c +++ b/src/modules/alsa-util.c @@ -326,7 +326,7 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *p if ((ret = snd_pcm_hw_params_malloc(&hwparams)) < 0 || (ret = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0 || (ret = snd_pcm_hw_params_set_rate_resample(pcm_handle, hwparams, 0)) < 0 || - (ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) + (ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) goto finish; if ((ret = set_format(pcm_handle, hwparams, &f)) < 0) diff --git a/src/modules/module-detect.c b/src/modules/module-detect.c index 41b68ac3..29d6fc27 100644 --- a/src/modules/module-detect.c +++ b/src/modules/module-detect.c @@ -139,7 +139,7 @@ static int detect_oss(pa_core *c, int just_one) { line[strcspn(line, "\r\n")] = 0; if (!b) { - b = strcmp(line, "Audio devices:") == 0 || strcmp(line, "Installed devices:") == 0; + b = strcmp(line, "Audio devices:") == 0 || strcmp(line, "Installed devices:") == 0; continue; } @@ -155,13 +155,13 @@ static int detect_oss(pa_core *c, int just_one) { if (!pa_module_load(c, "module-oss", args)) continue; - } else if (sscanf(line, "pcm%u: ", &device) == 1) { + } else if (sscanf(line, "pcm%u: ", &device) == 1) { /* FreeBSD support, the devices are named /dev/dsp0.0, dsp0.1 and so on */ snprintf(args, sizeof(args), "device=/dev/dsp%u.0", device); if (!pa_module_load(c, "module-oss", args)) continue; - } + } n++; diff --git a/src/modules/oss-util.c b/src/modules/oss-util.c index fb531468..4be71e2c 100644 --- a/src/modules/oss-util.c +++ b/src/modules/oss-util.c @@ -99,7 +99,7 @@ success: #ifdef DSP_CAP_BIND *pcaps & DSP_CAP_BIND ? " BIND" : "", #else - "", + "", #endif *pcaps & DSP_CAP_COPROC ? " COPROC" : "", *pcaps & DSP_CAP_DUPLEX ? " DUPLEX" : "", @@ -122,7 +122,7 @@ success: #ifdef DSP_CAP_MULTI *pcaps & DSP_CAP_MULTI ? " MULTI" : "", #else - "", + "", #endif #ifdef DSP_CAP_OUTPUT *pcaps & DSP_CAP_OUTPUT ? " OUTPUT" : "", diff --git a/src/pulse/utf8.c b/src/pulse/utf8.c index 2ac2d106..923e021d 100644 --- a/src/pulse/utf8.c +++ b/src/pulse/utf8.c @@ -37,7 +37,7 @@ * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public diff --git a/src/pulsecore/g711.c b/src/pulsecore/g711.c index 8c2bbf00..aa2d703a 100644 --- a/src/pulsecore/g711.c +++ b/src/pulsecore/g711.c @@ -43,30 +43,30 @@ #include "g711.h" -#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ -#define QUANT_MASK (0xf) /* Quantization field mask. */ -#define NSEGS (8) /* Number of A-law segments. */ -#define SEG_SHIFT (4) /* Left shift for segment number. */ -#define SEG_MASK (0x70) /* Segment field mask. */ +#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ +#define QUANT_MASK (0xf) /* Quantization field mask. */ +#define NSEGS (8) /* Number of A-law segments. */ +#define SEG_SHIFT (4) /* Left shift for segment number. */ +#define SEG_MASK (0x70) /* Segment field mask. */ #if !defined(FAST_ALAW_CONVERSION) || !defined(FAST_ULAW_CONVERSION) static int16_t seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF, - 0x1FF, 0x3FF, 0x7FF, 0xFFF}; + 0x1FF, 0x3FF, 0x7FF, 0xFFF}; static int16_t seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF, - 0x3FF, 0x7FF, 0xFFF, 0x1FFF}; + 0x3FF, 0x7FF, 0xFFF, 0x1FFF}; static int16_t search( - int16_t val, - int16_t *table, - int size) + int16_t val, + int16_t *table, + int size) { - int i; + int i; - for (i = 0; i < size; i++) { - if (val <= *table++) - return (i); - } - return (size); + for (i = 0; i < size; i++) { + if (val <= *table++) + return (i); + } + return (size); } #endif /* !FAST_*_CONVERSION */ @@ -77,55 +77,55 @@ static int16_t search( * the data shifted such that it only contains information in the lower * 13-bits. * - * Linear Input Code Compressed Code - * ------------------------ --------------- - * 0000000wxyza 000wxyz - * 0000001wxyza 001wxyz - * 000001wxyzab 010wxyz - * 00001wxyzabc 011wxyz - * 0001wxyzabcd 100wxyz - * 001wxyzabcde 101wxyz - * 01wxyzabcdef 110wxyz - * 1wxyzabcdefg 111wxyz + * Linear Input Code Compressed Code + * ------------------------ --------------- + * 0000000wxyza 000wxyz + * 0000001wxyza 001wxyz + * 000001wxyzab 010wxyz + * 00001wxyzabc 011wxyz + * 0001wxyzabcd 100wxyz + * 001wxyzabcde 101wxyz + * 01wxyzabcdef 110wxyz + * 1wxyzabcdefg 111wxyz * * For further information see John C. Bellamy's Digital Telephony, 1982, * John Wiley & Sons, pps 98-111 and 472-476. */ unsigned char st_13linear2alaw( - int16_t pcm_val) /* 2's complement (13-bit range) */ + int16_t pcm_val) /* 2's complement (13-bit range) */ { - int16_t mask; - short seg; - unsigned char aval; + int16_t mask; + short seg; + unsigned char aval; - /* Have calling software do it since its already doing a shift - * from 32-bits down to 16-bits. - */ - /* pcm_val = pcm_val >> 3; */ + /* Have calling software do it since its already doing a shift + * from 32-bits down to 16-bits. + */ + /* pcm_val = pcm_val >> 3; */ - /* A-law using even bit inversion */ - if (pcm_val >= 0) { - mask = 0xD5; /* sign (7th) bit = 1 */ - } else { - mask = 0x55; /* sign bit = 0 */ - pcm_val = -pcm_val - 1; - } + /* A-law using even bit inversion */ + if (pcm_val >= 0) { + mask = 0xD5; /* sign (7th) bit = 1 */ + } else { + mask = 0x55; /* sign bit = 0 */ + pcm_val = -pcm_val - 1; + } - /* Convert the scaled magnitude to segment number. */ - seg = search(pcm_val, seg_aend, 8); + /* Convert the scaled magnitude to segment number. */ + seg = search(pcm_val, seg_aend, 8); - /* Combine the sign, segment, and quantization bits. */ + /* Combine the sign, segment, and quantization bits. */ - if (seg >= 8) /* out of range, return maximum value. */ - return (unsigned char) (0x7F ^ mask); - else { - aval = (unsigned char) seg << SEG_SHIFT; - if (seg < 2) - aval |= (pcm_val >> 1) & QUANT_MASK; - else - aval |= (pcm_val >> seg) & QUANT_MASK; - return (aval ^ mask); - } + if (seg >= 8) /* out of range, return maximum value. */ + return (unsigned char) (0x7F ^ mask); + else { + aval = (unsigned char) seg << SEG_SHIFT; + if (seg < 2) + aval |= (pcm_val >> 1) & QUANT_MASK; + else + aval |= (pcm_val >> seg) & QUANT_MASK; + return (aval ^ mask); + } } /* @@ -133,31 +133,31 @@ unsigned char st_13linear2alaw( * */ int16_t st_alaw2linear16( - unsigned char a_val) + unsigned char a_val) { - int16_t t; - int16_t seg; + int16_t t; + int16_t seg; - a_val ^= 0x55; + a_val ^= 0x55; - t = (a_val & QUANT_MASK) << 4; - seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT; - switch (seg) { - case 0: - t += 8; - break; - case 1: - t += 0x108; - break; - default: - t += 0x108; - t <<= seg - 1; - } - return ((a_val & SIGN_BIT) ? t : -t); + t = (a_val & QUANT_MASK) << 4; + seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT; + switch (seg) { + case 0: + t += 8; + break; + case 1: + t += 0x108; + break; + default: + t += 0x108; + t <<= seg - 1; + } + return ((a_val & SIGN_BIT) ? t : -t); } #endif /* !FAST_ALAW_CONVERSION */ -#define BIAS (0x84) /* Bias for linear code. */ +#define BIAS (0x84) /* Bias for linear code. */ #define CLIP 8159 #ifndef FAST_ULAW_CONVERSION @@ -171,16 +171,16 @@ int16_t st_alaw2linear16( * is biased by adding 33 which shifts the encoding range from (0 - 8158) to * (33 - 8191). The result can be seen in the following encoding table: * - * Biased Linear Input Code Compressed Code - * ------------------------ --------------- - * 00000001wxyza 000wxyz - * 0000001wxyzab 001wxyz - * 000001wxyzabc 010wxyz - * 00001wxyzabcd 011wxyz - * 0001wxyzabcde 100wxyz - * 001wxyzabcdef 101wxyz - * 01wxyzabcdefg 110wxyz - * 1wxyzabcdefgh 111wxyz + * Biased Linear Input Code Compressed Code + * ------------------------ --------------- + * 00000001wxyza 000wxyz + * 0000001wxyzab 001wxyz + * 000001wxyzabc 010wxyz + * 00001wxyzabcd 011wxyz + * 0001wxyzabcde 100wxyz + * 001wxyzabcdef 101wxyz + * 01wxyzabcdefg 110wxyz + * 1wxyzabcdefgh 111wxyz * * Each biased linear code has a leading 1 which identifies the segment * number. The value of the segment number is equal to 7 minus the number @@ -194,41 +194,41 @@ int16_t st_alaw2linear16( * John Wiley & Sons, pps 98-111 and 472-476. */ unsigned char st_14linear2ulaw( - int16_t pcm_val) /* 2's complement (14-bit range) */ + int16_t pcm_val) /* 2's complement (14-bit range) */ { - int16_t mask; - int16_t seg; - unsigned char uval; + int16_t mask; + int16_t seg; + unsigned char uval; - /* Have calling software do it since its already doing a shift - * from 32-bits down to 16-bits. - */ - /* pcm_val = pcm_val >> 2; */ + /* Have calling software do it since its already doing a shift + * from 32-bits down to 16-bits. + */ + /* pcm_val = pcm_val >> 2; */ - /* u-law inverts all bits */ - /* Get the sign and the magnitude of the value. */ - if (pcm_val < 0) { - pcm_val = -pcm_val; - mask = 0x7F; - } else { - mask = 0xFF; - } - if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */ - pcm_val += (BIAS >> 2); + /* u-law inverts all bits */ + /* Get the sign and the magnitude of the value. */ + if (pcm_val < 0) { + pcm_val = -pcm_val; + mask = 0x7F; + } else { + mask = 0xFF; + } + if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */ + pcm_val += (BIAS >> 2); - /* Convert the scaled magnitude to segment number. */ - seg = search(pcm_val, seg_uend, 8); + /* Convert the scaled magnitude to segment number. */ + seg = search(pcm_val, seg_uend, 8); - /* - * Combine the sign, segment, quantization bits; - * and complement the code word. - */ - if (seg >= 8) /* out of range, return maximum value. */ - return (unsigned char) (0x7F ^ mask); - else { - uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF); - return (uval ^ mask); - } + /* + * Combine the sign, segment, quantization bits; + * and complement the code word. + */ + if (seg >= 8) /* out of range, return maximum value. */ + return (unsigned char) (0x7F ^ mask); + else { + uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF); + return (uval ^ mask); + } } @@ -242,21 +242,21 @@ unsigned char st_14linear2ulaw( * original code word. This is in keeping with ISDN conventions. */ int16_t st_ulaw2linear16( - unsigned char u_val) + unsigned char u_val) { - int16_t t; + int16_t t; - /* Complement to obtain normal u-law value. */ - u_val = ~u_val; + /* Complement to obtain normal u-law value. */ + u_val = ~u_val; - /* - * Extract and bias the quantization bits. Then - * shift up by the segment number and subtract out the bias. - */ - t = ((u_val & QUANT_MASK) << 3) + BIAS; - t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; + /* + * Extract and bias the quantization bits. Then + * shift up by the segment number and subtract out the bias. + */ + t = ((u_val & QUANT_MASK) << 3) + BIAS; + t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; - return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS)); + return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS)); } #endif /* !FAST_ULAW_CONVERSION */ @@ -2413,52 +2413,52 @@ int main() printf("int16_t _st_alaw2linear16[256] = {\n "); for (x = 0; x < 256; x++) { - printf("%8d,", st_alaw2linear16(x)); - y++; - if (y == 7) - { - y = 0; - printf("\n "); - } + printf("%8d,", st_alaw2linear16(x)); + y++; + if (y == 7) + { + y = 0; + printf("\n "); + } } printf("\n};\n\nuint8_t _st_13linear2alaw[0x2000] = {\n "); y = 0; for (x = 0; x < 0x2000; x++) { - printf(" 0x%02x,", st_13linear2alaw((-0x1000)+x)); - y++; - if (y == 12) - { - y = 0; - printf("\n "); - } + printf(" 0x%02x,", st_13linear2alaw((-0x1000)+x)); + y++; + if (y == 12) + { + y = 0; + printf("\n "); + } } printf("\n};\n\nint16_t _st_ulaw2linear16[256] = {\n "); y = 0; for (x = 0; x < 256; x++) { - printf("%8d,", st_ulaw2linear16(x)); - y++; - if (y == 7) - { - y = 0; - printf("\n "); - } + printf("%8d,", st_ulaw2linear16(x)); + y++; + if (y == 7) + { + y = 0; + printf("\n "); + } } printf("\n};\n\nuint8_t _st_14linear2ulaw[0x4000] = {\n "); y = 0; for (x = 0; x < 0x4000; x++) { - printf(" 0x%02x,", st_14linear2ulaw((-0x2000)+x)); - y++; - if (y == 12) - { - y = 0; - printf("\n "); - } + printf(" 0x%02x,", st_14linear2ulaw((-0x2000)+x)); + y++; + if (y == 12) + { + y = 0; + printf("\n "); + } } printf("\n};\n"); @@ -2468,64 +2468,64 @@ int main() /* The following is not used by SoX but kept for reference */ #if 0 /* copy from CCITT G.711 specifications */ -unsigned char _u2a[128] = { /* u- to A-law conversions */ - 1, 1, 2, 2, 3, 3, 4, 4, - 5, 5, 6, 6, 7, 7, 8, 8, - 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, - 25, 27, 29, 31, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, - 46, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, - 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, +unsigned char _u2a[128] = { /* u- to A-law conversions */ + 1, 1, 2, 2, 3, 3, 4, 4, + 5, 5, 6, 6, 7, 7, 8, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 27, 29, 31, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, + 46, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, /* corrected: - 81, 82, 83, 84, 85, 86, 87, 88, + 81, 82, 83, 84, 85, 86, 87, 88, should be: */ - 80, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 126, 127, 128}; + 80, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128}; -unsigned char _a2u[128] = { /* A- to u-law conversions */ - 1, 3, 5, 7, 9, 11, 13, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 32, 33, 33, 34, 34, 35, 35, - 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 48, 49, 49, - 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 64, - 65, 66, 67, 68, 69, 70, 71, 72, +unsigned char _a2u[128] = { /* A- to u-law conversions */ + 1, 3, 5, 7, 9, 11, 13, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 32, 33, 33, 34, 34, 35, 35, + 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 48, 49, 49, + 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 64, + 65, 66, 67, 68, 69, 70, 71, 72, /* corrected: - 73, 74, 75, 76, 77, 78, 79, 79, + 73, 74, 75, 76, 77, 78, 79, 79, should be: */ - 73, 74, 75, 76, 77, 78, 79, 80, + 73, 74, 75, 76, 77, 78, 79, 80, - 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127}; + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127}; /* A-law to u-law conversion */ unsigned char st_alaw2ulaw( - unsigned char aval) + unsigned char aval) { - aval &= 0xff; - return (unsigned char) ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) : - (0x7F ^ _a2u[aval ^ 0x55])); + aval &= 0xff; + return (unsigned char) ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) : + (0x7F ^ _a2u[aval ^ 0x55])); } /* u-law to A-law conversion */ unsigned char st_ulaw2alaw( - unsigned char uval) + unsigned char uval) { - uval &= 0xff; - return (unsigned char) ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) : - (unsigned char) (0x55 ^ (_u2a[0x7F ^ uval] - 1))); + uval &= 0xff; + return (unsigned char) ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) : + (unsigned char) (0x55 ^ (_u2a[0x7F ^ uval] - 1))); } #endif diff --git a/src/pulsecore/pipe.c b/src/pulsecore/pipe.c index 7f6bb2e9..e614c9c6 100644 --- a/src/pulsecore/pipe.c +++ b/src/pulsecore/pipe.c @@ -149,14 +149,14 @@ int pipe(int filedes[2]) { return 0; error: - if (listener >= 0) - pa_close(listener); - if (filedes[0] >= 0) - pa_close(filedes[0]); - if (filedes[1] >= 0) - pa_close(filedes[0]); - - return -1; + if (listener >= 0) + pa_close(listener); + if (filedes[0] >= 0) + pa_close(filedes[0]); + if (filedes[1] >= 0) + pa_close(filedes[0]); + + return -1; } #endif /* HAVE_PIPE */ diff --git a/src/pulsecore/shm.c b/src/pulsecore/shm.c index 444d4010..8c7fb4db 100644 --- a/src/pulsecore/shm.c +++ b/src/pulsecore/shm.c @@ -113,7 +113,7 @@ int pa_shm_create_rw(pa_shm *m, size_t size, int shared, mode_t mode) { close(fd); m->do_unlink = 1; #else - return -1; + return -1; #endif } @@ -139,36 +139,36 @@ void pa_shm_free(pa_shm *m) { assert(m->size > 0); #ifdef MAP_FAILED - assert(m->ptr != MAP_FAILED); + assert(m->ptr != MAP_FAILED); #endif - if (!m->shared) { + if (!m->shared) { #ifdef MAP_ANONYMOUS - if (munmap(m->ptr, m->size) < 0) - pa_log("munmap() failed: %s", pa_cstrerror(errno)); + if (munmap(m->ptr, m->size) < 0) + pa_log("munmap() failed: %s", pa_cstrerror(errno)); #elif defined(HAVE_POSIX_MEMALIGN) free(m->ptr); #else pa_xfree(m->ptr); #endif - } else { + } else { #ifdef HAVE_SHM_OPEN - if (munmap(m->ptr, m->size) < 0) - pa_log("munmap() failed: %s", pa_cstrerror(errno)); + if (munmap(m->ptr, m->size) < 0) + pa_log("munmap() failed: %s", pa_cstrerror(errno)); - if (m->do_unlink) { - char fn[32]; + if (m->do_unlink) { + char fn[32]; segment_name(fn, sizeof(fn), m->id); if (shm_unlink(fn) < 0) pa_log(" shm_unlink(%s) failed: %s", fn, pa_cstrerror(errno)); - } + } #else - /* We shouldn't be here without shm support */ - assert(0); + /* We shouldn't be here without shm support */ + assert(0); #endif - } + } memset(m, 0, sizeof(*m)); } @@ -182,7 +182,7 @@ void pa_shm_punch(pa_shm *m, size_t offset, size_t size) { assert(offset+size <= m->size); #ifdef MAP_FAILED - assert(m->ptr != MAP_FAILED); + assert(m->ptr != MAP_FAILED); #endif /* You're welcome to implement this as NOOP on systems that don't @@ -270,7 +270,7 @@ fail: #else /* HAVE_SHM_OPEN */ int pa_shm_attach_ro(pa_shm *m, unsigned id) { - return -1; + return -1; } #endif /* HAVE_SHM_OPEN */ diff --git a/src/pulsecore/socket-client.c b/src/pulsecore/socket-client.c index b99c8025..b83bfead 100644 --- a/src/pulsecore/socket-client.c +++ b/src/pulsecore/socket-client.c @@ -435,7 +435,7 @@ pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, const char*nam switch (a.type) { case PA_PARSED_ADDRESS_UNIX: if ((c = pa_socket_client_new_unix(m, a.path_or_host))) - start_timeout(c); + start_timeout(c); break; case PA_PARSED_ADDRESS_TCP4: /* Fallthrough */ @@ -479,7 +479,7 @@ pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, const char*nam if (res->ai_addr) { if ((c = pa_socket_client_new_sockaddr(m, res->ai_addr, res->ai_addrlen))) start_timeout(c); - } + } freeaddrinfo(res); #else /* HAVE_GETADDRINFO */ @@ -507,7 +507,7 @@ pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, const char*nam s.sin_port = htons(a.port); if ((c = pa_socket_client_new_sockaddr(m, (struct sockaddr*)&s, sizeof(s)))) - start_timeout(c); + start_timeout(c); #endif /* HAVE_GETADDRINFO */ } #endif /* HAVE_LIBASYNCNS */ diff --git a/src/pulsecore/socket-util.c b/src/pulsecore/socket-util.c index 673058e2..05cb3369 100644 --- a/src/pulsecore/socket-util.c +++ b/src/pulsecore/socket-util.c @@ -177,7 +177,7 @@ int pa_socket_tcp_low_delay(int fd) { #endif #if defined(IPTOS_LOWDELAY) && defined(IP_TOS) && (defined(SOL_IP) || \ - defined(IPPROTO_IP)) + defined(IPPROTO_IP)) tos = IPTOS_LOWDELAY; #ifdef SOL_IP if (setsockopt(fd, SOL_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) diff --git a/src/utils/padsp.c b/src/utils/padsp.c index 9a2bad44..041115ec 100644 --- a/src/utils/padsp.c +++ b/src/utils/padsp.c @@ -259,9 +259,9 @@ if (!(i)->context || pa_context_get_state((i)->context) != PA_CONTEXT_READY || \ static void debug(int level, const char *format, ...) PA_GCC_PRINTF_ATTR(2,3); -#define DEBUG_LEVEL_ALWAYS 0 -#define DEBUG_LEVEL_NORMAL 1 -#define DEBUG_LEVEL_VERBOSE 2 +#define DEBUG_LEVEL_ALWAYS 0 +#define DEBUG_LEVEL_NORMAL 1 +#define DEBUG_LEVEL_VERBOSE 2 static void debug(int level, const char *format, ...) { va_list ap; @@ -421,7 +421,7 @@ static void fd_info_unref(fd_info *i) { pthread_mutex_lock(&i->mutex); assert(i->ref >= 1); r = --i->ref; - debug(DEBUG_LEVEL_VERBOSE, __FILE__": ref--, now %i\n", i->ref); + debug(DEBUG_LEVEL_VERBOSE, __FILE__": ref--, now %i\n", i->ref); pthread_mutex_unlock(&i->mutex); if (r <= 0) @@ -1395,7 +1395,7 @@ static int sndstat_open(int flags, int *_errno) { if (flags != O_RDONLY #ifdef O_LARGEFILE - && flags != (O_RDONLY|O_LARGEFILE) + && flags != (O_RDONLY|O_LARGEFILE) #endif ) { *_errno = EACCES; @@ -1446,7 +1446,7 @@ int open(const char *filename, int flags, ...) { va_start(args, flags); if (flags & O_CREAT) { if (sizeof(mode_t) < sizeof(int)) - mode = va_arg(args, int); + mode = va_arg(args, int); else mode = va_arg(args, mode_t); } @@ -2023,9 +2023,9 @@ static int dsp_ioctl(fd_info *i, unsigned long request, void*argp, int *_errno) *(int*) argp = DSP_CAP_DUPLEX | DSP_CAP_TRIGGER #ifdef DSP_CAP_MULTI - | DSP_CAP_MULTI + | DSP_CAP_MULTI #endif - ; + ; break; case SNDCTL_DSP_GETODELAY: { @@ -2279,8 +2279,8 @@ static int dsp_ioctl(fd_info *i, unsigned long request, void*argp, int *_errno) case SNDCTL_DSP_SETDUPLEX: debug(DEBUG_LEVEL_NORMAL, __FILE__": SNDCTL_DSP_SETDUPLEX\n"); - /* this is a no-op */ - break; + /* this is a no-op */ + break; default: debug(DEBUG_LEVEL_NORMAL, __FILE__": unknown ioctl 0x%08lx\n", request); -- cgit From be4a8828360b3607414c3ebfd836494e6490267d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 13 Jun 2007 22:08:14 +0000 Subject: A lot of more work to get the lock-free stuff in place git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1474 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 171 +++++++++++++++++---------------- src/daemon/main.c | 2 +- src/modules/module-lirc.c | 12 +-- src/modules/module-mmkbd-evdev.c | 8 +- src/modules/module-null-sink.c | 132 ++++++++++++------------- src/modules/module-pipe-sink.c | 188 ++++++++++++++++++------------------ src/modules/module-pipe-source.c | 2 +- src/pulsecore/asyncmsgq.c | 29 +++--- src/pulsecore/asyncq.c | 69 ++++++++++--- src/pulsecore/asyncq.h | 2 +- src/pulsecore/cli-command.c | 71 +++++++++++++- src/pulsecore/cli-text.c | 18 ++-- src/pulsecore/core-subscribe.c | 6 +- src/pulsecore/core.c | 17 ++-- src/pulsecore/core.h | 2 +- src/pulsecore/log.c | 9 +- src/pulsecore/msgobject.c | 6 +- src/pulsecore/msgobject.h | 8 +- src/pulsecore/object.c | 16 +++- src/pulsecore/object.h | 72 ++++++++++---- src/pulsecore/protocol-simple.c | 197 +++++++++++++++++++------------------- src/pulsecore/resampler.c | 39 +++++++- src/pulsecore/resampler.h | 3 + src/pulsecore/sink-input.c | 80 ++++++++-------- src/pulsecore/sink-input.h | 4 +- src/pulsecore/sink.c | 135 ++++++++++++-------------- src/pulsecore/sink.h | 26 +++-- src/pulsecore/sound-file-stream.c | 2 +- src/pulsecore/source-output.c | 58 +++++------ src/pulsecore/source-output.h | 4 +- src/pulsecore/source.c | 178 ++++++++++++++++------------------ src/pulsecore/source.h | 24 ++--- src/tests/asyncmsgq-test.c | 8 +- 33 files changed, 906 insertions(+), 692 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index eab465c8..0a5d5297 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -283,14 +283,14 @@ flist_test_CFLAGS = $(AM_CFLAGS) flist_test_LDADD = $(AM_LDADD) libpulsecore.la flist_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) -asyncq_test_SOURCES = tests/asyncq-test.c pulsecore/thread-posix.c pulsecore/thread.h pulsecore/asyncq.c pulsecore/asyncq.h pulsecore/core-util.c pulsecore/core-util.h pulse/xmalloc.c pulse/xmalloc.h pulsecore/log.h pulsecore/log.c pulsecore/core-error.h pulsecore/core-error.c pulsecore/once-posix.c pulsecore/once.h pulsecore/mutex-posix.c pulsecore/mutex.h pulse/utf8.c pulse/utf8.h pulse/util.h pulse/util.c +asyncq_test_SOURCES = tests/asyncq-test.c asyncq_test_CFLAGS = $(AM_CFLAGS) -asyncq_test_LDADD = $(AM_LDADD) #libpulsecore.la +asyncq_test_LDADD = $(AM_LDADD) libpulsecore.la asyncq_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) -asyncmsgq_test_SOURCES = tests/asyncmsgq-test.c pulsecore/thread-posix.c pulsecore/thread.h pulsecore/asyncq.c pulsecore/asyncq.h pulsecore/asyncmsgq.c pulsecore/asyncmsgq.h pulsecore/core-util.c pulsecore/core-util.h pulse/xmalloc.c pulse/xmalloc.h pulsecore/log.h pulsecore/log.c pulsecore/core-error.h pulsecore/core-error.c pulsecore/once-posix.c pulsecore/once.h pulsecore/mutex-posix.c pulsecore/mutex.h pulse/utf8.c pulse/utf8.h pulse/util.h pulse/util.c pulsecore/semaphore.h pulsecore/semaphore-posix.c pulsecore/flist.h pulsecore/flist.c +asyncmsgq_test_SOURCES = tests/asyncmsgq-test.c asyncmsgq_test_CFLAGS = $(AM_CFLAGS) -asyncmsgq_test_LDADD = $(AM_LDADD) #libpulsecore.la +asyncmsgq_test_LDADD = $(AM_LDADD) libpulsecore.la asyncmsgq_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) mcalign_test_SOURCES = tests/mcalign-test.c @@ -653,7 +653,10 @@ libpulsecore_la_SOURCES += \ pulsecore/hook-list.c pulsecore/hook-list.h \ pulsecore/shm.c pulsecore/shm.h \ pulsecore/flist.c pulsecore/flist.h \ - pulsecore/anotify.c pulsecore/anotify.h \ + pulsecore/asyncmsgq.c pulsecore/asyncmsgqq.h \ + pulsecore/asyncq.c pulsecore/asyncq.h \ + pulsecore/object.c pulsecore/object.h \ + pulsecore/msgobject.c pulsecore/msgobject.h \ $(PA_THREAD_OBJS) if OS_IS_WIN32 @@ -718,9 +721,10 @@ modlibexec_LTLIBRARIES = \ libauthkey-prop.la \ libstrlist.la \ libprotocol-simple.la \ - libprotocol-esound.la \ - libprotocol-native.la \ - libprotocol-http.la + libprotocol-http.la + +# libprotocol-esound.la +# libprotocol-native.la # We need to emulate sendmsg/recvmsg to support this on Win32 if !OS_IS_WIN32 @@ -870,6 +874,11 @@ modlibexec_LTLIBRARIES += \ module-cli-protocol-tcp.la \ module-simple-protocol-tcp.la \ module-null-sink.la + module-detect.la \ + module-volume-restore.la \ + module-rescue-streams.la \ + module-http-protocol-tcp.la + # module-esound-protocol-tcp.la \ # module-native-protocol-tcp.la \ # module-native-protocol-fd.la \ @@ -877,11 +886,7 @@ modlibexec_LTLIBRARIES += \ # module-combine.la \ # module-tunnel-sink.la \ # module-tunnel-source.la \ -# module-esound-sink.la \ -# module-http-protocol-tcp.la \ -# module-detect.la \ -# module-volume-restore.la \ -# module-rescue-streams.la +# module-esound-sink.la # See comment at librtp.la above #if !OS_IS_WIN32 @@ -894,9 +899,9 @@ if HAVE_AF_UNIX modlibexec_LTLIBRARIES += \ module-cli-protocol-unix.la \ module-simple-protocol-unix.la + module-http-protocol-unix.la # module-esound-protocol-unix.la \ -# module-native-protocol-unix.la \ -# module-http-protocol-unix.la +# module-native-protocol-unix.la endif if HAVE_MKFIFO @@ -1079,44 +1084,44 @@ module_http_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-h # Native protocol -module_native_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c -module_native_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_NATIVE $(AM_CFLAGS) -module_native_protocol_tcp_la_LDFLAGS = -module -avoid-version -module_native_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-native.la libsocket-server.la +#module_native_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c +#module_native_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_NATIVE $(AM_CFLAGS) +#module_native_protocol_tcp_la_LDFLAGS = -module -avoid-version +#module_native_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-native.la libsocket-server.la -module_native_protocol_unix_la_SOURCES = modules/module-protocol-stub.c -module_native_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_NATIVE $(AM_CFLAGS) -module_native_protocol_unix_la_LDFLAGS = -module -avoid-version -module_native_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-native.la libsocket-server.la libsocket-util.la +#module_native_protocol_unix_la_SOURCES = modules/module-protocol-stub.c +#module_native_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_NATIVE $(AM_CFLAGS) +#module_native_protocol_unix_la_LDFLAGS = -module -avoid-version +#module_native_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-native.la libsocket-server.la libsocket-util.la -module_native_protocol_fd_la_SOURCES = modules/module-native-protocol-fd.c -module_native_protocol_fd_la_CFLAGS = $(AM_CFLAGS) -module_native_protocol_fd_la_LDFLAGS = -module -avoid-version -module_native_protocol_fd_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-native.la libsocket-server.la libsocket-util.la libiochannel.la +#module_native_protocol_fd_la_SOURCES = modules/module-native-protocol-fd.c +#module_native_protocol_fd_la_CFLAGS = $(AM_CFLAGS) +#module_native_protocol_fd_la_LDFLAGS = -module -avoid-version +#module_native_protocol_fd_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-native.la libsocket-server.la libsocket-util.la libiochannel.la # EsounD protocol -module_esound_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c -module_esound_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_ESOUND $(AM_CFLAGS) -module_esound_protocol_tcp_la_LDFLAGS = -module -avoid-version -module_esound_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-esound.la libsocket-server.la +#module_esound_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c +#module_esound_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_ESOUND $(AM_CFLAGS) +#module_esound_protocol_tcp_la_LDFLAGS = -module -avoid-version +#module_esound_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-esound.la libsocket-server.la -module_esound_protocol_unix_la_SOURCES = modules/module-protocol-stub.c -module_esound_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_ESOUND $(AM_CFLAGS) -module_esound_protocol_unix_la_LDFLAGS = -module -avoid-version -module_esound_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-esound.la libsocket-server.la libsocket-util.la +#module_esound_protocol_unix_la_SOURCES = modules/module-protocol-stub.c +#module_esound_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_ESOUND $(AM_CFLAGS) +#module_esound_protocol_unix_la_LDFLAGS = -module -avoid-version +#module_esound_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-esound.la libsocket-server.la libsocket-util.la -module_esound_compat_spawnfd_la_SOURCES = modules/module-esound-compat-spawnfd.c -module_esound_compat_spawnfd_la_LDFLAGS = -module -avoid-version -module_esound_compat_spawnfd_la_LIBADD = $(AM_LIBADD) libpulsecore.la +#module_esound_compat_spawnfd_la_SOURCES = modules/module-esound-compat-spawnfd.c +#module_esound_compat_spawnfd_la_LDFLAGS = -module -avoid-version +#module_esound_compat_spawnfd_la_LIBADD = $(AM_LIBADD) libpulsecore.la -module_esound_compat_spawnpid_la_SOURCES = modules/module-esound-compat-spawnpid.c -module_esound_compat_spawnpid_la_LDFLAGS = -module -avoid-version -module_esound_compat_spawnpid_la_LIBADD = $(AM_LIBADD) libpulsecore.la +#module_esound_compat_spawnpid_la_SOURCES = modules/module-esound-compat-spawnpid.c +#module_esound_compat_spawnpid_la_LDFLAGS = -module -avoid-version +#module_esound_compat_spawnpid_la_LIBADD = $(AM_LIBADD) libpulsecore.la -module_esound_sink_la_SOURCES = modules/module-esound-sink.c -module_esound_sink_la_LDFLAGS = -module -avoid-version -module_esound_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la libiochannel.la libsocket-client.la libauthkey.la +#module_esound_sink_la_SOURCES = modules/module-esound-sink.c +#module_esound_sink_la_LDFLAGS = -module -avoid-version +#module_esound_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la libiochannel.la libsocket-client.la libauthkey.la # Pipes @@ -1140,22 +1145,22 @@ module_null_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la # Couplings -module_combine_la_SOURCES = modules/module-combine.c -module_combine_la_LDFLAGS = -module -avoid-version -module_combine_la_LIBADD = $(AM_LIBADD) libpulsecore.la +#module_combine_la_SOURCES = modules/module-combine.c +#module_combine_la_LDFLAGS = -module -avoid-version +#module_combine_la_LIBADD = $(AM_LIBADD) libpulsecore.la module_match_la_SOURCES = modules/module-match.c module_match_la_LDFLAGS = -module -avoid-version module_match_la_LIBADD = $(AM_LIBADD) libpulsecore.la -module_tunnel_sink_la_SOURCES = modules/module-tunnel.c -module_tunnel_sink_la_CFLAGS = -DTUNNEL_SINK=1 $(AM_CFLAGS) -module_tunnel_sink_la_LDFLAGS = -module -avoid-version -module_tunnel_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la libsocket-client.la libpstream.la libpstream-util.la libpdispatch.la libtagstruct.la libauthkey.la libauthkey-prop.la libsocket-util.la libiochannel.la +#module_tunnel_sink_la_SOURCES = modules/module-tunnel.c +#module_tunnel_sink_la_CFLAGS = -DTUNNEL_SINK=1 $(AM_CFLAGS) +#module_tunnel_sink_la_LDFLAGS = -module -avoid-version +#module_tunnel_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la libsocket-client.la libpstream.la libpstream-util.la libpdispatch.la libtagstruct.la libauthkey.la libauthkey-prop.la libsocket-util.la libiochannel.la -module_tunnel_source_la_SOURCES = modules/module-tunnel.c -module_tunnel_source_la_LDFLAGS = -module -avoid-version -module_tunnel_source_la_LIBADD = $(AM_LIBADD) libpulsecore.la libsocket-client.la libpstream.la libpstream-util.la libpdispatch.la libtagstruct.la libauthkey.la libauthkey-prop.la libsocket-util.la libiochannel.la +#module_tunnel_source_la_SOURCES = modules/module-tunnel.c +#module_tunnel_source_la_LDFLAGS = -module -avoid-version +#module_tunnel_source_la_LIBADD = $(AM_LIBADD) libpulsecore.la libsocket-client.la libpstream.la libpstream-util.la libpdispatch.la libtagstruct.la libauthkey.la libauthkey-prop.la libsocket-util.la libiochannel.la # X11 @@ -1171,34 +1176,34 @@ module_x11_publish_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EX # OSS -liboss_util_la_SOURCES = modules/oss-util.c modules/oss-util.h -liboss_util_la_LDFLAGS = -avoid-version -liboss_util_la_LIBADD = libpulsecore.la +#liboss_util_la_SOURCES = modules/oss-util.c modules/oss-util.h +#liboss_util_la_LDFLAGS = -avoid-version +#liboss_util_la_LIBADD = libpulsecore.la -module_oss_la_SOURCES = modules/module-oss.c -module_oss_la_LDFLAGS = -module -avoid-version -module_oss_la_LIBADD = $(AM_LIBADD) libiochannel.la liboss-util.la +#module_oss_la_SOURCES = modules/module-oss.c +#module_oss_la_LDFLAGS = -module -avoid-version +#module_oss_la_LIBADD = $(AM_LIBADD) libiochannel.la liboss-util.la -module_oss_mmap_la_SOURCES = modules/module-oss-mmap.c -module_oss_mmap_la_LDFLAGS = -module -avoid-version -module_oss_mmap_la_LIBADD = $(AM_LIBADD) liboss-util.la libpulsecore.la +#module_oss_mmap_la_SOURCES = modules/module-oss-mmap.c +#module_oss_mmap_la_LDFLAGS = -module -avoid-version +#module_oss_mmap_la_LIBADD = $(AM_LIBADD) liboss-util.la libpulsecore.la # ALSA -libalsa_util_la_SOURCES = modules/alsa-util.c modules/alsa-util.h -libalsa_util_la_LDFLAGS = -avoid-version -libalsa_util_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libpulsecore.la -libalsa_util_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) +#libalsa_util_la_SOURCES = modules/alsa-util.c modules/alsa-util.h +#libalsa_util_la_LDFLAGS = -avoid-version +#libalsa_util_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libpulsecore.la +#libalsa_util_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) -module_alsa_sink_la_SOURCES = modules/module-alsa-sink.c -module_alsa_sink_la_LDFLAGS = -module -avoid-version -module_alsa_sink_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la libpulsecore.la -module_alsa_sink_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) +#module_alsa_sink_la_SOURCES = modules/module-alsa-sink.c +#module_alsa_sink_la_LDFLAGS = -module -avoid-version +#module_alsa_sink_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la libpulsecore.la +#module_alsa_sink_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) -module_alsa_source_la_SOURCES = modules/module-alsa-source.c -module_alsa_source_la_LDFLAGS = -module -avoid-version -module_alsa_source_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la libpulsecore.la -module_alsa_source_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) +#module_alsa_source_la_SOURCES = modules/module-alsa-source.c +#module_alsa_source_la_LDFLAGS = -module -avoid-version +#module_alsa_source_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la libpulsecore.la +#module_alsa_source_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) # Solaris @@ -1265,15 +1270,15 @@ module_rtp_recv_la_CFLAGS = $(AM_CFLAGS) # JACK -module_jack_sink_la_SOURCES = modules/module-jack-sink.c -module_jack_sink_la_LDFLAGS = -module -avoid-version -module_jack_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la $(JACK_LIBS) -module_jack_sink_la_CFLAGS = $(AM_LIBADD) $(JACK_CFLAGS) +#module_jack_sink_la_SOURCES = modules/module-jack-sink.c +#module_jack_sink_la_LDFLAGS = -module -avoid-version +#module_jack_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la $(JACK_LIBS) +#module_jack_sink_la_CFLAGS = $(AM_LIBADD) $(JACK_CFLAGS) -module_jack_source_la_SOURCES = modules/module-jack-source.c -module_jack_source_la_LDFLAGS = -module -avoid-version -module_jack_source_la_LIBADD = $(AM_LIBADD) libpulsecore.la $(JACK_LIBS) -module_jack_source_la_CFLAGS = $(AM_LIBADD) $(JACK_CFLAGS) +#module_jack_source_la_SOURCES = modules/module-jack-source.c +#module_jack_source_la_LDFLAGS = -module -avoid-version +#module_jack_source_la_LIBADD = $(AM_LIBADD) libpulsecore.la $(JACK_LIBS) +#module_jack_source_la_CFLAGS = $(AM_LIBADD) $(JACK_CFLAGS) # HAL libdbus_util_la_SOURCES = modules/dbus-util.c modules/dbus-util.h diff --git a/src/daemon/main.c b/src/daemon/main.c index 2424efa7..a1926fe5 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -656,7 +656,7 @@ int main(int argc, char *argv[]) { pa_mainloop_get_api(mainloop)->time_free(timer); #endif - pa_core_free(c); + pa_core_unref(c); if (!conf->no_cpu_limit) pa_cpu_limit_done(); diff --git a/src/modules/module-lirc.c b/src/modules/module-lirc.c index c8adbc8b..452fa1f3 100644 --- a/src/modules/module-lirc.c +++ b/src/modules/module-lirc.c @@ -121,7 +121,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC pa_log("failed to get sink '%s'", u->sink_name); else { int i; - pa_cvolume cv = *pa_sink_get_volume(s, PA_MIXER_HARDWARE); + pa_cvolume cv = *pa_sink_get_volume(s); #define DELTA (PA_VOLUME_NORM/20) @@ -134,7 +134,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC cv.values[i] = PA_VOLUME_NORM; } - pa_sink_set_volume(s, PA_MIXER_HARDWARE, &cv); + pa_sink_set_volume(s, &cv); break; case DOWN: @@ -145,20 +145,20 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC cv.values[i] = PA_VOLUME_MUTED; } - pa_sink_set_volume(s, PA_MIXER_HARDWARE, &cv); + pa_sink_set_volume(s, &cv); break; case MUTE: - pa_sink_set_mute(s, PA_MIXER_HARDWARE, 0); + pa_sink_set_mute(s, 0); break; case RESET: - pa_sink_set_mute(s, PA_MIXER_HARDWARE, 1); + pa_sink_set_mute(s, 1); break; case MUTE_TOGGLE: - pa_sink_set_mute(s, PA_MIXER_HARDWARE, !pa_sink_get_mute(s, PA_MIXER_HARDWARE)); + pa_sink_set_mute(s, !pa_sink_get_mute(s)); break; case INVALID: diff --git a/src/modules/module-mmkbd-evdev.c b/src/modules/module-mmkbd-evdev.c index b7433ac8..919b399d 100644 --- a/src/modules/module-mmkbd-evdev.c +++ b/src/modules/module-mmkbd-evdev.c @@ -114,7 +114,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC pa_log("failed to get sink '%s'", u->sink_name); else { int i; - pa_cvolume cv = *pa_sink_get_volume(s, PA_MIXER_HARDWARE); + pa_cvolume cv = *pa_sink_get_volume(s); #define DELTA (PA_VOLUME_NORM/20) @@ -127,7 +127,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC cv.values[i] = PA_VOLUME_NORM; } - pa_sink_set_volume(s, PA_MIXER_HARDWARE, &cv); + pa_sink_set_volume(s, &cv); break; case DOWN: @@ -138,12 +138,12 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC cv.values[i] = PA_VOLUME_MUTED; } - pa_sink_set_volume(s, PA_MIXER_HARDWARE, &cv); + pa_sink_set_volume(s, &cv); break; case MUTE_TOGGLE: - pa_sink_set_mute(s, PA_MIXER_HARDWARE, !pa_sink_get_mute(s, PA_MIXER_HARDWARE)); + pa_sink_set_mute(s, !pa_sink_get_mute(s)); break; case INVALID: diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index ce3b29b0..afe130d9 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -33,17 +33,19 @@ #include #include #include +#include #include #include #include -#include #include #include #include +#include #include #include +#include #include "module-null-sink-symdef.h" @@ -65,7 +67,9 @@ struct userdata { pa_module *module; pa_sink *sink; pa_thread *thread; + pa_asyncmsgq *asyncmsgq; size_t block_size; + struct timeval timestamp; }; @@ -79,85 +83,74 @@ static const char* const valid_modargs[] = { NULL }; +static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk *chunk) { + struct userdata *u = PA_SINK(o)->userdata; + + switch (code) { + case PA_SINK_MESSAGE_SET_STATE: + + if (PA_PTR_TO_UINT(data) == PA_SINK_RUNNING) + pa_gettimeofday(&u->timestamp); + + break; + + case PA_SINK_MESSAGE_GET_LATENCY: { + struct timeval now; + + pa_gettimeofday(&now); + + if (pa_timeval_cmp(&u->timestamp, &now) > 0) + *((pa_usec_t*) data) = 0; + else + *((pa_usec_t*) data) = pa_timeval_diff(&u->timestamp, &now); + break; + } + } + + return pa_sink_process_msg(o, code, data, chunk); +} + static void thread_func(void *userdata) { struct userdata *u = userdata; - int quit = 0; struct pollfd pollfd; - int running = 1; pa_assert(u); pa_log_debug("Thread starting up"); + pa_gettimeofday(&u->timestamp); + memset(&pollfd, 0, sizeof(pollfd)); - pollfd.fd = pa_asyncmsgq_get_fd(u->sink->asyncmsgq, PA_ASYNCQ_POP); + pollfd.fd = pa_asyncmsgq_get_fd(u->asyncmsgq); pollfd.events = POLLIN; - pa_gettimeofday(u->timestamp); - for (;;) { + pa_msgobject *object; int code; - void *data, *object; + void *data; + pa_memchunk chunk; int r, timeout; struct timeval now; /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->sink->asyncmsgq, &object, &code, &data) == 0) { - - - /* Now process these messages our own way */ - if (!object) { - - switch (code) { - case PA_MESSAGE_SHUTDOWN: - goto finish; - - default: - pa_sink_process_msg(u->sink->asyncmsgq, object, code, data); - - } + if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { + int ret; - } else if (object == u->sink) { - - switch (code) { - case PA_SINK_MESSAGE_STOP: - pa_assert(running); - running = 0; - break; - - case PA_SINK_MESSAGE_START: - pa_assert(!running); - running = 1; - - pa_gettimeofday(u->timestamp); - break; - - case PA_SINK_MESSAGE_GET_LATENCY: - - if (pa_timeval_cmp(&u->timestamp, &now) > 0) - *((pa_usec_t*) data) = 0; - else - *((pa_usec_t*) data) = pa_timeval_diff(&u->timestamp, &now); - break; - - /* ... */ - - default: - pa_sink_process_msg(u->sink->asyncmsgq, object, code, data); - } + if (!object && code == PA_MESSAGE_SHUTDOWN) { + pa_asyncmsgq_done(u->asyncmsgq, 0); + goto finish; } - - pa_asyncmsgq_done(u->sink->asyncmsgq); + + ret = pa_asyncmsgq_dispatch(object, code, data, &chunk); + pa_asyncmsgq_done(u->asyncmsgq, ret); continue; } /* Render some data and drop it immediately */ - - if (running) { + if (u->sink->thread_info.state == PA_SINK_RUNNING) { pa_gettimeofday(&now); - if (pa_timeval_cmp(u->timestamp, &now) <= 0) { - pa_memchunk chunk; + if (pa_timeval_cmp(&u->timestamp, &now) <= 0) { size_t l; if (pa_sink_render(u->sink, u->block_size, &chunk) >= 0) { @@ -179,11 +172,11 @@ static void thread_func(void *userdata) { /* Hmm, nothing to do. Let's sleep */ - if (pa_asyncmsgq_before_poll(u->sink->asyncmsgq) < 0) + if (pa_asyncmsgq_before_poll(u->asyncmsgq) < 0) continue; r = poll(&pollfd, 1, timeout); - pa_asyncmsgq_after_poll(u->sink->asyncmsgq); + pa_asyncmsgq_after_poll(u->asyncmsgq); if (r < 0) { if (errno == EINTR) @@ -199,8 +192,8 @@ static void thread_func(void *userdata) { fail: /* We have to continue processing messages until we receive the * SHUTDOWN message */ - pa_asyncmsgq_post(u->core->asyncmsgq, u->core, PA_CORE_MESSAGE_UNLOAD_MODULE, pa_module_ref(u->module), NULL, pa_module_unref); - pa_asyncmsgq_wait_for(PA_MESSAGE_SHUTDOWN); + pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, NULL, NULL); + pa_asyncmsgq_wait_for(u->asyncmsgq, PA_MESSAGE_SHUTDOWN); finish: pa_log_debug("Thread shutting down"); @@ -231,20 +224,24 @@ int pa__init(pa_core *c, pa_module*m) { u->module = m; m->userdata = u; + pa_assert_se(u->asyncmsgq = pa_asyncmsgq_new(0)); + if (!(u->sink = pa_sink_new(c, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map))) { pa_log("Failed to create sink."); goto fail; } + u->sink->parent.process_msg = sink_process_msg; u->sink->userdata = u; - pa_sink_set_owner(u->sink, m); + + pa_sink_set_module(u->sink, m); + pa_sink_set_asyncmsgq(u->sink, u->asyncmsgq); pa_sink_set_description(u->sink, pa_modargs_get_value(ma, "description", "NULL sink")); u->block_size = pa_bytes_per_second(&ss) / 20; /* 50 ms */ - if (u->block_size <= 0) u->block_size = pa_frame_size(&ss); - + if (!(u->thread = pa_thread_new(thread_func, u))) { pa_log("Failed to create thread."); goto fail; @@ -272,14 +269,19 @@ void pa__done(pa_core *c, pa_module*m) { if (!(u = m->userdata)) return; - pa_sink_disconnect(u->sink); + if (u->sink) + pa_sink_disconnect(u->sink); if (u->thread) { - pa_asyncmsgq_send(u->sink->asyncmsgq, PA_SINK_MESSAGE_SHUTDOWN, NULL); + pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, NULL); pa_thread_free(u->thread); } - pa_sink_unref(u->sink); + if (u->asyncmsgq) + pa_asyncmsgq_free(u->asyncmsgq); + + if (u->sink) + pa_sink_unref(u->sink); pa_xfree(u); } diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index e4735f61..da9124a7 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include @@ -44,6 +46,7 @@ #include #include #include +#include #include "module-pipe-sink-symdef.h" @@ -65,9 +68,12 @@ struct userdata { pa_core *core; pa_module *module; pa_sink *sink; + pa_thread *thread; + pa_asyncmsgq *asyncmsgq; char *filename; int fd; - pa_thread *thread; + + pa_memchunk memchunk; }; static const char* const valid_modargs[] = { @@ -80,109 +86,99 @@ static const char* const valid_modargs[] = { NULL }; -enum { - POLLFD_ASYNCQ, - POLLFD_FIFO, - POLLFD_MAX, -}; +static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk *chunk) { + struct userdata *u = PA_SINK(o)->userdata; + + switch (code) { + + case PA_SINK_MESSAGE_GET_LATENCY: { + size_t n = 0; + int l; + + if (ioctl(u->fd, TIOCINQ, &l) >= 0 && l > 0) + n = (size_t) l; + + n += u->memchunk.length; + + *((pa_usec_t*) data) = pa_bytes_to_usec(n, &u->sink->sample_spec); + break; + } + } + + return pa_sink_process_msg(o, code, data, chunk); +} static void thread_func(void *userdata) { + enum { + POLLFD_ASYNCQ, + POLLFD_FIFO, + POLLFD_MAX, + }; + struct userdata *u = userdata; - int quit = 0; struct pollfd pollfd[POLLFD_MAX]; - int running = 1, underrun = 0; - pa_memchunk memchunk; + int underrun = 0; + int write_type = 0; pa_assert(u); pa_log_debug("Thread starting up"); + pa_memchunk_reset(&u->memchunk); + memset(&pollfd, 0, sizeof(pollfd)); - pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->sink->asyncmsgq, PA_ASYNCQ_POP); + + pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq); pollfd[POLLFD_ASYNCQ].events = POLLIN; - pollfd[POLLFD_FIFO].fd = u->fd; - memset(&memchunk, 0, sizeof(memchunk)); - for (;;) { + pa_msgobject *object; int code; - void *object, *data; + void *data; + pa_memchunk chunk; int r; - struct timeval now; /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->sink->asyncmsgq, &object, &code, &data) == 0) { - - - /* Now process these messages our own way */ - if (!object) { - switch (code) { - case PA_SINK_MESSAGE_SHUTDOWN: - goto finish; - - default: - pa_sink_process_msg(u->sink->asyncmsgq, object, code, data); - } + if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { + int ret; - } else if (object == u->sink) { - - case PA_SINK_MESSAGE_STOP: - pa_assert(running); - running = 0; - break; - - case PA_SINK_MESSAGE_START: - pa_assert(!running); - running = 1; - break; - - case PA_SINK_MESSAGE_GET_LATENCY: { - size_t n = 0; - int l; - - if (ioctl(u->fd, TIOCINQ, &l) >= 0 && l > 0) - n = (size_t) l; - - n += memchunk.length; - - *((pa_usec_t*) data) pa_bytes_to_usec(n, &u->sink->sample_spec); - break; - } - - /* ... */ - - default: - pa_sink_process_msg(u->sink->asyncmsgq, object, code, data); + if (!object && code == PA_MESSAGE_SHUTDOWN) { + pa_asyncmsgq_done(u->asyncmsgq, 0); + goto finish; } - pa_asyncmsgq_done(u->sink->asyncmsgq); + ret = pa_asyncmsgq_dispatch(object, code, data, &chunk); + pa_asyncmsgq_done(u->asyncmsgq, ret); continue; } /* Render some data and write it to the fifo */ - if (running && (pollfd[POLLFD_FIFO].revents || underrun)) { + if (u->sink->thread_info.state == PA_SINK_RUNNING && (pollfd[POLLFD_FIFO].revents || underrun)) { - if (chunk.length <= 0) - pa_sink_render(u->fd, PIPE_BUF, &chunk); + if (u->memchunk.length <= 0) + pa_sink_render(u->sink, PIPE_BUF, &u->memchunk); - underrun = chunk.length <= 0; + underrun = u->memchunk.length <= 0; if (!underrun) { ssize_t l; + void *p; p = pa_memblock_acquire(u->memchunk.memblock); - l = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length); - pa_memblock_release(p); + l = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length, &write_type); + pa_memblock_release(u->memchunk.memblock); if (l < 0) { - if (errno != EINTR && errno != EAGAIN) { + if (errno == EINTR) + continue; + else if (errno != EAGAIN) { pa_log("Failed to write data to FIFO: %s", pa_cstrerror(errno)); goto fail; } - + } else { u->memchunk.index += l; @@ -190,24 +186,24 @@ static void thread_func(void *userdata) { if (u->memchunk.length <= 0) { pa_memblock_unref(u->memchunk.memblock); - u->memchunk.memblock = NULL; + pa_memchunk_reset(&u->memchunk); } - } - pollfd[POLLFD_FIFO].revents = 0; - continue; + pollfd[POLLFD_FIFO].revents = 0; + continue; + } } } - pollfd[POLLFD_FIFO].events = running && !underrun ? POLLOUT : 0; + pollfd[POLLFD_FIFO].events = (u->sink->thread_info.state == PA_SINK_RUNNING && !underrun) ? POLLOUT : 0; /* Hmm, nothing to do. Let's sleep */ - if (pa_asyncmsgq_before_poll(u->sink->asyncmsgq) < 0) + if (pa_asyncmsgq_before_poll(u->asyncmsgq) < 0) continue; - r = poll(&pollfd, 1, 0); - pa_asyncmsgq_after_poll(u->sink->asyncmsgq); + r = poll(pollfd, POLLFD_MAX, -1); + pa_asyncmsgq_after_poll(u->asyncmsgq); if (r < 0) { if (errno == EINTR) @@ -217,19 +213,19 @@ static void thread_func(void *userdata) { goto fail; } - if (pollfd[POLLFD_FIFO].revents & ~POLLIN) { + if (pollfd[POLLFD_FIFO].revents & ~POLLOUT) { pa_log("FIFO shutdown."); goto fail; } - pa_assert(pollfd[POLLFD_ASYNCQ].revents & ~POLLIN == 0); + pa_assert((pollfd[POLLFD_ASYNCQ].revents & ~POLLIN) == 0); } fail: /* We have to continue processing messages until we receive the * SHUTDOWN message */ - pa_asyncmsgq_post(u->core->asyncmsgq, u->core, PA_CORE_MESSAGE_UNLOAD_MODULE, pa_module_ref(u->module), pa_module_unref); - pa_asyncmsgq_wait_for(PA_SINK_MESSAGE_SHUTDOWN); + pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, NULL, NULL); + pa_asyncmsgq_wait_for(u->asyncmsgq, PA_MESSAGE_SHUTDOWN); finish: pa_log_debug("Thread shutting down"); @@ -253,23 +249,22 @@ int pa__init(pa_core *c, pa_module*m) { ss = c->default_sample_spec; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) { - pa_log("Invalid sample format specification"); + pa_log("Invalid sample format specification or channel map"); goto fail; } u = pa_xnew0(struct userdata, 1); u->core = c; u->module = m; - u->filename = pa_xstrdup(pa_modargs_get_value(ma, "file", DEFAULT_FIFO_NAME)); - u->fd = fd; - u->memchunk.memblock = NULL; - u->memchunk.length = 0; m->userdata = u; - mkfifo(u->filename, 0666); + pa_assert_se(u->asyncmsgq = pa_asyncmsgq_new(0)); + + u->filename = pa_xstrdup(pa_modargs_get_value(ma, "file", DEFAULT_FILE_NAME)); - if ((u->fd = open(u->filename, O_RDWR)) < 0) { - pa_log("open('%s'): %s", p, pa_cstrerror(errno)); + mkfifo(u->filename, 0666); + if ((u->fd = open(u->filename, O_RDWR|O_NOCTTY)) < 0) { + pa_log("open('%s'): %s", u->filename, pa_cstrerror(errno)); goto fail; } @@ -277,12 +272,12 @@ int pa__init(pa_core *c, pa_module*m) { pa_make_nonblock_fd(u->fd); if (fstat(u->fd, &st) < 0) { - pa_log("fstat('%s'): %s", p, pa_cstrerror(errno)); + pa_log("fstat('%s'): %s", u->filename, pa_cstrerror(errno)); goto fail; } if (!S_ISFIFO(st.st_mode)) { - pa_log("'%s' is not a FIFO.", p); + pa_log("'%s' is not a FIFO.", u->filename); goto fail; } @@ -291,9 +286,12 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } + u->sink->parent.process_msg = sink_process_msg; u->sink->userdata = u; - pa_sink_set_owner(u->sink, m); - pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Unix FIFO sink '%s'", p)); + + pa_sink_set_module(u->sink, m); + pa_sink_set_asyncmsgq(u->sink, u->asyncmsgq); + pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Unix FIFO sink '%s'", u->filename)); pa_xfree(t); if (!(u->thread = pa_thread_new(thread_func, u))) { @@ -316,20 +314,26 @@ fail: void pa__done(pa_core *c, pa_module*m) { struct userdata *u; + pa_assert(c); pa_assert(m); if (!(u = m->userdata)) return; - pa_sink_disconnect(u->sink); + if (u->sink) + pa_sink_disconnect(u->sink); if (u->thread) { - pa_asyncmsgq_send(u->sink->asyncmsgq, PA_SINK_MESSAGE_SHUTDOWN, NULL); + pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, NULL); pa_thread_free(u->thread); } - pa_sink_unref(u->sink); + if (u->asyncmsgq) + pa_asyncmsgq_free(u->asyncmsgq); + + if (u->sink) + pa_sink_unref(u->sink); if (u->memchunk.memblock) pa_memblock_unref(u->memchunk.memblock); diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index f275c5d4..ac2bef7d 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -179,7 +179,7 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } u->source->userdata = u; - pa_source_set_owner(u->source, m); + pa_source_set_module(u->source, m); pa_source_set_description(u->source, t = pa_sprintf_malloc("Unix FIFO source '%s'", p)); pa_xfree(t); diff --git a/src/pulsecore/asyncmsgq.c b/src/pulsecore/asyncmsgq.c index de5b2f9d..6becb629 100644 --- a/src/pulsecore/asyncmsgq.c +++ b/src/pulsecore/asyncmsgq.c @@ -48,6 +48,7 @@ struct asyncmsgq_item { pa_free_cb_t free_cb; pa_memchunk memchunk; pa_semaphore *semaphore; + int ret; }; struct pa_asyncmsgq { @@ -81,10 +82,10 @@ void pa_asyncmsgq_free(pa_asyncmsgq *a) { pa_msgobject_unref(i->object); if (i->memchunk.memblock) - pa_memblock_unref(i->object); + pa_memblock_unref(i->memchunk.memblock); - if (i->userdata_free_cb) - i->userdata_free_cb(i->userdata); + if (i->free_cb) + i->free_cb(i->userdata); if (pa_flist_push(PA_STATIC_FLIST_GET(asyncmsgq), i) < 0) pa_xfree(i); @@ -103,7 +104,7 @@ void pa_asyncmsgq_post(pa_asyncmsgq *a, pa_msgobject *object, int code, const vo i = pa_xnew(struct asyncmsgq_item, 1); i->code = code; - i->object = pa_msgobject_ref(object); + i->object = object ? pa_msgobject_ref(object) : NULL; i->userdata = (void*) userdata; i->free_cb = free_cb; if (chunk) { @@ -131,9 +132,9 @@ int pa_asyncmsgq_send(pa_asyncmsgq *a, pa_msgobject *object, int code, const voi i.ret = -1; if (chunk) { pa_assert(chunk->memblock); - i->memchunk = *chunk; + i.memchunk = *chunk; } else - pa_memchunk_reset(&i->memchunk); + pa_memchunk_reset(&i.memchunk); pa_assert_se(i.semaphore = pa_semaphore_new(0)); /* Thus mutex makes the queue multiple-writer safe. This lock is only used on the writing side */ @@ -161,8 +162,10 @@ int pa_asyncmsgq_get(pa_asyncmsgq *a, pa_msgobject **object, int *code, void **u if (object) *object = a->current->object; if (chunk) - *chunk = a->chunk; + *chunk = a->current->memchunk; + pa_log_debug("q=%p object=%p code=%i data=%p", a, a->current->object, a->current->code, a->current->userdata); + return 0; } @@ -196,11 +199,16 @@ int pa_asyncmsgq_wait_for(pa_asyncmsgq *a, int code) { pa_assert(a); do { + pa_msgobject *o; + void *data; + pa_memchunk chunk; + int ret; - if (pa_asyncmsgq_get(a, NULL, &c, NULL, 1) < 0) + if (pa_asyncmsgq_get(a, &o, &c, &data, &chunk, 1) < 0) return -1; - pa_asyncmsgq_done(a); + ret = pa_asyncmsgq_dispatch(o, c, data, &chunk); + pa_asyncmsgq_done(a, ret); } while (c != code); @@ -226,10 +234,9 @@ void pa_asyncmsgq_after_poll(pa_asyncmsgq *a) { } int pa_asyncmsgq_dispatch(pa_msgobject *object, int code, void *userdata, pa_memchunk *memchunk) { - pa_assert(q); if (object) - return object->msg_process(object, code, userdata, memchunk); + return object->process_msg(object, code, userdata, memchunk); return 0; } diff --git a/src/pulsecore/asyncq.c b/src/pulsecore/asyncq.c index 54d36dc0..da1f16fb 100644 --- a/src/pulsecore/asyncq.c +++ b/src/pulsecore/asyncq.c @@ -52,8 +52,8 @@ struct pa_asyncq { unsigned size; unsigned read_idx; unsigned write_idx; - pa_atomic_int_t read_waiting; - pa_atomic_int_t write_waiting; + pa_atomic_t read_waiting, n_read; + pa_atomic_t write_waiting, n_written; int read_fds[2], write_fds[2]; }; @@ -80,6 +80,8 @@ pa_asyncq *pa_asyncq_new(unsigned size) { l->size = size; pa_atomic_store(&l->read_waiting, 0); pa_atomic_store(&l->write_waiting, 0); + pa_atomic_store(&l->n_written, 0); + pa_atomic_store(&l->n_read, 0); if (pipe(l->read_fds) < 0) { pa_xfree(l); @@ -131,10 +133,26 @@ int pa_asyncq_push(pa_asyncq*l, void *p, int wait) { if (!pa_atomic_ptr_cmpxchg(&cells[idx], NULL, p)) { - /* First try failed. Let's wait for changes. */ - - if (!wait) + if (!wait) { + /* Let's empty the FIFO from old notifications, before we return */ + + while (pa_atomic_load(&l->n_read) > 0) { + ssize_t r; + int x[20]; + + errno = 0; + if ((r = read(l->write_fds[0], x, sizeof(x))) <= 0 && errno != EINTR) + return -1; + + if (r > 0) + if (pa_atomic_sub(&l->n_read, r) <= r) + break; + } + return -1; + } + + /* First try failed. Let's wait for changes. */ _Y; @@ -142,6 +160,7 @@ int pa_asyncq_push(pa_asyncq*l, void *p, int wait) { for (;;) { char x[20]; + ssize_t r; _Y; @@ -150,10 +169,13 @@ int pa_asyncq_push(pa_asyncq*l, void *p, int wait) { _Y; - if (read(l->write_fds[0], x, sizeof(x)) < 0 && errno != EINTR) { + if ((r = read(l->write_fds[0], x, sizeof(x))) < 0 && errno != EINTR) { pa_atomic_dec(&l->write_waiting); return -1; } + + if (r > 0) + pa_atomic_sub(&l->n_read, r); } _Y; @@ -167,7 +189,8 @@ int pa_asyncq_push(pa_asyncq*l, void *p, int wait) { if (pa_atomic_load(&l->read_waiting)) { char x = 'x'; _Y; - write(l->read_fds[1], &x, sizeof(x)); + if (write(l->read_fds[1], &x, sizeof(x)) > 0) + pa_atomic_inc(&l->n_written); } return 0; @@ -189,8 +212,24 @@ void* pa_asyncq_pop(pa_asyncq*l, int wait) { /* First try failed. Let's wait for changes. */ - if (!wait) + if (!wait) { + /* Let's empty the FIFO from old notifications, before we return */ + + while (pa_atomic_load(&l->n_written) > 0) { + ssize_t r; + int x[20]; + + errno = 0; + if ((r = read(l->read_fds[0], x, sizeof(x))) <= 0 && errno != EINTR) + return NULL; + + if (r > 0) + if (pa_atomic_sub(&l->n_written, r) <= r) + break; + } + return NULL; + } _Y; @@ -198,6 +237,7 @@ void* pa_asyncq_pop(pa_asyncq*l, int wait) { for (;;) { char x[20]; + ssize_t r; _Y; @@ -206,10 +246,13 @@ void* pa_asyncq_pop(pa_asyncq*l, int wait) { _Y; - if (read(l->read_fds[0], x, sizeof(x)) < 0 && errno != EINTR) { + if ((r = read(l->read_fds[0], x, sizeof(x)) < 0) && errno != EINTR) { pa_atomic_dec(&l->read_waiting); return NULL; } + + if (r > 0) + pa_atomic_sub(&l->n_written, r); } _Y; @@ -226,7 +269,8 @@ void* pa_asyncq_pop(pa_asyncq*l, int wait) { if (pa_atomic_load(&l->write_waiting)) { char x = 'x'; _Y; - write(l->write_fds[1], &x, sizeof(x)); + if (write(l->write_fds[1], &x, sizeof(x)) >= 0) + pa_atomic_inc(&l->n_read); } return ret; @@ -262,10 +306,13 @@ int pa_asyncq_before_poll(pa_asyncq *l) { return 0; } -int pa_asyncq_after_poll(pa_asyncq *l) { +void pa_asyncq_after_poll(pa_asyncq *l) { pa_assert(l); pa_assert(pa_atomic_load(&l->read_waiting) > 0); pa_atomic_dec(&l->read_waiting); + + + } diff --git a/src/pulsecore/asyncq.h b/src/pulsecore/asyncq.h index aac45b1d..729ec466 100644 --- a/src/pulsecore/asyncq.h +++ b/src/pulsecore/asyncq.h @@ -51,6 +51,6 @@ int pa_asyncq_push(pa_asyncq *q, void *p, int wait); int pa_asyncq_get_fd(pa_asyncq *q); int pa_asyncq_before_poll(pa_asyncq *a); -int pa_asyncq_after_poll(pa_asyncq *a); +void pa_asyncq_after_poll(pa_asyncq *a); #endif diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c index 36c85d60..d7613530 100644 --- a/src/pulsecore/cli-command.c +++ b/src/pulsecore/cli-command.c @@ -115,6 +115,8 @@ static int pa_cli_command_list_props(pa_core *c, pa_tokenizer *t, pa_strbuf *buf static int pa_cli_command_move_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); static int pa_cli_command_move_source_output(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); static int pa_cli_command_vacuum(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); +static int pa_cli_command_suspend_sink(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); +static int pa_cli_command_suspend_source(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); /* A method table for all available commands */ @@ -134,11 +136,11 @@ static const struct command commands[] = { { "load-module", pa_cli_command_load, "Load a module (args: name, arguments)", 3}, { "unload-module", pa_cli_command_unload, "Unload a module (args: index)", 2}, { "set-sink-volume", pa_cli_command_sink_volume, "Set the volume of a sink (args: index|name, volume)", 3}, - { "set-sink-input-volume", pa_cli_command_sink_input_volume, "Set the volume of a sink input (args: index|name, volume)", 3}, + { "set-sink-input-volume", pa_cli_command_sink_input_volume, "Set the volume of a sink input (args: index, volume)", 3}, { "set-source-volume", pa_cli_command_source_volume, "Set the volume of a source (args: index|name, volume)", 3}, - { "set-sink-mute", pa_cli_command_sink_mute, "Set the mute switch of a sink (args: index|name, mute)", 3}, - { "set-sink-input-mute", pa_cli_command_sink_input_mute, "Set the mute switch of a sink input (args: index|name, mute)", 3}, - { "set-source-mute", pa_cli_command_source_mute, "Set the mute switch of a source (args: index|name, mute)", 3}, + { "set-sink-mute", pa_cli_command_sink_mute, "Set the mute switch of a sink (args: index|name, bool)", 3}, + { "set-sink-input-mute", pa_cli_command_sink_input_mute, "Set the mute switch of a sink input (args: index, bool)", 3}, + { "set-source-mute", pa_cli_command_source_mute, "Set the mute switch of a source (args: index|name, bool)", 3}, { "set-default-sink", pa_cli_command_sink_default, "Set the default sink (args: index|name)", 2}, { "set-default-source", pa_cli_command_source_default, "Set the default source (args: index|name)", 2}, { "kill-client", pa_cli_command_kill_client, "Kill a client (args: index)", 2}, @@ -161,6 +163,8 @@ static const struct command commands[] = { { "move-sink-input", pa_cli_command_move_sink_input, "Move sink input to another sink (args: index, sink)", 3}, { "move-source-output", pa_cli_command_move_source_output, "Move source output to another source (args: index, source)", 3}, { "vacuum", pa_cli_command_vacuum, NULL, 1}, + { "suspend-sink", pa_cli_command_suspend_sink, "Suspend sink (args: index|name, bool)", 3}, + { "suspend-source", pa_cli_command_suspend_source, "Suspend source (args: index|name, bool)", 3}, { NULL, NULL, NULL, 0 } }; @@ -899,6 +903,64 @@ static int pa_cli_command_move_source_output(pa_core *c, pa_tokenizer *t, pa_str return 0; } +static int pa_cli_command_suspend_sink(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { + const char *n, *m; + pa_sink *sink; + int suspend; + + if (!(n = pa_tokenizer_get(t, 1))) { + pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n"); + return -1; + } + + if (!(m = pa_tokenizer_get(t, 2))) { + pa_strbuf_puts(buf, "You need to specify a suspend switch setting (0/1).\n"); + return -1; + } + + if (pa_atoi(m, &suspend) < 0) { + pa_strbuf_puts(buf, "Failed to parse suspend switch.\n"); + return -1; + } + + if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK, 1))) { + pa_strbuf_puts(buf, "No sink found by this name or index.\n"); + return -1; + } + + pa_sink_suspend(sink, suspend); + return 0; +} + +static int pa_cli_command_suspend_source(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { + const char *n, *m; + pa_source *source; + int suspend; + + if (!(n = pa_tokenizer_get(t, 1))) { + pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n"); + return -1; + } + + if (!(m = pa_tokenizer_get(t, 2))) { + pa_strbuf_puts(buf, "You need to specify a suspend switch setting (0/1).\n"); + return -1; + } + + if (pa_atoi(m, &suspend) < 0) { + pa_strbuf_puts(buf, "Failed to parse suspend switch.\n"); + return -1; + } + + if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE, 1))) { + pa_strbuf_puts(buf, "No source found by this name or index.\n"); + return -1; + } + + pa_source_suspend(source, suspend); + return 0; +} + static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { pa_module *m; pa_sink *sink; @@ -1162,3 +1224,4 @@ int pa_cli_command_execute(pa_core *c, const char *s, pa_strbuf *buf, int *fail) return 0; } + diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c index 05d681e3..c919e46d 100644 --- a/src/pulsecore/cli-text.c +++ b/src/pulsecore/cli-text.c @@ -114,14 +114,15 @@ char *pa_sink_list_to_string(pa_core *c) { " %c index: %u\n" "\tname: <%s>\n" "\tdriver: <%s>\n" - "\tis_hardware: <%i>\n" + "\tis hardware: <%i>\n" "\tstate: %s\n" "\tvolume: <%s>\n" "\tmute: <%i>\n" "\tlatency: <%0.0f usec>\n" - "\tmonitor_source: <%u>\n" + "\tmonitor source: <%u>\n" "\tsample spec: <%s>\n" - "\tchannel map: <%s>\n", + "\tchannel map: <%s>\n" + "\tused by: <%u>\n", c->default_sink_name && !strcmp(sink->name, c->default_sink_name) ? '*' : ' ', sink->index, sink->name, @@ -133,7 +134,8 @@ char *pa_sink_list_to_string(pa_core *c) { (double) pa_sink_get_latency(sink), sink->monitor_source ? sink->monitor_source->index : PA_INVALID_INDEX, pa_sample_spec_snprint(ss, sizeof(ss), &sink->sample_spec), - pa_channel_map_snprint(cm, sizeof(cm), &sink->channel_map)); + pa_channel_map_snprint(cm, sizeof(cm), &sink->channel_map), + pa_sink_used_by(sink)); if (sink->module) pa_strbuf_printf(s, "\tmodule: <%u>\n", sink->module->index); @@ -170,13 +172,14 @@ char *pa_source_list_to_string(pa_core *c) { " %c index: %u\n" "\tname: <%s>\n" "\tdriver: <%s>\n" - "\tis_hardware: <%i>\n" + "\tis hardware: <%i>\n" "\tstate: %s\n" "\tvolume: <%s>\n" "\tmute: <%u>\n" "\tlatency: <%0.0f usec>\n" "\tsample spec: <%s>\n" - "\tchannel map: <%s>\n", + "\tchannel map: <%s>\n" + "\tused by: <%u>\n", c->default_source_name && !strcmp(source->name, c->default_source_name) ? '*' : ' ', source->index, source->name, @@ -187,7 +190,8 @@ char *pa_source_list_to_string(pa_core *c) { !!pa_source_get_mute(source), (double) pa_source_get_latency(source), pa_sample_spec_snprint(ss, sizeof(ss), &source->sample_spec), - pa_channel_map_snprint(cm, sizeof(cm), &source->channel_map)); + pa_channel_map_snprint(cm, sizeof(cm), &source->channel_map), + pa_source_used_by(source)); if (source->monitor_of) pa_strbuf_printf(s, "\tmonitor_of: <%u>\n", source->monitor_of->index); diff --git a/src/pulsecore/core-subscribe.c b/src/pulsecore/core-subscribe.c index 6608d57a..288d1078 100644 --- a/src/pulsecore/core-subscribe.c +++ b/src/pulsecore/core-subscribe.c @@ -207,7 +207,7 @@ static void sched_event(pa_core *c) { } /* Append a new subscription event to the subscription event queue and schedule a main loop event */ -void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t index) { +void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t idx) { pa_subscription_event *e; assert(c); @@ -227,7 +227,7 @@ void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t i continue; /* not the same object */ - if (i->index != index) + if (i->index != idx) continue; if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -253,7 +253,7 @@ void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t i e = pa_xnew(pa_subscription_event, 1); e->core = c; e->type = t; - e->index = index; + e->index = idx; PA_LLIST_INSERT_AFTER(pa_subscription_event, c->subscription_event_queue, c->subscription_event_last, e); c->subscription_event_last = e; diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c index 99ac74e1..a940bfc0 100644 --- a/src/pulsecore/core.c +++ b/src/pulsecore/core.c @@ -49,6 +49,8 @@ #include "core.h" +static PA_DEFINE_CHECK_TYPE(pa_core, core_check_type, pa_msgobject_check_type); + static int core_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk) { pa_core *c = PA_CORE(o); @@ -81,8 +83,10 @@ static void asyncmsgq_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_even /* Check whether there is a message for us to process */ while (pa_asyncmsgq_get(c->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { - pa_asyncmsgq_dispatch(object, code, data, &chunk); - pa_asyncmsgq_done(c->asyncmsgq, 0); + int ret; + + ret = pa_asyncmsgq_dispatch(object, code, data, &chunk); + pa_asyncmsgq_done(c->asyncmsgq, ret); } if (pa_asyncmsgq_before_poll(c->asyncmsgq) == 0) @@ -112,7 +116,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { } } - c = pa_msgobject_new(pa_core); + c = pa_msgobject_new(pa_core, core_check_type); c->parent.parent.free = core_free; c->parent.process_msg = core_process_msg; @@ -181,7 +185,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { static void core_free(pa_object *o) { pa_core *c = PA_CORE(o); - pa_core_assert_ref(c); + pa_assert(c); pa_module_unload_all(c); assert(!c->modules); @@ -212,13 +216,14 @@ static void core_free(pa_object *o) { pa_xfree(c->default_source_name); pa_xfree(c->default_sink_name); + pa_asyncmsgq_after_poll(c->asyncmsgq); + pa_asyncmsgq_free(c->asyncmsgq); + pa_mempool_free(c->mempool); pa_property_cleanup(c); c->mainloop->io_free(c->asyncmsgq_event); - pa_asyncmsgq_after_poll(c->asyncmsgq); - pa_asyncmsgq_free(c->asyncmsgq); pa_hook_free(&c->hook_sink_input_new); pa_hook_free(&c->hook_sink_disconnect); diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index 86660b7a..a64f2179 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -98,7 +98,7 @@ struct pa_core { }; PA_DECLARE_CLASS(pa_core); -#define PA_CORE(o) ((pa_core*) o) +#define PA_CORE(o) pa_core_cast(o) enum { PA_CORE_MESSAGE_UNLOAD_MODULE, diff --git a/src/pulsecore/log.c b/src/pulsecore/log.c index 0033adb9..a1197eb5 100644 --- a/src/pulsecore/log.c +++ b/src/pulsecore/log.c @@ -71,14 +71,11 @@ static const char level_to_char[] = { }; void pa_log_set_ident(const char *p) { - if (log_ident) - pa_xfree(log_ident); - if (log_ident_local) - pa_xfree(log_ident_local); + pa_xfree(log_ident); + pa_xfree(log_ident_local); log_ident = pa_xstrdup(p); - log_ident_local = pa_utf8_to_locale(log_ident); - if (!log_ident_local) + if (!(log_ident_local = pa_utf8_to_locale(log_ident))) log_ident_local = pa_xstrdup(log_ident); } diff --git a/src/pulsecore/msgobject.c b/src/pulsecore/msgobject.c index ce9f22f2..6db630c5 100644 --- a/src/pulsecore/msgobject.c +++ b/src/pulsecore/msgobject.c @@ -28,13 +28,15 @@ #include "msgobject.h" -pa_msgobject *pa_msgobject_new_internal(size_t size, const char *type_name) { +PA_DEFINE_CHECK_TYPE(pa_msgobject, pa_msgobject_check_type, pa_object_check_type); + +pa_msgobject *pa_msgobject_new_internal(size_t size, const char *type_name, int (*check_type)(pa_object *o, const char *type_name)) { pa_msgobject *o; pa_assert(size > sizeof(pa_msgobject)); pa_assert(type_name); - o = PA_MSGOBJECT(pa_object_new_internal(size, type_name)); + o = PA_MSGOBJECT(pa_object_new_internal(size, type_name, check_type ? check_type : pa_msgobject_check_type)); o->process_msg = NULL; return o; } diff --git a/src/pulsecore/msgobject.h b/src/pulsecore/msgobject.h index 317ebd20..65761aea 100644 --- a/src/pulsecore/msgobject.h +++ b/src/pulsecore/msgobject.h @@ -40,12 +40,14 @@ struct pa_msgobject { int (*process_msg)(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk); }; -pa_msgobject *pa_msgobject_new_internal(size_t size, const char *type_name); +pa_msgobject *pa_msgobject_new_internal(size_t size, const char *type_name, int (*check_type)(pa_object *o, const char *type_name)); -#define pa_msgobject_new(type) ((type*) pa_msgobject_new_internal(sizeof(type), #type)) +int pa_msgobject_check_type(pa_object *o, const char *type); + +#define pa_msgobject_new(type, check_type) ((type*) pa_msgobject_new_internal(sizeof(type), #type, check_type)) #define pa_msgobject_free ((void (*) (pa_msgobject* o)) pa_object_free) -#define PA_MSGOBJECT(o) ((pa_msgobject*) (o)) +#define PA_MSGOBJECT(o) pa_msgobject_cast(o) PA_DECLARE_CLASS(pa_msgobject); diff --git a/src/pulsecore/object.c b/src/pulsecore/object.c index e6ed53b2..a983c5ae 100644 --- a/src/pulsecore/object.c +++ b/src/pulsecore/object.c @@ -28,7 +28,7 @@ #include "object.h" -pa_object *pa_object_new_internal(size_t size, const char *type_name) { +pa_object *pa_object_new_internal(size_t size, const char *type_name, int (*check_type)(pa_object *o, const char *type_name)) { pa_object *o; pa_assert(size > sizeof(pa_object)); @@ -38,24 +38,30 @@ pa_object *pa_object_new_internal(size_t size, const char *type_name) { PA_REFCNT_INIT(o); o->type_name = type_name; o->free = pa_object_free; + o->check_type = check_type ? check_type : pa_object_check_type; return o; } pa_object *pa_object_ref(pa_object *o) { - pa_assert(o); - pa_assert(PA_REFCNT_VALUE(o) >= 1); + pa_object_assert_ref(o); PA_REFCNT_INC(o); return o; } void pa_object_unref(pa_object *o) { - pa_assert(o); - pa_assert(PA_REFCNT_VALUE(o) >= 1); + pa_object_assert_ref(o); if (PA_REFCNT_DEC(o) <= 0) { pa_assert(o->free); o->free(o); } } + +int pa_object_check_type(pa_object *o, const char *type_name) { + pa_assert(o); + pa_assert(type_name); + + return type_name == "pa_object" || strcmp(type_name, "pa_object") == 0; +} diff --git a/src/pulsecore/object.h b/src/pulsecore/object.h index e195a359..270f289d 100644 --- a/src/pulsecore/object.h +++ b/src/pulsecore/object.h @@ -25,7 +25,9 @@ USA. ***/ +#include #include + #include #include #include @@ -36,13 +38,22 @@ struct pa_object { PA_REFCNT_DECLARE; const char *type_name; void (*free)(pa_object *o); + int (*check_type)(pa_object *o, const char *type_name); }; -pa_object *pa_object_new_internal(size_t size, const char *type_name); -#define pa_object_new(type) ((type*) pa_object_new_internal(sizeof(type), #type)) +pa_object *pa_object_new_internal(size_t size, const char *type_name, int (*check_type)(pa_object *o, const char *type_name)); +#define pa_object_new(type, check_type) ((type*) pa_object_new_internal(sizeof(type), #type, check_type) #define pa_object_free ((void (*) (pa_object* o)) pa_xfree) +int pa_object_check_type(pa_object *o, const char *type); + +static inline int pa_object_isinstance(void *o) { + pa_object *obj = (pa_object*) o; + pa_assert(obj); + return obj->check_type(obj, "pa_object"); +} + pa_object *pa_object_ref(pa_object *o); void pa_object_unref(pa_object *o); @@ -50,23 +61,50 @@ static inline int pa_object_refcnt(pa_object *o) { return o ? PA_REFCNT_VALUE(o) : 0; } +static inline pa_object* pa_object_cast(void *o) { + pa_object *obj = (pa_object*) o; + pa_assert(obj->check_type(obj, "pa_object")); + return obj; +} + #define pa_object_assert_ref(o) pa_assert(pa_object_refcnt(o)) -#define PA_OBJECT(o) ((pa_object*) (o)) - -#define PA_DECLARE_CLASS(c) \ - static inline c* c##_ref(c *o) { \ - return (c*) pa_object_ref(PA_OBJECT(o)); \ - } \ - static inline void c##_unref(c* o) { \ - pa_object_unref(PA_OBJECT(o)); \ - } \ - static inline int c##_refcnt(c* o) { \ - return pa_object_refcnt(PA_OBJECT(o)); \ - } \ - static inline void c##_assert_ref(c *o) { \ - pa_object_assert_ref(PA_OBJECT(o)); \ - } \ +#define PA_OBJECT(o) pa_object_cast(o) + +#define PA_DECLARE_CLASS(c) \ + static inline int c##_isinstance(void *o) { \ + pa_object *obj = (pa_object*) o; \ + pa_assert(obj); \ + return obj->check_type(obj, #c); \ + } \ + static inline c* c##_cast(void *o) { \ + pa_assert(c##_isinstance(o)); \ + return (c*) o; \ + } \ + static inline c* c##_ref(c *o) { \ + return (c*) pa_object_ref(PA_OBJECT(o)); \ + } \ + static inline void c##_unref(c* o) { \ + pa_object_unref(PA_OBJECT(o)); \ + } \ + static inline int c##_refcnt(c* o) { \ + return pa_object_refcnt(PA_OBJECT(o)); \ + } \ + static inline void c##_assert_ref(c *o) { \ + pa_object_assert_ref(PA_OBJECT(o)); \ + } \ + struct __stupid_useless_struct_to_allow_trailing_semicolon + +#define PA_DEFINE_CHECK_TYPE(c, func, parent) \ + int func(pa_object *o, const char *type) { \ + pa_assert(o); \ + pa_assert(type); \ + if (type == #c || \ + strcmp(type, #c) == 0) \ + return 1; \ + return parent(o, type); \ + } \ struct __stupid_useless_struct_to_allow_trailing_semicolon + #endif diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index b7a4cc78..67741bde 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -40,13 +40,15 @@ #include #include #include +#include #include "protocol-simple.h" /* Don't allow more than this many concurrent connections */ #define MAX_CONNECTIONS 10 -struct connection { +typedef struct connection { + pa_msgobject parent; pa_protocol_simple *protocol; pa_iochannel *io; pa_sink_input *sink_input; @@ -59,18 +61,21 @@ struct connection { struct { pa_memblock *current_memblock; size_t memblock_index, fragment_size; - pa_atomic_int missing; + pa_atomic_t missing; } playback; -}; +} connection; + +PA_DECLARE_CLASS(connection); +#define CONNECTION(o) (connection_cast(o)) +static PA_DEFINE_CHECK_TYPE(connection, connection_check_type, pa_msgobject_check_type); + struct pa_protocol_simple { pa_module *module; pa_core *core; pa_socket_server*server; pa_idxset *connections; - pa_asyncmsgq *asyncmsgq; - enum { RECORD = 1, PLAYBACK = 2, @@ -86,8 +91,9 @@ enum { }; enum { - MESSAGE_REQUEST_DATA, /* data from source output to main loop */ - MESSAGE_POST_DATA /* data from source output to main loop */ + MESSAGE_REQUEST_DATA, /* data requested from sink input from the main loop */ + MESSAGE_POST_DATA, /* data from source output to main loop */ + MESSAGE_DROP_CONNECTION /* Please drop a aconnection now */ }; @@ -96,37 +102,49 @@ enum { #define RECORD_BUFFER_SECONDS (5) #define RECORD_BUFFER_FRAGMENTS (100) -static void connection_free(struct connection *c) { +static void connection_free(pa_object *o) { + connection *c = CONNECTION(o); pa_assert(c); + if (c->playback.current_memblock) + pa_memblock_unref(c->playback.current_memblock); + + if (c->io) + pa_iochannel_free(c->io); + if (c->input_memblockq) + pa_memblockq_free(c->input_memblockq); + if (c->output_memblockq) + pa_memblockq_free(c->output_memblockq); + + pa_xfree(c); +} + +static void connection_drop(connection *c) { + pa_assert(c); + pa_idxset_remove_by_data(c->protocol->connections, c, NULL); if (c->sink_input) { pa_sink_input_disconnect(c->sink_input); pa_sink_input_unref(c->sink_input); + c->sink_input = NULL; } if (c->source_output) { pa_source_output_disconnect(c->source_output); pa_source_output_unref(c->source_output); + c->source_output = NULL; } - if (c->playback.current_memblock) - pa_memblock_unref(c->playback.current_memblock); - - if (c->client) + if (c->client) { pa_client_free(c->client); - if (c->io) - pa_iochannel_free(c->io); - if (c->input_memblockq) - pa_memblockq_free(c->input_memblockq); - if (c->output_memblockq) - pa_memblockq_free(c->output_memblockq); + c->client = NULL; + } - pa_xfree(c); + connection_unref(c); } -static int do_read(struct connection *c) { +static int do_read(connection *c) { pa_memchunk chunk; ssize_t r; size_t l; @@ -171,17 +189,17 @@ static int do_read(struct connection *c) { c->playback.memblock_index += r; - pa_asyncmsgq_post(c->protocol->asyncmsgq, c, MESSAGE_POST_DATA, NULL, &chunk, NULL, NULL); + pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, &chunk, NULL); return 0; } -static int do_write(struct connection *c) { +static int do_write(connection *c) { pa_memchunk chunk; ssize_t r; void *p; - p_assert(c); + pa_assert(c); if (!c->source_output) return 0; @@ -212,7 +230,7 @@ static int do_write(struct connection *c) { return 0; } -static void do_work(struct connection *c) { +static void do_work(connection *c) { pa_assert(c); if (c->dead) @@ -243,14 +261,39 @@ fail: pa_memblockq_prebuf_disable(c->input_memblockq); } else - connection_free(c); + connection_drop(c); +} + +static int connection_process_msg(pa_msgobject *o, int code, void*userdata, pa_memchunk *chunk) { + connection *c = CONNECTION(o); + + connection_assert_ref(c); + + switch (code) { + case MESSAGE_REQUEST_DATA: + do_work(c); + break; + + case MESSAGE_POST_DATA: + pa_memblockq_push(c->output_memblockq, chunk); + do_work(c); + break; + + case MESSAGE_DROP_CONNECTION: + connection_drop(c); + break; + + } + + return 0; } /*** sink_input callbacks ***/ /* Called from thread context */ -static int sink_input_process_msg(pa_sink_input *i, int code, void *userdata, const pa_memchunk *chunk) { - struct connection*c; +static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk) { + pa_sink_input *i = PA_SINK_INPUT(o); + connection*c; pa_assert(i); c = i->userdata; @@ -263,6 +306,8 @@ static int sink_input_process_msg(pa_sink_input *i, int code, void *userdata, co /* New data from the main loop */ pa_memblockq_push_align(c->input_memblockq, chunk); + pa_atomic_store(&c->playback.missing, pa_memblockq_missing(c->input_memblockq)); + return 0; } @@ -276,13 +321,14 @@ static int sink_input_process_msg(pa_sink_input *i, int code, void *userdata, co } default: - return pa_sink_input_process_msg(i, code, userdata); + return pa_sink_input_process_msg(o, code, userdata, chunk); } } /* Called from thread context */ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { - struct connection*c; + connection*c; + int r; pa_assert(i); c = i->userdata; @@ -292,14 +338,14 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { r = pa_memblockq_peek(c->input_memblockq, chunk); if (c->dead && r < 0) - connection_free(c); + pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), MESSAGE_DROP_CONNECTION, c, NULL, NULL); return r; } /* Called from thread context */ static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_t length) { - struct connection*c = i->userdata; + connection*c = i->userdata; size_t old, new; pa_assert(i); @@ -310,10 +356,10 @@ static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_ pa_memblockq_drop(c->input_memblockq, chunk, length); new = pa_memblockq_missing(c->input_memblockq); - pa_atomic_store(&c->playback.missing, &new); + pa_atomic_store(&c->playback.missing, new); if (new > old) - pa_asyncmsgq_post(c->protocol->asyncmsgq, c, MESSAGE_REQUEST_DATA, NULL, NULL, NULL, NULL); + pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), MESSAGE_REQUEST_DATA, NULL, NULL, NULL); } /* Called from main context */ @@ -321,34 +367,34 @@ static void sink_input_kill_cb(pa_sink_input *i) { pa_assert(i); pa_assert(i->userdata); - connection_free((struct connection *) i->userdata); + connection_drop((connection *) i->userdata); } /*** source_output callbacks ***/ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) { - struct connection *c; + connection *c; pa_assert(o); c = o->userdata; pa_assert(c); pa_assert(chunk); - pa_asyncmsgq_post(c->protocol->asyncmsgq, c, MESSAGE_REQUEST_DATA, NULL, chunk, NULL, NULL); + pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), MESSAGE_POST_DATA, NULL, chunk, NULL); } static void source_output_kill_cb(pa_source_output *o) { - struct connection*c; + connection*c; pa_assert(o); c = o->userdata; pa_assert(c); - connection_free(c); + connection_drop(c); } static pa_usec_t source_output_get_latency_cb(pa_source_output *o) { - struct connection*c; + connection*c; pa_assert(o); c = o->userdata; @@ -360,19 +406,19 @@ static pa_usec_t source_output_get_latency_cb(pa_source_output *o) { /*** client callbacks ***/ static void client_kill_cb(pa_client *client) { - struct connection*c; + connection*c; pa_assert(client); c = client->userdata; pa_assert(c); - connection_free(client); + connection_drop(c); } /*** pa_iochannel callbacks ***/ static void io_callback(pa_iochannel*io, void *userdata) { - struct connection *c = userdata; + connection *c = userdata; pa_assert(io); pa_assert(c); @@ -384,7 +430,7 @@ static void io_callback(pa_iochannel*io, void *userdata) { static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) { pa_protocol_simple *p = userdata; - struct connection *c = NULL; + connection *c = NULL; char cname[256]; pa_assert(s); @@ -397,7 +443,9 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) return; } - c = pa_xnew(struct connection, 1); + c = pa_msgobject_new(connection, connection_check_type); + c->parent.parent.free = connection_free; + c->parent.process_msg = connection_process_msg; c->io = io; c->sink_input = NULL; c->source_output = NULL; @@ -415,7 +463,6 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) c->client->kill = client_kill_cb; c->client->userdata = c; - if (p->mode & PLAYBACK) { pa_sink_input_new_data data; size_t l; @@ -432,10 +479,10 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) goto fail; } + c->sink_input->parent.process_msg = sink_input_process_msg; c->sink_input->peek = sink_input_peek_cb; c->sink_input->drop = sink_input_drop_cb; c->sink_input->kill = sink_input_kill_cb; - c->sink_input->get_latency = sink_input_get_latency_cb; c->sink_input->userdata = c; l = (size_t) (pa_bytes_per_second(&p->sample_spec)*PLAYBACK_BUFFER_SECONDS); @@ -449,7 +496,7 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) NULL); pa_assert(c->input_memblockq); pa_iochannel_socket_set_rcvbuf(io, l/PLAYBACK_BUFFER_FRAGMENTS*5); - c->playback.fragment_size = l/10; + c->playback.fragment_size = l/PLAYBACK_BUFFER_FRAGMENTS; pa_atomic_store(&c->playback.missing, pa_memblockq_missing(c->input_memblockq)); @@ -498,47 +545,7 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) fail: if (c) - connection_free(c); -} - -static void asyncmsgq_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) { - pa_protocol_simple *p = userdata; - int do_some_work = 0; - - pa_assert(pa_asyncmsgq_get_fd(p->asyncmsgq) == fd); - pa_assert(events == PA_IO_EVENT_INPUT); - - pa_asyncmsgq_after_poll(p->asyncmsgq); - - for (;;) { - int code; - void *object, *data; - - /* Check whether there is a message for us to process */ - while (pa_asyncmsgq_get(p->asyncmsgq, &object, &code, &data) == 0) { - - connection *c = object; - - pa_assert(c); - - switch (code) { - - case MESSAGE_REQUEST_DATA: - do_work(c); - break; - - case MESSAGE_POST_DATA: - pa_memblockq_push(c->output_memblockq, chunk); - do_work(c); - break; - } - - pa_asyncmsgq_done(p->asyncmsgq); - } - - if (pa_asyncmsgq_before_poll(p->asyncmsgq) == 0) - break; - } + connection_drop(c); } pa_protocol_simple* pa_protocol_simple_new(pa_core *core, pa_socket_server *server, pa_module *m, pa_modargs *ma) { @@ -554,7 +561,6 @@ pa_protocol_simple* pa_protocol_simple_new(pa_core *core, pa_socket_server *serv p->core = core; p->server = server; p->connections = pa_idxset_new(NULL, NULL); - pa_assert_se(p->asyncmsgq = pa_asyncmsgq_new(0)); p->sample_spec = core->default_sample_spec; if (pa_modargs_get_sample_spec(ma, &p->sample_spec) < 0) { @@ -586,9 +592,6 @@ pa_protocol_simple* pa_protocol_simple_new(pa_core *core, pa_socket_server *serv pa_socket_server_set_callback(p->server, on_connection, p); - pa_assert_se(pa_asyncmsgq_before_poll(p->asyncmsgq) == 0); - pa_assert_se(p->asyncmsgq_event = core->mainloop->io_event_new(core->mainloop, pa_asyncmsgq_get_fd(p->asyncmsgq), PA_IO_EVENT_INPUT, p)); - return p; fail: @@ -600,12 +603,12 @@ fail: void pa_protocol_simple_free(pa_protocol_simple *p) { - struct connection *c; + connection *c; pa_assert(p); if (p->connections) { while((c = pa_idxset_first(p->connections, NULL))) - connection_free(c); + connection_drop(c); pa_idxset_free(p->connections, NULL, NULL); } @@ -613,12 +616,6 @@ void pa_protocol_simple_free(pa_protocol_simple *p) { if (p->server) pa_socket_server_unref(p->server); - if (p->asyncmsgq) { - c->mainloop->io_event_free(c->asyncmsgq_event); - pa_asyncmsgq_after_poll(c->asyncmsgq); - pa_asyncmsgq_free(p->asyncmsgq); - } - pa_xfree(p); } diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index 248d7337..a43c7c7c 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -48,6 +48,7 @@ struct pa_resampler { void (*impl_free)(pa_resampler *r); void (*impl_update_input_rate)(pa_resampler *r, uint32_t rate); + void (*impl_update_output_rate)(pa_resampler *r, uint32_t rate); void (*impl_run)(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out); void *impl_data; }; @@ -165,6 +166,19 @@ void pa_resampler_set_input_rate(pa_resampler *r, uint32_t rate) { r->impl_update_input_rate(r, rate); } +void pa_resampler_set_output_rate(pa_resampler *r, uint32_t rate) { + assert(r); + assert(rate > 0); + + if (r->o_ss.rate == rate) + return; + + r->o_ss.rate = rate; + + if (r->impl_update_output_rate) + r->impl_update_output_rate(r, rate); +} + void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) { assert(r && in && out && r->impl_run); @@ -512,6 +526,25 @@ static void libsamplerate_update_input_rate(pa_resampler *r, uint32_t rate) { } } + +static void libsamplerate_update_output_rate(pa_resampler *r, uint32_t rate) { + struct impl_libsamplerate *u; + + assert(r); + assert(rate > 0); + assert(r->impl_data); + u = r->impl_data; + + if (!u->src_state) { + int err; + u->src_state = src_new(r->resample_method, r->o_ss.channels, &err); + assert(u->src_state); + } else { + int ret = src_set_ratio(u->src_state, (double) rate / r->i_ss.rate); + assert(ret == 0); + } +} + static int libsamplerate_init(pa_resampler *r) { struct impl_libsamplerate *u = NULL; int err; @@ -541,6 +574,7 @@ static int libsamplerate_init(pa_resampler *r) { r->impl_free = libsamplerate_free; r->impl_update_input_rate = libsamplerate_update_input_rate; + r->impl_update_output_rate = libsamplerate_update_output_rate; r->impl_run = libsamplerate_run; calc_map_table(r); @@ -631,7 +665,7 @@ static void trivial_free(pa_resampler *r) { pa_xfree(r->impl_data); } -static void trivial_update_input_rate(pa_resampler *r, uint32_t rate) { +static void trivial_update_rate(pa_resampler *r, uint32_t rate) { struct impl_trivial *u; assert(r); @@ -655,7 +689,8 @@ static int trivial_init(pa_resampler*r) { r->impl_run = trivial_run; r->impl_free = trivial_free; - r->impl_update_input_rate = trivial_update_input_rate; + r->impl_update_input_rate = trivial_update_rate; + r->impl_update_output_rate = trivial_update_rate; return 0; } diff --git a/src/pulsecore/resampler.h b/src/pulsecore/resampler.h index c283593d..ada293e5 100644 --- a/src/pulsecore/resampler.h +++ b/src/pulsecore/resampler.h @@ -63,6 +63,9 @@ void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out); /* Change the input rate of the resampler object */ void pa_resampler_set_input_rate(pa_resampler *r, uint32_t rate); +/* Change the output rate of the resampler object */ +void pa_resampler_set_output_rate(pa_resampler *r, uint32_t rate); + /* Return the resampling method of the resampler object */ pa_resample_method_t pa_resampler_get_method(pa_resampler *r); diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 00b82d26..2c6b356c 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -45,7 +45,9 @@ #define MOVE_BUFFER_LENGTH (1024*1024) #define SILENCE_BUFFER_LENGTH (64*1024) -static void sink_input_free(pa_msgobject *o); +static PA_DEFINE_CHECK_TYPE(pa_sink_input, sink_input_check_type, pa_msgobject_check_type); + +static void sink_input_free(pa_object *o); pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data) { pa_assert(data); @@ -159,13 +161,12 @@ pa_sink_input* pa_sink_input_new( data->resample_method = pa_resampler_get_method(resampler); } - i = pa_msgobject_new(pa_sink_input); - + i = pa_msgobject_new(pa_sink_input, sink_input_check_type); i->parent.parent.free = sink_input_free; i->parent.process_msg = pa_sink_input_process_msg; i->core = core; - pa_atomic_load(&i->state, PA_SINK_INPUT_DRAINED); + pa_atomic_store(&i->state, PA_SINK_INPUT_DRAINED); i->flags = flags; i->name = pa_xstrdup(data->name); i->driver = pa_xstrdup(data->driver); @@ -189,11 +190,11 @@ pa_sink_input* pa_sink_input_new( i->userdata = NULL; i->thread_info.silence_memblock = NULL; - i->thread_info.move_silence = 0; +/* i->thread_info.move_silence = 0; */ pa_memchunk_reset(&i->thread_info.resampled_chunk); i->thread_info.resampler = resampler; - i->thread_info.soft_volume = i->volume; - i->thread_info.soft_muted = i->muted; + i->thread_info.volume = i->volume; + i->thread_info.muted = i->muted; pa_assert_se(pa_idxset_put(core->sink_inputs, i, &i->index) == 0); pa_assert_se(pa_idxset_put(i->sink->inputs, i, NULL) == 0); @@ -213,14 +214,16 @@ void pa_sink_input_disconnect(pa_sink_input *i) { pa_assert(i); pa_return_if_fail(pa_sink_input_get_state(i) != PA_SINK_INPUT_DISCONNECTED); - pa_asyncmsgq_send(i->sink->asyncmsgq, i->sink, PA_SINK_MESSAGE_REMOVE_INPUT, i, NULL); + pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, NULL); pa_idxset_remove_by_data(i->sink->core->sink_inputs, i, NULL); pa_idxset_remove_by_data(i->sink->inputs, i, NULL); pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE, i->index); - i->sink = NULL; + pa_sink_update_status(i->sink); + + i->sink = NULL; i->process_msg = NULL; i->peek = NULL; i->drop = NULL; @@ -228,10 +231,10 @@ void pa_sink_input_disconnect(pa_sink_input *i) { i->get_latency = NULL; i->underrun = NULL; - pa_atomic_load(&i->state, PA_SINK_INPUT_DISCONNECTED); + pa_atomic_store(&i->state, PA_SINK_INPUT_DISCONNECTED); } -static void sink_input_free(pa_msgobject *o) { +static void sink_input_free(pa_object *o) { pa_sink_input* i = PA_SINK_INPUT(o); pa_assert(i); @@ -241,8 +244,8 @@ static void sink_input_free(pa_msgobject *o) { pa_log_info("Freeing output %u \"%s\"", i->index, i->name); - if (i->resampled_chunk.memblock) - pa_memblock_unref(i->resampled_chunk.memblock); + if (i->thread_info.resampled_chunk.memblock) + pa_memblock_unref(i->thread_info.resampled_chunk.memblock); if (i->thread_info.resampler) pa_resampler_free(i->thread_info.resampler); @@ -261,10 +264,10 @@ void pa_sink_input_put(pa_sink_input *i) { i->thread_info.volume = i->volume; i->thread_info.muted = i->muted; - pa_asyncmsgq_post(i->sink->asyncmsgq, i->sink, PA_SINK_MESSAGE_ADD_INPUT, i, NULL, pa_sink_unref, pa_sink_input_unref); + pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, pa_sink_input_ref(i), NULL, (pa_free_cb_t) pa_sink_input_unref); pa_sink_update_status(i->sink); - pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index); + pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index); } void pa_sink_input_kill(pa_sink_input*i) { @@ -279,7 +282,7 @@ pa_usec_t pa_sink_input_get_latency(pa_sink_input *i) { pa_sink_input_assert_ref(i); - if (pa_asyncmsgq_send(i->sink->asyncmsgq, i->sink, PA_SINK_INPUT_MESSAGE_GET_LATENCY, &r, NULL) < 0) + if (pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_LATENCY, &r, NULL) < 0) r = 0; if (i->get_latency) @@ -327,14 +330,14 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) /* goto finish; */ /* } */ - if (!i->resampler) { + if (!i->thread_info.resampler) { do_volume_adj_here = 0; ret = i->peek(i, chunk); goto finish; } do_volume_adj_here = !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map); - volume_is_norm = pa_cvolume_is_norm(&i->thread_info.soft_volume) && !i->thread_info.soft_muted; + volume_is_norm = pa_cvolume_is_norm(&i->thread_info.volume) && !i->thread_info.muted; while (!i->thread_info.resampled_chunk.memblock) { pa_memchunk tchunk; @@ -345,7 +348,7 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) pa_assert(tchunk.length); - l = pa_resampler_request(i->resampler, CONVERT_BUFFER_LENGTH); + l = pa_resampler_request(i->thread_info.resampler, CONVERT_BUFFER_LENGTH); if (l > tchunk.length) l = tchunk.length; @@ -356,10 +359,10 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) /* It might be necessary to adjust the volume here */ if (do_volume_adj_here && !volume_is_norm) { pa_memchunk_make_writable(&tchunk, 0); - pa_volume_memchunk(&tchunk, &i->sample_spec, &i->thread_info.soft_volume); + pa_volume_memchunk(&tchunk, &i->sample_spec, &i->thread_info.volume); } - pa_resampler_run(i->resampler, &tchunk, &i->thread_info.resampled_chunk); + pa_resampler_run(i->thread_info.resampler, &tchunk, &i->thread_info.resampled_chunk); pa_memblock_unref(tchunk.memblock); } @@ -378,7 +381,7 @@ finish: if (ret >= 0) pa_atomic_cmpxchg(&i->state, state, PA_SINK_INPUT_RUNNING); - else if (ret < 0 && i->state == PA_SINK_INPUT_RUNNING) + else if (ret < 0 && state == PA_SINK_INPUT_RUNNING) pa_atomic_cmpxchg(&i->state, state, PA_SINK_INPUT_DRAINED); if (ret >= 0) { @@ -427,7 +430,7 @@ void pa_sink_input_drop(pa_sink_input *i, const pa_memchunk *chunk, size_t lengt /* return; */ /* } */ - if (!i->resampler) { + if (!i->thread_info.resampler) { if (i->drop) i->drop(i, chunk, length); return; @@ -454,7 +457,7 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume) { i->volume = *volume; - pa_asyncmsgq_post(s->asyncmsgq, pa_sink_input_ref(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME, pa_xnewdup(struct pa_cvolume, volume, 1), pa_sink_input_unref, pa_xfree); + pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME, pa_xnewdup(struct pa_cvolume, volume, 1), NULL, pa_xfree); pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); } @@ -473,18 +476,17 @@ void pa_sink_input_set_mute(pa_sink_input *i, int mute) { i->muted = mute; - pa_asyncmsgq_post(s->asyncmsgq, pa_sink_input_ref(i), PA_SINK_INPUT_MESSAGE_SET_MUTE, PA_UINT_TO_PTR(mute), pa_sink_input_unref, NULL); + pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_MUTE, PA_UINT_TO_PTR(mute), NULL, NULL); pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); } int pa_sink_input_get_mute(pa_sink_input *i) { pa_sink_input_assert_ref(i); - return !!i->mute; + return !!i->muted; } void pa_sink_input_cork(pa_sink_input *i, int b) { - int n; pa_sink_input_state_t state; pa_sink_input_assert_ref(i); @@ -493,24 +495,24 @@ void pa_sink_input_cork(pa_sink_input *i, int b) { pa_assert(state != PA_SINK_INPUT_DISCONNECTED); if (b && state != PA_SINK_INPUT_CORKED) - pa_atomic_store(i->state, PA_SINK_INPUT_CORKED); + pa_atomic_store(&i->state, PA_SINK_INPUT_CORKED); else if (!b && state == PA_SINK_INPUT_CORKED) - pa_atomic_cmpxchg(i->state, state, PA_SINK_INPUT_DRAINED); + pa_atomic_cmpxchg(&i->state, state, PA_SINK_INPUT_DRAINED); } int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) { pa_sink_input_assert_ref(i); - pa_return_val_if_fail(u->thread_info.resampler, -1); + pa_return_val_if_fail(i->thread_info.resampler, -1); if (i->sample_spec.rate == rate) return 0; i->sample_spec.rate = rate; - pa_asyncmsgq_post(s->asyncmsgq, pa_sink_input_ref(i), PA_SINK_INPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), NULL, pa_sink_input_unref, NULL); + pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), NULL, NULL); pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); - return 0 + return 0; } void pa_sink_input_set_name(pa_sink_input *i, const char *name) { @@ -535,9 +537,9 @@ pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i) { } int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { - pa_resampler *new_resampler = NULL; - pa_memblockq *buffer = NULL; - pa_sink *origin; +/* pa_resampler *new_resampler = NULL; */ +/* pa_memblockq *buffer = NULL; */ +/* pa_sink *origin; */ pa_sink_input_assert_ref(i); pa_sink_assert_ref(dest); @@ -702,18 +704,18 @@ int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, pa_memc switch (code) { case PA_SINK_INPUT_MESSAGE_SET_VOLUME: - s->thread_info.soft_volume = *((pa_cvolume*) userdata); + i->thread_info.volume = *((pa_cvolume*) userdata); return 0; case PA_SINK_INPUT_MESSAGE_SET_MUTE: - s->thread_info.soft_muted = PA_PTR_TO_UINT(userdata); + i->thread_info.muted = PA_PTR_TO_UINT(userdata); return 0; case PA_SINK_INPUT_MESSAGE_GET_LATENCY: { pa_usec_t *r = userdata; if (i->thread_info.resampled_chunk.memblock) - *r += pa_bytes_to_usec(i->resampled_chunk.length, &i->sink->sample_spec); + *r += pa_bytes_to_usec(i->thread_info.resampled_chunk.length, &i->sink->sample_spec); /* if (i->move_silence) */ /* r += pa_bytes_to_usec(i->move_silence, &i->sink->sample_spec); */ @@ -724,7 +726,7 @@ int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, pa_memc case PA_SINK_INPUT_MESSAGE_SET_RATE: { i->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata); - pa_resampler_set_input_rate(i->resampler, PA_PTR_TO_UINT(userdata)); + pa_resampler_set_input_rate(i->thread_info.resampler, PA_PTR_TO_UINT(userdata)); return 0; } diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index 338d6962..a8c05b85 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -99,7 +99,7 @@ struct pa_sink_input { }; PA_DECLARE_CLASS(pa_sink_input); -#define PA_SINK_INPUT(o) ((pa_sink_input*) (o)) +#define PA_SINK_INPUT(o) pa_sink_input_cast(o) enum { PA_SINK_INPUT_MESSAGE_SET_VOLUME, @@ -160,7 +160,7 @@ int pa_sink_input_get_mute(pa_sink_input *i); void pa_sink_input_cork(pa_sink_input *i, int b); -void pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate); +int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate); pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i); diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 0e022d92..7f009048 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -47,6 +47,8 @@ #define MAX_MIX_CHANNELS 32 +static PA_DEFINE_CHECK_TYPE(pa_sink, sink_check_type, pa_msgobject_check_type); + static void sink_free(pa_object *s); pa_sink* pa_sink_new( @@ -77,7 +79,7 @@ pa_sink* pa_sink_new( pa_return_null_if_fail(!driver || pa_utf8_valid(driver)); pa_return_null_if_fail(name && pa_utf8_valid(name) && *name); - s = pa_msgobject_new(pa_sink); + s = pa_msgobject_new(pa_sink, sink_check_type); if (!(name = pa_namereg_register(core, name, PA_NAMEREG_SINK, s, fail))) { pa_xfree(s); @@ -88,7 +90,7 @@ pa_sink* pa_sink_new( s->parent.process_msg = pa_sink_process_msg; s->core = core; - pa_atomic_store(&s->state, PA_SINK_IDLE); + s->state = PA_SINK_IDLE; s->name = pa_xstrdup(name); s->description = NULL; s->driver = pa_xstrdup(driver); @@ -110,11 +112,10 @@ pa_sink* pa_sink_new( s->get_volume = NULL; s->set_mute = NULL; s->get_mute = NULL; - s->start = NULL; - s->stop = NULL; + s->set_state = NULL; s->userdata = NULL; - pa_assert_se(s->asyncmsgq = pa_asyncmsgq_new(0)); + s->asyncmsgq = NULL; r = pa_idxset_put(core->sinks, s, &s->index); pa_assert(s->index != PA_IDXSET_INVALID && r >= 0); @@ -139,56 +140,40 @@ pa_sink* pa_sink_new( s->thread_info.inputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); s->thread_info.soft_volume = s->volume; s->thread_info.soft_muted = s->muted; + s->thread_info.state = s->state; pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index); return s; } -static void sink_start(pa_sink *s) { - pa_sink_state_t state; +static int sink_set_state(pa_sink *s, pa_sink_state_t state) { + int ret; + pa_assert(s); - state = pa_sink_get_state(s); - pa_return_if_fail(state == PA_SINK_IDLE || state == PA_SINK_SUSPENDED); - - pa_atomic_store(&s->state, PA_SINK_RUNNING); - - if (s->start) - s->start(s); - else - pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_START, NULL, NULL, NULL); -} - -static void sink_stop(pa_sink *s) { - pa_sink_state_t state; - int stop; + if (s->state == state) + return 0; - pa_assert(s); - state = pa_sink_get_state(s); - pa_return_if_fail(state == PA_SINK_RUNNING || state == PA_SINK_SUSPENDED); + if (s->set_state) + if ((ret = s->set_state(s, state)) < 0) + return -1; - stop = state == PA_SINK_RUNNING; - pa_atomic_store(&s->state, PA_SINK_IDLE); + if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), NULL) < 0) + return -1; - if (stop) { - if (s->stop) - s->stop(s); - else - pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_STOP, NULL, NULL, NULL); - } + s->state = state; + return 0; } void pa_sink_disconnect(pa_sink* s) { pa_sink_input *i, *j = NULL; pa_assert(s); - pa_return_if_fail(pa_sink_get_state(s) != PA_SINK_DISCONNECTED); - - sink_stop(s); + pa_return_if_fail(s->state != PA_SINK_DISCONNECTED); - pa_atomic_store(&s->state, PA_SINK_DISCONNECTED); pa_namereg_unregister(s->core, s->name); + pa_idxset_remove_by_data(s->core->sinks, s, NULL); pa_hook_fire(&s->core->hook_sink_disconnect, s); @@ -201,26 +186,27 @@ void pa_sink_disconnect(pa_sink* s) { if (s->monitor_source) pa_source_disconnect(s->monitor_source); - pa_idxset_remove_by_data(s->core->sinks, s, NULL); + sink_set_state(s, PA_SINK_DISCONNECTED); s->get_latency = NULL; s->get_volume = NULL; s->set_volume = NULL; s->set_mute = NULL; s->get_mute = NULL; - s->start = NULL; - s->stop = NULL; + s->set_state = NULL; pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_REMOVE, s->index); } static void sink_free(pa_object *o) { pa_sink *s = PA_SINK(o); + pa_sink_input *i; pa_assert(s); pa_assert(pa_sink_refcnt(s) == 0); - pa_sink_disconnect(s); + if (s->state != PA_SINK_DISCONNECTED) + pa_sink_disconnect(s); pa_log_info("Freeing sink %u \"%s\"", s->index, s->name); @@ -231,9 +217,10 @@ static void sink_free(pa_object *o) { pa_idxset_free(s->inputs, NULL, NULL); - pa_hashmap_free(s->thread_info.inputs, (pa_free2_cb_t) pa_sink_input_unref, NULL); - - pa_asyncmsgq_free(s->asyncmsgq); + while ((i = pa_hashmap_steal_first(s->thread_info.inputs))) + pa_sink_input_unref(i); + + pa_hashmap_free(s->thread_info.inputs, NULL, NULL); pa_xfree(s->name); pa_xfree(s->description); @@ -241,44 +228,38 @@ static void sink_free(pa_object *o) { pa_xfree(s); } -void pa_sink_update_status(pa_sink*s) { +void pa_sink_set_asyncmsgq(pa_sink *s, pa_asyncmsgq *q) { pa_sink_assert_ref(s); + pa_assert(q); - if (pa_sink_get_state(s) == PA_SINK_SUSPENDED) - return; + s->asyncmsgq = q; - if (pa_sink_used_by(s) > 0) - sink_start(s); - else - sink_stop(s); + if (s->monitor_source) + pa_source_set_asyncmsgq(s->monitor_source, q); } -void pa_sink_suspend(pa_sink *s, int suspend) { - pa_sink_state_t state; - +int pa_sink_update_status(pa_sink*s) { pa_sink_assert_ref(s); - state = pa_sink_get_state(s); - pa_return_if_fail(suspend && (state == PA_SINK_RUNNING || state == PA_SINK_IDLE)); - pa_return_if_fail(!suspend && (state == PA_SINK_SUSPENDED)); + if (s->state == PA_SINK_SUSPENDED) + return 0; + return sink_set_state(s, pa_sink_used_by(s) ? PA_SINK_RUNNING : PA_SINK_IDLE); +} - if (suspend) { - pa_atomic_store(&s->state, PA_SINK_SUSPENDED); +int pa_sink_suspend(pa_sink *s, int suspend) { + pa_sink_assert_ref(s); - if (s->stop) - s->stop(s); - else - pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_STOP, NULL, NULL, NULL); + if (suspend) + return sink_set_state(s, PA_SINK_SUSPENDED); + else + return sink_set_state(s, pa_sink_used_by(s) ? PA_SINK_RUNNING : PA_SINK_IDLE); +} - } else { - pa_atomic_store(&s->state, PA_SINK_RUNNING); +void pa_sink_ping(pa_sink *s) { + pa_sink_assert_ref(s); - if (s->start) - s->start(s); - else - pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_START, NULL, NULL, NULL); - } + pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_PING, NULL, NULL, NULL); } static unsigned fill_mix_info(pa_sink *s, pa_mix_info *info, unsigned maxinfo) { @@ -652,7 +633,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk * pa_sink *s = PA_SINK(o); pa_sink_assert_ref(s); - switch (code) { + switch ((pa_sink_message_t) code) { case PA_SINK_MESSAGE_ADD_INPUT: { pa_sink_input *i = userdata; pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), pa_sink_input_ref(i)); @@ -681,7 +662,17 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk * *((int*) userdata) = s->thread_info.soft_muted; return 0; - default: - return -1; + case PA_SINK_MESSAGE_PING: + return 0; + + case PA_SINK_MESSAGE_SET_STATE: + s->thread_info.state = PA_PTR_TO_UINT(userdata); + return 0; + + case PA_SINK_MESSAGE_GET_LATENCY: + case PA_SINK_MESSAGE_MAX: + ; } + + return -1; } diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index 2939cc47..0b308e53 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -55,7 +55,7 @@ struct pa_sink { uint32_t index; pa_core *core; - pa_atomic_t state; + pa_sink_state_t state; char *name; char *description, *driver; /* may be NULL */ @@ -74,8 +74,7 @@ struct pa_sink { int refresh_volume; int refresh_mute; - int (*start)(pa_sink *s); - int (*stop)(pa_sink *s); + int (*set_state)(pa_sink *s, pa_sink_state_t state); int (*set_volume)(pa_sink *s); /* dito */ int (*get_volume)(pa_sink *s); /* dito */ int (*get_mute)(pa_sink *s); /* dito */ @@ -87,6 +86,7 @@ struct pa_sink { /* Contains copies of the above data so that the real-time worker * thread can work without access locking */ struct { + pa_sink_state_t state; pa_hashmap *inputs; pa_cvolume soft_volume; int soft_muted; @@ -96,7 +96,7 @@ struct pa_sink { }; PA_DECLARE_CLASS(pa_sink); -#define PA_SINK(s) ((pa_sink*) (s)) +#define PA_SINK(s) (pa_sink_cast(s)) typedef enum pa_sink_message { PA_SINK_MESSAGE_ADD_INPUT, @@ -106,8 +106,8 @@ typedef enum pa_sink_message { PA_SINK_MESSAGE_GET_MUTE, PA_SINK_MESSAGE_SET_MUTE, PA_SINK_MESSAGE_GET_LATENCY, - PA_SINK_MESSAGE_START, - PA_SINK_MESSAGE_STOP, + PA_SINK_MESSAGE_SET_STATE, + PA_SINK_MESSAGE_PING, PA_SINK_MESSAGE_MAX } pa_sink_message_t; @@ -125,13 +125,19 @@ void pa_sink_disconnect(pa_sink* s); void pa_sink_set_module(pa_sink *sink, pa_module *m); void pa_sink_set_description(pa_sink *s, const char *description); +void pa_sink_set_asyncmsgq(pa_sink *s, pa_asyncmsgq *q); /* Usable by everyone */ pa_usec_t pa_sink_get_latency(pa_sink *s); -void pa_sink_update_status(pa_sink*s); -void pa_sink_suspend(pa_sink *s, int suspend); +int pa_sink_update_status(pa_sink*s); +int pa_sink_suspend(pa_sink *s, int suspend); + +/* Sends a ping message to the sink thread, to make it wake up and + * check for data to process even if there is no real message is + * sent */ +void pa_sink_ping(pa_sink *s); void pa_sink_set_volume(pa_sink *sink, const pa_cvolume *volume); const pa_cvolume *pa_sink_get_volume(pa_sink *sink); @@ -139,7 +145,7 @@ void pa_sink_set_mute(pa_sink *sink, int mute); int pa_sink_get_mute(pa_sink *sink); unsigned pa_sink_used_by(pa_sink *s); -#define pa_sink_get_state(s) ((pa_sink_state_t) pa_atomic_load(&(s)->state)) +#define pa_sink_get_state(s) ((s)->state) /* To be used exclusively by the sink driver thread */ @@ -149,5 +155,5 @@ int pa_sink_render_into(pa_sink*s, pa_memchunk *target); void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target); int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk); - + #endif diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index a682ee6c..974c053a 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -200,7 +200,7 @@ int pa_play_file( u->sink_input->kill = sink_input_kill; u->sink_input->userdata = u; - pa_sink_notify(u->sink_input->sink); +/* pa_sink_notify(u->sink_input->sink); */ return 0; diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 517c033d..2211f251 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -38,6 +38,10 @@ #include "source-output.h" +static PA_DEFINE_CHECK_TYPE(pa_source_output, source_output_check_type, pa_msgobject_check_type); + +static void source_output_free(pa_object* mo); + pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data) { pa_assert(data); @@ -126,13 +130,12 @@ pa_source_output* pa_source_output_new( data->resample_method = pa_resampler_get_method(resampler); } - o = pa_source_output_new(pa_source_output); - + o = pa_msgobject_new(pa_source_output, source_output_check_type); o->parent.parent.free = source_output_free; o->parent.process_msg = pa_source_output_process_msg; o->core = core; - pa_atomic_load(&o->state, PA_SOURCE_OUTPUT_RUNNING); + pa_atomic_store(&o->state, PA_SOURCE_OUTPUT_RUNNING); o->flags = flags; o->name = pa_xstrdup(data->name); o->driver = pa_xstrdup(data->driver); @@ -168,27 +171,29 @@ pa_source_output* pa_source_output_new( void pa_source_output_disconnect(pa_source_output*o) { pa_assert(o); - pa_return_if_fail(pa_source_output_get_state(i) != PA_SOURCE_OUTPUT_DISCONNECTED); + pa_return_if_fail(pa_source_output_get_state(o) != PA_SOURCE_OUTPUT_DISCONNECTED); pa_assert(o->source); pa_assert(o->source->core); - pa_asyncmsgq_send(i->sink->asyncmsgq, i->sink, PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, NULL); + pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, NULL); pa_idxset_remove_by_data(o->source->core->source_outputs, o, NULL); pa_idxset_remove_by_data(o->source->outputs, o, NULL); pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_REMOVE, o->index); - o->source = NULL; + pa_source_update_status(o->source); + + o->source = NULL; o->process_msg = NULL; o->push = NULL; o->kill = NULL; o->get_latency = NULL; - pa_atomic_load(&i->state, PA_SOURCE_OUTPUT_DISCONNECTED); + pa_atomic_store(&o->state, PA_SOURCE_OUTPUT_DISCONNECTED); } -static void source_output_free(pa_msgobject* mo) { +static void source_output_free(pa_object* mo) { pa_source_output *o = PA_SOURCE_OUTPUT(mo); pa_assert(pa_source_output_refcnt(o) == 0); @@ -208,10 +213,10 @@ static void source_output_free(pa_msgobject* mo) { void pa_source_output_put(pa_source_output *o) { pa_source_output_assert_ref(o); - pa_asyncmsgq_post(o->source->asyncmsgq, o->source, PA_SOURCE_MESSAGE_ADD_OUTPUT, o, NULL, pa_source_unref, pa_source_output_unref); + pa_asyncmsgq_post(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_ADD_OUTPUT, pa_source_output_ref(o), NULL, (pa_free_cb_t) pa_source_output_unref); pa_source_update_status(o->source); - pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW, o->index); + pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW, o->index); } void pa_source_output_kill(pa_source_output*o) { @@ -226,7 +231,7 @@ pa_usec_t pa_source_output_get_latency(pa_source_output *o) { pa_source_output_assert_ref(o); - if (pa_asyncmsgq_send(o->source->asyncmsgq, i->source, PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY, &r, NULL) < 0) + if (pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY, &r, NULL) < 0) r = 0; if (o->get_latency) @@ -250,12 +255,12 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) { pa_assert(state = PA_SOURCE_OUTPUT_RUNNING); - if (!o->resampler) { + if (!o->thread_info.resampler) { o->push(o, chunk); return; } - pa_resampler_run(o->resampler, chunk, &rchunk); + pa_resampler_run(o->thread_info.resampler, chunk, &rchunk); if (!rchunk.length) return; @@ -265,7 +270,6 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) { } void pa_source_output_cork(pa_source_output *o, int b) { - int n; pa_source_output_state_t state; pa_source_output_assert_ref(o); @@ -274,23 +278,23 @@ void pa_source_output_cork(pa_source_output *o, int b) { pa_assert(state != PA_SOURCE_OUTPUT_DISCONNECTED); if (b && state != PA_SOURCE_OUTPUT_CORKED) - pa_atomic_store(o->state, PA_SOURCE_OUTPUT_CORKED); + pa_atomic_store(&o->state, PA_SOURCE_OUTPUT_CORKED); else if (!b && state == PA_SOURCE_OUTPUT_CORKED) - pa_atomic_cmpxchg(o->state, state, PA_SOURCE_OUTPUT_RUNNING); + pa_atomic_cmpxchg(&o->state, state, PA_SOURCE_OUTPUT_RUNNING); } int pa_source_output_set_rate(pa_source_output *o, uint32_t rate) { pa_source_output_assert_ref(o); pa_return_val_if_fail(o->thread_info.resampler, -1); - if (i->sample_spec.rate == rate) + if (o->sample_spec.rate == rate) return 0; - i->sample_spec.rate = rate; + o->sample_spec.rate = rate; - pa_asyncmsgq_post(s->asyncmsgq, pa_source_output_ref(i), PA_SOURCE_OUTPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), NULL, pa_source_output_unref, NULL); + pa_asyncmsgq_post(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), NULL, NULL); - pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT!|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); + pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); return 0; } @@ -316,8 +320,8 @@ pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o) { } int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { - pa_source *origin; - pa_resampler *new_resampler = NULL; +/* pa_source *origin; */ +/* pa_resampler *new_resampler = NULL; */ pa_source_output_assert_ref(o); pa_source_assert_ref(dest); @@ -344,7 +348,7 @@ int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { /* else if (!pa_sample_spec_equal(&o->sample_spec, &dest->sample_spec) || */ /* !pa_channel_map_equal(&o->channel_map, &dest->channel_map)) { */ -/* /\* Okey, we need a new resampler for the new sink *\/ */ +/* /\* Okey, we need a new resampler for the new source *\/ */ /* if (!(new_resampler = pa_resampler_new( */ /* dest->core->mempool, */ @@ -376,16 +380,16 @@ int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { } int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, pa_memchunk* chunk) { - pa_source_output *o = PA_SOURCE_OUTPUT(o); + pa_source_output *o = PA_SOURCE_OUTPUT(mo); - pa_source_output_assert_ref(i); + pa_source_output_assert_ref(o); switch (code) { case PA_SOURCE_OUTPUT_MESSAGE_SET_RATE: { - i->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata); - pa_resampler_set_output_rate(i->resampler, PA_PTR_TO_UINT(userdata)); + o->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata); + pa_resampler_set_output_rate(o->thread_info.resampler, PA_PTR_TO_UINT(userdata)); return 0; } diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h index e7c2c131..d3bc0bc4 100644 --- a/src/pulsecore/source-output.h +++ b/src/pulsecore/source-output.h @@ -80,7 +80,7 @@ struct pa_source_output { }; PA_DECLARE_CLASS(pa_source_output); -#define PA_SOURCE_OUTPUT(o) ((pa_source_output*) (o)) +#define PA_SOURCE_OUTPUT(o) pa_source_output_cast(o) enum { PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY, @@ -129,7 +129,7 @@ pa_usec_t pa_source_output_get_latency(pa_source_output *i); void pa_source_output_cork(pa_source_output *i, int b); -void pa_source_output_set_rate(pa_source_output *o, uint32_t rate); +int pa_source_output_set_rate(pa_source_output *o, uint32_t rate); pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o); diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 7d013387..f0a898f4 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -42,6 +42,10 @@ #include "source.h" +static PA_DEFINE_CHECK_TYPE(pa_source, source_check_type, pa_msgobject_check_type); + +static void source_free(pa_object *o); + pa_source* pa_source_new( pa_core *core, const char *driver, @@ -69,7 +73,7 @@ pa_source* pa_source_new( pa_return_null_if_fail(!driver || pa_utf8_valid(driver)); pa_return_null_if_fail(pa_utf8_valid(name) && *name); - s = pa_msgobject_new(pa_source); + s = pa_msgobject_new(pa_source, source_check_type); if (!(name = pa_namereg_register(core, name, PA_NAMEREG_SOURCE, s, fail))) { pa_xfree(s); @@ -80,7 +84,7 @@ pa_source* pa_source_new( s->parent.process_msg = pa_source_process_msg; s->core = core; - pa_atomic_store(&s->state, PA_SOURCE_IDLE); + s->state = PA_SOURCE_IDLE; s->name = pa_xstrdup(name); s->description = NULL; s->driver = pa_xstrdup(driver); @@ -94,7 +98,7 @@ pa_source* pa_source_new( pa_cvolume_reset(&s->volume, spec->channels); s->muted = 0; - s->refresh_volume = s->refresh_mute = 0; + s->refresh_volume = s->refresh_muted = 0; s->is_hardware = 0; @@ -103,11 +107,10 @@ pa_source* pa_source_new( s->get_volume = NULL; s->set_mute = NULL; s->get_mute = NULL; - s->start = NULL; - s->stop = NULL; + s->set_state = NULL; s->userdata = NULL; - pa_assert_se(s->asyncmsgq = pa_asyncmsgq_new(0)); + s->asyncmsgq = NULL; r = pa_idxset_put(core->sources, s, &s->index); assert(s->index != PA_IDXSET_INVALID && r >= 0); @@ -118,56 +121,40 @@ pa_source* pa_source_new( s->thread_info.outputs = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); s->thread_info.soft_volume = s->volume; s->thread_info.soft_muted = s->muted; + s->thread_info.state = s->state; pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index); return s; } -static void source_start(pa_source *s) { - pa_source_state_t state; +static int source_set_state(pa_source *s, pa_source_state_t state) { + int ret; + pa_assert(s); - state = pa_source_get_state(s); - pa_return_if_fail(state == PA_SOURCE_IDLE || state == PA_SOURCE_SUSPENDED); - - pa_atomic_store(&s->state, PA_SOURCE_RUNNING); - - if (s->start) - s->start(s); - else - pa_asyncmsgq_post(s->asyncmsgq, s, PA_SOURCE_MESSAGE_START, NULL, NULL, pa_source_unref, NULL); -} - -static void source_stop(pa_source *s) { - pa_source_state_t state; - int stop; + if (s->state == state) + return 0; - pa_assert(s); - state = pa_source_get_state(s); - pa_return_if_fail(state == PA_SOURCE_RUNNING || state == PA_SOURCE_SUSPENDED); + if (s->set_state) + if ((ret = s->set_state(s, state)) < 0) + return -1; - stop = state == PA_SOURCE_RUNNING; - pa_atomic_store(&s->state, PA_SOURCE_IDLE); + if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), NULL) < 0) + return -1; - if (stop) { - if (s->stop) - s->stop(s); - else - pa_asyncmsgq_post(s->asyncmsgq, s, PA_SOURCE_MESSAGE_STOP, NULL, NULL, pa_source_unref, NULL); - } + s->state = state; + return 0; } void pa_source_disconnect(pa_source *s) { pa_source_output *o, *j = NULL; pa_assert(s); - pa_return_if_fail(pa_sink_get_state(s) != PA_SINK_DISCONNECT); - - source_stop(s); + pa_return_if_fail(s->state != PA_SOURCE_DISCONNECTED); - pa_atomic_store(&s->state, PA_SOURCE_DISCONNECTED); pa_namereg_unregister(s->core, s->name); + pa_idxset_remove_by_data(s->core->sources, s, NULL); pa_hook_fire(&s->core->hook_source_disconnect, s); @@ -177,33 +164,36 @@ void pa_source_disconnect(pa_source *s) { j = o; } - pa_idxset_remove_by_data(s->core->sources, s, NULL); + source_set_state(s, PA_SOURCE_DISCONNECTED); s->get_latency = NULL; s->get_volume = NULL; s->set_volume = NULL; s->set_mute = NULL; s->get_mute = NULL; - s->start = NULL; - s->stop = NULL; + s->set_state = NULL; pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_REMOVE, s->index); } -static void source_free(pa_msgobject *o) { +static void source_free(pa_object *o) { + pa_source_output *so; pa_source *s = PA_SOURCE(o); pa_assert(s); pa_assert(pa_source_refcnt(s) == 0); - pa_source_disconnect(s); + if (s->state != PA_SOURCE_DISCONNECTED) + pa_source_disconnect(s); pa_log_info("Freeing source %u \"%s\"", s->index, s->name); pa_idxset_free(s->outputs, NULL, NULL); - pa_hashmap_free(s->thread_info.outputs, pa_sink_output_unref, NULL); - pa_asyncmsgq_free(s->asyncmsgq); + while ((so = pa_hashmap_steal_first(s->thread_info.outputs))) + pa_source_output_unref(so); + + pa_hashmap_free(s->thread_info.outputs, NULL, NULL); pa_xfree(s->name); pa_xfree(s->description); @@ -211,44 +201,28 @@ static void source_free(pa_msgobject *o) { pa_xfree(s); } -void pa_source_update_status(pa_source*s) { +int pa_source_update_status(pa_source*s) { pa_source_assert_ref(s); - if (pa_source_get_state(s) == PA_SOURCE_STATE_SUSPENDED) - return; + if (s->state == PA_SOURCE_SUSPENDED) + return 0; - if (pa_source_used_by(s) > 0) - source_start(s); - else - source_stop(s); + return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE); } -void pa_source_suspend(pa_source *s, int suspend) { - pa_source_state_t state; - +int pa_source_suspend(pa_source *s, int suspend) { pa_source_assert_ref(s); - state = pa_source_get_state(s); - pa_return_if_fail(suspend && (s->state == PA_SOURCE_RUNNING || s->state == PA_SOURCE_IDLE)); - pa_return_if_fail(!suspend && (s->state == PA_SOURCE_SUSPENDED)); - - - if (suspend) { - pa_atomic_store(&s->state, PA_SOURCE_SUSPENDED); - - if (s->stop) - s->stop(s); - else - pa_asyncmsgq_post(s->asyncmsgq, s, PA_SOURCE_MESSAGE_STOP, NULL, NULL, pa_source_unref, NULL); + if (suspend) + return source_set_state(s, PA_SOURCE_SUSPENDED); + else + return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE); +} - } else { - pa_atomic_store(&s->state, PA_SOURCE_RUNNING); +void pa_source_ping(pa_source *s) { + pa_source_assert_ref(s); - if (s->start) - s->start(s); - else - pa_asyncmsgq_post(s->asyncmsgq, s, PA_SOURCE_MESSAGE_START, NULL, NULL, pa_source_unref, NULL); - } + pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_PING, NULL, NULL, NULL); } void pa_source_post(pa_source*s, const pa_memchunk *chunk) { @@ -258,16 +232,16 @@ void pa_source_post(pa_source*s, const pa_memchunk *chunk) { pa_source_assert_ref(s); pa_assert(chunk); - if (s->sw_muted || !pa_cvolume_is_norm(&s->sw_volume)) { + if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&s->thread_info.soft_volume)) { pa_memchunk vchunk = *chunk; pa_memblock_ref(vchunk.memblock); pa_memchunk_make_writable(&vchunk, 0); - if (s->thread_info.muted || pa_cvolume_is_muted(s->thread_info.volume)) + if (s->thread_info.soft_muted || pa_cvolume_is_muted(&s->thread_info.soft_volume)) pa_silence_memchunk(&vchunk, &s->sample_spec); else - pa_volume_memchunk(&vchunk, &s->sample_spec, &s->thread_info.volume); + pa_volume_memchunk(&vchunk, &s->sample_spec, &s->thread_info.soft_volume); while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) pa_source_output_push(o, &vchunk); @@ -289,32 +263,33 @@ pa_usec_t pa_source_get_latency(pa_source *s) { if (s->get_latency) return s->get_latency(s); - if (pa_asyncmsgq_send(s->asyncmsgq, s, PA_SOURCE_MESSAGE_GET_LATENCY, &usec, NULL) < 0) + if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_LATENCY, &usec, NULL) < 0) return 0; return usec; } void pa_source_set_volume(pa_source *s, const pa_cvolume *volume) { - pa_cvolume *v; + int changed; pa_source_assert_ref(s); pa_assert(volume); - changed = !pa_cvolume_equal(volume, s->volume); + changed = !pa_cvolume_equal(volume, &s->volume); s->volume = *volume; if (s->set_volume && s->set_volume(s) < 0) s->set_volume = NULL; if (!s->set_volume) - pa_asyncmsgq_post(s->asyncmsgq, pa_source_ref(s), PA_SOURCE_MESSAGE_SET_VOLUME, pa_xnewdup(struct pa_cvolume, volume, 1), pa_source_unref, pa_xfree); + pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME, pa_xnewdup(struct pa_cvolume, volume, 1), NULL, pa_xfree); if (changed) pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); } const pa_cvolume *pa_source_get_volume(pa_source *s) { + pa_cvolume old_volume; pa_source_assert_ref(s); old_volume = s->volume; @@ -323,7 +298,7 @@ const pa_cvolume *pa_source_get_volume(pa_source *s) { s->get_volume = NULL; if (!s->get_volume && s->refresh_volume) - pa_asyncmsgq_send(s->asyncmsgq, s, PA_SOURCE_MESSAGE_GET_VOLUME, &s->volume); + pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_VOLUME, &s->volume, NULL); if (!pa_cvolume_equal(&old_volume, &s->volume)) pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); @@ -331,7 +306,7 @@ const pa_cvolume *pa_source_get_volume(pa_source *s) { return &s->volume; } -void pa_source_set_mute(pa_source *s, pa_mixer_t m, int mute) { +void pa_source_set_mute(pa_source *s, int mute) { int changed; pa_source_assert_ref(s); @@ -342,13 +317,13 @@ void pa_source_set_mute(pa_source *s, pa_mixer_t m, int mute) { s->set_mute = NULL; if (!s->set_mute) - pa_asyncmsgq_post(s->asyncmsgq, pa_source_ref(s), PA_SOURCE_MESSAGE_SET_MUTE, PA_UINT_TO_PTR(mute), pa_source_unref, NULL); + pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_MUTE, PA_UINT_TO_PTR(mute), NULL, NULL); if (changed) pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); } -int pa_source_get_mute(pa_source *s, pa_mixer_t m) { +int pa_source_get_mute(pa_source *s) { int old_muted; pa_source_assert_ref(s); @@ -358,8 +333,8 @@ int pa_source_get_mute(pa_source *s, pa_mixer_t m) { if (s->get_mute && s->get_mute(s) < 0) s->get_mute = NULL; - if (!s->get_mute && s->refresh_mute) - pa_asyncmsgq_send(s->asyncmsgq, s, PA_SOURCE_MESSAGE_GET_MUTE, &s->muted); + if (!s->get_mute && s->refresh_muted) + pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_MUTE, &s->muted, NULL); if (old_muted != s->muted) pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); @@ -393,26 +368,33 @@ void pa_source_set_description(pa_source *s, const char *description) { pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); } +void pa_source_set_asyncmsgq(pa_source *s, pa_asyncmsgq *q) { + pa_source_assert_ref(s); + pa_assert(q); + + s->asyncmsgq = q; +} + unsigned pa_source_used_by(pa_source *s) { pa_source_assert_ref(s); return pa_idxset_size(s->outputs); } -int pa_source_process_msg(pa_msgobject *o, void *object, int code, pa_memchunk *chunk, void *userdata) { +int pa_source_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk) { pa_source *s = PA_SOURCE(o); pa_source_assert_ref(s); - switch (code) { + switch ((pa_source_message_t) code) { case PA_SOURCE_MESSAGE_ADD_OUTPUT: { pa_source_output *i = userdata; pa_hashmap_put(s->thread_info.outputs, PA_UINT32_TO_PTR(i->index), pa_source_output_ref(i)); return 0; } - case PA_SOURCE_MESSAGE_REMOVE_INPUT: { - pa_source_input *i = userdata; - pa_hashmap_remove(s->thread_info.outputs, PA_UINT32_TO_PTR(i->index), pa_source_output_ref(i)); + case PA_SOURCE_MESSAGE_REMOVE_OUTPUT: { + pa_source_output *i = userdata; + pa_hashmap_remove(s->thread_info.outputs, PA_UINT32_TO_PTR(i->index)); return 0; } @@ -432,7 +414,17 @@ int pa_source_process_msg(pa_msgobject *o, void *object, int code, pa_memchunk * *((int*) userdata) = s->thread_info.soft_muted; return 0; - default: - return -1; + case PA_SOURCE_MESSAGE_PING: + return 0; + + case PA_SOURCE_MESSAGE_SET_STATE: + s->thread_info.state = PA_PTR_TO_UINT(userdata); + return 0; + + case PA_SOURCE_MESSAGE_GET_LATENCY: + case PA_SOURCE_MESSAGE_MAX: + ; } + + return -1; } diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index b41b1bc3..4db2dedf 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -57,7 +57,7 @@ struct pa_source { uint32_t index; pa_core *core; - pa_atomic_t state; + pa_source_state_t state; char *name; char *description, *driver; /* may be NULL */ @@ -74,10 +74,9 @@ struct pa_source { pa_cvolume volume; int muted; int refresh_volume; - int referesh_mute; + int refresh_muted; - void (*start)(pa_source*source); /* may be NULL */ - void (*stop)(pa_source*source); /* may be NULL */ + int (*set_state)(pa_source*source, pa_source_state_t state); /* may be NULL */ int (*set_volume)(pa_source *s); /* dito */ int (*get_volume)(pa_source *s); /* dito */ int (*set_mute)(pa_source *s); /* dito */ @@ -87,6 +86,7 @@ struct pa_source { pa_asyncmsgq *asyncmsgq; struct { + pa_source_state_t state; pa_hashmap *outputs; pa_cvolume soft_volume; int soft_muted; @@ -96,7 +96,7 @@ struct pa_source { }; PA_DECLARE_CLASS(pa_source); -#define PA_SOURCE(s) ((pa_source*) (s)) +#define PA_SOURCE(s) pa_source_cast(s) typedef enum pa_source_message { PA_SOURCE_MESSAGE_ADD_OUTPUT, @@ -106,8 +106,8 @@ typedef enum pa_source_message { PA_SOURCE_MESSAGE_GET_MUTE, PA_SOURCE_MESSAGE_SET_MUTE, PA_SOURCE_MESSAGE_GET_LATENCY, - PA_SOURCE_MESSAGE_START, - PA_SOURCE_MESSAGE_STOP, + PA_SOURCE_MESSAGE_SET_STATE, + PA_SOURCE_MESSAGE_PING, PA_SOURCE_MESSAGE_MAX } pa_source_message_t; @@ -125,13 +125,15 @@ void pa_source_disconnect(pa_source *s); void pa_source_set_module(pa_source *s, pa_module *m); void pa_source_set_description(pa_source *s, const char *description); +void pa_source_set_asyncmsgq(pa_source *s, pa_asyncmsgq *q); /* Callable by everyone */ pa_usec_t pa_source_get_latency(pa_source *s); -void pa_source_update_status(pa_source*s); -void pa_source_suspend(pa_source *s); +int pa_source_update_status(pa_source*s); +int pa_source_suspend(pa_source *s, int suspend); +void pa_source_ping(pa_source *s); void pa_source_set_volume(pa_source *source, const pa_cvolume *volume); const pa_cvolume *pa_source_get_volume(pa_source *source); @@ -139,11 +141,11 @@ void pa_source_set_mute(pa_source *source, int mute); int pa_source_get_mute(pa_source *source); unsigned pa_source_used_by(pa_source *s); -#define pa_source_get_state(s) ((pa_source_state_t) pa_atomic_load(&(s)->state)) +#define pa_source_get_state(s) ((pa_source_state_t) (s)->state) /* To be used exclusively by the source driver thread */ void pa_source_post(pa_source*s, const pa_memchunk *b); -void pa_source_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk); +int pa_source_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk); #endif diff --git a/src/tests/asyncmsgq-test.c b/src/tests/asyncmsgq-test.c index d10b512d..847d5be1 100644 --- a/src/tests/asyncmsgq-test.c +++ b/src/tests/asyncmsgq-test.c @@ -49,7 +49,7 @@ static void the_thread(void *_q) { do { int code = 0; - pa_assert_se(pa_asyncmsgq_get(q, NULL, &code, NULL, 1) == 0); + pa_assert_se(pa_asyncmsgq_get(q, NULL, &code, NULL, NULL, 1) == 0); switch (code) { @@ -71,7 +71,7 @@ static void the_thread(void *_q) { break; } - pa_asyncmsgq_done(q); + pa_asyncmsgq_done(q, 0); } while (!quit); } @@ -91,11 +91,11 @@ int main(int argc, char *argv[]) { printf("Operation B post\n"); pa_asyncmsgq_post(q, NULL, OPERATION_B, NULL, NULL, NULL); - + pa_thread_yield(); printf("Operation C send\n"); - pa_asyncmsgq_send(q, NULL, OPERATION_C, NULL); + pa_asyncmsgq_send(q, NULL, OPERATION_C, NULL, NULL); pa_thread_yield(); -- cgit From 111dcd5e34434324adafd9f43c656592f3a02d60 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 Jun 2007 16:53:40 +0000 Subject: trivial cleanups git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1475 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-pipe-sink.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index da9124a7..216e42ac 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -40,7 +39,6 @@ #include #include -#include #include #include #include @@ -170,6 +168,8 @@ static void thread_func(void *userdata) { l = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length, &write_type); pa_memblock_release(u->memchunk.memblock); + pa_assert(l != 0); + if (l < 0) { if (errno == EINTR) @@ -202,7 +202,10 @@ static void thread_func(void *userdata) { if (pa_asyncmsgq_before_poll(u->asyncmsgq) < 0) continue; +/* pa_log("polling for %u (underrun=%i)", pollfd[POLLFD_FIFO].events, underrun); */ r = poll(pollfd, POLLFD_MAX, -1); +/* pa_log("polling got %u", r > 0 ? pollfd[POLLFD_FIFO].revents : 0); */ + pa_asyncmsgq_after_poll(u->asyncmsgq); if (r < 0) { @@ -232,11 +235,11 @@ finish: } int pa__init(pa_core *c, pa_module*m) { - struct userdata *u = NULL; + struct userdata *u; struct stat st; pa_sample_spec ss; pa_channel_map map; - pa_modargs *ma = NULL; + pa_modargs *ma; char *t; pa_assert(c); -- cgit From 1b99fd2fc4c80ab581b08e1fb03ed8543dc763ec Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 Jun 2007 17:01:01 +0000 Subject: Move a few things between the threads git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1476 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-simple.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index 67741bde..288c1c03 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -88,6 +88,7 @@ struct pa_protocol_simple { enum { SINK_INPUT_MESSAGE_POST_DATA = PA_SINK_INPUT_MESSAGE_MAX, /* data from main loop to sink input */ + SINK_INPUT_MESSAGE_DISABLE_PREBUF /* disabled prebuf, get playback started. */ }; enum { @@ -189,7 +190,7 @@ static int do_read(connection *c) { c->playback.memblock_index += r; - pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, &chunk, NULL); + pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, &chunk, NULL); return 0; } @@ -259,7 +260,7 @@ fail: pa_iochannel_free(c->io); c->io = NULL; - pa_memblockq_prebuf_disable(c->input_memblockq); + pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_DISABLE_PREBUF, NULL, NULL, NULL); } else connection_drop(c); } @@ -282,7 +283,6 @@ static int connection_process_msg(pa_msgobject *o, int code, void*userdata, pa_m case MESSAGE_DROP_CONNECTION: connection_drop(c); break; - } return 0; @@ -307,10 +307,17 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, pa_ /* New data from the main loop */ pa_memblockq_push_align(c->input_memblockq, chunk); pa_atomic_store(&c->playback.missing, pa_memblockq_missing(c->input_memblockq)); + +/* pa_log("got data, %u", pa_memblockq_get_length(c->input_memblockq)); */ return 0; } + case SINK_INPUT_MESSAGE_DISABLE_PREBUF: { + pa_memblockq_prebuf_disable(c->input_memblockq); + return 0; + } + case PA_SINK_INPUT_MESSAGE_GET_LATENCY: { pa_usec_t *r = userdata; @@ -337,6 +344,8 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { r = pa_memblockq_peek(c->input_memblockq, chunk); +/* pa_log("peeked %u %i", r >= 0 ? chunk->length: 0, r); */ + if (c->dead && r < 0) pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), MESSAGE_DROP_CONNECTION, c, NULL, NULL); -- cgit From 260dd1e886dcc99147c48293c67b1910374b76ad Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 Jun 2007 17:06:11 +0000 Subject: Make debug message more useful git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1477 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/asyncmsgq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/asyncmsgq.c b/src/pulsecore/asyncmsgq.c index 6becb629..a46f038e 100644 --- a/src/pulsecore/asyncmsgq.c +++ b/src/pulsecore/asyncmsgq.c @@ -164,7 +164,7 @@ int pa_asyncmsgq_get(pa_asyncmsgq *a, pa_msgobject **object, int *code, void **u if (chunk) *chunk = a->current->memchunk; - pa_log_debug("q=%p object=%p code=%i data=%p", a, a->current->object, a->current->code, a->current->userdata); + pa_log_debug("q=%p object=%p (%s) code=%i data=%p", (void*) a, (void*) a->current->object, a->current->object ? a->current->object->parent.type_name : NULL, a->current->code, (void*) a->current->userdata); return 0; } -- cgit From 5e72ac353ed6f81ee1efc1691f725a2c8d67ac40 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 Jun 2007 17:12:40 +0000 Subject: rework sink input/source output state machine git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1478 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink-input.c | 83 +++++++++++++++++++++++++++---------------- src/pulsecore/sink-input.h | 15 +++++--- src/pulsecore/source-output.c | 53 +++++++++++++++------------ src/pulsecore/source-output.h | 8 +++-- 4 files changed, 98 insertions(+), 61 deletions(-) diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 2c6b356c..d27f00f0 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -166,7 +166,7 @@ pa_sink_input* pa_sink_input_new( i->parent.process_msg = pa_sink_input_process_msg; i->core = core; - pa_atomic_store(&i->state, PA_SINK_INPUT_DRAINED); + i->state = PA_SINK_INPUT_RUNNING; i->flags = flags; i->name = pa_xstrdup(data->name); i->driver = pa_xstrdup(data->driver); @@ -181,7 +181,6 @@ pa_sink_input* pa_sink_input_new( i->volume = data->volume; i->muted = data->muted; - i->process_msg = NULL; i->peek = NULL; i->drop = NULL; i->kill = NULL; @@ -189,6 +188,9 @@ pa_sink_input* pa_sink_input_new( i->underrun = NULL; i->userdata = NULL; + i->thread_info.state = i->state; + pa_atomic_store(&i->thread_info.drained, 1); + i->thread_info.sample_spec = i->sample_spec; i->thread_info.silence_memblock = NULL; /* i->thread_info.move_silence = 0; */ pa_memchunk_reset(&i->thread_info.resampled_chunk); @@ -210,28 +212,41 @@ pa_sink_input* pa_sink_input_new( return i; } +static int sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) { + pa_assert(i); + + if (state == PA_SINK_INPUT_DRAINED) + state = PA_SINK_INPUT_RUNNING; + + if (i->state == state) + return 0; + + if (pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), NULL) < 0) + return -1; + + i->state = state; + return 0; +} + void pa_sink_input_disconnect(pa_sink_input *i) { pa_assert(i); - pa_return_if_fail(pa_sink_input_get_state(i) != PA_SINK_INPUT_DISCONNECTED); + pa_return_if_fail(i->state != PA_SINK_INPUT_DISCONNECTED); pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, NULL); - pa_idxset_remove_by_data(i->sink->core->sink_inputs, i, NULL); pa_idxset_remove_by_data(i->sink->inputs, i, NULL); pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE, i->index); + sink_input_set_state(i, PA_SINK_INPUT_DISCONNECTED); pa_sink_update_status(i->sink); - + i->sink = NULL; - i->process_msg = NULL; i->peek = NULL; i->drop = NULL; i->kill = NULL; i->get_latency = NULL; i->underrun = NULL; - - pa_atomic_store(&i->state, PA_SINK_INPUT_DISCONNECTED); } static void sink_input_free(pa_object *o) { @@ -240,7 +255,8 @@ static void sink_input_free(pa_object *o) { pa_assert(i); pa_assert(pa_sink_input_refcnt(i) == 0); - pa_sink_input_disconnect(i); + if (i->state != PA_SINK_INPUT_DISCONNECTED) + pa_sink_input_disconnect(i); pa_log_info("Freeing output %u \"%s\"", i->index, i->name); @@ -295,21 +311,15 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) int ret = -1; int do_volume_adj_here; int volume_is_norm; - pa_sink_input_state_t state; pa_sink_input_assert_ref(i); pa_assert(chunk); pa_assert(volume); - state = pa_sink_input_get_state(i); - - if (state == PA_SINK_INPUT_DISCONNECTED) - return -1; - - if (!i->peek || !i->drop || state == PA_SINK_INPUT_CORKED) + if (!i->peek || !i->drop || i->thread_info.state == PA_SINK_INPUT_DISCONNECTED || i->thread_info.state == PA_SINK_INPUT_CORKED) goto finish; - pa_assert(state == PA_SINK_INPUT_RUNNING || state == PA_SINK_INPUT_DRAINED); + pa_assert(i->thread_info.state == PA_SINK_INPUT_RUNNING || i->thread_info.state == PA_SINK_INPUT_DRAINED); /* if (i->thread_info.move_silence > 0) { */ /* size_t l; */ @@ -359,7 +369,7 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) /* It might be necessary to adjust the volume here */ if (do_volume_adj_here && !volume_is_norm) { pa_memchunk_make_writable(&tchunk, 0); - pa_volume_memchunk(&tchunk, &i->sample_spec, &i->thread_info.volume); + pa_volume_memchunk(&tchunk, &i->thread_info.sample_spec, &i->thread_info.volume); } pa_resampler_run(i->thread_info.resampler, &tchunk, &i->thread_info.resampled_chunk); @@ -376,13 +386,13 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) finish: - if (ret < 0 && state == PA_SINK_INPUT_RUNNING && i->underrun) + if (ret < 0 && !pa_atomic_load(&i->thread_info.drained) && i->underrun) i->underrun(i); if (ret >= 0) - pa_atomic_cmpxchg(&i->state, state, PA_SINK_INPUT_RUNNING); - else if (ret < 0 && state == PA_SINK_INPUT_RUNNING) - pa_atomic_cmpxchg(&i->state, state, PA_SINK_INPUT_DRAINED); + pa_atomic_store(&i->thread_info.drained, 0); + else if (ret < 0) + pa_atomic_store(&i->thread_info.drained, 1); if (ret >= 0) { /* Let's see if we had to apply the volume adjustment @@ -487,17 +497,9 @@ int pa_sink_input_get_mute(pa_sink_input *i) { } void pa_sink_input_cork(pa_sink_input *i, int b) { - pa_sink_input_state_t state; - pa_sink_input_assert_ref(i); - state = pa_sink_input_get_state(i); - pa_assert(state != PA_SINK_INPUT_DISCONNECTED); - - if (b && state != PA_SINK_INPUT_CORKED) - pa_atomic_store(&i->state, PA_SINK_INPUT_CORKED); - else if (!b && state == PA_SINK_INPUT_CORKED) - pa_atomic_cmpxchg(&i->state, state, PA_SINK_INPUT_DRAINED); + sink_input_set_state(i, b ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING); } int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) { @@ -730,7 +732,26 @@ int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, pa_memc return 0; } + + case PA_SINK_INPUT_MESSAGE_SET_STATE: { + if ((PA_PTR_TO_UINT(userdata) == PA_SINK_INPUT_DRAINED || PA_PTR_TO_UINT(userdata) == PA_SINK_INPUT_RUNNING) && + (i->thread_info.state != PA_SINK_INPUT_DRAINED) && (i->thread_info.state != PA_SINK_INPUT_RUNNING)) + pa_atomic_store(&i->thread_info.drained, 1); + + i->thread_info.state = PA_PTR_TO_UINT(userdata); + + return 0; + } } return -1; } + +pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i) { + pa_sink_input_assert_ref(i); + + if (i->state == PA_SINK_INPUT_RUNNING || i->state == PA_SINK_INPUT_DRAINED) + return pa_atomic_load(&i->thread_info.drained) ? PA_SINK_INPUT_DRAINED : PA_SINK_INPUT_RUNNING; + + return i->state; +} diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index a8c05b85..426e48c0 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -39,8 +39,8 @@ typedef struct pa_sink_input pa_sink_input; #include typedef enum pa_sink_input_state { - PA_SINK_INPUT_RUNNING, /*< The stream is alive and kicking */ PA_SINK_INPUT_DRAINED, /*< The stream stopped playing because there was no data to play */ + PA_SINK_INPUT_RUNNING, /*< The stream is alive and kicking */ PA_SINK_INPUT_CORKED, /*< The stream was corked on user request */ PA_SINK_INPUT_DISCONNECTED /*< The stream is dead */ } pa_sink_input_state_t; @@ -55,7 +55,11 @@ struct pa_sink_input { uint32_t index; pa_core *core; - pa_atomic_t state; + + /* Please note that this state should only be read with + * pa_sink_input_get_state(). That function will transparently + * merge the thread_info.drained value in. */ + pa_sink_input_state_t state; pa_sink_input_flags_t flags; char *name, *driver; /* may be NULL */ @@ -70,7 +74,6 @@ struct pa_sink_input { pa_cvolume volume; int muted; - int (*process_msg)(pa_sink_input *i, int code, void *userdata); int (*peek) (pa_sink_input *i, pa_memchunk *chunk); void (*drop) (pa_sink_input *i, const pa_memchunk *chunk, size_t length); void (*kill) (pa_sink_input *i); /* may be NULL */ @@ -80,6 +83,9 @@ struct pa_sink_input { pa_resample_method_t resample_method; struct { + pa_sink_input_state_t state; + pa_atomic_t drained; + pa_sample_spec sample_spec; pa_memchunk resampled_chunk; @@ -106,6 +112,7 @@ enum { PA_SINK_INPUT_MESSAGE_SET_MUTE, PA_SINK_INPUT_MESSAGE_GET_LATENCY, PA_SINK_INPUT_MESSAGE_SET_RATE, + PA_SINK_INPUT_MESSAGE_SET_STATE, PA_SINK_INPUT_MESSAGE_MAX }; @@ -166,7 +173,7 @@ pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i); int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately); -#define pa_sink_input_get_state(i) ((pa_sink_input_state_t) pa_atomic_load(&i->state)) +pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i); /* To be used exclusively by the sink driver thread */ diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 2211f251..1b93c06d 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -135,7 +135,7 @@ pa_source_output* pa_source_output_new( o->parent.process_msg = pa_source_output_process_msg; o->core = core; - pa_atomic_store(&o->state, PA_SOURCE_OUTPUT_RUNNING); + o->state = PA_SOURCE_OUTPUT_RUNNING; o->flags = flags; o->name = pa_xstrdup(data->name); o->driver = pa_xstrdup(data->driver); @@ -147,12 +147,13 @@ pa_source_output* pa_source_output_new( o->sample_spec = data->sample_spec; o->channel_map = data->channel_map; - o->process_msg = NULL; o->push = NULL; o->kill = NULL; o->get_latency = NULL; o->userdata = NULL; + o->thread_info.state = o->state; + o->thread_info.sample_spec = o->sample_spec; o->thread_info.resampler = resampler; pa_assert_se(pa_idxset_put(core->source_outputs, o, &o->index) == 0); @@ -169,11 +170,22 @@ pa_source_output* pa_source_output_new( return o; } +static int source_output_set_state(pa_source_output *o, pa_source_output_state_t state) { + pa_assert(o); + + if (o->state == state) + return 0; + + if (pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), NULL) < 0) + return -1; + + o->state = state; + return 0; +} + void pa_source_output_disconnect(pa_source_output*o) { pa_assert(o); - pa_return_if_fail(pa_source_output_get_state(o) != PA_SOURCE_OUTPUT_DISCONNECTED); - pa_assert(o->source); - pa_assert(o->source->core); + pa_return_if_fail(o->state != PA_SOURCE_OUTPUT_DISCONNECTED); pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, NULL); @@ -182,15 +194,13 @@ void pa_source_output_disconnect(pa_source_output*o) { pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_REMOVE, o->index); + source_output_set_state(o, PA_SOURCE_OUTPUT_DISCONNECTED); pa_source_update_status(o->source); o->source = NULL; - o->process_msg = NULL; o->push = NULL; o->kill = NULL; o->get_latency = NULL; - - pa_atomic_store(&o->state, PA_SOURCE_OUTPUT_DISCONNECTED); } static void source_output_free(pa_object* mo) { @@ -198,7 +208,8 @@ static void source_output_free(pa_object* mo) { pa_assert(pa_source_output_refcnt(o) == 0); - pa_source_output_disconnect(o); + if (o->state != PA_SOURCE_OUTPUT_DISCONNECTED) + pa_source_output_disconnect(o); pa_log_info("Freeing output %u \"%s\"", o->index, o->name); @@ -242,18 +253,15 @@ pa_usec_t pa_source_output_get_latency(pa_source_output *o) { void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) { pa_memchunk rchunk; - pa_source_output_state_t state; pa_source_output_assert_ref(o); pa_assert(chunk); pa_assert(chunk->length); - state = pa_source_output_get_state(o); - - if (!o->push || state == PA_SOURCE_OUTPUT_DISCONNECTED || state == PA_SOURCE_OUTPUT_CORKED) + if (!o->push || o->state == PA_SOURCE_OUTPUT_DISCONNECTED || o->state == PA_SOURCE_OUTPUT_CORKED) return; - pa_assert(state = PA_SOURCE_OUTPUT_RUNNING); + pa_assert(o->state = PA_SOURCE_OUTPUT_RUNNING); if (!o->thread_info.resampler) { o->push(o, chunk); @@ -270,17 +278,9 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) { } void pa_source_output_cork(pa_source_output *o, int b) { - pa_source_output_state_t state; - pa_source_output_assert_ref(o); - state = pa_source_output_get_state(o); - pa_assert(state != PA_SOURCE_OUTPUT_DISCONNECTED); - - if (b && state != PA_SOURCE_OUTPUT_CORKED) - pa_atomic_store(&o->state, PA_SOURCE_OUTPUT_CORKED); - else if (!b && state == PA_SOURCE_OUTPUT_CORKED) - pa_atomic_cmpxchg(&o->state, state, PA_SOURCE_OUTPUT_RUNNING); + source_output_set_state(o, b ? PA_SOURCE_OUTPUT_CORKED : PA_SOURCE_OUTPUT_RUNNING); } int pa_source_output_set_rate(pa_source_output *o, uint32_t rate) { @@ -393,6 +393,13 @@ int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, pa_ return 0; } + + case PA_SOURCE_OUTPUT_MESSAGE_SET_STATE: { + o->thread_info.state = PA_PTR_TO_UINT(userdata); + + return 0; + } + } return -1; diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h index d3bc0bc4..7b6afe81 100644 --- a/src/pulsecore/source-output.h +++ b/src/pulsecore/source-output.h @@ -51,7 +51,7 @@ struct pa_source_output { uint32_t index; pa_core *core; - pa_atomic_t state; + pa_source_output_state_t state; pa_source_output_flags_t flags; char *name, *driver; /* may be NULL */ @@ -63,7 +63,6 @@ struct pa_source_output { pa_sample_spec sample_spec; pa_channel_map channel_map; - int (*process_msg)(pa_sink_input *i, int code, void *userdata); void (*push)(pa_source_output *o, const pa_memchunk *chunk); void (*kill)(pa_source_output* o); /* may be NULL */ pa_usec_t (*get_latency) (pa_source_output *o); /* may be NULL */ @@ -71,6 +70,8 @@ struct pa_source_output { pa_resample_method_t resample_method; struct { + pa_source_output_state_t state; + pa_sample_spec sample_spec; pa_resampler* resampler; /* may be NULL */ @@ -85,6 +86,7 @@ PA_DECLARE_CLASS(pa_source_output); enum { PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY, PA_SOURCE_OUTPUT_MESSAGE_SET_RATE, + PA_SOURCE_OUTPUT_MESSAGE_SET_STATE, PA_SOURCE_OUTPUT_MESSAGE_MAX }; @@ -135,7 +137,7 @@ pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o); int pa_source_output_move_to(pa_source_output *o, pa_source *dest); -#define pa_source_output_get_state(o) ((pa_source_output_state_t) pa_atomic_load(&o->state)) +#define pa_source_output_get_state(o) ((o)->state) /* To be used exclusively by the source driver thread */ -- cgit From 572c77f41822be193db603dd3c2d6f0f3ca9fa92 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 Jun 2007 18:48:40 +0000 Subject: Remove anotify.[ch], since it is now entirely replaced by pa_asyncmsgq git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1479 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/anotify.c | 145 ------------------------------------------------ src/pulsecore/anotify.h | 40 ------------- 2 files changed, 185 deletions(-) delete mode 100644 src/pulsecore/anotify.c delete mode 100644 src/pulsecore/anotify.h diff --git a/src/pulsecore/anotify.c b/src/pulsecore/anotify.c deleted file mode 100644 index 25c5fe7d..00000000 --- a/src/pulsecore/anotify.c +++ /dev/null @@ -1,145 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of PulseAudio. - - Copyright 2006 Lennart Poettering - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include - -#include - -#include "anotify.h" - -#define EVENTS_MAX 16 - -struct pa_anotify { - pa_mainloop_api *api; - pa_anotify_cb_t callback; - void *userdata; - int fds[2]; - pa_io_event *io_event; - pa_defer_event *defer_event; - - uint8_t queued_events[EVENTS_MAX]; - unsigned n_queued_events, queue_index; -}; - -static void dispatch_event(pa_anotify *a) { - assert(a); - assert(a->queue_index < a->n_queued_events); - - a->callback(a->queued_events[a->queue_index++], a->userdata); - - if (a->queue_index >= a->n_queued_events) { - a->n_queued_events = 0; - a->queue_index = 0; - - a->api->io_enable(a->io_event, PA_IO_EVENT_INPUT); - a->api->defer_enable(a->defer_event, 0); - } else { - a->api->io_enable(a->io_event, 0); - a->api->defer_enable(a->defer_event, 1); - } -} - -static void io_callback( - pa_mainloop_api *api, - pa_io_event *e, - int fd, - pa_io_event_flags_t events, - void *userdata) { - - pa_anotify *a = userdata; - ssize_t r; - - assert(a); - assert(events == PA_IO_EVENT_INPUT); - assert(a->n_queued_events == 0); - - r = read(fd, a->queued_events, sizeof(a->queued_events)); - assert(r > 0); - - a->n_queued_events = (unsigned) r; - a->queue_index = 0; - - /* Only dispatch a single event */ - dispatch_event(a); -} - -static void defer_callback(pa_mainloop_api *api, pa_defer_event *e, void *userdata) { - pa_anotify *a = userdata; - assert(a); - - dispatch_event(a); -} - -pa_anotify *pa_anotify_new(pa_mainloop_api*api, pa_anotify_cb_t cb, void *userdata) { - pa_anotify *a; - - assert(api); - assert(cb); - - a = pa_xnew(pa_anotify, 1); - - if (pipe(a->fds) < 0) { - pa_xfree(a); - return NULL; - } - - a->api = api; - a->callback = cb; - a->userdata = userdata; - - a->io_event = api->io_new(api, a->fds[0], PA_IO_EVENT_INPUT, io_callback, a); - a->defer_event = api->defer_new(api, defer_callback, a); - a->api->defer_enable(a->defer_event, 0); - - a->n_queued_events = 0; - - return a; -} - -void pa_anotify_free(pa_anotify *a) { - assert(a); - - a->api->io_free(a->io_event); - a->api->defer_free(a->defer_event); - - if (a->fds[0] >= 0) - close(a->fds[0]); - if (a->fds[1] >= 0) - close(a->fds[1]); - - pa_xfree(a); -} - -int pa_anotify_signal(pa_anotify *a, uint8_t event) { - ssize_t r; - assert(a); - - r = write(a->fds[1], &event, 1); - return r != 1 ? -1 : 0; -} diff --git a/src/pulsecore/anotify.h b/src/pulsecore/anotify.h deleted file mode 100644 index b3f75b7e..00000000 --- a/src/pulsecore/anotify.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef foopulseanotifyhfoo -#define foopulseanotifyhfoo - -/* $Id$ */ - -/*** - This file is part of PulseAudio. - - Copyright 2006 Lennart Poettering - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -/* Asynchronous thread-safe notification of mainloops */ - - -#include -#include - -typedef struct pa_anotify pa_anotify; -typedef void (*pa_anotify_cb_t)(uint8_t event, void *userdata); - -pa_anotify *pa_anotify_new(pa_mainloop_api*api, pa_anotify_cb_t cb, void *userdata); -void pa_anotify_free(pa_anotify *a); -int pa_anotify_signal(pa_anotify *a, uint8_t event); - -#endif -- cgit From 1c62ce6f860804cfb87aaef591d48f07dc36bbd2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 Jun 2007 20:11:46 +0000 Subject: Fix a nasty typo in pa_asyncq_pop git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1480 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/asyncq.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/pulsecore/asyncq.c b/src/pulsecore/asyncq.c index da1f16fb..c966e7dd 100644 --- a/src/pulsecore/asyncq.c +++ b/src/pulsecore/asyncq.c @@ -141,8 +141,10 @@ int pa_asyncq_push(pa_asyncq*l, void *p, int wait) { int x[20]; errno = 0; - if ((r = read(l->write_fds[0], x, sizeof(x))) <= 0 && errno != EINTR) + if ((r = read(l->write_fds[0], x, sizeof(x))) < 0 && errno != EINTR) return -1; + + pa_assert(r != 0); if (r > 0) if (pa_atomic_sub(&l->n_read, r) <= r) @@ -174,6 +176,8 @@ int pa_asyncq_push(pa_asyncq*l, void *p, int wait) { return -1; } + pa_assert(r != 0); + if (r > 0) pa_atomic_sub(&l->n_read, r); } @@ -220,8 +224,10 @@ void* pa_asyncq_pop(pa_asyncq*l, int wait) { int x[20]; errno = 0; - if ((r = read(l->read_fds[0], x, sizeof(x))) <= 0 && errno != EINTR) + if ((r = read(l->read_fds[0], x, sizeof(x))) < 0 && errno != EINTR) return NULL; + + pa_assert(r != 0); if (r > 0) if (pa_atomic_sub(&l->n_written, r) <= r) @@ -246,11 +252,13 @@ void* pa_asyncq_pop(pa_asyncq*l, int wait) { _Y; - if ((r = read(l->read_fds[0], x, sizeof(x)) < 0) && errno != EINTR) { + if ((r = read(l->read_fds[0], x, sizeof(x))) < 0 && errno != EINTR) { pa_atomic_dec(&l->read_waiting); return NULL; } + pa_assert(r != 0); + if (r > 0) pa_atomic_sub(&l->n_written, r); } @@ -312,7 +320,4 @@ void pa_asyncq_after_poll(pa_asyncq *l) { pa_assert(pa_atomic_load(&l->read_waiting) > 0); pa_atomic_dec(&l->read_waiting); - - - } -- cgit From 1d7096b19e0671ecc2824fda96cdd94b125eb80b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 Jun 2007 20:12:26 +0000 Subject: Show memchunk length in debug output git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1481 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/asyncmsgq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/asyncmsgq.c b/src/pulsecore/asyncmsgq.c index a46f038e..d650989b 100644 --- a/src/pulsecore/asyncmsgq.c +++ b/src/pulsecore/asyncmsgq.c @@ -164,7 +164,7 @@ int pa_asyncmsgq_get(pa_asyncmsgq *a, pa_msgobject **object, int *code, void **u if (chunk) *chunk = a->current->memchunk; - pa_log_debug("q=%p object=%p (%s) code=%i data=%p", (void*) a, (void*) a->current->object, a->current->object ? a->current->object->parent.type_name : NULL, a->current->code, (void*) a->current->userdata); + pa_log_debug("q=%p object=%p (%s) code=%i data=%p chunk.length=%u", (void*) a, (void*) a->current->object, a->current->object ? a->current->object->parent.type_name : NULL, a->current->code, (void*) a->current->userdata, a->current->memchunk.length); return 0; } -- cgit From e279778848f07c4c6ebb7b02555eea83d57430d5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 Jun 2007 20:13:44 +0000 Subject: use pa_memblockq_push_align() instead of pa_memblockq_push() to deal with unaligned data coming from clients git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1482 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-simple.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index 288c1c03..0e978c63 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -205,8 +205,10 @@ static int do_write(connection *c) { if (!c->source_output) return 0; - if (pa_memblockq_peek(c->output_memblockq, &chunk) < 0) + if (pa_memblockq_peek(c->output_memblockq, &chunk) < 0) { +/* pa_log("peek failed"); */ return 0; + } pa_assert(chunk.memblock); pa_assert(chunk.length); @@ -276,7 +278,8 @@ static int connection_process_msg(pa_msgobject *o, int code, void*userdata, pa_m break; case MESSAGE_POST_DATA: - pa_memblockq_push(c->output_memblockq, chunk); +/* pa_log("got data %u", chunk->length); */ + pa_memblockq_push_align(c->output_memblockq, chunk); do_work(c); break; -- cgit From 94f6ab5fba54db12a5373ab840ee973fb49bae9a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 Jun 2007 20:14:33 +0000 Subject: Fix another ugly typo, which made source outputs unusable git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1483 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/source-output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 1b93c06d..defb7797 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -261,7 +261,7 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) { if (!o->push || o->state == PA_SOURCE_OUTPUT_DISCONNECTED || o->state == PA_SOURCE_OUTPUT_CORKED) return; - pa_assert(o->state = PA_SOURCE_OUTPUT_RUNNING); + pa_assert(o->state == PA_SOURCE_OUTPUT_RUNNING); if (!o->thread_info.resampler) { o->push(o, chunk); -- cgit From deb523e0e8cf44bbb074b277a0a54cf9442c510e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 14 Jun 2007 20:15:06 +0000 Subject: Port module-pipe-source to the new threaded design git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1484 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-pipe-source.c | 276 ++++++++++++++++++++++++++------------- 1 file changed, 187 insertions(+), 89 deletions(-) diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index ac2bef7d..42224d52 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -28,22 +28,22 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include -#include #include #include #include #include #include +#include #include "module-pipe-source-symdef.h" @@ -58,18 +58,20 @@ PA_MODULE_USAGE( "rate= " "channel_map=") -#define DEFAULT_FIFO_NAME "/tmp/music.input" +#define DEFAULT_FILE_NAME "/tmp/music.input" #define DEFAULT_SOURCE_NAME "fifo_input" struct userdata { pa_core *core; - + pa_module *module; + pa_source *source; + pa_thread *thread; + pa_asyncmsgq *asyncmsgq; + char *filename; + int fd; - pa_source *source; - pa_iochannel *io; - pa_module *module; - pa_memchunk chunk; + pa_memchunk memchunk; }; static const char* const valid_modargs[] = { @@ -82,65 +84,146 @@ static const char* const valid_modargs[] = { NULL }; -static void do_read(struct userdata *u) { - ssize_t r; - void *p; - pa_memchunk chunk; - - assert(u); - - if (!pa_iochannel_is_readable(u->io)) - return; - - pa_module_set_used(u->module, pa_idxset_size(u->source->outputs)); - - if (!u->chunk.memblock) { - u->chunk.memblock = pa_memblock_new(u->core->mempool, PIPE_BUF); - u->chunk.index = chunk.length = 0; - } - - assert(u->chunk.memblock); - assert(pa_memblock_get_length(u->chunk.memblock) > u->chunk.index); - - p = pa_memblock_acquire(u->chunk.memblock); - if ((r = pa_iochannel_read(u->io, (uint8_t*) p + u->chunk.index, pa_memblock_get_length(u->chunk.memblock) - u->chunk.index)) <= 0) { - pa_memblock_release(u->chunk.memblock); - pa_log("read(): %s", pa_cstrerror(errno)); - return; +static void thread_func(void *userdata) { + enum { + POLLFD_ASYNCQ, + POLLFD_FIFO, + POLLFD_MAX, + }; + + struct userdata *u = userdata; + struct pollfd pollfd[POLLFD_MAX]; + int read_type = 0; + + pa_assert(u); + + pa_log_debug("Thread starting up"); + + pa_memchunk_reset(&u->memchunk); + + memset(&pollfd, 0, sizeof(pollfd)); + + pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq); + pollfd[POLLFD_ASYNCQ].events = POLLIN; + pollfd[POLLFD_FIFO].fd = u->fd; + + for (;;) { + pa_msgobject *object; + int code; + void *data; + pa_memchunk chunk; + int r; + + /* Check whether there is a message for us to process */ + if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { + int ret; + + if (!object && code == PA_MESSAGE_SHUTDOWN) { + pa_asyncmsgq_done(u->asyncmsgq, 0); + goto finish; + } + + ret = pa_asyncmsgq_dispatch(object, code, data, &chunk); + pa_asyncmsgq_done(u->asyncmsgq, ret); + continue; + } + + /* Render some data and write it to the fifo */ + + if (u->source->thread_info.state == PA_SOURCE_RUNNING && pollfd[POLLFD_FIFO].revents) { + void *p; + ssize_t l; + + if (!u->memchunk.memblock) { + u->memchunk.memblock = pa_memblock_new(u->core->mempool, PIPE_BUF); + u->memchunk.index = u->memchunk.length = 0; + } + + pa_assert(pa_memblock_get_length(u->memchunk.memblock) > u->memchunk.index); + + p = pa_memblock_acquire(u->memchunk.memblock); + l = pa_read(u->fd, (uint8_t*) p + u->memchunk.index, pa_memblock_get_length(u->memchunk.memblock) - u->memchunk.index, &read_type); + pa_memblock_release(u->memchunk.memblock); + + pa_assert(l != 0); /* EOF cannot happen, since we opened the fifo for both reading and writing */ + + if (l < 0) { + + if (errno == EINTR) + continue; + else if (errno != EAGAIN) { + pa_log("Faile to read data from FIFO: %s", pa_cstrerror(errno)); + goto fail; + } + + } else { + + u->memchunk.length = l; + pa_source_post(u->source, &u->memchunk); + u->memchunk.index += l; + + if (u->memchunk.index >= pa_memblock_get_length(u->memchunk.memblock)) { + pa_memblock_unref(u->memchunk.memblock); + pa_memchunk_reset(&u->memchunk); + } + + pollfd[POLLFD_FIFO].revents = 0; + continue; + } + } + + pollfd[POLLFD_FIFO].events = u->source->thread_info.state == PA_SINK_RUNNING ? POLLIN : 0; + + /* Hmm, nothing to do. Let's sleep */ + + if (pa_asyncmsgq_before_poll(u->asyncmsgq) < 0) + continue; + +/* pa_log("polling for %i", pollfd[POLLFD_FIFO].events); */ + r = poll(pollfd, POLLFD_MAX, -1); +/* pa_log("polling got %i (r=%i) %i", r > 0 ? pollfd[POLLFD_FIFO].revents : 0, r, r > 0 ? pollfd[POLLFD_ASYNCQ].revents: 0); */ + + pa_asyncmsgq_after_poll(u->asyncmsgq); + + if (r < 0) { + if (errno == EINTR) + continue; + + pa_log("poll() failed: %s", pa_cstrerror(errno)); + goto fail; + } + + if (pollfd[POLLFD_FIFO].revents & ~POLLIN) { + pa_log("FIFO shutdown."); + goto fail; + } + + pa_assert((pollfd[POLLFD_ASYNCQ].revents & ~POLLIN) == 0); } - pa_memblock_release(u->chunk.memblock); - - u->chunk.length = r; - pa_source_post(u->source, &u->chunk); - u->chunk.index += r; - if (u->chunk.index >= pa_memblock_get_length(u->chunk.memblock)) { - u->chunk.index = u->chunk.length = 0; - pa_memblock_unref(u->chunk.memblock); - u->chunk.memblock = NULL; - } -} +fail: + /* We have to continue processing messages until we receive the + * SHUTDOWN message */ + pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, NULL, NULL); + pa_asyncmsgq_wait_for(u->asyncmsgq, PA_MESSAGE_SHUTDOWN); -static void io_callback(PA_GCC_UNUSED pa_iochannel *io, void*userdata) { - struct userdata *u = userdata; - assert(u); - do_read(u); +finish: + pa_log_debug("Thread shutting down"); } int pa__init(pa_core *c, pa_module*m) { - struct userdata *u = NULL; + struct userdata *u; struct stat st; - const char *p; - int fd = -1; pa_sample_spec ss; pa_channel_map map; - pa_modargs *ma = NULL; + pa_modargs *ma; char *t; - assert(c && m); + pa_assert(c); + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { - pa_log("failed to parse module arguments"); + pa_log("failed to parse module arguments."); goto fail; } @@ -150,48 +233,50 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - mkfifo(p = pa_modargs_get_value(ma, "file", DEFAULT_FIFO_NAME), 0777); + u = pa_xnew0(struct userdata, 1); + u->core = c; + u->module = m; + m->userdata = u; - if ((fd = open(p, O_RDWR)) < 0) { - pa_log("open('%s'): %s", p, pa_cstrerror(errno)); + pa_assert_se(u->asyncmsgq = pa_asyncmsgq_new(0)); + + u->filename = pa_xstrdup(pa_modargs_get_value(ma, "file", DEFAULT_FILE_NAME)); + + mkfifo(u->filename, 0666); + if ((u->fd = open(u->filename, O_RDWR|O_NOCTTY)) < 0) { + pa_log("open('%s'): %s", u->filename, pa_cstrerror(errno)); goto fail; } - pa_fd_set_cloexec(fd, 1); + pa_fd_set_cloexec(u->fd, 1); + pa_make_nonblock_fd(u->fd); - if (fstat(fd, &st) < 0) { - pa_log("fstat('%s'): %s", p, pa_cstrerror(errno)); + if (fstat(u->fd, &st) < 0) { + pa_log("fstat('%s'): %s",u->filename, pa_cstrerror(errno)); goto fail; } if (!S_ISFIFO(st.st_mode)) { - pa_log("'%s' is not a FIFO.", p); + pa_log("'%s' is not a FIFO.", u->filename); goto fail; } - u = pa_xmalloc0(sizeof(struct userdata)); - - u->filename = pa_xstrdup(p); - u->core = c; - if (!(u->source = pa_source_new(c, __FILE__, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME), 0, &ss, &map))) { - pa_log("failed to create source."); + pa_log("Failed to create source."); goto fail; } + u->source->userdata = u; + pa_source_set_module(u->source, m); - pa_source_set_description(u->source, t = pa_sprintf_malloc("Unix FIFO source '%s'", p)); + pa_source_set_asyncmsgq(u->source, u->asyncmsgq); + pa_source_set_description(u->source, t = pa_sprintf_malloc("Unix FIFO source '%s'", u->filename)); pa_xfree(t); - u->io = pa_iochannel_new(c->mainloop, fd, -1); - assert(u->io); - pa_iochannel_set_callback(u->io, io_callback, u); - - u->chunk.memblock = NULL; - u->chunk.index = u->chunk.length = 0; - - u->module = m; - m->userdata = u; + if (!(u->thread = pa_thread_new(thread_func, u))) { + pa_log("Failed to create thread."); + goto fail; + } pa_modargs_free(ma); @@ -201,9 +286,6 @@ fail: if (ma) pa_modargs_free(ma); - if (fd >= 0) - close(fd); - pa__done(c, m); return -1; @@ -211,21 +293,37 @@ fail: void pa__done(pa_core *c, pa_module*m) { struct userdata *u; - assert(c && m); + + pa_assert(c); + pa_assert(m); if (!(u = m->userdata)) return; - if (u->chunk.memblock) - pa_memblock_unref(u->chunk.memblock); + if (u->source) + pa_source_disconnect(u->source); - pa_source_disconnect(u->source); - pa_source_unref(u->source); - pa_iochannel_free(u->io); + if (u->thread) { + pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, NULL); + pa_thread_free(u->thread); + } + + if (u->asyncmsgq) + pa_asyncmsgq_free(u->asyncmsgq); + + if (u->source) + pa_source_unref(u->source); + + if (u->memchunk.memblock) + pa_memblock_unref(u->memchunk.memblock); + + if (u->filename) { + unlink(u->filename); + pa_xfree(u->filename); + } - assert(u->filename); - unlink(u->filename); - pa_xfree(u->filename); + if (u->fd >= 0) + close(u->fd); pa_xfree(u); } -- cgit From e24c8dea5b359bd960660fa2d0100321cb627207 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 23 Jun 2007 19:53:11 +0000 Subject: Fix minor typo git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1485 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/memblockq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/memblockq.h b/src/pulsecore/memblockq.h index 437c5a41..c049d78c 100644 --- a/src/pulsecore/memblockq.h +++ b/src/pulsecore/memblockq.h @@ -62,7 +62,7 @@ typedef struct pa_memblockq pa_memblockq; - minreq: pa_memblockq_missing() will only return values greater than this value. Pass 0 for the default. - - silence: return this memblock whzen reading unitialized data + - silence: return this memblock when reading unitialized data */ pa_memblockq* pa_memblockq_new( int64_t idx, -- cgit From 1c9bd201ec88e3493f01b5cd2a7c5a713d829555 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 23 Jun 2007 20:01:40 +0000 Subject: minor cleanups and optimizations git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1486 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/oss-util.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/modules/oss-util.c b/src/modules/oss-util.c index 4be71e2c..155d42e4 100644 --- a/src/modules/oss-util.c +++ b/src/modules/oss-util.c @@ -26,7 +26,6 @@ #include #endif -#include #include #include #include @@ -40,6 +39,7 @@ #include #include #include +#include #include "oss-util.h" @@ -47,24 +47,23 @@ int pa_oss_open(const char *device, int *mode, int* pcaps) { int fd = -1; int caps; - assert(device && mode && (*mode == O_RDWR || *mode == O_RDONLY || *mode == O_WRONLY)); + pa_assert(device); + pa_assert(mode); + pa_assert(*mode == O_RDWR || *mode == O_RDONLY || *mode == O_WRONLY); if(!pcaps) pcaps = ∩︀ if (*mode == O_RDWR) { - if ((fd = open(device, O_RDWR|O_NDELAY)) >= 0) { - int dcaps, *tcaps; + if ((fd = open(device, O_RDWR|O_NDELAY|O_NOCTTY)) >= 0) { ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0); - tcaps = pcaps ? pcaps : &dcaps; - - if (ioctl(fd, SNDCTL_DSP_GETCAPS, tcaps) < 0) { + if (ioctl(fd, SNDCTL_DSP_GETCAPS, pcaps) < 0) { pa_log("SNDCTL_DSP_GETCAPS: %s", pa_cstrerror(errno)); goto fail; } - if (*tcaps & DSP_CAP_DUPLEX) + if (*pcaps & DSP_CAP_DUPLEX) goto success; pa_log_warn("'%s' doesn't support full duplex", device); @@ -72,21 +71,19 @@ int pa_oss_open(const char *device, int *mode, int* pcaps) { close(fd); } - if ((fd = open(device, (*mode = O_WRONLY)|O_NDELAY)) < 0) { - if ((fd = open(device, (*mode = O_RDONLY)|O_NDELAY)) < 0) { + if ((fd = open(device, (*mode = O_WRONLY)|O_NDELAY|O_NOCTTY)) < 0) { + if ((fd = open(device, (*mode = O_RDONLY)|O_NDELAY|O_NOCTTY)) < 0) { pa_log("open('%s'): %s", device, pa_cstrerror(errno)); goto fail; } } } else { - if ((fd = open(device, *mode|O_NDELAY)) < 0) { + if ((fd = open(device, *mode|O_NDELAY|O_NOCTTY)) < 0) { pa_log("open('%s'): %s", device, pa_cstrerror(errno)); goto fail; } } -success: - *pcaps = 0; if (ioctl(fd, SNDCTL_DSP_GETCAPS, pcaps) < 0) { @@ -94,6 +91,8 @@ success: goto fail; } +success: + pa_log_debug("capabilities:%s%s%s%s%s%s%s%s%s%s%s%s%s%s", *pcaps & DSP_CAP_BATCH ? " BATCH" : "", #ifdef DSP_CAP_BIND @@ -166,7 +165,8 @@ int pa_oss_auto_format(int fd, pa_sample_spec *ss) { [PA_SAMPLE_FLOAT32BE] = AFMT_QUERY, /* not supported */ }; - assert(fd >= 0 && ss); + pa_assert(fd >= 0); + pa_assert(ss); orig_format = ss->format; @@ -199,7 +199,7 @@ int pa_oss_auto_format(int fd, pa_sample_spec *ss) { pa_log("SNDCTL_DSP_CHANNELS: %s", pa_cstrerror(errno)); return -1; } - assert(channels > 0); + pa_assert(channels > 0); if (ss->channels != channels) { pa_log_warn("device doesn't support %i channels, using %i channels.", ss->channels, channels); @@ -211,7 +211,7 @@ int pa_oss_auto_format(int fd, pa_sample_spec *ss) { pa_log("SNDCTL_DSP_SPEED: %s", pa_cstrerror(errno)); return -1; } - assert(speed > 0); + pa_assert(speed > 0); if (ss->rate != (unsigned) speed) { pa_log_warn("device doesn't support %i Hz, changed to %i Hz.", ss->rate, speed); @@ -252,9 +252,9 @@ static int pa_oss_get_volume(int fd, int mixer, const pa_sample_spec *ss, pa_cvo char cv[PA_CVOLUME_SNPRINT_MAX]; unsigned vol; - assert(fd >= 0); - assert(ss); - assert(volume); + pa_assert(fd >= 0); + pa_assert(ss); + pa_assert(volume); if (ioctl(fd, mixer, &vol) < 0) return -1; @@ -357,7 +357,7 @@ int pa_oss_get_hw_description(const char *dev, char *name, size_t l) { if (device == n) { char *k = strchr(line, ':'); - assert(k); + pa_assert(k); k++; k += strspn(k, " "); -- cgit From fff9081c4bedded92caaabf9191aeb717709354b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 23 Jun 2007 20:02:28 +0000 Subject: fix a typo and some minor optimizations git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1487 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-pipe-source.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index 42224d52..5dbb1e7b 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -99,8 +99,6 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); - pa_memchunk_reset(&u->memchunk); - memset(&pollfd, 0, sizeof(pollfd)); pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq); @@ -128,19 +126,19 @@ static void thread_func(void *userdata) { continue; } - /* Render some data and write it to the fifo */ + /* Try to read some data and pass it on to the source driver */ if (u->source->thread_info.state == PA_SOURCE_RUNNING && pollfd[POLLFD_FIFO].revents) { void *p; ssize_t l; - + if (!u->memchunk.memblock) { u->memchunk.memblock = pa_memblock_new(u->core->mempool, PIPE_BUF); u->memchunk.index = u->memchunk.length = 0; } pa_assert(pa_memblock_get_length(u->memchunk.memblock) > u->memchunk.index); - + p = pa_memblock_acquire(u->memchunk.memblock); l = pa_read(u->fd, (uint8_t*) p + u->memchunk.index, pa_memblock_get_length(u->memchunk.memblock) - u->memchunk.index, &read_type); pa_memblock_release(u->memchunk.memblock); @@ -157,7 +155,7 @@ static void thread_func(void *userdata) { } } else { - + u->memchunk.length = l; pa_source_post(u->source, &u->memchunk); u->memchunk.index += l; @@ -172,7 +170,7 @@ static void thread_func(void *userdata) { } } - pollfd[POLLFD_FIFO].events = u->source->thread_info.state == PA_SINK_RUNNING ? POLLIN : 0; + pollfd[POLLFD_FIFO].events = u->source->thread_info.state == PA_SOURCE_RUNNING ? POLLIN : 0; /* Hmm, nothing to do. Let's sleep */ @@ -237,7 +235,8 @@ int pa__init(pa_core *c, pa_module*m) { u->core = c; u->module = m; m->userdata = u; - + pa_memchunk_reset(&u->memchunk); + pa_assert_se(u->asyncmsgq = pa_asyncmsgq_new(0)); u->filename = pa_xstrdup(pa_modargs_get_value(ma, "file", DEFAULT_FILE_NAME)); -- cgit From f0616367b32fbe993c4d0edb0457b10d241137a2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 23 Jun 2007 20:03:00 +0000 Subject: drop silence generation from sink drivers git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1488 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-null-sink.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index afe130d9..3e471d41 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -140,7 +140,7 @@ static void thread_func(void *userdata) { pa_asyncmsgq_done(u->asyncmsgq, 0); goto finish; } - + ret = pa_asyncmsgq_dispatch(object, code, data, &chunk); pa_asyncmsgq_done(u->asyncmsgq, ret); continue; @@ -151,15 +151,11 @@ static void thread_func(void *userdata) { pa_gettimeofday(&now); if (pa_timeval_cmp(&u->timestamp, &now) <= 0) { - size_t l; - if (pa_sink_render(u->sink, u->block_size, &chunk) >= 0) { - l = chunk.length; - pa_memblock_unref(chunk.memblock); - } else - l = u->block_size; + pa_sink_render(u->sink, u->block_size, &chunk); + pa_memblock_unref(chunk.memblock); - pa_timeval_add(&u->timestamp, pa_bytes_to_usec(l, &u->sink->sample_spec)); + pa_timeval_add(&u->timestamp, pa_bytes_to_usec(chunk.length, &u->sink->sample_spec)); continue; } -- cgit From 780f736547616e4e06941d94e77f456abca12a9c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 23 Jun 2007 20:03:30 +0000 Subject: don't handle underrun special git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1489 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-pipe-sink.c | 59 +++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index 216e42ac..e27a237e 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -115,15 +115,12 @@ static void thread_func(void *userdata) { struct userdata *u = userdata; struct pollfd pollfd[POLLFD_MAX]; - int underrun = 0; int write_type = 0; pa_assert(u); pa_log_debug("Thread starting up"); - pa_memchunk_reset(&u->memchunk); - memset(&pollfd, 0, sizeof(pollfd)); pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq); @@ -153,56 +150,53 @@ static void thread_func(void *userdata) { /* Render some data and write it to the fifo */ - if (u->sink->thread_info.state == PA_SINK_RUNNING && (pollfd[POLLFD_FIFO].revents || underrun)) { + if (u->sink->thread_info.state == PA_SINK_RUNNING && pollfd[POLLFD_FIFO].revents) { + ssize_t l; + void *p; if (u->memchunk.length <= 0) pa_sink_render(u->sink, PIPE_BUF, &u->memchunk); - underrun = u->memchunk.length <= 0; + pa_assert(u->memchunk.length > 0); - if (!underrun) { - ssize_t l; - void *p; + p = pa_memblock_acquire(u->memchunk.memblock); + l = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length, &write_type); + pa_memblock_release(u->memchunk.memblock); - p = pa_memblock_acquire(u->memchunk.memblock); - l = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length, &write_type); - pa_memblock_release(u->memchunk.memblock); + pa_assert(l != 0); - pa_assert(l != 0); - - if (l < 0) { + if (l < 0) { - if (errno == EINTR) - continue; - else if (errno != EAGAIN) { - pa_log("Failed to write data to FIFO: %s", pa_cstrerror(errno)); - goto fail; - } - - } else { + if (errno == EINTR) + continue; + else if (errno != EAGAIN) { + pa_log("Failed to write data to FIFO: %s", pa_cstrerror(errno)); + goto fail; + } - u->memchunk.index += l; - u->memchunk.length -= l; + } else { - if (u->memchunk.length <= 0) { - pa_memblock_unref(u->memchunk.memblock); - pa_memchunk_reset(&u->memchunk); - } + u->memchunk.index += l; + u->memchunk.length -= l; - pollfd[POLLFD_FIFO].revents = 0; - continue; + if (u->memchunk.length <= 0) { + pa_memblock_unref(u->memchunk.memblock); + pa_memchunk_reset(&u->memchunk); } + + pollfd[POLLFD_FIFO].revents = 0; + continue; } } - pollfd[POLLFD_FIFO].events = (u->sink->thread_info.state == PA_SINK_RUNNING && !underrun) ? POLLOUT : 0; + pollfd[POLLFD_FIFO].events = u->sink->thread_info.state == PA_SINK_RUNNING ? POLLOUT : 0; /* Hmm, nothing to do. Let's sleep */ if (pa_asyncmsgq_before_poll(u->asyncmsgq) < 0) continue; -/* pa_log("polling for %u (underrun=%i)", pollfd[POLLFD_FIFO].events, underrun); */ +/* pa_log("polling for %u", pollfd[POLLFD_FIFO].events); */ r = poll(pollfd, POLLFD_MAX, -1); /* pa_log("polling got %u", r > 0 ? pollfd[POLLFD_FIFO].revents : 0); */ @@ -260,6 +254,7 @@ int pa__init(pa_core *c, pa_module*m) { u->core = c; u->module = m; m->userdata = u; + pa_memchunk_reset(&u->memchunk); pa_assert_se(u->asyncmsgq = pa_asyncmsgq_new(0)); -- cgit From 013a55a692d652ce079b9dbd5f768a0a0680f727 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 23 Jun 2007 20:04:47 +0000 Subject: remove underrun condition in pa_sinks. Instead return silence in pa_sink_render() when necessary. This is required to guarantee that the time functions in connected sink inputs stays linear git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1490 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink.c | 130 ++++++++++++++++++++++++++++++--------------------- src/pulsecore/sink.h | 6 ++- 2 files changed, 81 insertions(+), 55 deletions(-) diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 7f009048..11effe2f 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -116,6 +116,7 @@ pa_sink* pa_sink_new( s->userdata = NULL; s->asyncmsgq = NULL; + s->silence = NULL; r = pa_idxset_put(core->sinks, s, &s->index); pa_assert(s->index != PA_IDXSET_INVALID && r >= 0); @@ -222,6 +223,9 @@ static void sink_free(pa_object *o) { pa_hashmap_free(s->thread_info.inputs, NULL, NULL); + if (s->silence) + pa_memblock_unref(s->silence); + pa_xfree(s->name); pa_xfree(s->description); pa_xfree(s->driver); @@ -270,53 +274,85 @@ static unsigned fill_mix_info(pa_sink *s, pa_mix_info *info, unsigned maxinfo) { pa_sink_assert_ref(s); pa_assert(info); - while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL))) { - /* Increase ref counter, to make sure that this input doesn't - * vanish while we still need it */ - pa_sink_input_ref(i); + while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)) && maxinfo > 0) { + pa_sink_input_assert_ref(i); - if (pa_sink_input_peek(i, &info->chunk, &info->volume) < 0) { - pa_sink_input_unref(i); + if (pa_sink_input_peek(i, &info->chunk, &info->volume) < 0) continue; - } - info->userdata = i; + info->userdata = pa_sink_input_ref(i); pa_assert(info->chunk.memblock); - pa_assert(info->chunk.length); + pa_assert(info->chunk.length > 0); info++; - maxinfo--; n++; + maxinfo--; } return n; } -static void inputs_drop(pa_sink *s, pa_mix_info *info, unsigned maxinfo, size_t length) { +static void inputs_drop(pa_sink *s, pa_mix_info *info, unsigned n, size_t length) { + pa_sink_input *i; + void *state = NULL; + unsigned p = 0; + unsigned n_unreffed = 0; + pa_sink_assert_ref(s); - pa_assert(info); - for (; maxinfo > 0; maxinfo--, info++) { - pa_sink_input *i = info->userdata; + /* We optimize for the case where the order of the inputs has not changed */ - pa_assert(i); - pa_assert(info->chunk.memblock); + while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL))) { + unsigned j; + pa_mix_info* m; + + pa_sink_input_assert_ref(i); + + m = NULL; + + /* Let's try to find the matching entry info the pa_mix_info array */ + for (j = 0; j < n; j ++) { + + if (info[p].userdata == i) { + m = info + p; + break; + } + + if (++p > n) + p = 0; + } /* Drop read data */ - pa_sink_input_drop(i, &info->chunk, length); - pa_memblock_unref(info->chunk.memblock); + pa_sink_input_drop(i, m ? &m->chunk : NULL, length); - /* Decrease ref counter */ - pa_sink_input_unref(i); - info->userdata = NULL; + if (m) { + pa_sink_input_unref(m->userdata); + m->userdata = NULL; + if (m->chunk.memblock) + pa_memblock_unref(m->chunk.memblock); + pa_memchunk_reset(&m->chunk); + + n_unreffed += 1; + } + } + + /* Now drop references to entries that are included in the + * pa_mix_info array but don't exist anymore */ + + if (n_unreffed < n) { + for (; n > 0; info++, n--) { + if (info->userdata) + pa_sink_input_unref(info->userdata); + if (info->chunk.memblock) + pa_memblock_unref(info->chunk.memblock); + } } } -int pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) { +void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) { pa_mix_info info[MAX_MIX_CHANNELS]; unsigned n; - int r = -1; pa_sink_assert_ref(s); pa_assert(length); @@ -326,10 +362,19 @@ int pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) { n = fill_mix_info(s, info, MAX_MIX_CHANNELS); - if (n <= 0) - goto finish; + if (n == 0) { + + if (!s->silence || pa_memblock_get_length(s->silence) < length) { + if (s->silence) + pa_memblock_unref(s->silence); + s->silence = pa_silence_memblock_new(s->core->mempool, &s->sample_spec, length); + } + + result->memblock = pa_memblock_ref(s->silence); + result->length = length; + result->index = 0; - if (n == 1) { + } else if (n == 1) { pa_cvolume volume; *result = info[0].chunk; @@ -363,18 +408,12 @@ int pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) { if (s->monitor_source) pa_source_post(s->monitor_source, result); - r = 0; - -finish: pa_sink_unref(s); - - return r; } -int pa_sink_render_into(pa_sink*s, pa_memchunk *target) { +void pa_sink_render_into(pa_sink*s, pa_memchunk *target) { pa_mix_info info[MAX_MIX_CHANNELS]; unsigned n; - int r = -1; pa_sink_assert_ref(s); pa_assert(target); @@ -385,11 +424,9 @@ int pa_sink_render_into(pa_sink*s, pa_memchunk *target) { n = fill_mix_info(s, info, MAX_MIX_CHANNELS); - if (n <= 0) - goto finish; - - - if (n == 1) { + if (n == 0) { + pa_silence_memchunk(target, &s->sample_spec); + } else if (n == 1) { if (target->length > info[0].chunk.length) target->length = info[0].chunk.length; @@ -435,12 +472,7 @@ int pa_sink_render_into(pa_sink*s, pa_memchunk *target) { if (s->monitor_source) pa_source_post(s->monitor_source, target); - r = 0; - -finish: pa_sink_unref(s); - - return r; } void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) { @@ -461,20 +493,12 @@ void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) { chunk.index += d; chunk.length -= d; - if (pa_sink_render_into(s, &chunk) < 0) - break; + pa_sink_render_into(s, &chunk); d += chunk.length; l -= chunk.length; } - if (l > 0) { - chunk = *target; - chunk.index += d; - chunk.length -= d; - pa_silence_memchunk(&chunk, &s->sample_spec); - } - pa_sink_unref(s); } @@ -668,7 +692,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk * case PA_SINK_MESSAGE_SET_STATE: s->thread_info.state = PA_PTR_TO_UINT(userdata); return 0; - + case PA_SINK_MESSAGE_GET_LATENCY: case PA_SINK_MESSAGE_MAX: ; diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index 0b308e53..dab97453 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -92,6 +92,8 @@ struct pa_sink { int soft_muted; } thread_info; + pa_memblock *silence; + void *userdata; }; @@ -149,9 +151,9 @@ unsigned pa_sink_used_by(pa_sink *s); /* To be used exclusively by the sink driver thread */ -int pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result); +void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result); void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result); -int pa_sink_render_into(pa_sink*s, pa_memchunk *target); +void pa_sink_render_into(pa_sink*s, pa_memchunk *target); void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target); int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk); -- cgit From bb3ad9d38e2be840838b6af5dc2a09e4863566ed Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 23 Jun 2007 20:05:20 +0000 Subject: Update OSS driver for new lock-free core git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1491 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 22 +- src/modules/module-oss.c | 740 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 523 insertions(+), 239 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 0a5d5297..a83424ce 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -927,12 +927,12 @@ modlibexec_LTLIBRARIES += \ module-x11-publish.la endif -#if HAVE_OSS -#modlibexec_LTLIBRARIES += \ -# liboss-util.la \ -# module-oss.la \ +if HAVE_OSS +modlibexec_LTLIBRARIES += \ + liboss-util.la \ + module-oss.la # module-oss-mmap.la -#endif +endif #if HAVE_ALSA #modlibexec_LTLIBRARIES += \ @@ -1176,13 +1176,13 @@ module_x11_publish_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EX # OSS -#liboss_util_la_SOURCES = modules/oss-util.c modules/oss-util.h -#liboss_util_la_LDFLAGS = -avoid-version -#liboss_util_la_LIBADD = libpulsecore.la +liboss_util_la_SOURCES = modules/oss-util.c modules/oss-util.h +liboss_util_la_LDFLAGS = -avoid-version +liboss_util_la_LIBADD = libpulsecore.la -#module_oss_la_SOURCES = modules/module-oss.c -#module_oss_la_LDFLAGS = -module -avoid-version -#module_oss_la_LIBADD = $(AM_LIBADD) libiochannel.la liboss-util.la +module_oss_la_SOURCES = modules/module-oss.c +module_oss_la_LDFLAGS = -module -avoid-version +module_oss_la_LIBADD = $(AM_LIBADD) libiochannel.la liboss-util.la #module_oss_mmap_la_SOURCES = modules/module-oss-mmap.c #module_oss_mmap_la_LDFLAGS = -module -avoid-version diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 9061e110..01fe2b6e 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -22,12 +22,31 @@ USA. ***/ +/* General power management rules: + * + * When SUSPENDED we close the audio device. + * + * We make no difference between IDLE and RUNNING in our handling. + * + * As long as we are in RUNNING/IDLE state we will *always* write data to + * the device. If none is avilable from the inputs, we write silence + * instead. + * + * If power should be saved on IDLE this should be implemented in a + * special suspend-on-idle module that will put us into SUSPEND mode + * as soon and we're idle for too long. + * + */ + +/* TODO: handle restoring of volume after suspend */ + #ifdef HAVE_CONFIG_H #include #endif #include #include +#include #include #include #include @@ -42,7 +61,7 @@ #include #include -#include +#include #include #include #include @@ -70,19 +89,33 @@ PA_MODULE_USAGE( "fragment_size= " "channel_map=") +#define DEFAULT_DEVICE "/dev/dsp" + struct userdata { + pa_core *core; + pa_module *module; pa_sink *sink; pa_source *source; - pa_iochannel *io; - pa_core *core; + pa_thread *thread; + pa_asyncmsgq *asyncmsgq; - pa_memchunk memchunk, silence; + char *device_name; + + pa_memchunk memchunk; uint32_t in_fragment_size, out_fragment_size, sample_size; int use_getospace, use_getispace; + int use_getodelay; + + int use_pcm_volume; + int use_input_volume; + + int sink_suspended, source_suspended; int fd; - pa_module *module; + int mode; + + int nfrags, frag_size; }; static const char* const valid_modargs[] = { @@ -100,264 +133,500 @@ static const char* const valid_modargs[] = { NULL }; -#define DEFAULT_DEVICE "/dev/dsp" +static int suspend(struct userdata *u) { + pa_assert(u); + pa_assert(u->fd >= 0); -static void update_usage(struct userdata *u) { - pa_module_set_used(u->module, - (u->sink ? pa_sink_used_by(u->sink) : 0) + - (u->source ? pa_source_used_by(u->source) : 0)); + /* Let's suspend */ + ioctl(u->fd, SNDCTL_DSP_SYNC); + close(u->fd); + u->fd = -1; + + return 0; } -static void clear_up(struct userdata *u) { - assert(u); +static int unsuspend(struct userdata *u) { + int m; + pa_sample_spec ss, *ss_original; + int frag_size, in_frag_size, out_frag_size; + struct audio_buf_info info; - if (u->sink) { - pa_sink_disconnect(u->sink); - pa_sink_unref(u->sink); - u->sink = NULL; + pa_assert(u); + pa_assert(u->fd < 0); + + m = u->mode; + + pa_log_debug("Trying resume..."); + + if ((u->fd = pa_oss_open(u->device_name, &m, NULL)) < 0) { + pa_log_warn("Resume failed, device busy (%s)", pa_cstrerror(errno)); + return -1; + + if (m != u->mode) + pa_log_warn("Resume failed, couldn't open device with original access mode."); + goto fail; } - if (u->source) { - pa_source_disconnect(u->source); - pa_source_unref(u->source); - u->source = NULL; + if (u->nfrags >= 2 && u->frag_size >= 1) + if (pa_oss_set_fragments(u->fd, u->nfrags, u->frag_size) < 0) { + pa_log_warn("Resume failed, couldn't set original fragment settings."); + goto fail; + } + + ss = *(ss_original = u->sink ? &u->sink->sample_spec : &u->source->sample_spec); + if (pa_oss_auto_format(u->fd, &ss) < 0 || !pa_sample_spec_equal(&ss, ss_original)) { + pa_log_warn("Resume failed, couldn't set original sample format settings."); + goto fail; } - if (u->io) { - pa_iochannel_free(u->io); - u->io = NULL; + if (ioctl(u->fd, SNDCTL_DSP_GETBLKSIZE, &frag_size) < 0) { + pa_log("SNDCTL_DSP_GETBLKSIZE: %s", pa_cstrerror(errno)); + goto fail; } -} -static void do_write(struct userdata *u) { - pa_memchunk *memchunk; - ssize_t r; - size_t l; - int loop = 0; + in_frag_size = out_frag_size = frag_size; - assert(u); + if (ioctl(u->fd, SNDCTL_DSP_GETISPACE, &info) >= 0) + in_frag_size = info.fragsize; - if (!u->sink || !pa_iochannel_is_writable(u->io)) - return; + if (ioctl(u->fd, SNDCTL_DSP_GETOSPACE, &info) >= 0) + out_frag_size = info.fragsize; - update_usage(u); + if ((u->source && in_frag_size != (int) u->in_fragment_size) || (u->sink && out_frag_size != (int) u->out_fragment_size)) { + pa_log_warn("Resume failed, fragment settings don't match."); + goto fail; + } - l = u->out_fragment_size; + /* + * Some crappy drivers do not start the recording until we read something. + * Without this snippet, poll will never register the fd as ready. + */ + if (u->source) { + uint8_t *buf = pa_xnew(uint8_t, u->sample_size); + pa_read(u->fd, buf, u->sample_size, NULL); + pa_xfree(buf); + } - if (u->use_getospace) { - audio_buf_info info; + return 0; - if (ioctl(u->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) - u->use_getospace = 0; - else { - if (info.bytes/l > 0) { - l = (info.bytes/l)*l; - loop = 1; +fail: + close(u->fd); + u->fd = -1; + return -1; +} + +static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk *chunk) { + struct userdata *u = PA_SINK(o)->userdata; + + switch (code) { + + case PA_SINK_MESSAGE_GET_LATENCY: { + pa_usec_t r = 0; + + if (u->fd >= 0) { + if (u->use_getodelay) { + int arg; + + if (ioctl(u->fd, SNDCTL_DSP_GETODELAY, &arg) < 0) { + pa_log_info("Device doesn't support SNDCTL_DSP_GETODELAY: %s", pa_cstrerror(errno)); + u->use_getodelay = 0; + } else + r = pa_bytes_to_usec(arg, &u->sink->sample_spec); + + } + + if (!u->use_getodelay && u->use_getospace) { + struct audio_buf_info info; + + if (ioctl(u->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) { + pa_log_info("Device doesn't support SNDCTL_DSP_GETOSPACE: %s", pa_cstrerror(errno)); + u->use_getospace = 0; + } else + r = pa_bytes_to_usec(info.bytes, &u->sink->sample_spec); + } } + + if (u->memchunk.memblock) + r += pa_bytes_to_usec(u->memchunk.length, &u->sink->sample_spec); + + *((pa_usec_t*) data) = r; + + break; } - } - do { - void *p; - memchunk = &u->memchunk; + case PA_SINK_MESSAGE_SET_STATE: + + if (PA_PTR_TO_UINT(data) != PA_SINK_RUNNING && u->fd >= 0) + ioctl(u->fd, SNDCTL_DSP_POST); + + if (PA_PTR_TO_UINT(data) == PA_SINK_SUSPENDED) { + pa_assert(u->sink->thread_info.state != PA_SINK_SUSPENDED); + + if (u->source_suspended) + if (suspend(u) < 0) + return -1; + + u->sink_suspended = 1; + } + + if (u->sink->thread_info.state == PA_SINK_SUSPENDED) { + pa_assert(PA_PTR_TO_UINT(data) != PA_SINK_SUSPENDED); - if (!memchunk->length) - if (pa_sink_render(u->sink, l, memchunk) < 0) - memchunk = &u->silence; + if (u->source_suspended) + if (unsuspend(u) < 0) + return -1; - assert(memchunk->memblock); - assert(memchunk->length); + u->sink_suspended = 0; + } + + break; - p = pa_memblock_acquire(memchunk->memblock); - if ((r = pa_iochannel_write(u->io, (uint8_t*) p + memchunk->index, memchunk->length)) < 0) { - pa_memblock_release(memchunk->memblock); + case PA_SINK_MESSAGE_SET_VOLUME: - if (errno != EAGAIN) { - pa_log("write() failed: %s", pa_cstrerror(errno)); + if (u->use_pcm_volume && u->fd >= 0) { - clear_up(u); - pa_module_unload_request(u->module); + if (pa_oss_set_pcm_volume(u->fd, &u->sink->sample_spec, ((pa_cvolume*) data)) < 0) { + pa_log_info("Device doesn't support setting mixer settings: %s", pa_cstrerror(errno)); + u->use_pcm_volume = 0; + } else + return 0; } break; - } - pa_memblock_release(memchunk->memblock); + case PA_SINK_MESSAGE_GET_VOLUME: - if (memchunk == &u->silence) - assert(r % u->sample_size == 0); - else { - u->memchunk.index += r; - u->memchunk.length -= r; + if (u->use_pcm_volume && u->fd >= 0) { - if (u->memchunk.length <= 0) { - pa_memblock_unref(u->memchunk.memblock); - u->memchunk.memblock = NULL; + if (pa_oss_get_pcm_volume(u->fd, &u->sink->sample_spec, ((pa_cvolume*) data)) < 0) { + pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno)); + u->use_pcm_volume = 0; + } else + return 0; } - } - l = l > (size_t) r ? l - r : 0; - } while (loop && l > 0); -} + break; + } -static void do_read(struct userdata *u) { - pa_memchunk memchunk; - ssize_t r; - size_t l; - int loop = 0; - assert(u); + return pa_sink_process_msg(o, code, data, chunk); +} - if (!u->source || !pa_iochannel_is_readable(u->io) || !pa_idxset_size(u->source->outputs)) - return; +static int source_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk *chunk) { + struct userdata *u = PA_SOURCE(o)->userdata; - update_usage(u); + switch (code) { - l = u->in_fragment_size; + case PA_SOURCE_MESSAGE_GET_LATENCY: { + pa_usec_t r = 0; - if (u->use_getispace) { - audio_buf_info info; + if (u->use_getispace && u->fd >= 0) { + struct audio_buf_info info; - if (ioctl(u->fd, SNDCTL_DSP_GETISPACE, &info) < 0) - u->use_getispace = 0; - else { - if (info.bytes/l > 0) { - l = (info.bytes/l)*l; - loop = 1; + if (ioctl(u->fd, SNDCTL_DSP_GETISPACE, &info) < 0) { + pa_log_info("Device doesn't support SNDCTL_DSP_GETISPACE: %s", pa_cstrerror(errno)); + u->use_getispace = 0; + } else + r = pa_bytes_to_usec(info.bytes, &u->sink->sample_spec); } + + *((pa_usec_t*) data) = r; + break; } - } - do { - void *p; - memchunk.memblock = pa_memblock_new(u->core->mempool, l); + case PA_SOURCE_MESSAGE_SET_STATE: - p = pa_memblock_acquire(memchunk.memblock); + if (PA_PTR_TO_UINT(data) == PA_SOURCE_SUSPENDED) { + pa_assert(u->source->thread_info.state != PA_SOURCE_SUSPENDED); + + if (u->sink_suspended) + if (suspend(u) < 0) + return -1; + + u->source_suspended = 1; + } - if ((r = pa_iochannel_read(u->io, p, pa_memblock_get_length(memchunk.memblock))) < 0) { - pa_memblock_release(memchunk.memblock); - pa_memblock_unref(memchunk.memblock); + if (u->source->thread_info.state == PA_SOURCE_SUSPENDED) { + pa_assert(PA_PTR_TO_UINT(data) != PA_SOURCE_SUSPENDED); - if (errno != EAGAIN) { - pa_log("read() failed: %s", pa_cstrerror(errno)); + if (u->sink_suspended) + if (unsuspend(u) < 0) + return -1; - clear_up(u); - pa_module_unload_request(u->module); + u->source_suspended = 0; } break; - } - pa_memblock_release(memchunk.memblock); + case PA_SOURCE_MESSAGE_SET_VOLUME: + + if (u->use_input_volume && u->fd >= 0) { + + if (pa_oss_set_input_volume(u->fd, &u->source->sample_spec, ((pa_cvolume*) data)) < 0) { + pa_log_info("Device doesn't support setting mixer settings: %s", pa_cstrerror(errno)); + u->use_input_volume = 0; + } else + return 0; + } + + break; - assert(r <= (ssize_t) pa_memblock_get_length(memchunk.memblock)); - memchunk.length = r; - memchunk.index = 0; + case PA_SOURCE_MESSAGE_GET_VOLUME: - pa_source_post(u->source, &memchunk); - pa_memblock_unref(memchunk.memblock); + if (u->use_input_volume && u->fd >= 0) { - l = l > (size_t) r ? l - r : 0; - } while (loop && l > 0); + if (pa_oss_get_input_volume(u->fd, &u->source->sample_spec, ((pa_cvolume*) data)) < 0) { + pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno)); + u->use_input_volume = 0; + } else + return 0; + } + + break; + } + + return pa_source_process_msg(o, code, data, chunk); } -static void io_callback(PA_GCC_UNUSED pa_iochannel *io, void*userdata) { +static void thread_func(void *userdata) { + enum { + POLLFD_ASYNCQ, + POLLFD_DSP, + POLLFD_MAX, + }; + struct userdata *u = userdata; - assert(u); - do_write(u); - do_read(u); -} + struct pollfd pollfd[POLLFD_MAX]; + int write_type = 0, read_type = 0; -static void source_notify_cb(pa_source *s) { - struct userdata *u = s->userdata; - assert(u); - do_read(u); -} + pa_assert(u); -static pa_usec_t sink_get_latency_cb(pa_sink *s) { - pa_usec_t r = 0; - int arg; - struct userdata *u = s->userdata; - assert(s && u && u->sink); + pa_log_debug("Thread starting up"); - if (ioctl(u->fd, SNDCTL_DSP_GETODELAY, &arg) < 0) { - pa_log_info("device doesn't support SNDCTL_DSP_GETODELAY: %s", pa_cstrerror(errno)); - s->get_latency = NULL; - return 0; + /* + * Some crappy drivers do not start the recording until we read something. + * Without this snippet, poll will never register the fd as ready. + */ + if (u->source) { + uint8_t *buf = pa_xnew(uint8_t, u->sample_size); + pa_read(u->fd, buf, u->sample_size, &read_type); + pa_xfree(buf); } - r += pa_bytes_to_usec(arg, &s->sample_spec); + memset(&pollfd, 0, sizeof(pollfd)); - if (u->memchunk.memblock) - r += pa_bytes_to_usec(u->memchunk.length, &s->sample_spec); + pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq); + pollfd[POLLFD_ASYNCQ].events = POLLIN; + pollfd[POLLFD_DSP].fd = u->fd; - return r; -} + for (;;) { + pa_msgobject *object; + int code; + void *data; + pa_memchunk chunk; + int r; -static pa_usec_t source_get_latency_cb(pa_source *s) { - struct userdata *u = s->userdata; - audio_buf_info info; - assert(s && u && u->source); + /* Check whether there is a message for us to process */ + if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { + int ret; - if (!u->use_getispace) - return 0; + if (!object && code == PA_MESSAGE_SHUTDOWN) { + pa_asyncmsgq_done(u->asyncmsgq, 0); + goto finish; + } - if (ioctl(u->fd, SNDCTL_DSP_GETISPACE, &info) < 0) { - u->use_getispace = 0; - return 0; - } + ret = pa_asyncmsgq_dispatch(object, code, data, &chunk); + pa_asyncmsgq_done(u->asyncmsgq, ret); + continue; + } - if (info.bytes <= 0) - return 0; + /* Render some data and write it to the dsp */ - return pa_bytes_to_usec(info.bytes, &s->sample_spec); -} + if (u->sink && u->sink->thread_info.state == PA_SINK_RUNNING && (pollfd[POLLFD_DSP].revents & POLLOUT)) { + ssize_t l; + void *p; + int loop = 0; -static int sink_get_hw_volume(pa_sink *s) { - struct userdata *u = s->userdata; + l = u->out_fragment_size; - if (pa_oss_get_pcm_volume(u->fd, &s->sample_spec, &s->hw_volume) < 0) { - pa_log_info("device doesn't support reading mixer settings: %s", pa_cstrerror(errno)); - s->get_hw_volume = NULL; - return -1; - } + if (u->use_getospace) { + audio_buf_info info; - return 0; -} + if (ioctl(u->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) { + pa_log_info("Device doesn't support SNDCTL_DSP_GETOSPACE: %s", pa_cstrerror(errno)); + u->use_getospace = 0; + } else { + if (info.bytes >= l) { + l = (info.bytes/l)*l; + loop = 1; + } + } + } -static int sink_set_hw_volume(pa_sink *s) { - struct userdata *u = s->userdata; + do { + ssize_t t; - if (pa_oss_set_pcm_volume(u->fd, &s->sample_spec, &s->hw_volume) < 0) { - pa_log_info("device doesn't support writing mixer settings: %s", pa_cstrerror(errno)); - s->set_hw_volume = NULL; - return -1; - } + pa_assert(l > 0); - return 0; -} + if (u->memchunk.length <= 0) + pa_sink_render(u->sink, l, &u->memchunk); -static int source_get_hw_volume(pa_source *s) { - struct userdata *u = s->userdata; + pa_assert(u->memchunk.length > 0); - if (pa_oss_get_input_volume(u->fd, &s->sample_spec, &s->hw_volume) < 0) { - pa_log_info("device doesn't support reading mixer settings: %s", pa_cstrerror(errno)); - s->get_hw_volume = NULL; - return -1; - } + p = pa_memblock_acquire(u->memchunk.memblock); + t = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length, &write_type); + pa_memblock_release(u->memchunk.memblock); - return 0; -} + pa_assert(t != 0); -static int source_set_hw_volume(pa_source *s) { - struct userdata *u = s->userdata; + if (t < 0) { - if (pa_oss_set_input_volume(u->fd, &s->sample_spec, &s->hw_volume) < 0) { - pa_log_info("device doesn't support writing mixer settings: %s", pa_cstrerror(errno)); - s->set_hw_volume = NULL; - return -1; + if (errno == EINTR) + continue; + + else if (errno == EAGAIN) { + + pollfd[POLLFD_DSP].revents &= ~POLLOUT; + break; + + } else { + pa_log("Failed to write data to DSP: %s", pa_cstrerror(errno)); + goto fail; + } + + } else { + + u->memchunk.index += t; + u->memchunk.length -= t; + + if (u->memchunk.length <= 0) { + pa_memblock_unref(u->memchunk.memblock); + pa_memchunk_reset(&u->memchunk); + } + + l -= t; + + pollfd[POLLFD_DSP].revents &= ~POLLOUT; + } + + } while (loop && l > 0); + + continue; + } + + /* Try to read some data and pass it on to the source driver */ + + if (u->source && u->source->thread_info.state == PA_SOURCE_RUNNING && ((pollfd[POLLFD_DSP].revents & POLLIN))) { + void *p; + ssize_t l; + pa_memchunk memchunk; + int loop = 0; + + l = u->in_fragment_size; + + if (u->use_getispace) { + audio_buf_info info; + + if (ioctl(u->fd, SNDCTL_DSP_GETISPACE, &info) < 0) { + pa_log_info("Device doesn't support SNDCTL_DSP_GETISPACE: %s", pa_cstrerror(errno)); + u->use_getispace = 0; + } else { + if (info.bytes >= l) { + l = (info.bytes/l)*l; + loop = 1; + } + } + } + + do { + ssize_t t; + + pa_assert(l > 0); + + memchunk.memblock = pa_memblock_new(u->core->mempool, l); + + p = pa_memblock_acquire(memchunk.memblock); + t = pa_read(u->fd, p, l, &read_type); + pa_memblock_release(memchunk.memblock); + + pa_assert(t != 0); /* EOF cannot happen */ + + if (t < 0) { + pa_memblock_unref(memchunk.memblock); + + if (errno == EINTR) + continue; + + else if (errno == EAGAIN) { + pollfd[POLLFD_DSP].revents &= ~POLLIN; + break; + + } else { + pa_log("Faile to read data from DSP: %s", pa_cstrerror(errno)); + goto fail; + } + + } else { + memchunk.index = 0; + memchunk.length = t; + + pa_source_post(u->source, &memchunk); + pa_memblock_unref(memchunk.memblock); + + l -= t; + + pollfd[POLLFD_DSP].revents &= ~POLLIN; + } + } while (loop && l > 0); + + continue; + } + + + if (u->fd >= 0) { + pollfd[POLLFD_DSP].fd = u->fd; + pollfd[POLLFD_DSP].events = + ((u->source && u->source->thread_info.state == PA_SOURCE_RUNNING) ? POLLIN : 0) | + ((u->sink && u->sink->thread_info.state == PA_SINK_RUNNING) ? POLLOUT : 0); + } + + /* Hmm, nothing to do. Let's sleep */ + + if (pa_asyncmsgq_before_poll(u->asyncmsgq) < 0) + continue; + +/* pa_log("polling for %u", pollfd[POLLFD_DSP].events); */ + r = poll(pollfd, u->fd >= 0 ? POLLFD_MAX : POLLFD_DSP, -1); +/* pa_log("polling got %u", r > 0 ? pollfd[POLLFD_DSP].revents : 0); */ + + pa_asyncmsgq_after_poll(u->asyncmsgq); + + if (u->fd < 0) + pollfd[POLLFD_DSP].revents = 0; + + if (r < 0) { + if (errno == EINTR) + continue; + + pa_log("poll() failed: %s", pa_cstrerror(errno)); + goto fail; + } + + if (pollfd[POLLFD_DSP].revents & ~(POLLOUT|POLLIN)) { + pa_log("DSP shutdown."); + goto fail; + } + + pa_assert((pollfd[POLLFD_ASYNCQ].revents & ~POLLIN) == 0); } - return 0; +fail: + /* We have to continue processing messages until we receive the + * SHUTDOWN message */ + pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, NULL, NULL); + pa_asyncmsgq_wait_for(u->asyncmsgq, PA_MESSAGE_SHUTDOWN); + +finish: + pa_log_debug("Thread shutting down"); } int pa__init(pa_core *c, pa_module*m) { @@ -380,7 +649,7 @@ int pa__init(pa_core *c, pa_module*m) { assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { - pa_log("failed to parse module arguments."); + pa_log("Failed to parse module arguments."); goto fail; } @@ -390,15 +659,15 @@ int pa__init(pa_core *c, pa_module*m) { } if (!playback && !record) { - pa_log("neither playback nor record enabled for device."); + pa_log("Neither playback nor record enabled for device."); goto fail; } - mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0)); + mode = (playback && record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0)); ss = c->default_sample_spec; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_OSS) < 0) { - pa_log("failed to parse sample specification or channel map"); + pa_log("Failed to parse sample specification or channel map"); goto fail; } @@ -407,7 +676,7 @@ int pa__init(pa_core *c, pa_module*m) { frag_size = pa_bytes_per_second(&ss)/128; if (pa_modargs_get_value_s32(ma, "fragments", &nfrags) < 0 || pa_modargs_get_value_s32(ma, "fragment_size", &frag_size) < 0) { - pa_log("failed to parse fragments arguments"); + pa_log("Failed to parse fragments arguments"); goto fail; } @@ -415,11 +684,11 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; if (pa_oss_get_hw_description(p, hwdesc, sizeof(hwdesc)) >= 0) - pa_log_info("hardware name is '%s'.", hwdesc); + pa_log_info("Hardware name is '%s'.", hwdesc); else hwdesc[0] = 0; - pa_log_info("device opened in %s mode.", mode == O_WRONLY ? "O_WRONLY" : (mode == O_RDONLY ? "O_RDONLY" : "O_RDWR")); + pa_log_info("Device opened in %s mode.", mode == O_WRONLY ? "O_WRONLY" : (mode == O_RDONLY ? "O_RDONLY" : "O_RDWR")); if (nfrags >= 2 && frag_size >= 1) if (pa_oss_set_fragments(fd, nfrags, frag_size) < 0) @@ -435,18 +704,27 @@ int pa__init(pa_core *c, pa_module*m) { assert(frag_size); in_frag_size = out_frag_size = frag_size; - u = pa_xmalloc(sizeof(struct userdata)); + u = pa_xnew0(struct userdata, 1); u->core = c; + u->module = m; + m->userdata = u; u->use_getospace = u->use_getispace = 0; + u->use_getodelay = 0; + u->use_input_volume = u->use_pcm_volume = 0; + u->mode = mode; + u->device_name = pa_xstrdup(p); + u->nfrags = nfrags; + u->frag_size = frag_size; + pa_assert_se(u->asyncmsgq = pa_asyncmsgq_new(0)); if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) >= 0) { - pa_log_info("input -- %u fragments of size %u.", info.fragstotal, info.fragsize); + pa_log_info("Input -- %u fragments of size %u.", info.fragstotal, info.fragsize); in_frag_size = info.fragsize; u->use_getispace = 1; } if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) >= 0) { - pa_log_info("output -- %u fragments of size %u.", info.fragstotal, info.fragsize); + pa_log_info("Output -- %u fragments of size %u.", info.fragstotal, info.fragsize); out_frag_size = info.fragsize; u->use_getospace = 1; } @@ -462,12 +740,11 @@ int pa__init(pa_core *c, pa_module*m) { if (!(u->source = pa_source_new(c, __FILE__, name, namereg_fail, &ss, &map))) goto fail; + u->source->parent.process_msg = source_process_msg; u->source->userdata = u; - u->source->notify = source_notify_cb; - u->source->get_latency = source_get_latency_cb; - u->source->get_hw_volume = source_get_hw_volume; - u->source->set_hw_volume = source_set_hw_volume; - pa_source_set_owner(u->source, m); + + pa_source_set_module(u->source, m); + pa_source_set_asyncmsgq(u->source, u->asyncmsgq); pa_source_set_description(u->source, t = pa_sprintf_malloc("OSS PCM on %s%s%s%s", p, hwdesc[0] ? " (" : "", @@ -475,6 +752,7 @@ int pa__init(pa_core *c, pa_module*m) { hwdesc[0] ? ")" : "")); pa_xfree(t); u->source->is_hardware = 1; + u->source->refresh_volume = 1; } else u->source = NULL; @@ -492,11 +770,11 @@ int pa__init(pa_core *c, pa_module*m) { if (!(u->sink = pa_sink_new(c, __FILE__, name, namereg_fail, &ss, &map))) goto fail; - u->sink->get_latency = sink_get_latency_cb; - u->sink->get_hw_volume = sink_get_hw_volume; - u->sink->set_hw_volume = sink_set_hw_volume; + u->sink->parent.process_msg = sink_process_msg; u->sink->userdata = u; - pa_sink_set_owner(u->sink, m); + + pa_sink_set_module(u->sink, m); + pa_sink_set_asyncmsgq(u->sink, u->asyncmsgq); pa_sink_set_description(u->sink, t = pa_sprintf_malloc("OSS PCM on %s%s%s%s", p, hwdesc[0] ? " (" : "", @@ -504,6 +782,7 @@ int pa__init(pa_core *c, pa_module*m) { hwdesc[0] ? ")" : "")); pa_xfree(t); u->sink->is_hardware = 1; + u->sink->refresh_volume = 1; } else u->sink = NULL; @@ -512,42 +791,26 @@ int pa__init(pa_core *c, pa_module*m) { assert(u->source || u->sink); - u->io = pa_iochannel_new(c->mainloop, u->source ? fd : -1, u->sink ? fd : -1); - assert(u->io); - pa_iochannel_set_callback(u->io, io_callback, u); u->fd = fd; - u->memchunk.memblock = NULL; - u->memchunk.length = 0; + pa_memchunk_reset(&u->memchunk); u->sample_size = pa_frame_size(&ss); u->out_fragment_size = out_frag_size; u->in_fragment_size = in_frag_size; - u->silence.memblock = pa_memblock_new(u->core->mempool, u->silence.length = u->out_fragment_size); - assert(u->silence.memblock); - pa_silence_memblock(u->silence.memblock, &ss); - u->silence.index = 0; - u->module = m; - m->userdata = u; + if (!(u->thread = pa_thread_new(thread_func, u))) { + pa_log("Failed to create thread."); + goto fail; + } pa_modargs_free(ma); - /* - * Some crappy drivers do not start the recording until we read something. - * Without this snippet, poll will never register the fd as ready. - */ - if (u->source) { - char *buf = pa_xnew(char, u->sample_size); - pa_read(u->fd, buf, u->sample_size, NULL); - pa_xfree(buf); - } - /* Read mixer settings */ if (u->source) - source_get_hw_volume(u->source); + pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->source), PA_SOURCE_MESSAGE_GET_VOLUME, &u->source->volume, NULL, NULL); if (u->sink) - sink_get_hw_volume(u->sink); + pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_GET_VOLUME, &u->sink->volume, NULL, NULL); return 0; @@ -572,12 +835,33 @@ void pa__done(pa_core *c, pa_module*m) { if (!(u = m->userdata)) return; - clear_up(u); + if (u->sink) + pa_sink_disconnect(u->sink); + + if (u->source) + pa_source_disconnect(u->source); + + if (u->thread) { + pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, NULL); + pa_thread_free(u->thread); + } + + if (u->asyncmsgq) + pa_asyncmsgq_free(u->asyncmsgq); + + if (u->sink) + pa_sink_unref(u->sink); + + if (u->source) + pa_source_unref(u->source); if (u->memchunk.memblock) pa_memblock_unref(u->memchunk.memblock); - if (u->silence.memblock) - pa_memblock_unref(u->silence.memblock); + if (u->fd >= 0) + close(u->fd); + + pa_xfree(u->device_name); + pa_xfree(u); } -- cgit From fdd3ac97ff17505454ae1af7ce9fe2f56c86f4fb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 24 Jun 2007 16:06:32 +0000 Subject: Make use of dbus_watch_get_unix_fd() instead of dbus_watch_get_fd() because of deprecation of the latter git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1492 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/dbus-util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/dbus-util.c b/src/modules/dbus-util.c index 48a45174..7cd9c1d6 100644 --- a/src/modules/dbus-util.c +++ b/src/modules/dbus-util.c @@ -93,7 +93,7 @@ static void handle_io_event(PA_GCC_UNUSED pa_mainloop_api *ea, pa_io_event *e, unsigned int flags = 0; DBusWatch *watch = (DBusWatch*) userdata; - assert(fd == dbus_watch_get_fd(watch)); + assert(fd == dbus_watch_get_unix_fd(watch)); if (!dbus_watch_get_enabled(watch)) { pa_log_warn("Asked to handle disabled watch: %p %i", @@ -135,7 +135,7 @@ static dbus_bool_t add_watch(DBusWatch *watch, void *data) pa_io_event *ev; pa_core *c = (pa_core*) data; - ev = c->mainloop->io_new(c->mainloop, dbus_watch_get_fd(watch), + ev = c->mainloop->io_new(c->mainloop, dbus_watch_get_unix_fd(watch), get_watch_flags(watch), handle_io_event, (void*) watch); if (NULL == ev) -- cgit From a9fcd5956b3e91c9ecf1ab43562d4d54ada29e3e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 24 Jun 2007 16:09:43 +0000 Subject: Fix length calculation in pa_silence_memblock_new() and make use of pa_assert() everywhere instead of assert() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1493 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sample-util.c | 47 +++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c index 2e514279..4603f7ee 100644 --- a/src/pulsecore/sample-util.c +++ b/src/pulsecore/sample-util.c @@ -28,12 +28,12 @@ #include #include -#include #include #include #include +#include #include "sample-util.h" #include "endianmacros.h" @@ -42,20 +42,23 @@ pa_memblock *pa_silence_memblock_new(pa_mempool *pool, const pa_sample_spec *spec, size_t length) { size_t fs; - assert(pool); - assert(spec); + pa_assert(pool); + pa_assert(spec); - if (length == 0) + if (length <= 0) length = pa_bytes_per_second(spec)/20; /* 50 ms */ if (length > PA_SILENCE_MAX) length = PA_SILENCE_MAX; fs = pa_frame_size(spec); - length = ((PA_SILENCE_MAX+fs-1) / fs) * fs; + + length = (length+fs-1)/fs; if (length <= 0) - length = fs; + length = 1; + + length *= fs; return pa_silence_memblock(pa_memblock_new(pool, length), spec); } @@ -63,8 +66,8 @@ pa_memblock *pa_silence_memblock_new(pa_mempool *pool, const pa_sample_spec *spe pa_memblock *pa_silence_memblock(pa_memblock* b, const pa_sample_spec *spec) { void *data; - assert(b); - assert(spec); + pa_assert(b); + pa_assert(spec); data = pa_memblock_acquire(b); pa_silence_memory(data, pa_memblock_get_length(b), spec); @@ -75,9 +78,9 @@ pa_memblock *pa_silence_memblock(pa_memblock* b, const pa_sample_spec *spec) { void pa_silence_memchunk(pa_memchunk *c, const pa_sample_spec *spec) { void *data; - assert(c); - assert(c->memblock); - assert(spec); + pa_assert(c); + pa_assert(c->memblock); + pa_assert(spec); data = pa_memblock_acquire(c->memblock); pa_silence_memory((uint8_t*) data+c->index, c->length, spec); @@ -86,7 +89,9 @@ void pa_silence_memchunk(pa_memchunk *c, const pa_sample_spec *spec) { void pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) { uint8_t c = 0; - assert(p && length && spec); + pa_assert(p); + pa_assert(length > 0); + pa_assert(spec); switch (spec->format) { case PA_SAMPLE_U8: @@ -103,7 +108,7 @@ void pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) { c = 80; break; default: - assert(0); + pa_assert_not_reached(); } memset(p, c, length); @@ -122,10 +127,10 @@ size_t pa_mix( size_t d = 0; unsigned k; - assert(streams); - assert(data); - assert(length); - assert(spec); + pa_assert(streams); + pa_assert(data); + pa_assert(length); + pa_assert(spec); if (!volume) volume = pa_cvolume_reset(&full_volume, spec->channels); @@ -347,10 +352,10 @@ void pa_volume_memchunk( void *ptr; - assert(c); - assert(spec); - assert(c->length % pa_frame_size(spec) == 0); - assert(volume); + pa_assert(c); + pa_assert(spec); + pa_assert(c->length % pa_frame_size(spec) == 0); + pa_assert(volume); if (pa_cvolume_channels_equal_to(volume, PA_VOLUME_NORM)) return; -- cgit From 099f3f22d16549f6e6e4f4fb71ffcf2e050ad232 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 24 Jun 2007 16:10:12 +0000 Subject: Include assert.h, since we use assert() for our pa_assert() macro git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1494 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/macro.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pulsecore/macro.h b/src/pulsecore/macro.h index 215c5c02..e0381cf7 100644 --- a/src/pulsecore/macro.h +++ b/src/pulsecore/macro.h @@ -25,6 +25,7 @@ ***/ #include +#include #include static inline size_t pa_align(size_t l) { -- cgit From 77ebe7044350705648b082812d3580735127430a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 24 Jun 2007 16:11:52 +0000 Subject: Make sure the returned pa_msgobject object has a valid refcnt before returning it git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1495 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/asyncmsgq.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/pulsecore/asyncmsgq.c b/src/pulsecore/asyncmsgq.c index d650989b..26714a08 100644 --- a/src/pulsecore/asyncmsgq.c +++ b/src/pulsecore/asyncmsgq.c @@ -153,18 +153,24 @@ int pa_asyncmsgq_get(pa_asyncmsgq *a, pa_msgobject **object, int *code, void **u pa_assert(code); pa_assert(!a->current); - if (!(a->current = pa_asyncq_pop(a->asyncq, wait))) + if (!(a->current = pa_asyncq_pop(a->asyncq, wait))) { +/* pa_log("failure"); */ return -1; + } + +/* pa_log("success"); */ *code = a->current->code; if (userdata) *userdata = a->current->userdata; - if (object) - *object = a->current->object; + if (object) { + if ((*object = a->current->object)) + pa_msgobject_assert_ref(*object); + } if (chunk) *chunk = a->current->memchunk; - pa_log_debug("q=%p object=%p (%s) code=%i data=%p chunk.length=%u", (void*) a, (void*) a->current->object, a->current->object ? a->current->object->parent.type_name : NULL, a->current->code, (void*) a->current->userdata, a->current->memchunk.length); + pa_log_debug("Get q=%p object=%p (%s) code=%i data=%p chunk.length=%u", (void*) a, (void*) a->current->object, a->current->object ? a->current->object->parent.type_name : NULL, a->current->code, (void*) a->current->userdata, a->current->memchunk.length); return 0; } -- cgit From d87373181071afe38c35d997facee62f5a3cb604 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 24 Jun 2007 16:15:56 +0000 Subject: rework the logic of pa_asyncq git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1496 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/asyncq.c | 201 +++++++++++++++++++++++++++---------------------- 1 file changed, 113 insertions(+), 88 deletions(-) diff --git a/src/pulsecore/asyncq.c b/src/pulsecore/asyncq.c index c966e7dd..025c695e 100644 --- a/src/pulsecore/asyncq.c +++ b/src/pulsecore/asyncq.c @@ -52,9 +52,10 @@ struct pa_asyncq { unsigned size; unsigned read_idx; unsigned write_idx; - pa_atomic_t read_waiting, n_read; - pa_atomic_t write_waiting, n_written; + pa_atomic_t read_waiting; /* a bool */ + pa_atomic_t write_waiting; /* a bool */ int read_fds[2], write_fds[2]; + pa_atomic_t in_read_fifo, in_write_fifo; }; #define PA_ASYNCQ_CELLS(x) ((pa_atomic_ptr_t*) ((uint8_t*) (x) + PA_ALIGN(sizeof(struct pa_asyncq)))) @@ -80,8 +81,8 @@ pa_asyncq *pa_asyncq_new(unsigned size) { l->size = size; pa_atomic_store(&l->read_waiting, 0); pa_atomic_store(&l->write_waiting, 0); - pa_atomic_store(&l->n_written, 0); - pa_atomic_store(&l->n_read, 0); + pa_atomic_store(&l->in_read_fifo, 0); + pa_atomic_store(&l->in_write_fifo, 0); if (pipe(l->read_fds) < 0) { pa_xfree(l); @@ -133,68 +134,79 @@ int pa_asyncq_push(pa_asyncq*l, void *p, int wait) { if (!pa_atomic_ptr_cmpxchg(&cells[idx], NULL, p)) { - if (!wait) { - /* Let's empty the FIFO from old notifications, before we return */ + /* Let's empty the FIFO from old notifications, before we return */ - while (pa_atomic_load(&l->n_read) > 0) { - ssize_t r; - int x[20]; - - errno = 0; - if ((r = read(l->write_fds[0], x, sizeof(x))) < 0 && errno != EINTR) - return -1; + while (pa_atomic_load(&l->in_write_fifo) > 0) { + ssize_t r; + int x[20]; + + if ((r = read(l->write_fds[0], x, sizeof(x))) < 0) { - pa_assert(r != 0); + if (errno == EINTR) + continue; - if (r > 0) - if (pa_atomic_sub(&l->n_read, r) <= r) - break; + return -1; } - - return -1; - } - - /* First try failed. Let's wait for changes. */ - _Y; + pa_assert(r > 0); + + if (pa_atomic_sub(&l->in_write_fifo, r) <= r) + break; - pa_atomic_inc(&l->write_waiting); + } - for (;;) { - char x[20]; - ssize_t r; + /* Now let's make sure that we didn't lose any events */ + if (!pa_atomic_ptr_cmpxchg(&cells[idx], NULL, p)) { - _Y; + if (!wait) + return -1; - if (pa_atomic_ptr_cmpxchg(&cells[idx], NULL, p)) - break; + /* Let's wait for changes. */ _Y; - if ((r = read(l->write_fds[0], x, sizeof(x))) < 0 && errno != EINTR) { - pa_atomic_dec(&l->write_waiting); - return -1; - } + pa_assert_se(pa_atomic_cmpxchg(&l->write_waiting, 0, 1)); - pa_assert(r != 0); + for (;;) { + char x[20]; + ssize_t r; + + _Y; + + if (pa_atomic_ptr_cmpxchg(&cells[idx], NULL, p)) + break; + + _Y; - if (r > 0) - pa_atomic_sub(&l->n_read, r); - } + if ((r = read(l->write_fds[0], x, sizeof(x))) < 0) { - _Y; + if (errno == EINTR) + continue; + + pa_assert_se(pa_atomic_cmpxchg(&l->write_waiting, 1, 0)); + return -1; + } - pa_atomic_dec(&l->write_waiting); + pa_assert(r > 0); + pa_atomic_sub(&l->in_write_fifo, r); + } + + _Y; + + pa_assert_se(pa_atomic_cmpxchg(&l->write_waiting, 1, 0)); + } } _Y; l->write_idx++; - if (pa_atomic_load(&l->read_waiting)) { + if (pa_atomic_load(&l->read_waiting) > 0) { char x = 'x'; _Y; - if (write(l->read_fds[1], &x, sizeof(x)) > 0) - pa_atomic_inc(&l->n_written); + if (write(l->read_fds[1], &x, sizeof(x)) > 0) { + pa_atomic_inc(&l->in_read_fifo); +/* pa_log("increasing %p by 1", l); */ + } } return 0; @@ -206,7 +218,7 @@ void* pa_asyncq_pop(pa_asyncq*l, int wait) { pa_atomic_ptr_t *cells; pa_assert(l); - + cells = PA_ASYNCQ_CELLS(l); _Y; @@ -214,71 +226,86 @@ void* pa_asyncq_pop(pa_asyncq*l, int wait) { if (!(ret = pa_atomic_ptr_load(&cells[idx]))) { - /* First try failed. Let's wait for changes. */ +/* pa_log("pop failed wait=%i", wait); */ - if (!wait) { - /* Let's empty the FIFO from old notifications, before we return */ + /* Hmm, nothing, here, so let's drop all queued events. */ + while (pa_atomic_load(&l->in_read_fifo) > 0) { + ssize_t r; + int x[20]; - while (pa_atomic_load(&l->n_written) > 0) { - ssize_t r; - int x[20]; + if ((r = read(l->read_fds[0], x, sizeof(x))) < 0) { - errno = 0; - if ((r = read(l->read_fds[0], x, sizeof(x))) < 0 && errno != EINTR) - return NULL; - - pa_assert(r != 0); + if (errno == EINTR) + continue; - if (r > 0) - if (pa_atomic_sub(&l->n_written, r) <= r) - break; + return NULL; } + + pa_assert(r > 0); + +/* pa_log("decreasing %p by %i", l, r); */ - return NULL; + if (pa_atomic_sub(&l->in_read_fifo, r) <= r) + break; } - _Y; - - pa_atomic_inc(&l->read_waiting); + /* Now let's make sure that we didn't lose any events */ + if (!(ret = pa_atomic_ptr_load(&cells[idx]))) { - for (;;) { - char x[20]; - ssize_t r; + if (!wait) + return NULL; + /* Let's wait for changes. */ + _Y; + + pa_assert_se(pa_atomic_cmpxchg(&l->read_waiting, 0, 1)); + + for (;;) { + char x[20]; + ssize_t r; + + _Y; + + if ((ret = pa_atomic_ptr_load(&cells[idx]))) + break; + + _Y; + + if ((r = read(l->read_fds[0], x, sizeof(x))) < 0) { - if ((ret = pa_atomic_ptr_load(&cells[idx]))) - break; - - _Y; + if (errno == EINTR) + continue; + + pa_assert_se(pa_atomic_cmpxchg(&l->read_waiting, 1, 0)); + return NULL; + } - if ((r = read(l->read_fds[0], x, sizeof(x))) < 0 && errno != EINTR) { - pa_atomic_dec(&l->read_waiting); - return NULL; +/* pa_log("decreasing %p by %i", l, r); */ + + pa_assert(r > 0); + pa_atomic_sub(&l->in_read_fifo, r); } - pa_assert(r != 0); + _Y; - if (r > 0) - pa_atomic_sub(&l->n_written, r); + pa_assert_se(pa_atomic_cmpxchg(&l->read_waiting, 1, 0)); } - - _Y; - - pa_atomic_dec(&l->read_waiting); } + pa_assert(ret); + /* Guaranteed if we only have a single reader */ pa_assert_se(pa_atomic_ptr_cmpxchg(&cells[idx], ret, NULL)); _Y; l->read_idx++; - if (pa_atomic_load(&l->write_waiting)) { + if (pa_atomic_load(&l->write_waiting) > 0) { char x = 'x'; _Y; if (write(l->write_fds[1], &x, sizeof(x)) >= 0) - pa_atomic_inc(&l->n_read); + pa_atomic_inc(&l->in_write_fifo); } return ret; @@ -301,13 +328,13 @@ int pa_asyncq_before_poll(pa_asyncq *l) { _Y; idx = reduce(l, l->read_idx); - if (pa_atomic_ptr_load(&cells[idx])) + if (pa_atomic_ptr_load(&cells[idx]) || pa_atomic_load(&l->in_read_fifo) > 0) return -1; - pa_atomic_inc(&l->read_waiting); + pa_assert_se(pa_atomic_cmpxchg(&l->read_waiting, 0, 1)); - if (pa_atomic_ptr_load(&cells[idx])) { - pa_atomic_dec(&l->read_waiting); + if (pa_atomic_ptr_load(&cells[idx]) || pa_atomic_load(&l->in_read_fifo) > 0) { + pa_assert_se(pa_atomic_cmpxchg(&l->read_waiting, 1, 0)); return -1; } @@ -317,7 +344,5 @@ int pa_asyncq_before_poll(pa_asyncq *l) { void pa_asyncq_after_poll(pa_asyncq *l) { pa_assert(l); - pa_assert(pa_atomic_load(&l->read_waiting) > 0); - - pa_atomic_dec(&l->read_waiting); + pa_assert_se(pa_atomic_cmpxchg(&l->read_waiting, 1, 0)); } -- cgit From de02c74916d60db6454a6691aca0b8401b9c88fd Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 24 Jun 2007 16:17:02 +0000 Subject: Track the 'missing' variable safely between the threads git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1497 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-simple.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index 0e978c63..fd304c67 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -123,7 +123,7 @@ static void connection_free(pa_object *o) { static void connection_drop(connection *c) { pa_assert(c); - pa_idxset_remove_by_data(c->protocol->connections, c, NULL); + pa_assert_se(pa_idxset_remove_by_data(c->protocol->connections, c, NULL) == c); if (c->sink_input) { pa_sink_input_disconnect(c->sink_input); @@ -153,7 +153,7 @@ static int do_read(connection *c) { pa_assert(c); - if (!c->sink_input || !(l = pa_atomic_load(&c->playback.missing))) + if (!c->sink_input || (l = pa_atomic_load(&c->playback.missing)) <= 0) return 0; if (l > c->playback.fragment_size) @@ -191,6 +191,7 @@ static int do_read(connection *c) { c->playback.memblock_index += r; pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, &chunk, NULL); + pa_atomic_sub(&c->playback.missing, r); return 0; } @@ -309,7 +310,6 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, pa_ /* New data from the main loop */ pa_memblockq_push_align(c->input_memblockq, chunk); - pa_atomic_store(&c->playback.missing, pa_memblockq_missing(c->input_memblockq)); /* pa_log("got data, %u", pa_memblockq_get_length(c->input_memblockq)); */ @@ -368,10 +368,10 @@ static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_ pa_memblockq_drop(c->input_memblockq, chunk, length); new = pa_memblockq_missing(c->input_memblockq); - pa_atomic_store(&c->playback.missing, new); - - if (new > old) - pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), MESSAGE_REQUEST_DATA, NULL, NULL, NULL); + if (new > old) { + if (pa_atomic_add(&c->playback.missing, new - old) <= 0) + pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), MESSAGE_REQUEST_DATA, NULL, NULL, NULL); + } } /* Called from main context */ -- cgit From 67766785a587ead4bf604ae789bc1112783ad97c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 24 Jun 2007 16:17:30 +0000 Subject: Limit silence buffer size for pa_sink_render() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1498 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 11effe2f..d5ca061f 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -46,6 +46,7 @@ #include "sink.h" #define MAX_MIX_CHANNELS 32 +#define SILENCE_BUFFER_LENGTH (64*1024) static PA_DEFINE_CHECK_TYPE(pa_sink, sink_check_type, pa_msgobject_check_type); @@ -364,6 +365,9 @@ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) { if (n == 0) { + if (length > SILENCE_BUFFER_LENGTH) + length = SILENCE_BUFFER_LENGTH; + if (!s->silence || pa_memblock_get_length(s->silence) < length) { if (s->silence) pa_memblock_unref(s->silence); -- cgit From a482b9fd99a970cda92bef53dfac500c4ad6ecd9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 25 Jun 2007 22:33:04 +0000 Subject: make sure we don't free the same connection twice git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1499 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-simple.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index fd304c67..c423487a 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -123,7 +123,8 @@ static void connection_free(pa_object *o) { static void connection_drop(connection *c) { pa_assert(c); - pa_assert_se(pa_idxset_remove_by_data(c->protocol->connections, c, NULL) == c); + if (!pa_idxset_remove_by_data(c->protocol->connections, c, NULL)) + return; if (c->sink_input) { pa_sink_input_disconnect(c->sink_input); -- cgit From 63129389c9d8396b8ea819afb217b6da0b2d6a18 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 25 Jun 2007 22:53:09 +0000 Subject: remove pa_memblockq_is_writable() (because it is stupid and not used anywhere anyway, and replace all assert()s with pa_assert()s git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1500 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/memblockq.c | 102 +++++++++++++++++++++------------------------- src/pulsecore/memblockq.h | 3 -- 2 files changed, 46 insertions(+), 59 deletions(-) diff --git a/src/pulsecore/memblockq.c b/src/pulsecore/memblockq.c index a80df338..0c31166a 100644 --- a/src/pulsecore/memblockq.c +++ b/src/pulsecore/memblockq.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -36,6 +35,7 @@ #include #include +#include #include "memblockq.h" @@ -66,8 +66,8 @@ pa_memblockq* pa_memblockq_new( pa_memblockq* bq; - assert(base > 0); - assert(maxlength >= base); + pa_assert(base > 0); + pa_assert(maxlength >= base); bq = pa_xnew(pa_memblockq, 1); bq->blocks = bq->blocks_tail = NULL; @@ -80,7 +80,7 @@ pa_memblockq* pa_memblockq_new( (unsigned long)maxlength, (unsigned long)tlength, (unsigned long)base, (unsigned long)prebuf, (unsigned long)minreq); bq->maxlength = ((maxlength+base-1)/base)*base; - assert(bq->maxlength >= base); + pa_assert(bq->maxlength >= base); bq->tlength = ((tlength+base-1)/base)*base; if (!bq->tlength || bq->tlength >= bq->maxlength) @@ -110,7 +110,7 @@ pa_memblockq* pa_memblockq_new( } void pa_memblockq_free(pa_memblockq* bq) { - assert(bq); + pa_assert(bq); pa_memblockq_flush(bq); @@ -124,10 +124,10 @@ void pa_memblockq_free(pa_memblockq* bq) { } static void drop_block(pa_memblockq *bq, struct memblock_list *q) { - assert(bq); - assert(q); + pa_assert(bq); + pa_assert(q); - assert(bq->n_blocks >= 1); + pa_assert(bq->n_blocks >= 1); if (q->prev) q->prev->next = q->next; @@ -148,7 +148,7 @@ static void drop_block(pa_memblockq *bq, struct memblock_list *q) { static int can_push(pa_memblockq *bq, size_t l) { int64_t end; - assert(bq); + pa_assert(bq); if (bq->read_index > bq->write_index) { size_t d = bq->read_index - bq->write_index; @@ -174,11 +174,11 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { struct memblock_list *q, *n; pa_memchunk chunk; - assert(bq); - assert(uchunk); - assert(uchunk->memblock); - assert(uchunk->length > 0); - assert(uchunk->index + uchunk->length <= pa_memblock_get_length(uchunk->memblock)); + pa_assert(bq); + pa_assert(uchunk); + pa_assert(uchunk->memblock); + pa_assert(uchunk->length > 0); + pa_assert(uchunk->index + uchunk->length <= pa_memblock_get_length(uchunk->memblock)); if (uchunk->length % bq->base) return -1; @@ -244,7 +244,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { /* Calculate offset */ d = bq->write_index + chunk.length - q->index; - assert(d > 0); + pa_assert(d > 0); /* Drop it from the new entry */ p->index = q->index + d; @@ -274,7 +274,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { } else { size_t d; - assert(bq->write_index + (int64_t)chunk.length > q->index && + pa_assert(bq->write_index + (int64_t)chunk.length > q->index && bq->write_index + (int64_t)chunk.length < q->index + (int64_t)q->chunk.length && bq->write_index < q->index); @@ -291,8 +291,8 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { } if (q) { - assert(bq->write_index >= q->index + (int64_t)q->chunk.length); - assert(!q->next || (bq->write_index + (int64_t)chunk.length <= q->next->index)); + pa_assert(bq->write_index >= q->index + (int64_t)q->chunk.length); + pa_assert(!q->next || (bq->write_index + (int64_t)chunk.length <= q->next->index)); /* Try to merge memory blocks */ @@ -305,7 +305,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { return 0; } } else - assert(!bq->blocks || (bq->write_index + (int64_t)chunk.length <= bq->blocks->index)); + pa_assert(!bq->blocks || (bq->write_index + (int64_t)chunk.length <= bq->blocks->index)); n = pa_xnew(struct memblock_list, 1); @@ -332,8 +332,8 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { } int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) { - assert(bq); - assert(chunk); + pa_assert(bq); + pa_assert(chunk); if (bq->state == PREBUF) { @@ -382,7 +382,7 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) { } /* Ok, let's pass real data to the caller */ - assert(bq->blocks->index == bq->read_index); + pa_assert(bq->blocks->index == bq->read_index); *chunk = bq->blocks->chunk; pa_memblock_ref(chunk->memblock); @@ -391,10 +391,9 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) { } void pa_memblockq_drop(pa_memblockq *bq, const pa_memchunk *chunk, size_t length) { - assert(bq); - assert(length % bq->base == 0); - - assert(!chunk || length <= chunk->length); + pa_assert(bq); + pa_assert(length % bq->base == 0); + pa_assert(!chunk || length <= chunk->length); if (chunk) { @@ -410,7 +409,7 @@ void pa_memblockq_drop(pa_memblockq *bq, const pa_memchunk *chunk, size_t length /* The first item in the queue is not yet relevant */ - assert(!bq->blocks || bq->blocks->index > bq->read_index); + pa_assert(!bq->blocks || bq->blocks->index > bq->read_index); l = bq->blocks ? bq->blocks->index - bq->read_index : 0; if (bq->silence) { @@ -431,7 +430,7 @@ void pa_memblockq_drop(pa_memblockq *bq, const pa_memchunk *chunk, size_t length if (bq->blocks) { size_t d; - assert(bq->blocks->index >= bq->read_index); + pa_assert(bq->blocks->index >= bq->read_index); d = (size_t) (bq->blocks->index - bq->read_index); @@ -446,7 +445,7 @@ void pa_memblockq_drop(pa_memblockq *bq, const pa_memchunk *chunk, size_t length bq->read_index += d; } - assert(bq->blocks->index == bq->read_index); + pa_assert(bq->blocks->index == bq->read_index); if (bq->blocks->chunk.length <= length) { /* We need to drop the full block */ @@ -475,7 +474,7 @@ void pa_memblockq_drop(pa_memblockq *bq, const pa_memchunk *chunk, size_t length } int pa_memblockq_is_readable(pa_memblockq *bq) { - assert(bq); + pa_assert(bq); if (bq->prebuf > 0) { size_t l = pa_memblockq_get_length(bq); @@ -490,17 +489,8 @@ int pa_memblockq_is_readable(pa_memblockq *bq) { return 1; } -int pa_memblockq_is_writable(pa_memblockq *bq, size_t length) { - assert(bq); - - if (length % bq->base) - return 0; - - return pa_memblockq_get_length(bq) + length <= bq->tlength; -} - size_t pa_memblockq_get_length(pa_memblockq *bq) { - assert(bq); + pa_assert(bq); if (bq->write_index <= bq->read_index) return 0; @@ -510,7 +500,7 @@ size_t pa_memblockq_get_length(pa_memblockq *bq) { size_t pa_memblockq_missing(pa_memblockq *bq) { size_t l; - assert(bq); + pa_assert(bq); if ((l = pa_memblockq_get_length(bq)) >= bq->tlength) return 0; @@ -520,13 +510,13 @@ size_t pa_memblockq_missing(pa_memblockq *bq) { } size_t pa_memblockq_get_minreq(pa_memblockq *bq) { - assert(bq); + pa_assert(bq); return bq->minreq; } void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek) { - assert(bq); + pa_assert(bq); switch (seek) { case PA_SEEK_RELATIVE: @@ -543,16 +533,16 @@ void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek) { return; } - assert(0); + pa_assert_not_reached(); } void pa_memblockq_flush(pa_memblockq *bq) { - assert(bq); + pa_assert(bq); while (bq->blocks) drop_block(bq, bq->blocks); - assert(bq->n_blocks == 0); + pa_assert(bq->n_blocks == 0); bq->write_index = bq->read_index; @@ -560,26 +550,26 @@ void pa_memblockq_flush(pa_memblockq *bq) { } size_t pa_memblockq_get_tlength(pa_memblockq *bq) { - assert(bq); + pa_assert(bq); return bq->tlength; } int64_t pa_memblockq_get_read_index(pa_memblockq *bq) { - assert(bq); + pa_assert(bq); return bq->read_index; } int64_t pa_memblockq_get_write_index(pa_memblockq *bq) { - assert(bq); + pa_assert(bq); return bq->write_index; } int pa_memblockq_push_align(pa_memblockq* bq, const pa_memchunk *chunk) { pa_memchunk rchunk; - assert(bq); - assert(chunk && bq->base); + pa_assert(bq); + pa_assert(chunk && bq->base); if (bq->base == 1) return pa_memblockq_push(bq, chunk); @@ -606,7 +596,7 @@ int pa_memblockq_push_align(pa_memblockq* bq, const pa_memchunk *chunk) { void pa_memblockq_shorten(pa_memblockq *bq, size_t length) { size_t l; - assert(bq); + pa_assert(bq); l = pa_memblockq_get_length(bq); @@ -615,27 +605,27 @@ void pa_memblockq_shorten(pa_memblockq *bq, size_t length) { } void pa_memblockq_prebuf_disable(pa_memblockq *bq) { - assert(bq); + pa_assert(bq); if (bq->state == PREBUF) bq->state = RUNNING; } void pa_memblockq_prebuf_force(pa_memblockq *bq) { - assert(bq); + pa_assert(bq); if (bq->state == RUNNING && bq->prebuf > 0) bq->state = PREBUF; } size_t pa_memblockq_get_maxlength(pa_memblockq *bq) { - assert(bq); + pa_assert(bq); return bq->maxlength; } size_t pa_memblockq_get_prebuf(pa_memblockq *bq) { - assert(bq); + pa_assert(bq); return bq->prebuf; } diff --git a/src/pulsecore/memblockq.h b/src/pulsecore/memblockq.h index c049d78c..e8243568 100644 --- a/src/pulsecore/memblockq.h +++ b/src/pulsecore/memblockq.h @@ -94,9 +94,6 @@ void pa_memblockq_drop(pa_memblockq *bq, const pa_memchunk *chunk, size_t length /* Test if the pa_memblockq is currently readable, that is, more data than base */ int pa_memblockq_is_readable(pa_memblockq *bq); -/* Test if the pa_memblockq is currently writable for the specified amount of bytes */ -int pa_memblockq_is_writable(pa_memblockq *bq, size_t length); - /* Return the length of the queue in bytes */ size_t pa_memblockq_get_length(pa_memblockq *bq); -- cgit From eec2fbe6232eedc2decb6b7808ae14dfd6c9f974 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 25 Jun 2007 22:54:06 +0000 Subject: Port module-oss to the new lock-free core git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1501 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-oss.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 01fe2b6e..d8ff95bc 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -138,7 +139,7 @@ static int suspend(struct userdata *u) { pa_assert(u->fd >= 0); /* Let's suspend */ - ioctl(u->fd, SNDCTL_DSP_SYNC); + ioctl(u->fd, SNDCTL_DSP_SYNC, NULL); close(u->fd); u->fd = -1; @@ -180,7 +181,7 @@ static int unsuspend(struct userdata *u) { } if (ioctl(u->fd, SNDCTL_DSP_GETBLKSIZE, &frag_size) < 0) { - pa_log("SNDCTL_DSP_GETBLKSIZE: %s", pa_cstrerror(errno)); + pa_log_warn("SNDCTL_DSP_GETBLKSIZE: %s", pa_cstrerror(errno)); goto fail; } @@ -256,9 +257,6 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk * case PA_SINK_MESSAGE_SET_STATE: - if (PA_PTR_TO_UINT(data) != PA_SINK_RUNNING && u->fd >= 0) - ioctl(u->fd, SNDCTL_DSP_POST); - if (PA_PTR_TO_UINT(data) == PA_SINK_SUSPENDED) { pa_assert(u->sink->thread_info.state != PA_SINK_SUSPENDED); @@ -425,10 +423,14 @@ static void thread_func(void *userdata) { pa_memchunk chunk; int r; +/* pa_log("loop"); */ + /* Check whether there is a message for us to process */ if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { int ret; +/* pa_log("processing msg"); */ + if (!object && code == PA_MESSAGE_SHUTDOWN) { pa_asyncmsgq_done(u->asyncmsgq, 0); goto finish; @@ -437,11 +439,13 @@ static void thread_func(void *userdata) { ret = pa_asyncmsgq_dispatch(object, code, data, &chunk); pa_asyncmsgq_done(u->asyncmsgq, ret); continue; - } + } + +/* pa_log("loop2"); */ /* Render some data and write it to the dsp */ - if (u->sink && u->sink->thread_info.state == PA_SINK_RUNNING && (pollfd[POLLFD_DSP].revents & POLLOUT)) { + if (u->sink && u->sink->thread_info.state != PA_SINK_SUSPENDED && (pollfd[POLLFD_DSP].revents & POLLOUT)) { ssize_t l; void *p; int loop = 0; @@ -476,6 +480,8 @@ static void thread_func(void *userdata) { t = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length, &write_type); pa_memblock_release(u->memchunk.memblock); +/* pa_log("wrote %i bytes", t); */ + pa_assert(t != 0); if (t < 0) { @@ -515,7 +521,7 @@ static void thread_func(void *userdata) { /* Try to read some data and pass it on to the source driver */ - if (u->source && u->source->thread_info.state == PA_SOURCE_RUNNING && ((pollfd[POLLFD_DSP].revents & POLLIN))) { + if (u->source && u->source->thread_info.state != PA_SOURCE_SUSPENDED && ((pollfd[POLLFD_DSP].revents & POLLIN))) { void *p; ssize_t l; pa_memchunk memchunk; @@ -585,8 +591,8 @@ static void thread_func(void *userdata) { if (u->fd >= 0) { pollfd[POLLFD_DSP].fd = u->fd; pollfd[POLLFD_DSP].events = - ((u->source && u->source->thread_info.state == PA_SOURCE_RUNNING) ? POLLIN : 0) | - ((u->sink && u->sink->thread_info.state == PA_SINK_RUNNING) ? POLLOUT : 0); + ((u->source && u->source->thread_info.state != PA_SOURCE_SUSPENDED) ? POLLIN : 0) | + ((u->sink && u->sink->thread_info.state != PA_SINK_SUSPENDED) ? POLLOUT : 0); } /* Hmm, nothing to do. Let's sleep */ @@ -594,9 +600,9 @@ static void thread_func(void *userdata) { if (pa_asyncmsgq_before_poll(u->asyncmsgq) < 0) continue; -/* pa_log("polling for %u", pollfd[POLLFD_DSP].events); */ +/* pa_log("polling for %i", u->fd >= 0 ? pollfd[POLLFD_DSP].events : -1); */ r = poll(pollfd, u->fd >= 0 ? POLLFD_MAX : POLLFD_DSP, -1); -/* pa_log("polling got %u", r > 0 ? pollfd[POLLFD_DSP].revents : 0); */ +/* pa_log("polling got dsp=%i amq=%i (%i)", r > 0 ? pollfd[POLLFD_DSP].revents : 0, r > 0 ? pollfd[POLLFD_ASYNCQ].revents : 0, r); */ pa_asyncmsgq_after_poll(u->asyncmsgq); @@ -611,6 +617,8 @@ static void thread_func(void *userdata) { goto fail; } + pa_assert(r > 0); + if (pollfd[POLLFD_DSP].revents & ~(POLLOUT|POLLIN)) { pa_log("DSP shutdown."); goto fail; @@ -708,9 +716,9 @@ int pa__init(pa_core *c, pa_module*m) { u->core = c; u->module = m; m->userdata = u; - u->use_getospace = u->use_getispace = 0; - u->use_getodelay = 0; - u->use_input_volume = u->use_pcm_volume = 0; + u->use_getospace = u->use_getispace = 1; + u->use_getodelay = 1; + u->use_input_volume = u->use_pcm_volume = 1; u->mode = mode; u->device_name = pa_xstrdup(p); u->nfrags = nfrags; -- cgit From 683fc4cef8e0cd785a4af484bad48ba034cbd07a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 12 Jul 2007 15:40:29 +0000 Subject: fix segfault when recording with module-oss.c git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1506 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-oss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index d8ff95bc..a0fc0aa3 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -324,7 +324,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk pa_log_info("Device doesn't support SNDCTL_DSP_GETISPACE: %s", pa_cstrerror(errno)); u->use_getispace = 0; } else - r = pa_bytes_to_usec(info.bytes, &u->sink->sample_spec); + r = pa_bytes_to_usec(info.bytes, &u->source->sample_spec); } *((pa_usec_t*) data) = r; -- cgit From 1a84664edbb9acf460a020c6a2c3000369d44e3f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 12 Jul 2007 16:00:51 +0000 Subject: Make sure pollfd[POLLFD_ASYNCQ].revents is properly initialized on signal git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1507 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-oss.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index a0fc0aa3..f402fb6f 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -142,6 +142,8 @@ static int suspend(struct userdata *u) { ioctl(u->fd, SNDCTL_DSP_SYNC, NULL); close(u->fd); u->fd = -1; + + pa_log_debug("Device suspended..."); return 0; } @@ -208,6 +210,8 @@ static int unsuspend(struct userdata *u) { pa_xfree(buf); } + pa_log_debug("Resumed successfully..."); + return 0; fail: @@ -610,8 +614,11 @@ static void thread_func(void *userdata) { pollfd[POLLFD_DSP].revents = 0; if (r < 0) { - if (errno == EINTR) + if (errno == EINTR) { + pollfd[POLLFD_ASYNCQ].revents = 0; + pollfd[POLLFD_DSP].revents = 0; continue; + } pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; -- cgit From 0a095f6266e44df8b2ddf10fa0ee82159bcd65db Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 12 Jul 2007 16:15:35 +0000 Subject: Properly initialize all revents on EINTR git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1508 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-null-sink.c | 4 +++- src/modules/module-pipe-sink.c | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index 3e471d41..bb0a5045 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -175,8 +175,10 @@ static void thread_func(void *userdata) { pa_asyncmsgq_after_poll(u->asyncmsgq); if (r < 0) { - if (errno == EINTR) + if (errno == EINTR) { + pollfd.revents = 0; continue; + } pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index e27a237e..db8b2e10 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -203,8 +203,11 @@ static void thread_func(void *userdata) { pa_asyncmsgq_after_poll(u->asyncmsgq); if (r < 0) { - if (errno == EINTR) + if (errno == EINTR) { + pollfd[POLLFD_ASYNCQ].revents = 0; + pollfd[POLLFD_FIFO].revents = 0; continue; + } pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; -- cgit From 295e1c83aca1928cf4473d67a4a888aab472cf03 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Jul 2007 00:09:59 +0000 Subject: Make pa_sink_render_* and pa_source_post work only when in RUNNING state, to fix handling of monitor sources when their sink is suspended git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1509 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink.c | 4 ++-- src/pulsecore/source.c | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index d5ca061f..ced23a51 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -361,7 +361,7 @@ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) { pa_sink_ref(s); - n = fill_mix_info(s, info, MAX_MIX_CHANNELS); + n = s->thread_info.state == PA_SINK_RUNNING ? fill_mix_info(s, info, MAX_MIX_CHANNELS) : 0; if (n == 0) { @@ -426,7 +426,7 @@ void pa_sink_render_into(pa_sink*s, pa_memchunk *target) { pa_sink_ref(s); - n = fill_mix_info(s, info, MAX_MIX_CHANNELS); + n = s->thread_info.state == PA_SINK_RUNNING ? fill_mix_info(s, info, MAX_MIX_CHANNELS) : 0; if (n == 0) { pa_silence_memchunk(target, &s->sample_spec); diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index f0a898f4..ce1ee987 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -232,6 +232,9 @@ void pa_source_post(pa_source*s, const pa_memchunk *chunk) { pa_source_assert_ref(s); pa_assert(chunk); + if (s->thread_info.state != PA_SOURCE_RUNNING) + return; + if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&s->thread_info.soft_volume)) { pa_memchunk vchunk = *chunk; -- cgit From a42c19edc7b668cf605cec37430dab13fa5c0307 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Jul 2007 00:14:11 +0000 Subject: Merge module-oss-mmap into module-oss and make suspending working properly git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1510 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-oss.c | 859 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 653 insertions(+), 206 deletions(-) diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index f402fb6f..249982c9 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -44,6 +44,10 @@ #include #endif +#ifdef HAVE_SYS_MMAN_H +#include +#endif + #include #include #include @@ -88,10 +92,14 @@ PA_MODULE_USAGE( "rate= " "fragments= " "fragment_size= " - "channel_map=") + "channel_map= " + "mmap=") #define DEFAULT_DEVICE "/dev/dsp" +#define DEFAULT_NFRAGS 4 +#define DEFAULT_FRAGSIZE_MSEC 25 + struct userdata { pa_core *core; pa_module *module; @@ -104,7 +112,7 @@ struct userdata { pa_memchunk memchunk; - uint32_t in_fragment_size, out_fragment_size, sample_size; + uint32_t in_fragment_size, out_fragment_size, in_nfrags, out_nfrags, in_hwbuf_size, out_hwbuf_size; int use_getospace, use_getispace; int use_getodelay; @@ -117,6 +125,13 @@ struct userdata { int mode; int nfrags, frag_size; + + int use_mmap; + unsigned out_mmap_current, in_mmap_current; + void *in_mmap, *out_mmap; + pa_memblock **in_mmap_memblocks, **out_mmap_memblocks; + + int in_mmap_saved_nfrags, out_mmap_saved_nfrags; }; static const char* const valid_modargs[] = { @@ -131,13 +146,320 @@ static const char* const valid_modargs[] = { "rate", "channels", "channel_map", + "mmap", NULL }; +static void trigger(struct userdata *u, int quick) { + int enable_bits = 0, zero = 0; + +/* pa_log_debug("trigger"); */ + + if (u->source && u->source->thread_info.state != PA_SOURCE_SUSPENDED) + enable_bits |= PCM_ENABLE_INPUT; + + if (u->sink && u->sink->thread_info.state != PA_SINK_SUSPENDED) + enable_bits |= PCM_ENABLE_OUTPUT; + + if (u->use_mmap) { + + if (!quick) + /* First, let's stop all playback, capturing */ + ioctl(u->fd, SNDCTL_DSP_SETTRIGGER, &zero); + +#ifdef SNDCTL_DSP_HALT + if (enable_bits == 0) + if (ioctl(u->fd, SNDCTL_DSP_HALT, NULL) < 0) + pa_log_warn("SNDCTL_DSP_HALT: %s", pa_cstrerror(errno)); +#endif + + if (ioctl(u->fd, SNDCTL_DSP_SETTRIGGER, &enable_bits) < 0) + pa_log_warn("SNDCTL_DSP_SETTRIGGER: %s", pa_cstrerror(errno)); + + if (u->sink && !(enable_bits & PCM_ENABLE_OUTPUT)) { + pa_log_debug("clearing playback buffer"); + pa_silence_memory(u->out_mmap, u->out_hwbuf_size, &u->sink->sample_spec); + } + + } else { + + if (enable_bits) + if (ioctl(u->fd, SNDCTL_DSP_POST, NULL) < 0) + pa_log_warn("SNDCTL_DSP_POST: %s", pa_cstrerror(errno)); + + if (!quick) { + /* + * Some crappy drivers do not start the recording until we + * read something. Without this snippet, poll will never + * register the fd as ready. + */ + + if (u->source && u->source->thread_info.state != PA_SOURCE_SUSPENDED) { + uint8_t *buf = pa_xnew(uint8_t, u->in_fragment_size); + pa_read(u->fd, buf, u->in_fragment_size, NULL); + pa_xfree(buf); + } + } + } +} + +static void mmap_fill_memblocks(struct userdata *u, unsigned n) { + pa_assert(u); + pa_assert(u->out_mmap_memblocks); + + while (n > 0) { + pa_memchunk chunk; + + if (u->out_mmap_memblocks[u->out_mmap_current]) + pa_memblock_unref_fixed(u->out_mmap_memblocks[u->out_mmap_current]); + + chunk.memblock = u->out_mmap_memblocks[u->out_mmap_current] = + pa_memblock_new_fixed( + u->core->mempool, + (uint8_t*) u->out_mmap + u->out_fragment_size * u->out_mmap_current, + u->out_fragment_size, + 1); + + chunk.length = pa_memblock_get_length(chunk.memblock); + chunk.index = 0; + + pa_sink_render_into_full(u->sink, &chunk); + + u->out_mmap_current++; + while (u->out_mmap_current >= u->out_nfrags) + u->out_mmap_current -= u->out_nfrags; + + n--; + } +} + +static int mmap_write(struct userdata *u) { + struct count_info info; + + + pa_assert(u); + pa_assert(u->sink); + + if (ioctl(u->fd, SNDCTL_DSP_GETOPTR, &info) < 0) { + pa_log("SNDCTL_DSP_GETOPTR: %s", pa_cstrerror(errno)); + return -1; + } + + info.blocks += u->out_mmap_saved_nfrags; + u->out_mmap_saved_nfrags = 0; + + if (info.blocks > 0) + mmap_fill_memblocks(u, info.blocks); + + return info.blocks; +} + +static void mmap_post_memblocks(struct userdata *u, unsigned n) { + pa_assert(u); + pa_assert(u->in_mmap_memblocks); + + while (n > 0) { + pa_memchunk chunk; + + if (!u->in_mmap_memblocks[u->in_mmap_current]) { + + chunk.memblock = u->in_mmap_memblocks[u->in_mmap_current] = + pa_memblock_new_fixed( + u->core->mempool, + (uint8_t*) u->in_mmap + u->in_fragment_size*u->in_mmap_current, + u->in_fragment_size, + 1); + + chunk.length = pa_memblock_get_length(chunk.memblock); + chunk.index = 0; + + pa_source_post(u->source, &chunk); + } + + u->in_mmap_current++; + while (u->in_mmap_current >= u->in_nfrags) + u->in_mmap_current -= u->in_nfrags; + + n--; + } +} + +static void mmap_clear_memblocks(struct userdata*u, unsigned n) { + unsigned i = u->in_mmap_current; + + pa_assert(u); + pa_assert(u->in_mmap_memblocks); + + if (n > u->in_nfrags) + n = u->in_nfrags; + + while (n > 0) { + if (u->in_mmap_memblocks[i]) { + pa_memblock_unref_fixed(u->in_mmap_memblocks[i]); + u->in_mmap_memblocks[i] = NULL; + } + + i++; + while (i >= u->in_nfrags) + i -= u->in_nfrags; + + n--; + } +} + +static int mmap_read(struct userdata *u) { + struct count_info info; + pa_assert(u); + pa_assert(u->source); + + if (ioctl(u->fd, SNDCTL_DSP_GETIPTR, &info) < 0) { + pa_log("SNDCTL_DSP_GETIPTR: %s", pa_cstrerror(errno)); + return -1; + } + + info.blocks += u->in_mmap_saved_nfrags; + u->in_mmap_saved_nfrags = 0; + + if (info.blocks > 0) { + mmap_post_memblocks(u, info.blocks); + mmap_clear_memblocks(u, u->in_nfrags/2); + } + + return info.blocks; +} + +static pa_usec_t mmap_sink_get_latency(struct userdata *u) { + struct count_info info; + size_t bpos, n; + + pa_assert(u); + + if (ioctl(u->fd, SNDCTL_DSP_GETOPTR, &info) < 0) { + pa_log("SNDCTL_DSP_GETOPTR: %s", pa_cstrerror(errno)); + return 0; + } + + u->out_mmap_saved_nfrags += info.blocks; + + bpos = ((u->out_mmap_current + u->out_mmap_saved_nfrags) * u->out_fragment_size) % u->out_hwbuf_size; + + if (bpos <= (size_t) info.ptr) + n = u->out_hwbuf_size - (info.ptr - bpos); + else + n = bpos - info.ptr; + +/* pa_log("n = %u, bpos = %u, ptr = %u, total=%u, fragsize = %u, n_frags = %u\n", n, bpos, (unsigned) info.ptr, total, u->out_fragment_size, u->out_fragments); */ + + return pa_bytes_to_usec(n, &u->sink->sample_spec); +} + +static pa_usec_t mmap_source_get_latency(struct userdata *u) { + struct count_info info; + size_t bpos, n; + + pa_assert(u); + + if (ioctl(u->fd, SNDCTL_DSP_GETIPTR, &info) < 0) { + pa_log("SNDCTL_DSP_GETIPTR: %s", pa_cstrerror(errno)); + return 0; + } + + u->in_mmap_saved_nfrags += info.blocks; + bpos = ((u->in_mmap_current + u->in_mmap_saved_nfrags) * u->in_fragment_size) % u->in_hwbuf_size; + + if (bpos <= (size_t) info.ptr) + n = info.ptr - bpos; + else + n = u->in_hwbuf_size - bpos + info.ptr; + +/* pa_log("n = %u, bpos = %u, ptr = %u, total=%u, fragsize = %u, n_frags = %u\n", n, bpos, (unsigned) info.ptr, total, u->in_fragment_size, u->in_fragments); */ + + return pa_bytes_to_usec(n, &u->source->sample_spec); +} + +static pa_usec_t io_sink_get_latency(struct userdata *u) { + pa_usec_t r = 0; + + pa_assert(u); + + if (u->use_getodelay) { + int arg; + + if (ioctl(u->fd, SNDCTL_DSP_GETODELAY, &arg) < 0) { + pa_log_info("Device doesn't support SNDCTL_DSP_GETODELAY: %s", pa_cstrerror(errno)); + u->use_getodelay = 0; + } else + r = pa_bytes_to_usec(arg, &u->sink->sample_spec); + + } + + if (!u->use_getodelay && u->use_getospace) { + struct audio_buf_info info; + + if (ioctl(u->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) { + pa_log_info("Device doesn't support SNDCTL_DSP_GETOSPACE: %s", pa_cstrerror(errno)); + u->use_getospace = 0; + } else + r = pa_bytes_to_usec(info.bytes, &u->sink->sample_spec); + } + + if (u->memchunk.memblock) + r += pa_bytes_to_usec(u->memchunk.length, &u->sink->sample_spec); + + return r; +} + + +static pa_usec_t io_source_get_latency(struct userdata *u) { + pa_usec_t r = 0; + + pa_assert(u); + + if (u->use_getispace) { + struct audio_buf_info info; + + if (ioctl(u->fd, SNDCTL_DSP_GETISPACE, &info) < 0) { + pa_log_info("Device doesn't support SNDCTL_DSP_GETISPACE: %s", pa_cstrerror(errno)); + u->use_getispace = 0; + } else + r = pa_bytes_to_usec(info.bytes, &u->source->sample_spec); + } + + return r; +} + static int suspend(struct userdata *u) { pa_assert(u); pa_assert(u->fd >= 0); + if (u->out_mmap_memblocks) { + unsigned i; + for (i = 0; i < u->out_nfrags; i++) + if (u->out_mmap_memblocks[i]) { + pa_memblock_unref_fixed(u->out_mmap_memblocks[i]); + u->out_mmap_memblocks[i] = NULL; + } + } + + if (u->in_mmap_memblocks) { + unsigned i; + for (i = 0; i < u->in_nfrags; i++) + if (u->in_mmap_memblocks[i]) { + pa_memblock_unref_fixed(u->in_mmap_memblocks[i]); + u->in_mmap_memblocks[i] = NULL; + } + } + + if (u->in_mmap && u->in_mmap != MAP_FAILED) { + munmap(u->in_mmap, u->in_hwbuf_size); + u->in_mmap = NULL; + } + + if (u->out_mmap && u->out_mmap != MAP_FAILED) { + munmap(u->out_mmap, u->out_hwbuf_size); + u->out_mmap = NULL; + } + /* Let's suspend */ ioctl(u->fd, SNDCTL_DSP_SYNC, NULL); close(u->fd); @@ -152,6 +474,7 @@ static int unsuspend(struct userdata *u) { int m; pa_sample_spec ss, *ss_original; int frag_size, in_frag_size, out_frag_size; + int in_nfrags, out_nfrags; struct audio_buf_info info; pa_assert(u); @@ -188,28 +511,53 @@ static int unsuspend(struct userdata *u) { } in_frag_size = out_frag_size = frag_size; + in_nfrags = out_nfrags = u->nfrags; - if (ioctl(u->fd, SNDCTL_DSP_GETISPACE, &info) >= 0) + if (ioctl(u->fd, SNDCTL_DSP_GETISPACE, &info) >= 0) { in_frag_size = info.fragsize; + in_nfrags = info.fragstotal; + } - if (ioctl(u->fd, SNDCTL_DSP_GETOSPACE, &info) >= 0) + if (ioctl(u->fd, SNDCTL_DSP_GETOSPACE, &info) >= 0) { out_frag_size = info.fragsize; + out_nfrags = info.fragstotal; + } - if ((u->source && in_frag_size != (int) u->in_fragment_size) || (u->sink && out_frag_size != (int) u->out_fragment_size)) { - pa_log_warn("Resume failed, fragment settings don't match."); + if ((u->source && (in_frag_size != (int) u->in_fragment_size || in_nfrags != (int) u->in_nfrags)) || + (u->sink && (out_frag_size != (int) u->out_fragment_size || out_nfrags != (int) u->out_nfrags))) { + pa_log_warn("Resume failed, input fragment settings don't match."); goto fail; } - /* - * Some crappy drivers do not start the recording until we read something. - * Without this snippet, poll will never register the fd as ready. - */ - if (u->source) { - uint8_t *buf = pa_xnew(uint8_t, u->sample_size); - pa_read(u->fd, buf, u->sample_size, NULL); - pa_xfree(buf); + if (u->use_mmap) { + if (u->source) { + if ((u->in_mmap = mmap(NULL, u->in_hwbuf_size, PROT_READ, MAP_SHARED, u->fd, 0)) == MAP_FAILED) { + pa_log("Resume failed, mmap(): %s", pa_cstrerror(errno)); + goto fail; + } + } + + if (u->sink) { + if ((u->out_mmap = mmap(NULL, u->out_hwbuf_size, PROT_WRITE, MAP_SHARED, u->fd, 0)) == MAP_FAILED) { + pa_log("Resume failed, mmap(): %s", pa_cstrerror(errno)); + if (u->in_mmap && u->in_mmap != MAP_FAILED) { + munmap(u->in_mmap, u->in_hwbuf_size); + u->in_mmap = NULL; + } + + goto fail; + } + + pa_silence_memory(u->out_mmap, u->out_hwbuf_size, &ss); + } } + u->out_mmap_current = u->in_mmap_current = 0; + u->out_mmap_saved_nfrags = u->in_mmap_saved_nfrags = 0; + + /* Now, start only what we need */ + trigger(u, 0); + pa_log_debug("Resumed successfully..."); return 0; @@ -222,6 +570,7 @@ fail: static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk *chunk) { struct userdata *u = PA_SINK(o)->userdata; + int do_trigger = 0, ret; switch (code) { @@ -229,31 +578,12 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk * pa_usec_t r = 0; if (u->fd >= 0) { - if (u->use_getodelay) { - int arg; - - if (ioctl(u->fd, SNDCTL_DSP_GETODELAY, &arg) < 0) { - pa_log_info("Device doesn't support SNDCTL_DSP_GETODELAY: %s", pa_cstrerror(errno)); - u->use_getodelay = 0; - } else - r = pa_bytes_to_usec(arg, &u->sink->sample_spec); - - } - - if (!u->use_getodelay && u->use_getospace) { - struct audio_buf_info info; - - if (ioctl(u->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) { - pa_log_info("Device doesn't support SNDCTL_DSP_GETOSPACE: %s", pa_cstrerror(errno)); - u->use_getospace = 0; - } else - r = pa_bytes_to_usec(info.bytes, &u->sink->sample_spec); - } + if (u->use_mmap) + r = mmap_sink_get_latency(u); + else + r = io_sink_get_latency(u); } - if (u->memchunk.memblock) - r += pa_bytes_to_usec(u->memchunk.length, &u->sink->sample_spec); - *((pa_usec_t*) data) = r; break; @@ -264,19 +594,25 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk * if (PA_PTR_TO_UINT(data) == PA_SINK_SUSPENDED) { pa_assert(u->sink->thread_info.state != PA_SINK_SUSPENDED); - if (u->source_suspended) + if (u->source_suspended) { if (suspend(u) < 0) return -1; + } else + do_trigger = 1; u->sink_suspended = 1; - } - - if (u->sink->thread_info.state == PA_SINK_SUSPENDED) { + + } else if (u->sink->thread_info.state == PA_SINK_SUSPENDED) { pa_assert(PA_PTR_TO_UINT(data) != PA_SINK_SUSPENDED); - if (u->source_suspended) - if (unsuspend(u) < 0) + if (u->source_suspended) { + if (unsuspend(u) < 0) return -1; + } else + do_trigger = 1; + + u->out_mmap_current = 0; + u->out_mmap_saved_nfrags = 0; u->sink_suspended = 0; } @@ -310,27 +646,30 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk * break; } - return pa_sink_process_msg(o, code, data, chunk); + ret = pa_sink_process_msg(o, code, data, chunk); + + if (do_trigger) + trigger(u, 1); + + return ret; } static int source_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk *chunk) { struct userdata *u = PA_SOURCE(o)->userdata; + int do_trigger = 0, ret; switch (code) { case PA_SOURCE_MESSAGE_GET_LATENCY: { pa_usec_t r = 0; - if (u->use_getispace && u->fd >= 0) { - struct audio_buf_info info; - - if (ioctl(u->fd, SNDCTL_DSP_GETISPACE, &info) < 0) { - pa_log_info("Device doesn't support SNDCTL_DSP_GETISPACE: %s", pa_cstrerror(errno)); - u->use_getispace = 0; - } else - r = pa_bytes_to_usec(info.bytes, &u->source->sample_spec); + if (u->fd >= 0) { + if (u->use_mmap) + r = mmap_source_get_latency(u); + else + r = io_source_get_latency(u); } - + *((pa_usec_t*) data) = r; break; } @@ -340,19 +679,25 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk if (PA_PTR_TO_UINT(data) == PA_SOURCE_SUSPENDED) { pa_assert(u->source->thread_info.state != PA_SOURCE_SUSPENDED); - if (u->sink_suspended) - if (suspend(u) < 0) + if (u->sink_suspended) { + if (suspend(u) < 0) return -1; + } else + do_trigger = 1; u->source_suspended = 1; - } - if (u->source->thread_info.state == PA_SOURCE_SUSPENDED) { + } else if (u->source->thread_info.state == PA_SOURCE_SUSPENDED) { pa_assert(PA_PTR_TO_UINT(data) != PA_SOURCE_SUSPENDED); - if (u->sink_suspended) - if (unsuspend(u) < 0) + if (u->sink_suspended) { + if (unsuspend(u) < 0) return -1; + } else + do_trigger = 1; + + u->in_mmap_current = 0; + u->in_mmap_saved_nfrags = 0; u->source_suspended = 0; } @@ -386,7 +731,12 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk break; } - return pa_source_process_msg(o, code, data, chunk); + ret = pa_source_process_msg(o, code, data, chunk); + + if (do_trigger) + trigger(u, 1); + + return ret; } static void thread_func(void *userdata) { @@ -404,16 +754,8 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); - /* - * Some crappy drivers do not start the recording until we read something. - * Without this snippet, poll will never register the fd as ready. - */ - if (u->source) { - uint8_t *buf = pa_xnew(uint8_t, u->sample_size); - pa_read(u->fd, buf, u->sample_size, &read_type); - pa_xfree(buf); - } - + trigger(u, 0); + memset(&pollfd, 0, sizeof(pollfd)); pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq); @@ -427,7 +769,7 @@ static void thread_func(void *userdata) { pa_memchunk chunk; int r; -/* pa_log("loop"); */ +/* pa_log("loop"); */ /* Check whether there is a message for us to process */ if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { @@ -450,148 +792,181 @@ static void thread_func(void *userdata) { /* Render some data and write it to the dsp */ if (u->sink && u->sink->thread_info.state != PA_SINK_SUSPENDED && (pollfd[POLLFD_DSP].revents & POLLOUT)) { - ssize_t l; - void *p; - int loop = 0; - l = u->out_fragment_size; + if (u->use_mmap) { + int ret; - if (u->use_getospace) { - audio_buf_info info; + if ((ret = mmap_write(u)) < 0) + goto fail; - if (ioctl(u->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) { - pa_log_info("Device doesn't support SNDCTL_DSP_GETOSPACE: %s", pa_cstrerror(errno)); - u->use_getospace = 0; - } else { - if (info.bytes >= l) { - l = (info.bytes/l)*l; - loop = 1; + pollfd[POLLFD_DSP].revents &= ~POLLOUT; + + if (ret > 0) + continue; + + } else { + ssize_t l; + void *p; + int loop = 0; + + l = u->out_fragment_size; + + if (u->use_getospace) { + audio_buf_info info; + + if (ioctl(u->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) { + pa_log_info("Device doesn't support SNDCTL_DSP_GETOSPACE: %s", pa_cstrerror(errno)); + u->use_getospace = 0; + } else { + if (info.bytes >= l) { + l = (info.bytes/l)*l; + loop = 1; + } } } + + do { + ssize_t t; + + pa_assert(l > 0); + + if (u->memchunk.length <= 0) + pa_sink_render(u->sink, l, &u->memchunk); + + pa_assert(u->memchunk.length > 0); + + p = pa_memblock_acquire(u->memchunk.memblock); + t = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length, &write_type); + pa_memblock_release(u->memchunk.memblock); + +/* pa_log("wrote %i bytes of %u", t, l); */ + + pa_assert(t != 0); + + if (t < 0) { + + if (errno == EINTR) + continue; + + else if (errno == EAGAIN) { + pa_log_debug("EAGAIN"); + + pollfd[POLLFD_DSP].revents &= ~POLLOUT; + break; + + } else { + pa_log("Failed to write data to DSP: %s", pa_cstrerror(errno)); + goto fail; + } + + } else { + + u->memchunk.index += t; + u->memchunk.length -= t; + + if (u->memchunk.length <= 0) { + pa_memblock_unref(u->memchunk.memblock); + pa_memchunk_reset(&u->memchunk); + } + + l -= t; + + pollfd[POLLFD_DSP].revents &= ~POLLOUT; + } + + } while (loop && l > 0); + + continue; } + } - do { - ssize_t t; - - pa_assert(l > 0); + /* Try to read some data and pass it on to the source driver */ - if (u->memchunk.length <= 0) - pa_sink_render(u->sink, l, &u->memchunk); + if (u->source && u->source->thread_info.state != PA_SOURCE_SUSPENDED && ((pollfd[POLLFD_DSP].revents & POLLIN))) { - pa_assert(u->memchunk.length > 0); + if (u->use_mmap) { + int ret; - p = pa_memblock_acquire(u->memchunk.memblock); - t = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length, &write_type); - pa_memblock_release(u->memchunk.memblock); + if ((ret = mmap_read(u)) < 0) + goto fail; -/* pa_log("wrote %i bytes", t); */ + pollfd[POLLFD_DSP].revents &= ~POLLIN; - pa_assert(t != 0); + if (ret > 0) + continue; - if (t < 0) { + } else { - if (errno == EINTR) - continue; + void *p; + ssize_t l; + pa_memchunk memchunk; + int loop = 0; - else if (errno == EAGAIN) { + l = u->in_fragment_size; - pollfd[POLLFD_DSP].revents &= ~POLLOUT; - break; + if (u->use_getispace) { + audio_buf_info info; + if (ioctl(u->fd, SNDCTL_DSP_GETISPACE, &info) < 0) { + pa_log_info("Device doesn't support SNDCTL_DSP_GETISPACE: %s", pa_cstrerror(errno)); + u->use_getispace = 0; } else { - pa_log("Failed to write data to DSP: %s", pa_cstrerror(errno)); - goto fail; + if (info.bytes >= l) { + l = (info.bytes/l)*l; + loop = 1; + } } - - } else { - - u->memchunk.index += t; - u->memchunk.length -= t; - - if (u->memchunk.length <= 0) { - pa_memblock_unref(u->memchunk.memblock); - pa_memchunk_reset(&u->memchunk); - } - - l -= t; - - pollfd[POLLFD_DSP].revents &= ~POLLOUT; } - } while (loop && l > 0); - - continue; - } + do { + ssize_t t; - /* Try to read some data and pass it on to the source driver */ + pa_assert(l > 0); - if (u->source && u->source->thread_info.state != PA_SOURCE_SUSPENDED && ((pollfd[POLLFD_DSP].revents & POLLIN))) { - void *p; - ssize_t l; - pa_memchunk memchunk; - int loop = 0; + memchunk.memblock = pa_memblock_new(u->core->mempool, l); - l = u->in_fragment_size; + p = pa_memblock_acquire(memchunk.memblock); + t = pa_read(u->fd, p, l, &read_type); + pa_memblock_release(memchunk.memblock); - if (u->use_getispace) { - audio_buf_info info; + pa_assert(t != 0); /* EOF cannot happen */ - if (ioctl(u->fd, SNDCTL_DSP_GETISPACE, &info) < 0) { - pa_log_info("Device doesn't support SNDCTL_DSP_GETISPACE: %s", pa_cstrerror(errno)); - u->use_getispace = 0; - } else { - if (info.bytes >= l) { - l = (info.bytes/l)*l; - loop = 1; - } - } - } +/* pa_log("read %i bytes of %u", t, l); */ + + if (t < 0) { + pa_memblock_unref(memchunk.memblock); - do { - ssize_t t; + if (errno == EINTR) + continue; - pa_assert(l > 0); + else if (errno == EAGAIN) { + pa_log_debug("EAGAIN"); - memchunk.memblock = pa_memblock_new(u->core->mempool, l); + pollfd[POLLFD_DSP].revents &= ~POLLIN; + break; - p = pa_memblock_acquire(memchunk.memblock); - t = pa_read(u->fd, p, l, &read_type); - pa_memblock_release(memchunk.memblock); + } else { + pa_log("Failed to read data from DSP: %s", pa_cstrerror(errno)); + goto fail; + } - pa_assert(t != 0); /* EOF cannot happen */ + } else { + memchunk.index = 0; + memchunk.length = t; - if (t < 0) { - pa_memblock_unref(memchunk.memblock); + pa_source_post(u->source, &memchunk); + pa_memblock_unref(memchunk.memblock); - if (errno == EINTR) - continue; + l -= t; - else if (errno == EAGAIN) { pollfd[POLLFD_DSP].revents &= ~POLLIN; - break; - - } else { - pa_log("Faile to read data from DSP: %s", pa_cstrerror(errno)); - goto fail; } + } while (loop && l > 0); - } else { - memchunk.index = 0; - memchunk.length = t; - - pa_source_post(u->source, &memchunk); - pa_memblock_unref(memchunk.memblock); - - l -= t; - - pollfd[POLLFD_DSP].revents &= ~POLLIN; - } - } while (loop && l > 0); - - continue; + continue; + } } - if (u->fd >= 0) { pollfd[POLLFD_DSP].fd = u->fd; pollfd[POLLFD_DSP].events = @@ -604,9 +979,9 @@ static void thread_func(void *userdata) { if (pa_asyncmsgq_before_poll(u->asyncmsgq) < 0) continue; -/* pa_log("polling for %i", u->fd >= 0 ? pollfd[POLLFD_DSP].events : -1); */ +/* pa_log("polling for %i (legend: %i=POLLIN, %i=POLLOUT)", u->fd >= 0 ? pollfd[POLLFD_DSP].events : -1, POLLIN, POLLOUT); */ r = poll(pollfd, u->fd >= 0 ? POLLFD_MAX : POLLFD_DSP, -1); -/* pa_log("polling got dsp=%i amq=%i (%i)", r > 0 ? pollfd[POLLFD_DSP].revents : 0, r > 0 ? pollfd[POLLFD_ASYNCQ].revents : 0, r); */ +/* pa_log("polling got dsp=%i amq=%i (%i)", r > 0 ? pollfd[POLLFD_DSP].revents : 0, r > 0 ? pollfd[POLLFD_ASYNCQ].revents : 0, r); */ pa_asyncmsgq_after_poll(u->asyncmsgq); @@ -649,15 +1024,14 @@ int pa__init(pa_core *c, pa_module*m) { struct userdata *u = NULL; const char *p; int fd = -1; - int nfrags, frag_size, in_frag_size, out_frag_size; - int mode; - int record = 1, playback = 1; + int nfrags, frag_size; + int mode, caps; + int record = 1, playback = 1, use_mmap = 1; pa_sample_spec ss; pa_channel_map map; pa_modargs *ma = NULL; char hwdesc[64], *t; const char *name; - char *name_buf = NULL; int namereg_fail; assert(c); @@ -686,18 +1060,29 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - /* Fix latency to 100ms */ - nfrags = 12; - frag_size = pa_bytes_per_second(&ss)/128; + nfrags = DEFAULT_NFRAGS; + frag_size = pa_usec_to_bytes(DEFAULT_FRAGSIZE_MSEC*1000, &ss); + if (frag_size <= 0) + frag_size = pa_frame_size(&ss); if (pa_modargs_get_value_s32(ma, "fragments", &nfrags) < 0 || pa_modargs_get_value_s32(ma, "fragment_size", &frag_size) < 0) { pa_log("Failed to parse fragments arguments"); goto fail; } - if ((fd = pa_oss_open(p = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), &mode, NULL)) < 0) + if (pa_modargs_get_value_boolean(ma, "mmap", &use_mmap) < 0) { + pa_log("Failed to parse mmap argument."); + goto fail; + } + + if ((fd = pa_oss_open(p = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), &mode, &caps)) < 0) goto fail; + if (use_mmap && (!(caps & DSP_CAP_MMAP) || !(caps & DSP_CAP_TRIGGER))) { + pa_log("OSS device not mmap capable, falling back to UNIX read/write mode"); + use_mmap = 0; + } + if (pa_oss_get_hw_description(p, hwdesc, sizeof(hwdesc)) >= 0) pa_log_info("Hardware name is '%s'.", hwdesc); else @@ -717,7 +1102,6 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } assert(frag_size); - in_frag_size = out_frag_size = frag_size; u = pa_xnew0(struct userdata, 1); u->core = c; @@ -728,23 +1112,46 @@ int pa__init(pa_core *c, pa_module*m) { u->use_input_volume = u->use_pcm_volume = 1; u->mode = mode; u->device_name = pa_xstrdup(p); - u->nfrags = nfrags; - u->frag_size = frag_size; + u->in_nfrags = u->out_nfrags = u->nfrags = nfrags; + u->out_fragment_size = u->in_fragment_size = u->frag_size = frag_size; + u->use_mmap = use_mmap; pa_assert_se(u->asyncmsgq = pa_asyncmsgq_new(0)); if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) >= 0) { pa_log_info("Input -- %u fragments of size %u.", info.fragstotal, info.fragsize); - in_frag_size = info.fragsize; + u->in_fragment_size = info.fragsize; + u->in_nfrags = info.fragstotal; u->use_getispace = 1; } if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) >= 0) { pa_log_info("Output -- %u fragments of size %u.", info.fragstotal, info.fragsize); - out_frag_size = info.fragsize; + u->out_fragment_size = info.fragsize; + u->out_nfrags = info.fragstotal; u->use_getospace = 1; } + u->in_hwbuf_size = u->in_nfrags * u->in_fragment_size; + u->out_hwbuf_size = u->out_nfrags * u->out_fragment_size; + if (mode != O_WRONLY) { + char *name_buf = NULL; + + if (use_mmap) { + if ((u->in_mmap = mmap(NULL, u->in_hwbuf_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { + if (mode == O_RDWR) { + pa_log_debug("mmap() failed for input. Changing to O_WRONLY mode."); + mode = O_WRONLY; + goto try_write; + } else { + pa_log("mmap(): %s", pa_cstrerror(errno)); + goto fail; + } + } + + pa_log_debug("Successfully mmap()ed input buffer."); + } + if ((name = pa_modargs_get_value(ma, "source_name", NULL))) namereg_fail = 1; else { @@ -752,7 +1159,9 @@ int pa__init(pa_core *c, pa_module*m) { namereg_fail = 0; } - if (!(u->source = pa_source_new(c, __FILE__, name, namereg_fail, &ss, &map))) + u->source = pa_source_new(c, __FILE__, name, namereg_fail, &ss, &map); + pa_xfree(name_buf); + if (!u->source) goto fail; u->source->parent.process_msg = source_process_msg; @@ -768,13 +1177,32 @@ int pa__init(pa_core *c, pa_module*m) { pa_xfree(t); u->source->is_hardware = 1; u->source->refresh_volume = 1; - } else - u->source = NULL; - pa_xfree(name_buf); - name_buf = NULL; + if (use_mmap) + u->in_mmap_memblocks = pa_xnew0(pa_memblock*, u->in_nfrags); + } +try_write: + if (mode != O_RDONLY) { + char *name_buf = NULL; + + if (use_mmap) { + if ((u->out_mmap = mmap(NULL, u->out_hwbuf_size, PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) { + if (mode == O_RDWR) { + pa_log_debug("mmap() failed for input. Changing to O_WRONLY mode."); + mode = O_WRONLY; + goto go_on; + } else { + pa_log("mmap(): %s", pa_cstrerror(errno)); + goto fail; + } + } + + pa_log_debug("Successfully mmap()ed output buffer."); + pa_silence_memory(u->out_mmap, u->out_hwbuf_size, &ss); + } + if ((name = pa_modargs_get_value(ma, "sink_name", NULL))) namereg_fail = 1; else { @@ -782,7 +1210,9 @@ int pa__init(pa_core *c, pa_module*m) { namereg_fail = 0; } - if (!(u->sink = pa_sink_new(c, __FILE__, name, namereg_fail, &ss, &map))) + u->sink = pa_sink_new(c, __FILE__, name, namereg_fail, &ss, &map); + pa_xfree(name_buf); + if (!u->sink) goto fail; u->sink->parent.process_msg = sink_process_msg; @@ -798,21 +1228,18 @@ int pa__init(pa_core *c, pa_module*m) { pa_xfree(t); u->sink->is_hardware = 1; u->sink->refresh_volume = 1; - } else - u->sink = NULL; - pa_xfree(name_buf); - name_buf = NULL; + if (use_mmap) + u->out_mmap_memblocks = pa_xnew0(pa_memblock*, u->out_nfrags); + } - assert(u->source || u->sink); +go_on: + + pa_assert(u->source || u->sink); u->fd = fd; pa_memchunk_reset(&u->memchunk); - u->sample_size = pa_frame_size(&ss); - - u->out_fragment_size = out_frag_size; - u->in_fragment_size = in_frag_size; if (!(u->thread = pa_thread_new(thread_func, u))) { pa_log("Failed to create thread."); @@ -836,8 +1263,6 @@ fail: if (ma) pa_modargs_free(ma); - pa_xfree(name_buf); - return -1; } @@ -873,9 +1298,31 @@ void pa__done(pa_core *c, pa_module*m) { if (u->memchunk.memblock) pa_memblock_unref(u->memchunk.memblock); + if (u->in_mmap && u->in_mmap != MAP_FAILED) + munmap(u->in_mmap, u->in_hwbuf_size); + + if (u->out_mmap && u->out_mmap != MAP_FAILED) + munmap(u->out_mmap, u->out_hwbuf_size); + if (u->fd >= 0) close(u->fd); + if (u->out_mmap_memblocks) { + unsigned i; + for (i = 0; i < u->out_nfrags; i++) + if (u->out_mmap_memblocks[i]) + pa_memblock_unref_fixed(u->out_mmap_memblocks[i]); + pa_xfree(u->out_mmap_memblocks); + } + + if (u->in_mmap_memblocks) { + unsigned i; + for (i = 0; i < u->in_nfrags; i++) + if (u->in_mmap_memblocks[i]) + pa_memblock_unref_fixed(u->in_mmap_memblocks[i]); + pa_xfree(u->in_mmap_memblocks); + } + pa_xfree(u->device_name); pa_xfree(u); -- cgit From ac1387d3cc8c2f9f92268ac7d007661c7c32ad52 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Jul 2007 00:15:59 +0000 Subject: Remove module-oss-mmap, since it is now merged into module-oss git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1511 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 6 - src/modules/module-oss-mmap.c | 637 ------------------------------------------ 2 files changed, 643 deletions(-) delete mode 100644 src/modules/module-oss-mmap.c diff --git a/src/Makefile.am b/src/Makefile.am index a83424ce..c382bcdb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -931,7 +931,6 @@ if HAVE_OSS modlibexec_LTLIBRARIES += \ liboss-util.la \ module-oss.la -# module-oss-mmap.la endif #if HAVE_ALSA @@ -1018,7 +1017,6 @@ SYMDEF_FILES = \ modules/module-x11-bell-symdef.h \ modules/module-x11-publish-symdef.h \ modules/module-oss-symdef.h \ - modules/module-oss-mmap-symdef.h \ modules/module-alsa-sink-symdef.h \ modules/module-alsa-source-symdef.h \ modules/module-solaris-symdef.h \ @@ -1184,10 +1182,6 @@ module_oss_la_SOURCES = modules/module-oss.c module_oss_la_LDFLAGS = -module -avoid-version module_oss_la_LIBADD = $(AM_LIBADD) libiochannel.la liboss-util.la -#module_oss_mmap_la_SOURCES = modules/module-oss-mmap.c -#module_oss_mmap_la_LDFLAGS = -module -avoid-version -#module_oss_mmap_la_LIBADD = $(AM_LIBADD) liboss-util.la libpulsecore.la - # ALSA #libalsa_util_la_SOURCES = modules/alsa-util.c modules/alsa-util.h diff --git a/src/modules/module-oss-mmap.c b/src/modules/module-oss-mmap.c deleted file mode 100644 index 567230e0..00000000 --- a/src/modules/module-oss-mmap.c +++ /dev/null @@ -1,637 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of PulseAudio. - - Copyright 2004-2006 Lennart Poettering - Copyright 2006 Pierre Ossman for Cendio AB - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_SYS_MMAN_H -#include -#endif - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "oss-util.h" -#include "module-oss-mmap-symdef.h" - -PA_MODULE_AUTHOR("Lennart Poettering") -PA_MODULE_DESCRIPTION("OSS Sink/Source (mmap)") -PA_MODULE_VERSION(PACKAGE_VERSION) -PA_MODULE_USAGE( - "sink_name= " - "source_name= " - "device= " - "record= " - "playback= " - "format= " - "channels= " - "rate= " - "fragments= " - "fragment_size= " - "channel_map=") - -struct userdata { - pa_sink *sink; - pa_source *source; - pa_core *core; - pa_sample_spec sample_spec; - - size_t in_fragment_size, out_fragment_size; - unsigned in_fragments, out_fragments; - unsigned out_blocks_saved, in_blocks_saved; - - int fd; - - void *in_mmap, *out_mmap; - size_t in_mmap_length, out_mmap_length; - - pa_io_event *io_event; - - pa_memblock **in_memblocks, **out_memblocks; - unsigned out_current, in_current; - pa_module *module; -}; - -static const char* const valid_modargs[] = { - "sink_name", - "source_name", - "device", - "record", - "playback", - "fragments", - "fragment_size", - "format", - "rate", - "channels", - "channel_map", - NULL -}; - -#define DEFAULT_DEVICE "/dev/dsp" -#define DEFAULT_NFRAGS 12 -#define DEFAULT_FRAGSIZE 1024 - -static void update_usage(struct userdata *u) { - pa_module_set_used(u->module, - (u->sink ? pa_sink_used_by(u->sink) : 0) + - (u->source ? pa_source_used_by(u->source) : 0)); -} - -static void clear_up(struct userdata *u) { - assert(u); - - if (u->sink) { - pa_sink_disconnect(u->sink); - pa_sink_unref(u->sink); - u->sink = NULL; - } - - if (u->source) { - pa_source_disconnect(u->source); - pa_source_unref(u->source); - u->source = NULL; - } - - if (u->in_mmap && u->in_mmap != MAP_FAILED) { - munmap(u->in_mmap, u->in_mmap_length); - u->in_mmap = NULL; - } - - if (u->out_mmap && u->out_mmap != MAP_FAILED) { - munmap(u->out_mmap, u->out_mmap_length); - u->out_mmap = NULL; - } - - if (u->io_event) { - u->core->mainloop->io_free(u->io_event); - u->io_event = NULL; - } - - if (u->fd >= 0) { - close(u->fd); - u->fd = -1; - } -} - -static void out_fill_memblocks(struct userdata *u, unsigned n) { - assert(u && u->out_memblocks); - - while (n > 0) { - pa_memchunk chunk; - - if (u->out_memblocks[u->out_current]) - pa_memblock_unref_fixed(u->out_memblocks[u->out_current]); - - chunk.memblock = u->out_memblocks[u->out_current] = - pa_memblock_new_fixed( - u->core->mempool, - (uint8_t*) u->out_mmap+u->out_fragment_size*u->out_current, - u->out_fragment_size, - 1); - assert(chunk.memblock); - chunk.length = pa_memblock_get_length(chunk.memblock); - chunk.index = 0; - - pa_sink_render_into_full(u->sink, &chunk); - - u->out_current++; - while (u->out_current >= u->out_fragments) - u->out_current -= u->out_fragments; - - n--; - } -} - -static void do_write(struct userdata *u) { - struct count_info info; - assert(u && u->sink); - - update_usage(u); - - if (ioctl(u->fd, SNDCTL_DSP_GETOPTR, &info) < 0) { - pa_log("SNDCTL_DSP_GETOPTR: %s", pa_cstrerror(errno)); - - clear_up(u); - pa_module_unload_request(u->module); - return; - } - - info.blocks += u->out_blocks_saved; - u->out_blocks_saved = 0; - - if (!info.blocks) - return; - - out_fill_memblocks(u, info.blocks); -} - -static void in_post_memblocks(struct userdata *u, unsigned n) { - assert(u && u->in_memblocks); - - while (n > 0) { - pa_memchunk chunk; - - if (!u->in_memblocks[u->in_current]) { - chunk.memblock = u->in_memblocks[u->in_current] = pa_memblock_new_fixed(u->core->mempool, (uint8_t*) u->in_mmap+u->in_fragment_size*u->in_current, u->in_fragment_size, 1); - chunk.length = pa_memblock_get_length(chunk.memblock); - chunk.index = 0; - - pa_source_post(u->source, &chunk); - } - - u->in_current++; - while (u->in_current >= u->in_fragments) - u->in_current -= u->in_fragments; - - n--; - } -} - -static void in_clear_memblocks(struct userdata*u, unsigned n) { - unsigned i = u->in_current; - assert(u && u->in_memblocks); - - if (n > u->in_fragments) - n = u->in_fragments; - - while (n > 0) { - if (u->in_memblocks[i]) { - pa_memblock_unref_fixed(u->in_memblocks[i]); - u->in_memblocks[i] = NULL; - } - - i++; - while (i >= u->in_fragments) - i -= u->in_fragments; - - n--; - } -} - -static void do_read(struct userdata *u) { - struct count_info info; - assert(u && u->source); - - update_usage(u); - - if (ioctl(u->fd, SNDCTL_DSP_GETIPTR, &info) < 0) { - pa_log("SNDCTL_DSP_GETIPTR: %s", pa_cstrerror(errno)); - - clear_up(u); - pa_module_unload_request(u->module); - return; - } - - info.blocks += u->in_blocks_saved; - u->in_blocks_saved = 0; - - if (!info.blocks) - return; - - in_post_memblocks(u, info.blocks); - in_clear_memblocks(u, u->in_fragments/2); -} - -static void io_callback(pa_mainloop_api *m, pa_io_event *e, PA_GCC_UNUSED int fd, pa_io_event_flags_t f, void *userdata) { - struct userdata *u = userdata; - assert (u && u->core->mainloop == m && u->io_event == e); - - if (f & PA_IO_EVENT_ERROR) { - clear_up(u); - pa_module_unload_request(u->module); - return; - } - - if (f & PA_IO_EVENT_INPUT) - do_read(u); - if (f & PA_IO_EVENT_OUTPUT) - do_write(u); -} - -static pa_usec_t sink_get_latency_cb(pa_sink *s) { - struct userdata *u = s->userdata; - struct count_info info; - size_t bpos, n, total; - assert(s && u); - - if (ioctl(u->fd, SNDCTL_DSP_GETOPTR, &info) < 0) { - pa_log("SNDCTL_DSP_GETOPTR: %s", pa_cstrerror(errno)); - return 0; - } - - u->out_blocks_saved += info.blocks; - - total = u->out_fragments * u->out_fragment_size; - bpos = ((u->out_current + u->out_blocks_saved) * u->out_fragment_size) % total; - - if (bpos <= (size_t) info.ptr) - n = total - (info.ptr - bpos); - else - n = bpos - info.ptr; - -/* pa_log("n = %u, bpos = %u, ptr = %u, total=%u, fragsize = %u, n_frags = %u\n", n, bpos, (unsigned) info.ptr, total, u->out_fragment_size, u->out_fragments); */ - - return pa_bytes_to_usec(n, &s->sample_spec); -} - -static pa_usec_t source_get_latency_cb(pa_source *s) { - struct userdata *u = s->userdata; - struct count_info info; - size_t bpos, n, total; - assert(s && u); - - if (ioctl(u->fd, SNDCTL_DSP_GETIPTR, &info) < 0) { - pa_log("SNDCTL_DSP_GETIPTR: %s", pa_cstrerror(errno)); - return 0; - } - - u->in_blocks_saved += info.blocks; - - total = u->in_fragments * u->in_fragment_size; - bpos = ((u->in_current + u->in_blocks_saved) * u->in_fragment_size) % total; - - if (bpos <= (size_t) info.ptr) - n = info.ptr - bpos; - else - n = (u->in_fragments * u->in_fragment_size) - bpos + info.ptr; - -/* pa_log("n = %u, bpos = %u, ptr = %u, total=%u, fragsize = %u, n_frags = %u\n", n, bpos, (unsigned) info.ptr, total, u->in_fragment_size, u->in_fragments); */ - - return pa_bytes_to_usec(n, &s->sample_spec); -} - -static int sink_get_hw_volume(pa_sink *s) { - struct userdata *u = s->userdata; - - if (pa_oss_get_pcm_volume(u->fd, &s->sample_spec, &s->hw_volume) < 0) { - pa_log_info("device doesn't support reading mixer settings: %s", pa_cstrerror(errno)); - s->get_hw_volume = NULL; - return -1; - } - - return 0; -} - -static int sink_set_hw_volume(pa_sink *s) { - struct userdata *u = s->userdata; - - if (pa_oss_set_pcm_volume(u->fd, &s->sample_spec, &s->hw_volume) < 0) { - pa_log_info("device doesn't support writing mixer settings: %s", pa_cstrerror(errno)); - s->set_hw_volume = NULL; - return -1; - } - - return 0; -} - -static int source_get_hw_volume(pa_source *s) { - struct userdata *u = s->userdata; - - if (pa_oss_get_input_volume(u->fd, &s->sample_spec, &s->hw_volume) < 0) { - pa_log_info("device doesn't support reading mixer settings: %s", pa_cstrerror(errno)); - s->get_hw_volume = NULL; - return -1; - } - - return 0; -} - -static int source_set_hw_volume(pa_source *s) { - struct userdata *u = s->userdata; - - if (pa_oss_set_input_volume(u->fd, &s->sample_spec, &s->hw_volume) < 0) { - pa_log_info("device doesn't support writing mixer settings: %s", pa_cstrerror(errno)); - s->set_hw_volume = NULL; - return -1; - } - - return 0; -} - -int pa__init(pa_core *c, pa_module*m) { - struct audio_buf_info info; - struct userdata *u = NULL; - const char *p; - int nfrags, frag_size; - int mode, caps; - int enable_bits = 0, zero = 0; - int playback = 1, record = 1; - pa_modargs *ma = NULL; - char hwdesc[64], *t; - pa_channel_map map; - const char *name; - char *name_buf = NULL; - int namereg_fail; - - assert(c); - assert(m); - - m->userdata = u = pa_xnew0(struct userdata, 1); - u->module = m; - u->fd = -1; - u->core = c; - - if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { - pa_log("failed to parse module arguments."); - goto fail; - } - - if (pa_modargs_get_value_boolean(ma, "record", &record) < 0 || pa_modargs_get_value_boolean(ma, "playback", &playback) < 0) { - pa_log("record= and playback= expect numeric arguments."); - goto fail; - } - - if (!playback && !record) { - pa_log("neither playback nor record enabled for device."); - goto fail; - } - - mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0)); - - nfrags = DEFAULT_NFRAGS; - frag_size = DEFAULT_FRAGSIZE; - if (pa_modargs_get_value_s32(ma, "fragments", &nfrags) < 0 || pa_modargs_get_value_s32(ma, "fragment_size", &frag_size) < 0) { - pa_log("failed to parse fragments arguments"); - goto fail; - } - - u->sample_spec = c->default_sample_spec; - if (pa_modargs_get_sample_spec_and_channel_map(ma, &u->sample_spec, &map, PA_CHANNEL_MAP_OSS) < 0) { - pa_log("failed to parse sample specification or channel map"); - goto fail; - } - - if ((u->fd = pa_oss_open(p = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), &mode, &caps)) < 0) - goto fail; - - if (!(caps & DSP_CAP_MMAP) || !(caps & DSP_CAP_TRIGGER)) { - pa_log("OSS device not mmap capable."); - goto fail; - } - - pa_log_info("device opened in %s mode.", mode == O_WRONLY ? "O_WRONLY" : (mode == O_RDONLY ? "O_RDONLY" : "O_RDWR")); - - if (pa_oss_get_hw_description(p, hwdesc, sizeof(hwdesc)) >= 0) - pa_log_info("hardware name is '%s'.", hwdesc); - else - hwdesc[0] = 0; - - if (nfrags >= 2 && frag_size >= 1) - if (pa_oss_set_fragments(u->fd, nfrags, frag_size) < 0) - goto fail; - - if (pa_oss_auto_format(u->fd, &u->sample_spec) < 0) - goto fail; - - if (mode != O_WRONLY) { - if (ioctl(u->fd, SNDCTL_DSP_GETISPACE, &info) < 0) { - pa_log("SNDCTL_DSP_GETISPACE: %s", pa_cstrerror(errno)); - goto fail; - } - - pa_log_info("input -- %u fragments of size %u.", info.fragstotal, info.fragsize); - u->in_mmap_length = (u->in_fragment_size = info.fragsize) * (u->in_fragments = info.fragstotal); - - if ((u->in_mmap = mmap(NULL, u->in_mmap_length, PROT_READ, MAP_SHARED, u->fd, 0)) == MAP_FAILED) { - if (mode == O_RDWR) { - pa_log("mmap failed for input. Changing to O_WRONLY mode."); - mode = O_WRONLY; - } else { - pa_log("mmap(): %s", pa_cstrerror(errno)); - goto fail; - } - } else { - if ((name = pa_modargs_get_value(ma, "source_name", NULL))) - namereg_fail = 1; - else { - name = name_buf = pa_sprintf_malloc("oss_input.%s", pa_path_get_filename(p)); - namereg_fail = 0; - } - - if (!(u->source = pa_source_new(c, __FILE__, name, namereg_fail, &u->sample_spec, &map))) - goto fail; - - u->source->userdata = u; - u->source->get_latency = source_get_latency_cb; - u->source->get_hw_volume = source_get_hw_volume; - u->source->set_hw_volume = source_set_hw_volume; - pa_source_set_owner(u->source, m); - pa_source_set_description(u->source, t = pa_sprintf_malloc("OSS PCM/mmap() on %s%s%s%s", - p, - hwdesc[0] ? " (" : "", - hwdesc[0] ? hwdesc : "", - hwdesc[0] ? ")" : "")); - pa_xfree(t); - u->source->is_hardware = 1; - - u->in_memblocks = pa_xnew0(pa_memblock*, u->in_fragments); - - enable_bits |= PCM_ENABLE_INPUT; - } - } - - pa_xfree(name_buf); - name_buf = NULL; - - if (mode != O_RDONLY) { - if (ioctl(u->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) { - pa_log("SNDCTL_DSP_GETOSPACE: %s", pa_cstrerror(errno)); - goto fail; - } - - pa_log_info("output -- %u fragments of size %u.", info.fragstotal, info.fragsize); - u->out_mmap_length = (u->out_fragment_size = info.fragsize) * (u->out_fragments = info.fragstotal); - - if ((u->out_mmap = mmap(NULL, u->out_mmap_length, PROT_WRITE, MAP_SHARED, u->fd, 0)) == MAP_FAILED) { - if (mode == O_RDWR) { - pa_log("mmap filed for output. Changing to O_RDONLY mode."); - mode = O_RDONLY; - } else { - pa_log("mmap(): %s", pa_cstrerror(errno)); - goto fail; - } - } else { - pa_silence_memory(u->out_mmap, u->out_mmap_length, &u->sample_spec); - - if ((name = pa_modargs_get_value(ma, "sink_name", NULL))) - namereg_fail = 1; - else { - name = name_buf = pa_sprintf_malloc("oss_output.%s", pa_path_get_filename(p)); - namereg_fail = 0; - } - - if (!(u->sink = pa_sink_new(c, __FILE__, name, namereg_fail, &u->sample_spec, &map))) - goto fail; - - u->sink->get_latency = sink_get_latency_cb; - u->sink->get_hw_volume = sink_get_hw_volume; - u->sink->set_hw_volume = sink_set_hw_volume; - u->sink->userdata = u; - pa_sink_set_owner(u->sink, m); - pa_sink_set_description(u->sink, t = pa_sprintf_malloc("OSS PCM/mmap() on %s%s%s%s", - p, - hwdesc[0] ? " (" : "", - hwdesc[0] ? hwdesc : "", - hwdesc[0] ? ")" : "")); - pa_xfree(t); - - u->sink->is_hardware = 1; - u->out_memblocks = pa_xmalloc0(sizeof(struct memblock *)*u->out_fragments); - - enable_bits |= PCM_ENABLE_OUTPUT; - } - } - - pa_xfree(name_buf); - name_buf = NULL; - - zero = 0; - if (ioctl(u->fd, SNDCTL_DSP_SETTRIGGER, &zero) < 0) { - pa_log("SNDCTL_DSP_SETTRIGGER: %s", pa_cstrerror(errno)); - goto fail; - } - - if (ioctl(u->fd, SNDCTL_DSP_SETTRIGGER, &enable_bits) < 0) { - pa_log("SNDCTL_DSP_SETTRIGGER: %s", pa_cstrerror(errno)); - goto fail; - } - - assert(u->source || u->sink); - - u->io_event = c->mainloop->io_new(c->mainloop, u->fd, (u->source ? PA_IO_EVENT_INPUT : 0) | (u->sink ? PA_IO_EVENT_OUTPUT : 0), io_callback, u); - assert(u->io_event); - - pa_modargs_free(ma); - - /* Read mixer settings */ - if (u->source) - source_get_hw_volume(u->source); - if (u->sink) - sink_get_hw_volume(u->sink); - - return 0; - -fail: - pa__done(c, m); - - if (ma) - pa_modargs_free(ma); - - pa_xfree(name_buf); - - return -1; -} - -void pa__done(pa_core *c, pa_module*m) { - struct userdata *u; - - assert(c); - assert(m); - - if (!(u = m->userdata)) - return; - - clear_up(u); - - if (u->out_memblocks) { - unsigned i; - for (i = 0; i < u->out_fragments; i++) - if (u->out_memblocks[i]) - pa_memblock_unref_fixed(u->out_memblocks[i]); - pa_xfree(u->out_memblocks); - } - - if (u->in_memblocks) { - unsigned i; - for (i = 0; i < u->in_fragments; i++) - if (u->in_memblocks[i]) - pa_memblock_unref_fixed(u->in_memblocks[i]); - pa_xfree(u->in_memblocks); - } - - pa_xfree(u); -} -- cgit From ca5874da9bfc0e8bc5dd4ad6dd41e4add3977828 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Jul 2007 12:10:44 +0000 Subject: Replace a couple of assert()s by pa_assert()s git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1512 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-oss.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 249982c9..cabdf162 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -54,7 +54,6 @@ #include #include #include -#include #include #include #include @@ -1034,8 +1033,8 @@ int pa__init(pa_core *c, pa_module*m) { const char *name; int namereg_fail; - assert(c); - assert(m); + pa_assert(c); + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments."); @@ -1101,7 +1100,7 @@ int pa__init(pa_core *c, pa_module*m) { pa_log("SNDCTL_DSP_GETBLKSIZE: %s", pa_cstrerror(errno)); goto fail; } - assert(frag_size); + pa_assert(frag_size > 0); u = pa_xnew0(struct userdata, 1); u->core = c; @@ -1269,8 +1268,8 @@ fail: void pa__done(pa_core *c, pa_module*m) { struct userdata *u; - assert(c); - assert(m); + pa_assert(c); + pa_assert(m); if (!(u = m->userdata)) return; -- cgit From 481b425a28ac02246fc051ab1e9f9a65f2701cf4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Jul 2007 12:11:19 +0000 Subject: Fix off-by-one in mixing code git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1513 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index ced23a51..5a79a41c 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -320,7 +320,8 @@ static void inputs_drop(pa_sink *s, pa_mix_info *info, unsigned n, size_t length break; } - if (++p > n) + p++; + if (p >= n) p = 0; } -- cgit From 63c231ed36f834a62b3a0f8cc21756ecc6d8533e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Jul 2007 12:12:40 +0000 Subject: Fix concurrency bug when turning memblock into a local memblock git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1514 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/memblock.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index 71b576ac..e5df11f7 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -567,10 +567,10 @@ void pa_memblock_unref_fixed(pa_memblock *b) { assert(PA_REFCNT_VALUE(b) > 0); assert(b->type == PA_MEMBLOCK_FIXED); - if (PA_REFCNT_DEC(b) > 0) + if (PA_REFCNT_VALUE(b) > 1) memblock_make_local(b); - else - memblock_free(b); + + pa_memblock_unref(b); } /* Self-locked. This function is not multiple-caller safe */ -- cgit From 59faa5d38b3dc0b59d7ff20a5fd65f495a5e660f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Jul 2007 12:13:25 +0000 Subject: Remove a superfluous pa_memblock_release(); properly handle buf4 allocation git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1515 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/resampler.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index a43c7c7c..7c716ddb 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -455,7 +455,7 @@ static pa_memchunk *convert_from_float(pa_resampler *r, pa_memchunk *input) { n_frames = input->length / sizeof(float) / r->o_ss.channels; n_samples = n_frames * r->o_ss.channels; - if (u->buf4_samples < n_samples) { + if (!u->buf4.memblock || u->buf4_samples < n_samples) { if (u->buf4.memblock) pa_memblock_unref(u->buf4.memblock); @@ -503,9 +503,6 @@ static void libsamplerate_run(pa_resampler *r, const pa_memchunk *in, pa_memchun pa_memchunk_reset(buf); } else pa_memchunk_reset(out); - - pa_memblock_release(in->memblock); - } static void libsamplerate_update_input_rate(pa_resampler *r, uint32_t rate) { @@ -526,7 +523,6 @@ static void libsamplerate_update_input_rate(pa_resampler *r, uint32_t rate) { } } - static void libsamplerate_update_output_rate(pa_resampler *r, uint32_t rate) { struct impl_libsamplerate *u; -- cgit From 8442926483403d7e2fd9b768e70df87db6759b04 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Jul 2007 12:13:55 +0000 Subject: Reenable a couple of more modules git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1516 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index c382bcdb..2e37b295 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -873,16 +873,16 @@ modlibexec_LTLIBRARIES += \ module-cli.la \ module-cli-protocol-tcp.la \ module-simple-protocol-tcp.la \ - module-null-sink.la + module-null-sink.la \ module-detect.la \ module-volume-restore.la \ module-rescue-streams.la \ - module-http-protocol-tcp.la + module-http-protocol-tcp.la \ + module-sine.la # module-esound-protocol-tcp.la \ # module-native-protocol-tcp.la \ # module-native-protocol-fd.la \ -# module-sine.la \ # module-combine.la \ # module-tunnel-sink.la \ # module-tunnel-source.la \ -- cgit From 3b912ac41f5406b5f7b02c718bb87cb19965843c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Jul 2007 12:14:30 +0000 Subject: Port module-sine to the new lock-free core git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1517 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-sine.c | 57 +++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/src/modules/module-sine.c b/src/modules/module-sine.c index baf37346..b5b7e60b 100644 --- a/src/modules/module-sine.c +++ b/src/modules/module-sine.c @@ -58,34 +58,42 @@ static const char* const valid_modargs[] = { NULL, }; -static int sink_input_peek(pa_sink_input *i, pa_memchunk *chunk) { +static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { struct userdata *u; - assert(i && chunk && i->userdata); + + pa_assert(i); u = i->userdata; + pa_assert(u); + pa_assert(chunk); chunk->memblock = pa_memblock_ref(u->memblock); chunk->index = u->peek_index; chunk->length = pa_memblock_get_length(u->memblock) - u->peek_index; + return 0; } -static void sink_input_drop(pa_sink_input *i, const pa_memchunk *chunk, size_t length) { +static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_t length) { struct userdata *u; - assert(i && chunk && length && i->userdata); + size_t l; + + pa_assert(i); u = i->userdata; - - assert(chunk->memblock == u->memblock); - assert(length <= pa_memblock_get_length(u->memblock)-u->peek_index); + pa_assert(u); + pa_assert(chunk); + pa_assert(length > 0); u->peek_index += length; - if (u->peek_index >= pa_memblock_get_length(u->memblock)) - u->peek_index = 0; + l = pa_memblock_get_length(u->memblock); + + while (u->peek_index >= l) + u->peek_index -= l; } -static void sink_input_kill(pa_sink_input *i) { +static void sink_input_kill_cb(pa_sink_input *i) { struct userdata *u; - assert(i && i->userdata); + pa_assert(i && i->userdata); u = i->userdata; pa_sink_input_disconnect(u->sink_input); @@ -108,7 +116,6 @@ int pa__init(pa_core *c, pa_module*m) { pa_modargs *ma = NULL; struct userdata *u; pa_sink *sink; - const char *sink_name; pa_sample_spec ss; uint32_t frequency; char t[256]; @@ -120,15 +127,14 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - m->userdata = u = pa_xmalloc(sizeof(struct userdata)); + m->userdata = u = pa_xnew0(struct userdata, 1); u->core = c; u->module = m; u->sink_input = NULL; u->memblock = NULL; + u->peek_index = 0; - sink_name = pa_modargs_get_value(ma, "sink", NULL); - - if (!(sink = pa_namereg_get(c, sink_name, PA_NAMEREG_SINK, 1))) { + if (!(sink = pa_namereg_get(c, pa_modargs_get_value(ma, "sink", NULL), PA_NAMEREG_SINK, 1))) { pa_log("No such sink."); goto fail; } @@ -160,13 +166,13 @@ int pa__init(pa_core *c, pa_module*m) { if (!(u->sink_input = pa_sink_input_new(c, &data, 0))) goto fail; - u->sink_input->peek = sink_input_peek; - u->sink_input->drop = sink_input_drop; - u->sink_input->kill = sink_input_kill; + u->sink_input->peek = sink_input_peek_cb; + u->sink_input->drop = sink_input_drop_cb; + u->sink_input->kill = sink_input_kill_cb; u->sink_input->userdata = u; - u->peek_index = 0; - + pa_sink_input_put(u->sink_input); + pa_modargs_free(ma); return 0; @@ -179,10 +185,12 @@ fail: } void pa__done(pa_core *c, pa_module*m) { - struct userdata *u = m->userdata; - assert(c && m); + struct userdata *u; + + pa_assert(c); + pa_assert(m); - if (!u) + if (!(u = m->userdata)) return; if (u->sink_input) { @@ -192,6 +200,7 @@ void pa__done(pa_core *c, pa_module*m) { if (u->memblock) pa_memblock_unref(u->memblock); + pa_xfree(u); } -- cgit From 69bfa351ba89f17b22efad95f1dc6f946cf2df20 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Jul 2007 23:21:54 +0000 Subject: Actually make the static flist static git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1518 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/flist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/flist.h b/src/pulsecore/flist.h index 80fd86c1..102d30ea 100644 --- a/src/pulsecore/flist.h +++ b/src/pulsecore/flist.h @@ -41,7 +41,7 @@ int pa_flist_push(pa_flist*l, void *p); void* pa_flist_pop(pa_flist*l); #define PA_STATIC_FLIST_DECLARE(name, size) \ - struct { \ + static struct { \ pa_flist *flist; \ pa_once_t once; \ } name##_static_flist = { NULL, PA_ONCE_INIT }; \ -- cgit From f2c98d74837e4e98173ef528d25a5f583340fc2c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Jul 2007 23:22:38 +0000 Subject: Make use of static flist for hashmap entry alllocation git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1519 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/hashmap.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/hashmap.c b/src/pulsecore/hashmap.c index 818e12bf..450f89ca 100644 --- a/src/pulsecore/hashmap.c +++ b/src/pulsecore/hashmap.c @@ -33,6 +33,7 @@ #include #include +#include #include "hashmap.h" @@ -55,6 +56,8 @@ struct pa_hashmap { pa_compare_func_t compare_func; }; +PA_STATIC_FLIST_DECLARE(entries, 0); + pa_hashmap *pa_hashmap_new(pa_hash_func_t hash_func, pa_compare_func_t compare_func) { pa_hashmap *h; @@ -88,7 +91,9 @@ static void remove(pa_hashmap *h, struct hashmap_entry *e) { h->data[e->hash] = e->bucket_next; } - pa_xfree(e); + if (pa_flist_push(PA_STATIC_FLIST_GET(entries), e) < 0) + pa_xfree(e); + h->n_entries--; } @@ -127,7 +132,9 @@ int pa_hashmap_put(pa_hashmap *h, const void *key, void *value) { if ((e = get(h, hash, key))) return -1; - e = pa_xnew(struct hashmap_entry, 1); + if (!(e = pa_flist_pop(PA_STATIC_FLIST_GET(entries)))) + e = pa_xnew(struct hashmap_entry, 1); + e->hash = hash; e->key = key; e->value = value; -- cgit From 0e84f044dd531ff23b165d8bc07c282b923e5d1e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Jul 2007 23:23:03 +0000 Subject: Minor clarification git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1520 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/resampler.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index 7c716ddb..9c8e32f9 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -489,7 +489,8 @@ static void libsamplerate_run(pa_resampler *r, const pa_memchunk *in, pa_memchun u = r->impl_data; - buf = convert_to_float(r, (pa_memchunk*) in); + buf = (pa_memchunk*) in; + buf = convert_to_float(r, buf); buf = remap_channels(r, buf); buf = resample(r, buf); -- cgit From 65d54d6aaf62cca5bac5ec3c5588b797f0ed4c7e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Jul 2007 23:27:15 +0000 Subject: s/assert/pa_assert/g; make use of static flist for memblock allocation where applicable; properly initialize length value in pa_memexport_put() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1521 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/memblock.c | 229 +++++++++++++++++++++++++---------------------- 1 file changed, 122 insertions(+), 107 deletions(-) diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index e5df11f7..8da9cebb 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -14,7 +14,7 @@ PulseAudio is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + Lesser General Public License for more details You should have received a copy of the GNU Lesser General Public License along with PulseAudio; if not, write to the Free Software @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -149,10 +150,12 @@ struct pa_mempool { static void segment_detach(pa_memimport_segment *seg); +PA_STATIC_FLIST_DECLARE(unused_memblocks, 0); + /* No lock necessary */ static void stat_add(pa_memblock*b) { - assert(b); - assert(b->pool); + pa_assert(b); + pa_assert(b->pool); pa_atomic_inc(&b->pool->stat.n_allocated); pa_atomic_add(&b->pool->stat.allocated_size, b->length); @@ -171,18 +174,18 @@ static void stat_add(pa_memblock*b) { /* No lock necessary */ static void stat_remove(pa_memblock *b) { - assert(b); - assert(b->pool); + pa_assert(b); + pa_assert(b->pool); - assert(pa_atomic_load(&b->pool->stat.n_allocated) > 0); - assert(pa_atomic_load(&b->pool->stat.allocated_size) >= (int) b->length); + pa_assert(pa_atomic_load(&b->pool->stat.n_allocated) > 0); + pa_assert(pa_atomic_load(&b->pool->stat.allocated_size) >= (int) b->length); pa_atomic_dec(&b->pool->stat.n_allocated); pa_atomic_sub(&b->pool->stat.allocated_size, b->length); if (b->type == PA_MEMBLOCK_IMPORTED) { - assert(pa_atomic_load(&b->pool->stat.n_imported) > 0); - assert(pa_atomic_load(&b->pool->stat.imported_size) >= (int) b->length); + pa_assert(pa_atomic_load(&b->pool->stat.n_imported) > 0); + pa_assert(pa_atomic_load(&b->pool->stat.imported_size) >= (int) b->length); pa_atomic_dec(&b->pool->stat.n_imported); pa_atomic_sub(&b->pool->stat.imported_size, b->length); @@ -197,8 +200,8 @@ static pa_memblock *memblock_new_appended(pa_mempool *p, size_t length); pa_memblock *pa_memblock_new(pa_mempool *p, size_t length) { pa_memblock *b; - assert(p); - assert(length > 0); + pa_assert(p); + pa_assert(length > 0); if (!(b = pa_memblock_new_pool(p, length))) b = memblock_new_appended(p, length); @@ -210,8 +213,8 @@ pa_memblock *pa_memblock_new(pa_mempool *p, size_t length) { static pa_memblock *memblock_new_appended(pa_mempool *p, size_t length) { pa_memblock *b; - assert(p); - assert(length > 0); + pa_assert(p); + pa_assert(length > 0); b = pa_xmalloc(PA_ALIGN(sizeof(pa_memblock)) + length); PA_REFCNT_INIT(b); @@ -230,7 +233,7 @@ static pa_memblock *memblock_new_appended(pa_mempool *p, size_t length) { /* No lock necessary */ static struct mempool_slot* mempool_allocate_slot(pa_mempool *p) { struct mempool_slot *slot; - assert(p); + pa_assert(p); if (!(slot = pa_flist_pop(p->free_slots))) { int idx; @@ -254,17 +257,17 @@ static struct mempool_slot* mempool_allocate_slot(pa_mempool *p) { /* No lock necessary */ static void* mempool_slot_data(struct mempool_slot *slot) { - assert(slot); + pa_assert(slot); return (uint8_t*) slot + sizeof(struct mempool_slot); } /* No lock necessary */ static unsigned mempool_slot_idx(pa_mempool *p, void *ptr) { - assert(p); + pa_assert(p); - assert((uint8_t*) ptr >= (uint8_t*) p->memory.ptr); - assert((uint8_t*) ptr < (uint8_t*) p->memory.ptr + p->memory.size); + pa_assert((uint8_t*) ptr >= (uint8_t*) p->memory.ptr); + pa_assert((uint8_t*) ptr < (uint8_t*) p->memory.ptr + p->memory.size); return ((uint8_t*) ptr - (uint8_t*) p->memory.ptr) / p->block_size; } @@ -284,8 +287,8 @@ pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) { pa_memblock *b = NULL; struct mempool_slot *slot; - assert(p); - assert(length > 0); + pa_assert(p); + pa_assert(length > 0); if (p->block_size - sizeof(struct mempool_slot) >= sizeof(pa_memblock) + length) { @@ -301,7 +304,9 @@ pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) { if (!(slot = mempool_allocate_slot(p))) return NULL; - b = pa_xnew(pa_memblock, 1); + if (!(b = pa_flist_pop(PA_STATIC_FLIST_GET(unused_memblocks)))) + b = pa_xnew(pa_memblock, 1); + b->type = PA_MEMBLOCK_POOL_EXTERNAL; pa_atomic_ptr_store(&b->data, mempool_slot_data(slot)); @@ -326,11 +331,12 @@ pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) { pa_memblock *pa_memblock_new_fixed(pa_mempool *p, void *d, size_t length, int read_only) { pa_memblock *b; - assert(p); - assert(d); - assert(length > 0); + pa_assert(p); + pa_assert(d); + pa_assert(length > 0); - b = pa_xnew(pa_memblock, 1); + if (!(b = pa_flist_pop(PA_STATIC_FLIST_GET(unused_memblocks)))) + b = pa_xnew(pa_memblock, 1); PA_REFCNT_INIT(b); b->pool = p; b->type = PA_MEMBLOCK_FIXED; @@ -348,12 +354,13 @@ pa_memblock *pa_memblock_new_fixed(pa_mempool *p, void *d, size_t length, int re pa_memblock *pa_memblock_new_user(pa_mempool *p, void *d, size_t length, void (*free_cb)(void *p), int read_only) { pa_memblock *b; - assert(p); - assert(d); - assert(length > 0); - assert(free_cb); + pa_assert(p); + pa_assert(d); + pa_assert(length > 0); + pa_assert(free_cb); - b = pa_xnew(pa_memblock, 1); + if (!(b = pa_flist_pop(PA_STATIC_FLIST_GET(unused_memblocks)))) + b = pa_xnew(pa_memblock, 1); PA_REFCNT_INIT(b); b->pool = p; b->type = PA_MEMBLOCK_USER; @@ -371,16 +378,16 @@ pa_memblock *pa_memblock_new_user(pa_mempool *p, void *d, size_t length, void (* /* No lock necessary */ int pa_memblock_is_read_only(pa_memblock *b) { - assert(b); - assert(PA_REFCNT_VALUE(b) > 0); + pa_assert(b); + pa_assert(PA_REFCNT_VALUE(b) > 0); return b->read_only && PA_REFCNT_VALUE(b) == 1; } /* No lock necessary */ void* pa_memblock_acquire(pa_memblock *b) { - assert(b); - assert(PA_REFCNT_VALUE(b) > 0); + pa_assert(b); + pa_assert(PA_REFCNT_VALUE(b) > 0); pa_atomic_inc(&b->n_acquired); @@ -390,11 +397,11 @@ void* pa_memblock_acquire(pa_memblock *b) { /* No lock necessary, in corner cases locks by its own */ void pa_memblock_release(pa_memblock *b) { int r; - assert(b); - assert(PA_REFCNT_VALUE(b) > 0); + pa_assert(b); + pa_assert(PA_REFCNT_VALUE(b) > 0); r = pa_atomic_dec(&b->n_acquired); - assert(r >= 1); + pa_assert(r >= 1); /* Signal a waiting thread that this memblock is no longer used */ if (r == 1 && pa_atomic_load(&b->please_signal)) @@ -402,45 +409,47 @@ void pa_memblock_release(pa_memblock *b) { } size_t pa_memblock_get_length(pa_memblock *b) { - assert(b); - assert(PA_REFCNT_VALUE(b) > 0); + pa_assert(b); + pa_assert(PA_REFCNT_VALUE(b) > 0); return b->length; } pa_mempool* pa_memblock_get_pool(pa_memblock *b) { - assert(b); - assert(PA_REFCNT_VALUE(b) > 0); + pa_assert(b); + pa_assert(PA_REFCNT_VALUE(b) > 0); return b->pool; } /* No lock necessary */ pa_memblock* pa_memblock_ref(pa_memblock*b) { - assert(b); - assert(PA_REFCNT_VALUE(b) > 0); + pa_assert(b); + pa_assert(PA_REFCNT_VALUE(b) > 0); PA_REFCNT_INC(b); return b; } static void memblock_free(pa_memblock *b) { - assert(b); + pa_assert(b); - assert(pa_atomic_load(&b->n_acquired) == 0); + pa_assert(pa_atomic_load(&b->n_acquired) == 0); stat_remove(b); switch (b->type) { case PA_MEMBLOCK_USER : - assert(b->per_type.user.free_cb); + pa_assert(b->per_type.user.free_cb); b->per_type.user.free_cb(pa_atomic_ptr_load(&b->data)); /* Fall through */ case PA_MEMBLOCK_FIXED: case PA_MEMBLOCK_APPENDED : - pa_xfree(b); + if (pa_flist_push(PA_STATIC_FLIST_GET(unused_memblocks), b) < 0) + pa_xfree(b); + break; case PA_MEMBLOCK_IMPORTED : { @@ -450,9 +459,9 @@ static void memblock_free(pa_memblock *b) { /* FIXME! This should be implemented lock-free */ segment = b->per_type.imported.segment; - assert(segment); + pa_assert(segment); import = segment->import; - assert(import); + pa_assert(import); pa_mutex_lock(import->mutex); pa_hashmap_remove(import->blocks, PA_UINT32_TO_PTR(b->per_type.imported.id)); @@ -463,7 +472,8 @@ static void memblock_free(pa_memblock *b) { import->release_cb(import, b->per_type.imported.id, import->userdata); - pa_xfree(b); + if (pa_flist_push(PA_STATIC_FLIST_GET(unused_memblocks), b) < 0) + pa_xfree(b); break; } @@ -473,7 +483,7 @@ static void memblock_free(pa_memblock *b) { int call_free; slot = mempool_slot_by_ptr(b->pool, pa_atomic_ptr_load(&b->data)); - assert(slot); + pa_assert(slot); call_free = b->type == PA_MEMBLOCK_POOL_EXTERNAL; @@ -484,21 +494,22 @@ static void memblock_free(pa_memblock *b) { ; if (call_free) - pa_xfree(b); + if (pa_flist_push(PA_STATIC_FLIST_GET(unused_memblocks), b) < 0) + pa_xfree(b); break; } case PA_MEMBLOCK_TYPE_MAX: default: - abort(); + pa_assert_not_reached(); } } /* No lock necessary */ void pa_memblock_unref(pa_memblock*b) { - assert(b); - assert(PA_REFCNT_VALUE(b) > 0); + pa_assert(b); + pa_assert(PA_REFCNT_VALUE(b) > 0); if (PA_REFCNT_DEC(b) > 0) return; @@ -508,7 +519,7 @@ void pa_memblock_unref(pa_memblock*b) { /* Self locked */ static void memblock_wait(pa_memblock *b) { - assert(b); + pa_assert(b); if (pa_atomic_load(&b->n_acquired) > 0) { /* We need to wait until all threads gave up access to the @@ -526,7 +537,7 @@ static void memblock_wait(pa_memblock *b) { /* No lock necessary. This function is not multiple caller safe! */ static void memblock_make_local(pa_memblock *b) { - assert(b); + pa_assert(b); pa_atomic_dec(&b->pool->stat.n_allocated_by_type[b->type]); @@ -563,9 +574,9 @@ finish: /* No lock necessary. This function is not multiple caller safe*/ void pa_memblock_unref_fixed(pa_memblock *b) { - assert(b); - assert(PA_REFCNT_VALUE(b) > 0); - assert(b->type == PA_MEMBLOCK_FIXED); + pa_assert(b); + pa_assert(PA_REFCNT_VALUE(b) > 0); + pa_assert(b->type == PA_MEMBLOCK_FIXED); if (PA_REFCNT_VALUE(b) > 1) memblock_make_local(b); @@ -577,17 +588,17 @@ void pa_memblock_unref_fixed(pa_memblock *b) { static void memblock_replace_import(pa_memblock *b) { pa_memimport_segment *seg; - assert(b); - assert(b->type == PA_MEMBLOCK_IMPORTED); + pa_assert(b); + pa_assert(b->type == PA_MEMBLOCK_IMPORTED); - assert(pa_atomic_load(&b->pool->stat.n_imported) > 0); - assert(pa_atomic_load(&b->pool->stat.imported_size) >= (int) b->length); + pa_assert(pa_atomic_load(&b->pool->stat.n_imported) > 0); + pa_assert(pa_atomic_load(&b->pool->stat.imported_size) >= (int) b->length); pa_atomic_dec(&b->pool->stat.n_imported); pa_atomic_sub(&b->pool->stat.imported_size, b->length); seg = b->per_type.imported.segment; - assert(seg); - assert(seg->import); + pa_assert(seg); + pa_assert(seg->import); pa_mutex_lock(seg->import->mutex); @@ -627,7 +638,7 @@ pa_mempool* pa_mempool_new(int shared) { p->n_blocks = PA_MEMPOOL_SLOTS_MAX; - assert(p->block_size > sizeof(struct mempool_slot)); + pa_assert(p->block_size > sizeof(struct mempool_slot)); if (pa_shm_create_rw(&p->memory, p->n_blocks * p->block_size, shared, 0700) < 0) { pa_xfree(p); @@ -646,7 +657,7 @@ pa_mempool* pa_mempool_new(int shared) { } void pa_mempool_free(pa_mempool *p) { - assert(p); + pa_assert(p); pa_mutex_lock(p->mutex); @@ -658,8 +669,10 @@ void pa_mempool_free(pa_mempool *p) { pa_mutex_unlock(p->mutex); - if (pa_atomic_load(&p->stat.n_allocated) > 0) + if (pa_atomic_load(&p->stat.n_allocated) > 0) { + raise(SIGTRAP); pa_log_warn("WARNING! Memory pool destroyed but not all memory blocks freed!"); + } pa_flist_free(p->free_slots, NULL); pa_shm_free(&p->memory); @@ -672,7 +685,7 @@ void pa_mempool_free(pa_mempool *p) { /* No lock necessary */ const pa_mempool_stat* pa_mempool_get_stat(pa_mempool *p) { - assert(p); + pa_assert(p); return &p->stat; } @@ -682,7 +695,7 @@ void pa_mempool_vacuum(pa_mempool *p) { struct mempool_slot *slot; pa_flist *list; - assert(p); + pa_assert(p); list = pa_flist_new(p->n_blocks*2); @@ -704,7 +717,7 @@ void pa_mempool_vacuum(pa_mempool *p) { /* No lock necessary */ int pa_mempool_get_shm_id(pa_mempool *p, uint32_t *id) { - assert(p); + pa_assert(p); if (!p->memory.shared) return -1; @@ -716,7 +729,7 @@ int pa_mempool_get_shm_id(pa_mempool *p, uint32_t *id) { /* No lock necessary */ int pa_mempool_is_shared(pa_mempool *p) { - assert(p); + pa_assert(p); return !!p->memory.shared; } @@ -725,8 +738,8 @@ int pa_mempool_is_shared(pa_mempool *p) { pa_memimport* pa_memimport_new(pa_mempool *p, pa_memimport_release_cb_t cb, void *userdata) { pa_memimport *i; - assert(p); - assert(cb); + pa_assert(p); + pa_assert(cb); i = pa_xnew(pa_memimport, 1); i->mutex = pa_mutex_new(0); @@ -768,7 +781,7 @@ static pa_memimport_segment* segment_attach(pa_memimport *i, uint32_t shm_id) { /* Should be called locked */ static void segment_detach(pa_memimport_segment *seg) { - assert(seg); + pa_assert(seg); pa_hashmap_remove(seg->import->segments, PA_UINT32_TO_PTR(seg->memory.id)); pa_shm_free(&seg->memory); @@ -780,14 +793,14 @@ void pa_memimport_free(pa_memimport *i) { pa_memexport *e; pa_memblock *b; - assert(i); + pa_assert(i); pa_mutex_lock(i->mutex); while ((b = pa_hashmap_get_first(i->blocks))) memblock_replace_import(b); - assert(pa_hashmap_size(i->segments) == 0); + pa_assert(pa_hashmap_size(i->segments) == 0); pa_mutex_unlock(i->mutex); @@ -814,7 +827,7 @@ pa_memblock* pa_memimport_get(pa_memimport *i, uint32_t block_id, uint32_t shm_i pa_memblock *b = NULL; pa_memimport_segment *seg; - assert(i); + pa_assert(i); pa_mutex_lock(i->mutex); @@ -828,7 +841,9 @@ pa_memblock* pa_memimport_get(pa_memimport *i, uint32_t block_id, uint32_t shm_i if (offset+size > seg->memory.size) goto finish; - b = pa_xnew(pa_memblock, 1); + if (!(b = pa_flist_pop(PA_STATIC_FLIST_GET(unused_memblocks)))) + b = pa_xnew(pa_memblock, 1); + PA_REFCNT_INIT(b); b->pool = i->pool; b->type = PA_MEMBLOCK_IMPORTED; @@ -855,7 +870,7 @@ finish: int pa_memimport_process_revoke(pa_memimport *i, uint32_t id) { pa_memblock *b; - assert(i); + pa_assert(i); pa_mutex_lock(i->mutex); @@ -873,8 +888,8 @@ int pa_memimport_process_revoke(pa_memimport *i, uint32_t id) { pa_memexport* pa_memexport_new(pa_mempool *p, pa_memexport_revoke_cb_t cb, void *userdata) { pa_memexport *e; - assert(p); - assert(cb); + pa_assert(p); + pa_assert(cb); if (!p->memory.shared) return NULL; @@ -895,7 +910,7 @@ pa_memexport* pa_memexport_new(pa_mempool *p, pa_memexport_revoke_cb_t cb, void } void pa_memexport_free(pa_memexport *e) { - assert(e); + pa_assert(e); pa_mutex_lock(e->mutex); while (e->used_slots) @@ -906,6 +921,7 @@ void pa_memexport_free(pa_memexport *e) { PA_LLIST_REMOVE(pa_memexport, e->pool->exports, e); pa_mutex_unlock(e->pool->mutex); + pa_mutex_free(e->mutex); pa_xfree(e); } @@ -913,7 +929,7 @@ void pa_memexport_free(pa_memexport *e) { int pa_memexport_process_release(pa_memexport *e, uint32_t id) { pa_memblock *b; - assert(e); + pa_assert(e); pa_mutex_lock(e->mutex); @@ -933,8 +949,8 @@ int pa_memexport_process_release(pa_memexport *e, uint32_t id) { /* pa_log("Processing release for %u", id); */ - assert(pa_atomic_load(&e->pool->stat.n_exported) > 0); - assert(pa_atomic_load(&e->pool->stat.exported_size) >= (int) b->length); + pa_assert(pa_atomic_load(&e->pool->stat.n_exported) > 0); + pa_assert(pa_atomic_load(&e->pool->stat.exported_size) >= (int) b->length); pa_atomic_dec(&e->pool->stat.n_exported); pa_atomic_sub(&e->pool->stat.exported_size, b->length); @@ -952,8 +968,8 @@ fail: /* Self-locked */ static void memexport_revoke_blocks(pa_memexport *e, pa_memimport *i) { struct memexport_slot *slot, *next; - assert(e); - assert(i); + pa_assert(e); + pa_assert(i); pa_mutex_lock(e->mutex); @@ -977,13 +993,13 @@ static void memexport_revoke_blocks(pa_memexport *e, pa_memimport *i) { static pa_memblock *memblock_shared_copy(pa_mempool *p, pa_memblock *b) { pa_memblock *n; - assert(p); - assert(b); + pa_assert(p); + pa_assert(b); if (b->type == PA_MEMBLOCK_IMPORTED || b->type == PA_MEMBLOCK_POOL || b->type == PA_MEMBLOCK_POOL_EXTERNAL) { - assert(b->pool == p); + pa_assert(b->pool == p); return pa_memblock_ref(b); } @@ -999,15 +1015,14 @@ int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32 pa_shm *memory; struct memexport_slot *slot; void *data; - size_t length; - assert(e); - assert(b); - assert(block_id); - assert(shm_id); - assert(offset); - assert(size); - assert(b->pool == e->pool); + pa_assert(e); + pa_assert(b); + pa_assert(block_id); + pa_assert(shm_id); + pa_assert(offset); + pa_assert(size); + pa_assert(b->pool == e->pool); if (!(b = memblock_shared_copy(e->pool, b))) return -1; @@ -1035,25 +1050,25 @@ int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32 data = pa_memblock_acquire(b); if (b->type == PA_MEMBLOCK_IMPORTED) { - assert(b->per_type.imported.segment); + pa_assert(b->per_type.imported.segment); memory = &b->per_type.imported.segment->memory; } else { - assert(b->type == PA_MEMBLOCK_POOL || b->type == PA_MEMBLOCK_POOL_EXTERNAL); - assert(b->pool); + pa_assert(b->type == PA_MEMBLOCK_POOL || b->type == PA_MEMBLOCK_POOL_EXTERNAL); + pa_assert(b->pool); memory = &b->pool->memory; } - assert(data >= memory->ptr); - assert((uint8_t*) data + length <= (uint8_t*) memory->ptr + memory->size); + pa_assert(data >= memory->ptr); + pa_assert((uint8_t*) data + b->length <= (uint8_t*) memory->ptr + memory->size); *shm_id = memory->id; *offset = (uint8_t*) data - (uint8_t*) memory->ptr; - *size = length; + *size = b->length; pa_memblock_release(b); pa_atomic_inc(&e->pool->stat.n_exported); - pa_atomic_add(&e->pool->stat.exported_size, length); + pa_atomic_add(&e->pool->stat.exported_size, b->length); return 0; } -- cgit From 2a19c466bc66bb5ec8bfc1a5ab7fabe5e4399881 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Jul 2007 23:28:11 +0000 Subject: Fix typo in pa_memblock_release() call; s/assert/pa_assert/ git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1522 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/tests/memblock-test.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/tests/memblock-test.c b/src/tests/memblock-test.c index 1f63499e..2b9d3401 100644 --- a/src/tests/memblock-test.c +++ b/src/tests/memblock-test.c @@ -23,11 +23,11 @@ #include #endif -#include #include #include #include +#include #include static void release_cb(pa_memimport *i, uint32_t block_id, void *userdata) { @@ -88,7 +88,7 @@ int main(int argc, char *argv[]) { pa_mempool_get_shm_id(pool_b, &id_b); pa_mempool_get_shm_id(pool_c, &id_c); - assert(pool_a && pool_b && pool_c); + pa_assert(pool_a && pool_b && pool_c); blocks[0] = pa_memblock_new_fixed(pool_a, (void*) txt, sizeof(txt), 1); @@ -100,7 +100,7 @@ int main(int argc, char *argv[]) { blocks[2] = pa_memblock_new_pool(pool_a, sizeof(txt)); x = pa_memblock_acquire(blocks[2]); snprintf(x, pa_memblock_get_length(blocks[2]), "%s", txt); - pa_memblock_release(blocks[1]); + pa_memblock_release(blocks[2]); blocks[3] = pa_memblock_new_malloced(pool_a, pa_xstrdup(txt), sizeof(txt)); blocks[4] = NULL; @@ -109,35 +109,35 @@ int main(int argc, char *argv[]) { printf("Memory block %u\n", i); mb_a = blocks[i]; - assert(mb_a); + pa_assert(mb_a); export_a = pa_memexport_new(pool_a, revoke_cb, (void*) "A"); export_b = pa_memexport_new(pool_b, revoke_cb, (void*) "B"); - assert(export_a && export_b); + pa_assert(export_a && export_b); import_b = pa_memimport_new(pool_b, release_cb, (void*) "B"); import_c = pa_memimport_new(pool_c, release_cb, (void*) "C"); - assert(import_b && import_c); + pa_assert(import_b && import_c); r = pa_memexport_put(export_a, mb_a, &id, &shm_id, &offset, &size); - assert(r >= 0); - assert(shm_id == id_a); + pa_assert(r >= 0); + pa_assert(shm_id == id_a); printf("A: Memory block exported as %u\n", id); mb_b = pa_memimport_get(import_b, id, shm_id, offset, size); - assert(mb_b); + pa_assert(mb_b); r = pa_memexport_put(export_b, mb_b, &id, &shm_id, &offset, &size); - assert(r >= 0); - assert(shm_id == id_a || shm_id == id_b); + pa_assert(r >= 0); + pa_assert(shm_id == id_a || shm_id == id_b); pa_memblock_unref(mb_b); printf("B: Memory block exported as %u\n", id); mb_c = pa_memimport_get(import_c, id, shm_id, offset, size); - assert(mb_c); + pa_assert(mb_c); x = pa_memblock_acquire(mb_c); printf("1 data=%s\n", x); pa_memblock_release(mb_c); -- cgit From c76d035dad2f5c8768b4ee707a7c84272dfca697 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 14 Jul 2007 11:26:55 +0000 Subject: Fix a couple of typos in the resampler code git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1523 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/resampler.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index 9c8e32f9..a8c90050 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -315,7 +315,9 @@ static pa_memchunk* convert_to_float(pa_resampler *r, pa_memchunk *input) { src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index; dst = (uint8_t*) pa_memblock_acquire(u->buf1.memblock); + u->to_float32ne_func(n_samples, src, dst); + pa_memblock_release(input->memblock); pa_memblock_release(u->buf1.memblock); @@ -402,9 +404,9 @@ static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) { return input; in_n_samples = input->length / sizeof(float); - in_n_frames = in_n_samples * r->o_ss.channels; + in_n_frames = in_n_samples / r->o_ss.channels; - out_n_frames = (in_n_frames*r->o_ss.rate/r->i_ss.rate)+1024; + out_n_frames = ((in_n_frames*r->o_ss.rate)/r->i_ss.rate)+1024; out_n_samples = out_n_frames * r->o_ss.channels; if (!u->buf3.memblock || u->buf3_samples < out_n_samples) { @@ -464,7 +466,7 @@ static pa_memchunk *convert_from_float(pa_resampler *r, pa_memchunk *input) { u->buf4.index = 0; } - src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->length; + src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index; dst = pa_memblock_acquire(u->buf4.memblock); u->from_float32ne_func(n_samples, src, dst); pa_memblock_release(input->memblock); -- cgit From a094923fd5f5012d71383e031256dd9cc5b26a5d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jul 2007 14:40:12 +0000 Subject: change order of munmap and freeing of memblocks git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1524 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-oss.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index cabdf162..b210c17c 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -1297,15 +1297,6 @@ void pa__done(pa_core *c, pa_module*m) { if (u->memchunk.memblock) pa_memblock_unref(u->memchunk.memblock); - if (u->in_mmap && u->in_mmap != MAP_FAILED) - munmap(u->in_mmap, u->in_hwbuf_size); - - if (u->out_mmap && u->out_mmap != MAP_FAILED) - munmap(u->out_mmap, u->out_hwbuf_size); - - if (u->fd >= 0) - close(u->fd); - if (u->out_mmap_memblocks) { unsigned i; for (i = 0; i < u->out_nfrags; i++) @@ -1322,6 +1313,15 @@ void pa__done(pa_core *c, pa_module*m) { pa_xfree(u->in_mmap_memblocks); } + if (u->in_mmap && u->in_mmap != MAP_FAILED) + munmap(u->in_mmap, u->in_hwbuf_size); + + if (u->out_mmap && u->out_mmap != MAP_FAILED) + munmap(u->out_mmap, u->out_hwbuf_size); + + if (u->fd >= 0) + close(u->fd); + pa_xfree(u->device_name); pa_xfree(u); -- cgit From 279b1b3311d5e71348a3d5ffa3bc76468e047333 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jul 2007 14:41:54 +0000 Subject: wrap destructor gcc attribute in macro git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1525 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/gccmacro.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pulsecore/gccmacro.h b/src/pulsecore/gccmacro.h index 57d28006..f3ace593 100644 --- a/src/pulsecore/gccmacro.h +++ b/src/pulsecore/gccmacro.h @@ -52,4 +52,10 @@ #define PA_GCC_UNUSED #endif +#ifdef __GNUC__ +#define PA_GCC_DESTRUCTOR __attribute__ ((destructor)) +#else +#define PA_GCC_DESTRUCTOR +#endif + #endif -- cgit From f42e4438eb5cf81a0a96e2763846faa2f3193223 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jul 2007 14:43:05 +0000 Subject: destruct freelists properly, by using gcc destructors. we do this only to make valgrind shut up, not because it would have any real value during runtime git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1526 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/flist.h | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/pulsecore/flist.h b/src/pulsecore/flist.h index 102d30ea..177edd6a 100644 --- a/src/pulsecore/flist.h +++ b/src/pulsecore/flist.h @@ -27,6 +27,7 @@ #include #include +#include /* A multiple-reader multipler-write lock-free free list implementation */ @@ -40,20 +41,26 @@ void pa_flist_free(pa_flist *l, pa_free_cb_t free_cb); int pa_flist_push(pa_flist*l, void *p); void* pa_flist_pop(pa_flist*l); -#define PA_STATIC_FLIST_DECLARE(name, size) \ - static struct { \ - pa_flist *flist; \ - pa_once_t once; \ - } name##_static_flist = { NULL, PA_ONCE_INIT }; \ - \ - static void name##_init(void) { \ - name##_static_flist.flist = pa_flist_new(size); \ - } \ - \ - static inline pa_flist* name##_get(void) { \ - pa_once(&name##_static_flist.once, name##_init); \ - return name##_static_flist.flist; \ - } \ +/* Please not that the destructor stuff is not really necesary, we do + * this just to make valgrind output more useful. */ + +#define PA_STATIC_FLIST_DECLARE(name, size, destroy_cb) \ + static struct { \ + pa_flist *flist; \ + pa_once_t once; \ + } name##_static_flist = { NULL, PA_ONCE_INIT }; \ + static void name##_init(void) { \ + name##_static_flist.flist = pa_flist_new(size); \ + } \ + static inline pa_flist* name##_get(void) { \ + pa_once(&name##_static_flist.once, name##_init); \ + return name##_static_flist.flist; \ + } \ + static void name##_destructor(void) PA_GCC_DESTRUCTOR; \ + static void name##_destructor(void) { \ + if (name##_static_flist.flist) \ + pa_flist_free(name##_static_flist.flist, destroy_cb); \ + } \ struct __stupid_useless_struct_to_allow_trailing_semicolon #define PA_STATIC_FLIST_GET(name) (name##_get()) -- cgit From e339d4b9c49a4e0bc56d8d6608b2f55230d42258 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jul 2007 14:44:00 +0000 Subject: update static free list usage in hashmap git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1527 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/hashmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/hashmap.c b/src/pulsecore/hashmap.c index 450f89ca..57be8180 100644 --- a/src/pulsecore/hashmap.c +++ b/src/pulsecore/hashmap.c @@ -56,7 +56,7 @@ struct pa_hashmap { pa_compare_func_t compare_func; }; -PA_STATIC_FLIST_DECLARE(entries, 0); +PA_STATIC_FLIST_DECLARE(entries, 0, pa_xfree); pa_hashmap *pa_hashmap_new(pa_hash_func_t hash_func, pa_compare_func_t compare_func) { pa_hashmap *h; -- cgit From 9cc20b46b7f8eba94f52a563e7781aff90274bef Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jul 2007 14:44:25 +0000 Subject: update static free list usage in asyncmsgq git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1528 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/asyncmsgq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/asyncmsgq.c b/src/pulsecore/asyncmsgq.c index 26714a08..1b6d8025 100644 --- a/src/pulsecore/asyncmsgq.c +++ b/src/pulsecore/asyncmsgq.c @@ -39,7 +39,7 @@ #include "asyncmsgq.h" -PA_STATIC_FLIST_DECLARE(asyncmsgq, 0); +PA_STATIC_FLIST_DECLARE(asyncmsgq, 0, pa_xfree); struct asyncmsgq_item { int code; -- cgit From 068f5d5eef1cab3615f9899e0e458d59e54e95a2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jul 2007 14:46:40 +0000 Subject: drop chunk argument from various drop() functions, since it doesn't make any sense if we want to guarantee always monotonously increasing read pointers; a couple of other fixes git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1529 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-sine.c | 7 +- src/modules/rtp/rtp.c | 2 +- src/pulse/stream.c | 2 +- src/pulsecore/memblock.c | 6 +- src/pulsecore/memblockq.c | 146 ++++++++++++-------------- src/pulsecore/memblockq.h | 13 ++- src/pulsecore/play-memblockq.c | 20 ++-- src/pulsecore/play-memchunk.c | 29 +++--- src/pulsecore/protocol-simple.c | 13 +-- src/pulsecore/sink-input.c | 88 ++++++++++++---- src/pulsecore/sink-input.h | 4 +- src/pulsecore/sink.c | 2 +- src/pulsecore/sound-file-stream.c | 214 +++++++++++++++++++++++++++----------- src/tests/memblockq-test.c | 16 +-- 14 files changed, 343 insertions(+), 219 deletions(-) diff --git a/src/modules/module-sine.c b/src/modules/module-sine.c index b5b7e60b..a784f218 100644 --- a/src/modules/module-sine.c +++ b/src/modules/module-sine.c @@ -73,14 +73,13 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { return 0; } -static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_t length) { +static void sink_input_drop_cb(pa_sink_input *i, size_t length) { struct userdata *u; size_t l; pa_assert(i); u = i->userdata; pa_assert(u); - pa_assert(chunk); pa_assert(length > 0); u->peek_index += length; @@ -93,8 +92,10 @@ static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_ static void sink_input_kill_cb(pa_sink_input *i) { struct userdata *u; - pa_assert(i && i->userdata); + + pa_assert(i); u = i->userdata; + pa_assert(u); pa_sink_input_disconnect(u->sink_input); pa_sink_input_unref(u->sink_input); diff --git a/src/modules/rtp/rtp.c b/src/modules/rtp/rtp.c index f0ab7d8a..31dec653 100644 --- a/src/modules/rtp/rtp.c +++ b/src/modules/rtp/rtp.c @@ -90,7 +90,7 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) { } skip += k; - pa_memblockq_drop(q, &chunk, k); + pa_memblockq_drop(q, k); } if (r < 0 || !chunk.memblock || n >= size || iov_idx >= MAX_IOVECS) { diff --git a/src/pulse/stream.c b/src/pulse/stream.c index 44fce52f..f18a5dde 100644 --- a/src/pulse/stream.c +++ b/src/pulse/stream.c @@ -700,7 +700,7 @@ int pa_stream_drop(pa_stream *s) { PA_CHECK_VALIDITY(s->context, s->direction == PA_STREAM_RECORD, PA_ERR_BADSTATE); PA_CHECK_VALIDITY(s->context, s->peek_memchunk.memblock, PA_ERR_BADSTATE); - pa_memblockq_drop(s->record_memblockq, &s->peek_memchunk, s->peek_memchunk.length); + pa_memblockq_drop(s->record_memblockq, s->peek_memchunk.length); /* Fix the simulated local read index */ if (s->timing_info_valid && !s->timing_info.read_index_corrupt) diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index 8da9cebb..c39147d1 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -150,7 +150,7 @@ struct pa_mempool { static void segment_detach(pa_memimport_segment *seg); -PA_STATIC_FLIST_DECLARE(unused_memblocks, 0); +PA_STATIC_FLIST_DECLARE(unused_memblocks, 0, pa_xfree); /* No lock necessary */ static void stat_add(pa_memblock*b) { @@ -670,8 +670,8 @@ void pa_mempool_free(pa_mempool *p) { pa_mutex_unlock(p->mutex); if (pa_atomic_load(&p->stat.n_allocated) > 0) { - raise(SIGTRAP); - pa_log_warn("WARNING! Memory pool destroyed but not all memory blocks freed!"); +/* raise(SIGTRAP); */ + pa_log_warn("WARNING! Memory pool destroyed but not all memory blocks freed! %u remain.", pa_atomic_load(&p->stat.n_allocated)); } pa_flist_free(p->free_slots, NULL); diff --git a/src/pulsecore/memblockq.c b/src/pulsecore/memblockq.c index 0c31166a..ecdf45b6 100644 --- a/src/pulsecore/memblockq.c +++ b/src/pulsecore/memblockq.c @@ -36,21 +36,24 @@ #include #include #include +#include #include "memblockq.h" -struct memblock_list { - struct memblock_list *next, *prev; +struct list_item { + struct list_item *next, *prev; int64_t index; pa_memchunk chunk; }; +PA_STATIC_FLIST_DECLARE(list_items, 0, pa_xfree); + struct pa_memblockq { - struct memblock_list *blocks, *blocks_tail; + struct list_item *blocks, *blocks_tail; unsigned n_blocks; size_t maxlength, tlength, base, prebuf, minreq; int64_t read_index, write_index; - enum { PREBUF, RUNNING } state; + int in_prebuf; pa_memblock *silence; pa_mcalign *mcalign; }; @@ -77,13 +80,13 @@ pa_memblockq* pa_memblockq_new( bq->read_index = bq->write_index = idx; pa_log_debug("memblockq requested: maxlength=%lu, tlength=%lu, base=%lu, prebuf=%lu, minreq=%lu", - (unsigned long)maxlength, (unsigned long)tlength, (unsigned long)base, (unsigned long)prebuf, (unsigned long)minreq); + (unsigned long) maxlength, (unsigned long) tlength, (unsigned long) base, (unsigned long) prebuf, (unsigned long) minreq); bq->maxlength = ((maxlength+base-1)/base)*base; pa_assert(bq->maxlength >= base); bq->tlength = ((tlength+base-1)/base)*base; - if (!bq->tlength || bq->tlength >= bq->maxlength) + if (bq->tlength <= 0 || bq->tlength > bq->maxlength) bq->tlength = bq->maxlength; bq->prebuf = (prebuf == (size_t) -1) ? bq->tlength/2 : prebuf; @@ -102,7 +105,7 @@ pa_memblockq* pa_memblockq_new( pa_log_debug("memblockq sanitized: maxlength=%lu, tlength=%lu, base=%lu, prebuf=%lu, minreq=%lu", (unsigned long)bq->maxlength, (unsigned long)bq->tlength, (unsigned long)bq->base, (unsigned long)bq->prebuf, (unsigned long)bq->minreq); - bq->state = bq->prebuf ? PREBUF : RUNNING; + bq->in_prebuf = bq->prebuf > 0; bq->silence = silence ? pa_memblock_ref(silence) : NULL; bq->mcalign = NULL; @@ -113,7 +116,7 @@ void pa_memblockq_free(pa_memblockq* bq) { pa_assert(bq); pa_memblockq_flush(bq); - + if (bq->silence) pa_memblock_unref(bq->silence); @@ -123,7 +126,7 @@ void pa_memblockq_free(pa_memblockq* bq) { pa_xfree(bq); } -static void drop_block(pa_memblockq *bq, struct memblock_list *q) { +static void drop_block(pa_memblockq *bq, struct list_item *q) { pa_assert(bq); pa_assert(q); @@ -140,7 +143,9 @@ static void drop_block(pa_memblockq *bq, struct memblock_list *q) { bq->blocks_tail = q->prev; pa_memblock_unref(q->chunk.memblock); - pa_xfree(q); + + if (pa_flist_push(PA_STATIC_FLIST_GET(list_items), q) < 0) + pa_xfree(q); bq->n_blocks--; } @@ -171,7 +176,7 @@ static int can_push(pa_memblockq *bq, size_t l) { int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { - struct memblock_list *q, *n; + struct list_item *q, *n; pa_memchunk chunk; pa_assert(bq); @@ -198,7 +203,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { if (chunk.length > d) { chunk.index += d; chunk.length -= d; - bq->write_index = bq->read_index; + bq->write_index += d; } else { /* We drop the incoming data completely */ bq->write_index += chunk.length; @@ -212,10 +217,10 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { q = bq->blocks_tail; while (q) { - if (bq->write_index >= q->index + (int64_t)q->chunk.length) + if (bq->write_index >= q->index + (int64_t) q->chunk.length) /* We found the entry where we need to place the new entry immediately after */ break; - else if (bq->write_index + (int64_t)chunk.length <= q->index) { + else if (bq->write_index + (int64_t) chunk.length <= q->index) { /* This entry isn't touched at all, let's skip it */ q = q->prev; } else if (bq->write_index <= q->index && @@ -223,7 +228,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { /* This entry is fully replaced by the new entry, so let's drop it */ - struct memblock_list *p; + struct list_item *p; p = q; q = q->prev; drop_block(bq, p); @@ -234,11 +239,13 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { if (bq->write_index + chunk.length < q->index + q->chunk.length) { /* We need to save the end of this memchunk */ - struct memblock_list *p; + struct list_item *p; size_t d; /* Create a new list entry for the end of thie memchunk */ - p = pa_xnew(struct memblock_list, 1); + if (!(p = pa_flist_pop(PA_STATIC_FLIST_GET(list_items)))) + p = pa_xnew(struct list_item, 1); + p->chunk = q->chunk; pa_memblock_ref(p->chunk.memblock); @@ -263,7 +270,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { /* Truncate the chunk */ if (!(q->chunk.length = bq->write_index - q->index)) { - struct memblock_list *p; + struct list_item *p; p = q; q = q->prev; drop_block(bq, p); @@ -287,7 +294,6 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { q = q->prev; } - } if (q) { @@ -308,7 +314,9 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { pa_assert(!bq->blocks || (bq->write_index + (int64_t)chunk.length <= bq->blocks->index)); - n = pa_xnew(struct memblock_list, 1); + if (!(n = pa_flist_pop(PA_STATIC_FLIST_GET(list_items)))) + n = pa_xnew(struct list_item, 1); + n->chunk = chunk; pa_memblock_ref(n->chunk.memblock); n->index = bq->write_index; @@ -331,24 +339,34 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { return 0; } -int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) { +static int memblockq_check_prebuf(pa_memblockq *bq) { pa_assert(bq); - pa_assert(chunk); + + if (bq->in_prebuf) { + + if (pa_memblockq_get_length(bq) < bq->prebuf) + return 1; - if (bq->state == PREBUF) { + bq->in_prebuf = 0; + return 0; + } else { - /* We need to pre-buffer */ - if (pa_memblockq_get_length(bq) < bq->prebuf) - return -1; + if (bq->prebuf > 0 && bq->read_index >= bq->write_index) { + bq->in_prebuf = 1; + return 1; + } - bq->state = RUNNING; + return 0; + } +} - } else if (bq->prebuf > 0 && bq->read_index >= bq->write_index) { +int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) { + pa_assert(bq); + pa_assert(chunk); - /* Buffer underflow protection */ - bq->state = PREBUF; + /* We need to pre-buffer */ + if (memblockq_check_prebuf(bq)) return -1; - } /* Do we need to spit out silence? */ if (!bq->blocks || bq->blocks->index > bq->read_index) { @@ -390,43 +408,16 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) { return 0; } -void pa_memblockq_drop(pa_memblockq *bq, const pa_memchunk *chunk, size_t length) { +void pa_memblockq_drop(pa_memblockq *bq, size_t length) { pa_assert(bq); pa_assert(length % bq->base == 0); - pa_assert(!chunk || length <= chunk->length); - - if (chunk) { - - if (bq->blocks && bq->blocks->index == bq->read_index) { - /* The first item in queue is valid */ - - /* Does the chunk match with what the user supplied us? */ - if (memcmp(chunk, &bq->blocks->chunk, sizeof(pa_memchunk)) != 0) - return; - - } else { - size_t l; - - /* The first item in the queue is not yet relevant */ - - pa_assert(!bq->blocks || bq->blocks->index > bq->read_index); - l = bq->blocks ? bq->blocks->index - bq->read_index : 0; - - if (bq->silence) { - - if (!l || l > pa_memblock_get_length(bq->silence)) - l = pa_memblock_get_length(bq->silence); - - } - - /* Do the entries still match? */ - if (chunk->index != 0 || chunk->length != l || chunk->memblock != bq->silence) - return; - } - } - + while (length > 0) { + /* Do not drop any data when we are in prebuffering mode */ + if (memblockq_check_prebuf(bq)) + break; + if (bq->blocks) { size_t d; @@ -476,15 +467,11 @@ void pa_memblockq_drop(pa_memblockq *bq, const pa_memchunk *chunk, size_t length int pa_memblockq_is_readable(pa_memblockq *bq) { pa_assert(bq); - if (bq->prebuf > 0) { - size_t l = pa_memblockq_get_length(bq); - - if (bq->state == PREBUF && l < bq->prebuf) - return 0; + if (memblockq_check_prebuf(bq)) + return 0; - if (l <= 0) - return 0; - } + if (pa_memblockq_get_length(bq) <= 0) + return 0; return 1; } @@ -506,7 +493,7 @@ size_t pa_memblockq_missing(pa_memblockq *bq) { return 0; l = bq->tlength - l; - return (l >= bq->minreq) ? l : 0; + return l >= bq->minreq ? l : 0; } size_t pa_memblockq_get_minreq(pa_memblockq *bq) { @@ -529,7 +516,7 @@ void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek) { bq->write_index = bq->read_index + offset; return; case PA_SEEK_RELATIVE_END: - bq->write_index = (bq->blocks_tail ? bq->blocks_tail->index + (int64_t)bq->blocks_tail->chunk.length : bq->read_index) + offset; + bq->write_index = (bq->blocks_tail ? bq->blocks_tail->index + (int64_t) bq->blocks_tail->chunk.length : bq->read_index) + offset; return; } @@ -569,7 +556,7 @@ int pa_memblockq_push_align(pa_memblockq* bq, const pa_memchunk *chunk) { pa_memchunk rchunk; pa_assert(bq); - pa_assert(chunk && bq->base); + pa_assert(chunk); if (bq->base == 1) return pa_memblockq_push(bq, chunk); @@ -601,21 +588,20 @@ void pa_memblockq_shorten(pa_memblockq *bq, size_t length) { l = pa_memblockq_get_length(bq); if (l > length) - pa_memblockq_drop(bq, NULL, l - length); + pa_memblockq_drop(bq, l - length); } void pa_memblockq_prebuf_disable(pa_memblockq *bq) { pa_assert(bq); - if (bq->state == PREBUF) - bq->state = RUNNING; + bq->in_prebuf = 0; } void pa_memblockq_prebuf_force(pa_memblockq *bq) { pa_assert(bq); - if (bq->state == RUNNING && bq->prebuf > 0) - bq->state = PREBUF; + if (!bq->in_prebuf && bq->prebuf > 0) + bq->in_prebuf = 1; } size_t pa_memblockq_get_maxlength(pa_memblockq *bq) { diff --git a/src/pulsecore/memblockq.h b/src/pulsecore/memblockq.h index e8243568..5eb23aac 100644 --- a/src/pulsecore/memblockq.h +++ b/src/pulsecore/memblockq.h @@ -83,13 +83,16 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *chunk); * you know what you do. */ int pa_memblockq_push_align(pa_memblockq* bq, const pa_memchunk *chunk); -/* Return a copy of the next memory chunk in the queue. It is not removed from the queue */ +/* Return a copy of the next memory chunk in the queue. It is not + * removed from the queue. There are two reasons this function might + * fail: 1. prebuffering is active, 2. queue is empty and no silence + * memblock was passed at initialization. If the queue is not empty, + * but we're currently at a hole in the queue and no silence memblock + * was passed we return the length of the hole in chunk->length. */ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk); -/* Drop the specified bytes from the queue, but only if the first - * chunk in the queue matches the one passed here. If NULL is passed, - * this check isn't done. */ -void pa_memblockq_drop(pa_memblockq *bq, const pa_memchunk *chunk, size_t length); +/* Drop the specified bytes from the queue. */ +void pa_memblockq_drop(pa_memblockq *bq, size_t length); /* Test if the pa_memblockq is currently readable, that is, more data than base */ int pa_memblockq_is_readable(pa_memblockq *bq); diff --git a/src/pulsecore/play-memblockq.c b/src/pulsecore/play-memblockq.c index 9c5945af..51ea22e8 100644 --- a/src/pulsecore/play-memblockq.c +++ b/src/pulsecore/play-memblockq.c @@ -37,7 +37,7 @@ #include "play-memblockq.h" -static void sink_input_kill(pa_sink_input *i) { +static void sink_input_kill_cb(pa_sink_input *i) { pa_memblockq *q; assert(i); assert(i->userdata); @@ -50,7 +50,7 @@ static void sink_input_kill(pa_sink_input *i) { pa_memblockq_free(q); } -static int sink_input_peek(pa_sink_input *i, pa_memchunk *chunk) { +static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { pa_memblockq *q; assert(i); assert(chunk); @@ -61,11 +61,11 @@ static int sink_input_peek(pa_sink_input *i, pa_memchunk *chunk) { return pa_memblockq_peek(q, chunk); } -static void si_kill(PA_GCC_UNUSED pa_mainloop_api *m, void *i) { - sink_input_kill(i); +static void si_kill_cb(PA_GCC_UNUSED pa_mainloop_api *m, void *i) { + sink_input_kill_cb(i); } -static void sink_input_drop(pa_sink_input *i, const pa_memchunk*chunk, size_t length) { +static void sink_input_drop_cb(pa_sink_input *i, size_t length) { pa_memblockq *q; assert(i); @@ -74,10 +74,10 @@ static void sink_input_drop(pa_sink_input *i, const pa_memchunk*chunk, size_t le q = i->userdata; - pa_memblockq_drop(q, chunk, length); + pa_memblockq_drop(q, length); if (pa_memblockq_get_length(q) <= 0) - pa_mainloop_api_once(i->sink->core->mainloop, si_kill, i); + pa_mainloop_api_once(i->sink->core->mainloop, si_kill_cb, i); } int pa_play_memblockq( @@ -116,9 +116,9 @@ int pa_play_memblockq( if (!(si = pa_sink_input_new(sink->core, &data, 0))) return -1; - si->peek = sink_input_peek; - si->drop = sink_input_drop; - si->kill = sink_input_kill; + si->peek = sink_input_peek_cb; + si->drop = sink_input_drop_cb; + si->kill = sink_input_kill_cb; si->userdata = q; diff --git a/src/pulsecore/play-memchunk.c b/src/pulsecore/play-memchunk.c index 65b6e825..7e750baa 100644 --- a/src/pulsecore/play-memchunk.c +++ b/src/pulsecore/play-memchunk.c @@ -37,7 +37,7 @@ #include "play-memchunk.h" -static void sink_input_kill(pa_sink_input *i) { +static void sink_input_kill_cb(pa_sink_input *i) { pa_memchunk *c; assert(i && i->userdata); c = i->userdata; @@ -49,7 +49,7 @@ static void sink_input_kill(pa_sink_input *i) { pa_xfree(c); } -static int sink_input_peek(pa_sink_input *i, pa_memchunk *chunk) { +static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { pa_memchunk *c; assert(i && chunk && i->userdata); c = i->userdata; @@ -64,23 +64,24 @@ static int sink_input_peek(pa_sink_input *i, pa_memchunk *chunk) { return 0; } -static void si_kill(PA_GCC_UNUSED pa_mainloop_api *m, void *i) { - sink_input_kill(i); +static void si_kill_cb(PA_GCC_UNUSED pa_mainloop_api *m, void *i) { + sink_input_kill_cb(i); } -static void sink_input_drop(pa_sink_input *i, const pa_memchunk*chunk, size_t length) { +static void sink_input_drop_cb(pa_sink_input *i, size_t length) { pa_memchunk *c; assert(i && length && i->userdata); c = i->userdata; - assert(!memcmp(chunk, c, sizeof(chunk))); - assert(length <= c->length); + if (length >= c->length) { + c->length -= length; + c->index += length; + } else { - c->length -= length; - c->index += length; + c->length = 0; - if (c->length <= 0) - pa_mainloop_api_once(i->sink->core->mainloop, si_kill, i); + pa_mainloop_api_once(i->sink->core->mainloop, si_kill_cb, i); + } } int pa_play_memchunk( @@ -113,9 +114,9 @@ int pa_play_memchunk( if (!(si = pa_sink_input_new(sink->core, &data, 0))) return -1; - si->peek = sink_input_peek; - si->drop = sink_input_drop; - si->kill = sink_input_kill; + si->peek = sink_input_peek_cb; + si->drop = sink_input_drop_cb; + si->kill = sink_input_kill_cb; si->userdata = nchunk = pa_xnew(pa_memchunk, 1); *nchunk = *chunk; diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index c423487a..8f9aed58 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -67,7 +67,6 @@ typedef struct connection { PA_DECLARE_CLASS(connection); #define CONNECTION(o) (connection_cast(o)) - static PA_DEFINE_CHECK_TYPE(connection, connection_check_type, pa_msgobject_check_type); struct pa_protocol_simple { @@ -230,7 +229,7 @@ static int do_write(connection *c) { return -1; } - pa_memblockq_drop(c->output_memblockq, &chunk, r); + pa_memblockq_drop(c->output_memblockq, r); return 0; } @@ -271,7 +270,6 @@ fail: static int connection_process_msg(pa_msgobject *o, int code, void*userdata, pa_memchunk *chunk) { connection *c = CONNECTION(o); - connection_assert_ref(c); switch (code) { @@ -351,13 +349,13 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { /* pa_log("peeked %u %i", r >= 0 ? chunk->length: 0, r); */ if (c->dead && r < 0) - pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), MESSAGE_DROP_CONNECTION, c, NULL, NULL); + pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), MESSAGE_DROP_CONNECTION, NULL, NULL, NULL); return r; } /* Called from thread context */ -static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_t length) { +static void sink_input_drop_cb(pa_sink_input *i, size_t length) { connection*c = i->userdata; size_t old, new; @@ -366,7 +364,7 @@ static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_ pa_assert(length); old = pa_memblockq_missing(c->input_memblockq); - pa_memblockq_drop(c->input_memblockq, chunk, length); + pa_memblockq_drop(c->input_memblockq, length); new = pa_memblockq_missing(c->input_memblockq); if (new > old) { @@ -378,9 +376,8 @@ static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_ /* Called from main context */ static void sink_input_kill_cb(pa_sink_input *i) { pa_assert(i); - pa_assert(i->userdata); - connection_drop((connection *) i->userdata); + connection_drop(CONNECTION(i->userdata)); } /*** source_output callbacks ***/ diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index d27f00f0..db98dd54 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -341,7 +341,7 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) /* } */ if (!i->thread_info.resampler) { - do_volume_adj_here = 0; + do_volume_adj_here = 0; /* FIXME??? */ ret = i->peek(i, chunk); goto finish; } @@ -356,15 +356,14 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) if ((ret = i->peek(i, &tchunk)) < 0) goto finish; - pa_assert(tchunk.length); + pa_assert(tchunk.length > 0); l = pa_resampler_request(i->thread_info.resampler, CONVERT_BUFFER_LENGTH); - if (l > tchunk.length) - l = tchunk.length; + if (tchunk.length > l) + tchunk.length = l; - i->drop(i, &tchunk, l); - tchunk.length = l; + i->drop(i, tchunk.length); /* It might be necessary to adjust the volume here */ if (do_volume_adj_here && !volume_is_norm) { @@ -377,7 +376,7 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) } pa_assert(i->thread_info.resampled_chunk.memblock); - pa_assert(i->thread_info.resampled_chunk.length); + pa_assert(i->thread_info.resampled_chunk.length > 0); *chunk = i->thread_info.resampled_chunk; pa_memblock_ref(i->thread_info.resampled_chunk.memblock); @@ -409,7 +408,7 @@ finish: return ret; } -void pa_sink_input_drop(pa_sink_input *i, const pa_memchunk *chunk, size_t length) { +void pa_sink_input_drop(pa_sink_input *i, size_t length) { pa_sink_input_assert_ref(i); pa_assert(length > 0); @@ -440,22 +439,67 @@ void pa_sink_input_drop(pa_sink_input *i, const pa_memchunk *chunk, size_t lengt /* return; */ /* } */ - if (!i->thread_info.resampler) { - if (i->drop) - i->drop(i, chunk, length); - return; - } - - pa_assert(i->thread_info.resampled_chunk.memblock); - pa_assert(i->thread_info.resampled_chunk.length >= length); + pa_log("dropping %u", length); + + if (i->thread_info.resampled_chunk.memblock) { + size_t l = length; + + if (l > i->thread_info.resampled_chunk.length) + l = i->thread_info.resampled_chunk.length; + + pa_log("really dropping %u", l); + + i->thread_info.resampled_chunk.index += l; + i->thread_info.resampled_chunk.length -= l; + + if (i->thread_info.resampled_chunk.length <= 0) { + pa_memblock_unref(i->thread_info.resampled_chunk.memblock); + pa_memchunk_reset(&i->thread_info.resampled_chunk); + } - i->thread_info.resampled_chunk.index += length; - i->thread_info.resampled_chunk.length -= length; + length -= l; + } - if (i->thread_info.resampled_chunk.length <= 0) { - pa_memblock_unref(i->thread_info.resampled_chunk.memblock); - i->thread_info.resampled_chunk.memblock = NULL; - i->thread_info.resampled_chunk.index = i->thread_info.resampled_chunk.length = 0; + pa_log("really remaining %u", length); + + if (length > 0) { + + if (i->thread_info.resampler) { + /* So, we have a resampler. To avoid discontinuities we + * have to actually read all data that could be read and + * pass it through the resampler. */ + + while (length > 0) { + pa_memchunk chunk; + pa_cvolume volume; + + if (pa_sink_input_peek(i, &chunk, &volume) >= 0) { + size_t l = chunk.length; + + if (l > length) + l = length; + + pa_sink_input_drop(i, l); + length -= l; + + } else { + /* Hmmm, peeking failed, so let's at least drop + * the right amount of data */ + + if (i->drop) + i->drop(i, pa_resampler_request(i->thread_info.resampler, length)); + + break; + } + } + + } else { + + /* We have no resampler, hence let's just drop the data */ + + if (i->drop) + i->drop(i, length); + } } } diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index 426e48c0..fe62917a 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -75,7 +75,7 @@ struct pa_sink_input { int muted; int (*peek) (pa_sink_input *i, pa_memchunk *chunk); - void (*drop) (pa_sink_input *i, const pa_memchunk *chunk, size_t length); + void (*drop) (pa_sink_input *i, size_t length); void (*kill) (pa_sink_input *i); /* may be NULL */ pa_usec_t (*get_latency) (pa_sink_input *i); /* may be NULL */ void (*underrun) (pa_sink_input *i); /* may be NULL */ @@ -178,7 +178,7 @@ pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i); /* To be used exclusively by the sink driver thread */ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume); -void pa_sink_input_drop(pa_sink_input *i, const pa_memchunk *chunk, size_t length); +void pa_sink_input_drop(pa_sink_input *i, size_t length); int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk); #endif diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 5a79a41c..a66097bc 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -326,7 +326,7 @@ static void inputs_drop(pa_sink *s, pa_mix_info *info, unsigned n, size_t length } /* Drop read data */ - pa_sink_input_drop(i, m ? &m->chunk : NULL, length); + pa_sink_input_drop(i, length); if (m) { pa_sink_input_unref(m->userdata); diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index 974c053a..c31187c5 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -26,7 +26,6 @@ #endif #include -#include #include #include @@ -41,89 +40,177 @@ #define BUF_SIZE (1024*10) -struct userdata { +typedef struct file_stream { + pa_msgobject parent; + pa_core *core; SNDFILE *sndfile; pa_sink_input *sink_input; pa_memchunk memchunk; sf_count_t (*readf_function)(SNDFILE *sndfile, void *ptr, sf_count_t frames); + size_t drop; +} file_stream; + +enum { + MESSAGE_DROP_FILE_STREAM }; -static void free_userdata(struct userdata *u) { - assert(u); - if (u->sink_input) { - pa_sink_input_disconnect(u->sink_input); - pa_sink_input_unref(u->sink_input); - } +PA_DECLARE_CLASS(file_stream); +#define FILE_STREAM(o) (file_stream_cast(o)) +static PA_DEFINE_CHECK_TYPE(file_stream, file_stream_check_type, pa_msgobject_check_type); + +static void file_stream_free(pa_object *o) { + file_stream *u = FILE_STREAM(o); + pa_assert(u); + pa_log("xxxx ffreee"); + if (u->memchunk.memblock) pa_memblock_unref(u->memchunk.memblock); + if (u->sndfile) sf_close(u->sndfile); pa_xfree(u); } -static void sink_input_kill(pa_sink_input *i) { - assert(i && i->userdata); - free_userdata(i->userdata); -} - -static int sink_input_peek(pa_sink_input *i, pa_memchunk *chunk) { - struct userdata *u; - assert(i && chunk && i->userdata); - u = i->userdata; +static void file_stream_drop(file_stream *u) { + file_stream_assert_ref(u); - if (!u->memchunk.memblock) { - uint32_t fs = pa_frame_size(&i->sample_spec); - sf_count_t n; - void *p; + pa_log("xxxx drop"); + + + if (u->sink_input) { + pa_sink_input_disconnect(u->sink_input); + pa_sink_input_unref(u->sink_input); + u->sink_input = NULL; - u->memchunk.memblock = pa_memblock_new(i->sink->core->mempool, BUF_SIZE); - u->memchunk.index = 0; + /* Make sure we don't decrease the ref count twice. */ + file_stream_unref(u); + } +} - p = pa_memblock_acquire(u->memchunk.memblock); +static int file_stream_process_msg(pa_msgobject *o, int code, void*userdata, pa_memchunk *chunk) { + file_stream *u = FILE_STREAM(o); + file_stream_assert_ref(u); + + switch (code) { + case MESSAGE_DROP_FILE_STREAM: + file_stream_drop(u); + break; + } - if (u->readf_function) { - if ((n = u->readf_function(u->sndfile, p, BUF_SIZE/fs)) <= 0) - n = 0; + return 0; +} - u->memchunk.length = n * fs; - } else { - if ((n = sf_read_raw(u->sndfile, p, BUF_SIZE)) <= 0) - n = 0; +static void sink_input_kill_cb(pa_sink_input *i) { + pa_assert(i); + + file_stream_drop(FILE_STREAM(i->userdata)); +} - u->memchunk.length = n; +static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { + file_stream *u; + + pa_assert(i); + pa_assert(chunk); + u = FILE_STREAM(i->userdata); + file_stream_assert_ref(u); + + for (;;) { + + if (!u->memchunk.memblock) { + + u->memchunk.memblock = pa_memblock_new(i->sink->core->mempool, BUF_SIZE); + u->memchunk.index = 0; + + if (u->readf_function) { + sf_count_t n; + void *p; + size_t fs = pa_frame_size(&i->sample_spec); + + p = pa_memblock_acquire(u->memchunk.memblock); + n = u->readf_function(u->sndfile, p, BUF_SIZE/fs); + pa_memblock_release(u->memchunk.memblock); + + pa_log("%u/%u = data: %02x %02x %02x %02x %02x %02x %02x %02x", + (unsigned int) n, BUF_SIZE/fs, + ((uint8_t*)p)[0], ((uint8_t*)p)[1], ((uint8_t*)p)[2], ((uint8_t*)p)[3], + ((uint8_t*)p)[4], ((uint8_t*)p)[5], ((uint8_t*)p)[6], ((uint8_t*)p)[7]); + + if (n <= 0) + n = 0; + + u->memchunk.length = n * fs; + } else { + sf_count_t n; + void *p; + + p = pa_memblock_acquire(u->memchunk.memblock); + n = sf_read_raw(u->sndfile, p, BUF_SIZE); + pa_memblock_release(u->memchunk.memblock); + + if (n <= 0) + n = 0; + + u->memchunk.length = n; + } + + if (u->memchunk.length <= 0) { + + pa_memblock_unref(u->memchunk.memblock); + pa_memchunk_reset(&u->memchunk); + + pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u), MESSAGE_DROP_FILE_STREAM, NULL, NULL, NULL); + return -1; + } } - pa_memblock_release(u->memchunk.memblock); - if (!u->memchunk.length) { - free_userdata(u); - return -1; + pa_assert(u->memchunk.memblock); + pa_assert(u->memchunk.length > 0); + + if (u->drop < u->memchunk.length) { + u->memchunk.index += u->drop; + u->memchunk.length -= u->drop; + u->drop = 0; + break; } + + u->drop -= u->memchunk.length; + pa_memblock_unref(u->memchunk.memblock); + pa_memchunk_reset(&u->memchunk); } *chunk = u->memchunk; pa_memblock_ref(chunk->memblock); - assert(chunk->length); + + pa_assert(chunk->length > 0); + pa_assert(u->drop <= 0); + return 0; } -static void sink_input_drop(pa_sink_input *i, const pa_memchunk*chunk, size_t length) { - struct userdata *u; - assert(i && chunk && length && i->userdata); - u = i->userdata; +static void sink_input_drop_cb(pa_sink_input *i, size_t length) { + file_stream *u; - assert(!memcmp(chunk, &u->memchunk, sizeof(chunk))); - assert(length <= u->memchunk.length); + pa_assert(i); + pa_assert(length > 0); + u = FILE_STREAM(i->userdata); + file_stream_assert_ref(u); + + if (u->memchunk.memblock) { - u->memchunk.index += length; - u->memchunk.length -= length; + if (length < u->memchunk.length) { + u->memchunk.index += length; + u->memchunk.length -= length; + return; + } - if (u->memchunk.length <= 0) { + length -= u->memchunk.length; pa_memblock_unref(u->memchunk.memblock); - u->memchunk.memblock = NULL; - u->memchunk.index = u->memchunk.length = 0; + pa_memchunk_reset(&u->memchunk); } + + u->drop += length; } int pa_play_file( @@ -131,19 +218,23 @@ int pa_play_file( const char *fname, const pa_cvolume *volume) { - struct userdata *u = NULL; + file_stream *u = NULL; SF_INFO sfinfo; pa_sample_spec ss; pa_sink_input_new_data data; - assert(sink); - assert(fname); + pa_assert(sink); + pa_assert(fname); - u = pa_xnew(struct userdata, 1); + u = pa_msgobject_new(file_stream, file_stream_check_type); + u->parent.parent.free = file_stream_free; + u->parent.process_msg = file_stream_process_msg; + u->core = sink->core; u->sink_input = NULL; - u->memchunk.memblock = NULL; - u->memchunk.index = u->memchunk.length = 0; + pa_memchunk_reset(&u->memchunk); u->sndfile = NULL; + u->readf_function = NULL; + u->drop = 0; memset(&sfinfo, 0, sizeof(sfinfo)); @@ -152,8 +243,6 @@ int pa_play_file( goto fail; } - u->readf_function = NULL; - switch (sfinfo.format & 0xFF) { case SF_FORMAT_PCM_16: case SF_FORMAT_PCM_U8: @@ -195,18 +284,21 @@ int pa_play_file( if (!(u->sink_input = pa_sink_input_new(sink->core, &data, 0))) goto fail; - u->sink_input->peek = sink_input_peek; - u->sink_input->drop = sink_input_drop; - u->sink_input->kill = sink_input_kill; + u->sink_input->peek = sink_input_peek_cb; + u->sink_input->drop = sink_input_drop_cb; + u->sink_input->kill = sink_input_kill_cb; u->sink_input->userdata = u; -/* pa_sink_notify(u->sink_input->sink); */ + pa_sink_input_put(u->sink_input); + + /* The reference to u is dangling here, because we want to keep + * this stream around until it is fully played. */ return 0; fail: if (u) - free_userdata(u); + file_stream_unref(u); return -1; } diff --git a/src/tests/memblockq-test.c b/src/tests/memblockq-test.c index 7ad3b2f3..25ea399b 100644 --- a/src/tests/memblockq-test.c +++ b/src/tests/memblockq-test.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -48,22 +49,22 @@ int main(int argc, char *argv[]) { bq = pa_memblockq_new(0, 40, 10, 2, 4, 4, silence); assert(bq); - chunk1.memblock = pa_memblock_new_fixed(p, (char*) "AA", 2, 1); + chunk1.memblock = pa_memblock_new_fixed(p, (char*) "11", 2, 1); chunk1.index = 0; chunk1.length = 2; assert(chunk1.memblock); - chunk2.memblock = pa_memblock_new_fixed(p, (char*) "TTBB", 4, 1); + chunk2.memblock = pa_memblock_new_fixed(p, (char*) "XX22", 4, 1); chunk2.index = 2; chunk2.length = 2; assert(chunk2.memblock); - chunk3.memblock = pa_memblock_new_fixed(p, (char*) "ZZZZ", 4, 1); + chunk3.memblock = pa_memblock_new_fixed(p, (char*) "3333", 4, 1); chunk3.index = 0; chunk3.length = 4; assert(chunk3.memblock); - chunk4.memblock = pa_memblock_new_fixed(p, (char*) "KKKKKKKK", 8, 1); + chunk4.memblock = pa_memblock_new_fixed(p, (char*) "44444444", 8, 1); chunk4.index = 0; chunk4.length = 8; assert(chunk4.memblock); @@ -115,13 +116,12 @@ int main(int argc, char *argv[]) { chunk3.index += 2; chunk3.length -= 2; - ret = pa_memblockq_push(bq, &chunk3); assert(ret == 0); - printf(">"); + pa_memblockq_shorten(bq, pa_memblockq_get_length(bq)-2); - pa_memblockq_shorten(bq, 6); + printf(">"); for (;;) { pa_memchunk out; @@ -137,7 +137,7 @@ int main(int argc, char *argv[]) { pa_memblock_release(out.memblock); pa_memblock_unref(out.memblock); - pa_memblockq_drop(bq, &out, out.length); + pa_memblockq_drop(bq, out.length); } printf("<\n"); -- cgit From 9e9dc0b14d42ebe5465c5dfa63c9ba29ebbdc410 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jul 2007 15:44:28 +0000 Subject: Simplify implementation of pa_assert_se() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1530 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/macro.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pulsecore/macro.h b/src/pulsecore/macro.h index e0381cf7..fe944ae8 100644 --- a/src/pulsecore/macro.h +++ b/src/pulsecore/macro.h @@ -68,10 +68,11 @@ static inline size_t pa_align(size_t l) { #define pa_assert_not_reached() pa_assert(!"Should not be reached.") /* An assert which guarantees side effects of x */ -#define pa_assert_se(x) do { \ - int _r = !!(x); \ - pa_assert(_r); \ - } while(0) +#ifdef NDEBUG +#define pa_assert_se(x) x +#else +#define pa_assert_se(x) pa_assert(x) +#endif #define PA_PTR_TO_UINT(p) ((unsigned int) (unsigned long) (p)) #define PA_UINT_TO_PTR(u) ((void*) (unsigned long) (u)) -- cgit From 2380ad9254a410235869b18c523787071e2a71d4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jul 2007 15:49:35 +0000 Subject: add our own implementation for pa_snprintf() because NUL termination is apparently not guaranteed on windows and a couple of other libcs git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1531 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core-util.c | 20 +++++++++++++++++++- src/pulsecore/core-util.h | 2 ++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index e5766b2f..98790484 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -83,6 +82,7 @@ #include #include #include +#include #include "core-util.h" @@ -1202,3 +1202,21 @@ int pa_atou(const char *s, uint32_t *ret_u) { return 0; } + +/* Same as snprintf, but guarantees NUL-termination on every platform */ +int pa_snprintf(char *str, size_t size, const char *format, ...) { + int ret; + va_list ap; + + pa_assert(str); + pa_assert(size > 0); + pa_assert(format); + + va_start(ap, format); + ret = vsnprintf(str, size, format, ap); + va_end(ap); + + str[size-1] = 0; + + return ret; +} diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index 1d921e03..a593317d 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -92,4 +92,6 @@ char *pa_runtime_path(const char *fn, char *s, size_t l); int pa_atoi(const char *s, int32_t *ret_i); int pa_atou(const char *s, uint32_t *ret_u); +int pa_snprintf(char *str, size_t size, const char *format, ...); + #endif -- cgit From 2a43bbf206ea513af77a83c20496ebf99d0ebe5f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jul 2007 15:50:09 +0000 Subject: Modernize things a little git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1532 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/authkey.c | 66 ++++++++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/src/pulsecore/authkey.c b/src/pulsecore/authkey.c index a6150d0e..1476482d 100644 --- a/src/pulsecore/authkey.c +++ b/src/pulsecore/authkey.c @@ -26,7 +26,6 @@ #include #endif -#include #include #include #include @@ -43,13 +42,17 @@ #include #include #include +#include #include "authkey.h" /* Generate a new authorization key, store it in file fd and return it in *data */ static int generate(int fd, void *ret_data, size_t length) { ssize_t r; - assert(fd >= 0 && ret_data && length); + + pa_assert(fd >= 0); + pa_assert(ret_data); + pa_assert(length > 0); pa_random(ret_data, length); @@ -57,7 +60,7 @@ static int generate(int fd, void *ret_data, size_t length) { ftruncate(fd, 0); if ((r = pa_loop_write(fd, ret_data, length, NULL)) < 0 || (size_t) r != length) { - pa_log("failed to write cookie file: %s", pa_cstrerror(errno)); + pa_log("Failed to write cookie file: %s", pa_cstrerror(errno)); return -1; } @@ -75,11 +78,15 @@ static int load(const char *fn, void *data, size_t length) { int writable = 1; int unlock = 0, ret = -1; ssize_t r; - assert(fn && data && length); - - if ((fd = open(fn, O_RDWR|O_CREAT|O_BINARY, S_IRUSR|S_IWUSR)) < 0) { - if (errno != EACCES || (fd = open(fn, O_RDONLY|O_BINARY)) < 0) { - pa_log("failed to open cookie file '%s': %s", fn, pa_cstrerror(errno)); + + pa_assert(fn); + pa_assert(data); + pa_assert(length > 0); + + if ((fd = open(fn, O_RDWR|O_CREAT|O_BINARY|O_NOCTTY, S_IRUSR|S_IWUSR)) < 0) { + + if (errno != EACCES || (fd = open(fn, O_RDONLY|O_BINARY|O_NOCTTY)) < 0) { + pa_log("Failed to open cookie file '%s': %s", fn, pa_cstrerror(errno)); goto finish; } else writable = 0; @@ -88,15 +95,15 @@ static int load(const char *fn, void *data, size_t length) { unlock = pa_lock_fd(fd, 1) >= 0; if ((r = pa_loop_read(fd, data, length, NULL)) < 0) { - pa_log("failed to read cookie file '%s': %s", fn, pa_cstrerror(errno)); + pa_log("Failed to read cookie file '%s': %s", fn, pa_cstrerror(errno)); goto finish; } if ((size_t) r != length) { - pa_log_debug("got %d bytes from cookie file '%s', expected %d", (int)r, fn, (int)length); + pa_log_debug("Got %d bytes from cookie file '%s', expected %d", (int) r, fn, (int) length); if (!writable) { - pa_log("unable to write cookie to read only file"); + pa_log("Unable to write cookie to read only file"); goto finish; } @@ -123,13 +130,12 @@ finish: int pa_authkey_load(const char *path, void *data, size_t length) { int ret; - assert(path && data && length); - - ret = load(path, data, length); + pa_assert(path); + pa_assert(data); + pa_assert(length > 0); - if (ret < 0) - pa_log("Failed to load authorization key '%s': %s", path, - (ret == -1) ? pa_cstrerror(errno) : "file corrupt"); + if ((ret = load(path, data, length)) < 0) + pa_log("Failed to load authorization key '%s': %s", path, (ret < 0) ? pa_cstrerror(errno) : "File corrupt"); return ret; } @@ -137,7 +143,10 @@ int pa_authkey_load(const char *path, void *data, size_t length) { /* If the specified file path starts with / return it, otherwise * return path prepended with home directory */ static const char *normalize_path(const char *fn, char *s, size_t l) { - assert(fn && s && l > 0); + + pa_assert(fn); + pa_assert(s); + pa_assert(l > 0); #ifndef OS_IS_WIN32 if (fn[0] != '/') { @@ -145,13 +154,14 @@ static const char *normalize_path(const char *fn, char *s, size_t l) { if (strlen(fn) < 3 || !isalpha(fn[0]) || fn[1] != ':' || fn[2] != '\\') { #endif char homedir[PATH_MAX]; + if (!pa_get_home_dir(homedir, sizeof(homedir))) return NULL; #ifndef OS_IS_WIN32 - snprintf(s, l, "%s/%s", homedir, fn); + pa_snprintf(s, l, "%s/%s", homedir, fn); #else - snprintf(s, l, "%s\\%s", homedir, fn); + pa_snprintf(s, l, "%s\\%s", homedir, fn); #endif return s; } @@ -164,7 +174,10 @@ static const char *normalize_path(const char *fn, char *s, size_t l) { int pa_authkey_load_auto(const char *fn, void *data, size_t length) { char path[PATH_MAX]; const char *p; - assert(fn && data && length); + + pa_assert(fn); + pa_assert(data); + pa_assert(length > 0); if (!(p = normalize_path(fn, path, sizeof(path)))) return -2; @@ -179,20 +192,23 @@ int pa_authkey_save(const char *fn, const void *data, size_t length) { ssize_t r; char path[PATH_MAX]; const char *p; - assert(fn && data && length); + + pa_assert(fn); + pa_assert(data); + pa_assert(length > 0); if (!(p = normalize_path(fn, path, sizeof(path)))) return -2; - if ((fd = open(p, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR)) < 0) { - pa_log("failed to open cookie file '%s': %s", fn, pa_cstrerror(errno)); + if ((fd = open(p, O_RDWR|O_CREAT|O_NOCTTY, S_IRUSR|S_IWUSR)) < 0) { + pa_log("Failed to open cookie file '%s': %s", fn, pa_cstrerror(errno)); goto finish; } unlock = pa_lock_fd(fd, 1) >= 0; if ((r = pa_loop_write(fd, data, length, NULL)) < 0 || (size_t) r != length) { - pa_log("failed to read cookie file '%s': %s", fn, pa_cstrerror(errno)); + pa_log("Failed to read cookie file '%s': %s", fn, pa_cstrerror(errno)); goto finish; } -- cgit From 8e838381541d090b5bfd0d68acefd2d6676f0d64 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jul 2007 15:50:40 +0000 Subject: Modernize things a little bith more git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1533 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sound-file.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/pulsecore/sound-file.c b/src/pulsecore/sound-file.c index 6e93f8aa..416ae93e 100644 --- a/src/pulsecore/sound-file.c +++ b/src/pulsecore/sound-file.c @@ -26,31 +26,35 @@ #endif #include -#include #include #include #include +#include #include "sound-file.h" #include "core-scache.h" -int pa_sound_file_load(pa_mempool *pool, const char *fname, pa_sample_spec *ss, pa_channel_map *map, pa_memchunk *chunk) { - SNDFILE*sf = NULL; +int pa_sound_file_load( + pa_mempool *pool, + const char *fname, + pa_sample_spec *ss, + pa_channel_map *map, + pa_memchunk *chunk) { + + SNDFILE *sf = NULL; SF_INFO sfinfo; int ret = -1; size_t l; sf_count_t (*readf_function)(SNDFILE *sndfile, void *ptr, sf_count_t frames) = NULL; void *ptr = NULL; - assert(fname); - assert(ss); - assert(chunk); - - chunk->memblock = NULL; - chunk->index = chunk->length = 0; + pa_assert(fname); + pa_assert(ss); + pa_assert(chunk); + pa_memchunk_reset(chunk); memset(&sfinfo, 0, sizeof(sfinfo)); if (!(sf = sf_open(fname, SFM_READ, &sfinfo))) { @@ -93,13 +97,12 @@ int pa_sound_file_load(pa_mempool *pool, const char *fname, pa_sample_spec *ss, if (map) pa_channel_map_init_auto(map, ss->channels, PA_CHANNEL_MAP_DEFAULT); - if ((l = pa_frame_size(ss)*sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) { + if ((l = pa_frame_size(ss) * sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) { pa_log("File too large"); goto finish; } chunk->memblock = pa_memblock_new(pool, l); - assert(chunk->memblock); chunk->index = 0; chunk->length = l; @@ -125,17 +128,19 @@ finish: pa_memblock_unref(chunk->memblock); return ret; - } int pa_sound_file_too_big_to_cache(const char *fname) { + SNDFILE*sf = NULL; SF_INFO sfinfo; pa_sample_spec ss; + pa_assert(fname); + if (!(sf = sf_open(fname, SFM_READ, &sfinfo))) { pa_log("Failed to open file %s", fname); - return 0; + return -1; } sf_close(sf); @@ -165,8 +170,13 @@ int pa_sound_file_too_big_to_cache(const char *fname) { ss.rate = sfinfo.samplerate; ss.channels = sfinfo.channels; + if (!pa_sample_spec_valid(&ss)) { + pa_log("Unsupported sample format in file %s", fname); + return -1; + } + if ((pa_frame_size(&ss) * sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) { - pa_log("File too large %s", fname); + pa_log("File too large: %s", fname); return 1; } -- cgit From 929526de33b60ba48e47071be60619616661c97f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jul 2007 16:23:03 +0000 Subject: Convert most snprintf() calls to pa_snprintf() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1534 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 2 +- src/daemon/cpulimit.c | 2 +- src/daemon/dumpmodules.c | 5 +++-- src/modules/gconf/gconf-helper.c | 10 ++++++---- src/modules/module-combine.c | 2 +- src/modules/module-detect.c | 10 +++++----- src/modules/module-hal-detect.c | 6 +++--- src/modules/module-sine.c | 3 ++- src/modules/module-tunnel.c | 4 ++-- src/pulse/browser.c | 4 ++-- src/pulse/channelmap.c | 2 +- src/pulse/context.c | 2 +- src/pulse/sample.c | 13 +++++++------ src/pulse/util.c | 2 +- src/pulse/volume.c | 3 ++- src/pulsecore/core-scache.c | 2 +- src/pulsecore/core-util.c | 17 ++++++++++------- src/pulsecore/inet_ntop.c | 4 ++-- src/pulsecore/namereg.c | 2 +- src/pulsecore/pdispatch.c | 2 +- src/pulsecore/pid.c | 2 +- src/pulsecore/protocol-esound.c | 4 ++-- src/pulsecore/protocol-http.c | 4 ++-- src/pulsecore/protocol-native.c | 2 +- src/pulsecore/shm.c | 3 ++- src/pulsecore/socket-client.c | 2 +- src/pulsecore/socket-server.c | 14 +++++++------- src/pulsecore/socket-util.c | 14 +++++++------- src/pulsecore/strbuf.c | 1 + src/pulsecore/x11wrap.c | 3 ++- 30 files changed, 79 insertions(+), 67 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 2e37b295..cda35733 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1292,7 +1292,7 @@ module_gconf_la_LIBADD = $(AM_LIBADD) libpulsecore.la module_gconf_la_CFLAGS = $(AM_CFLAGS) -DPA_GCONF_HELPER=\"$(pulselibexecdir)/gconf-helper\" gconf_helper_SOURCES = modules/gconf/gconf-helper.c -gconf_helper_LDADD = $(AM_LDADD) $(GCONF_LIBS) +gconf_helper_LDADD = $(AM_LDADD) $(GCONF_LIBS) libpulsecore.la gconf_helper_CFLAGS = $(AM_CFLAGS) $(GCONF_CFLAGS) gconf_helper_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) diff --git a/src/daemon/cpulimit.c b/src/daemon/cpulimit.c index d4ac1d86..6536f468 100644 --- a/src/daemon/cpulimit.c +++ b/src/daemon/cpulimit.c @@ -130,7 +130,7 @@ static void signal_handler(int sig) { time(&now); #ifdef PRINT_CPU_LOAD - snprintf(t, sizeof(t), "Using %0.1f%% CPU\n", (double)CPUTIME_INTERVAL_SOFT/(now-last_time)*100); + pa_snprintf(t, sizeof(t), "Using %0.1f%% CPU\n", (double)CPUTIME_INTERVAL_SOFT/(now-last_time)*100); write_err(t); #endif diff --git a/src/daemon/dumpmodules.c b/src/daemon/dumpmodules.c index 6743622a..cbbf94f3 100644 --- a/src/daemon/dumpmodules.c +++ b/src/daemon/dumpmodules.c @@ -35,6 +35,7 @@ #include #include +#include #include "dumpmodules.h" @@ -93,7 +94,7 @@ static int is_preloaded(const char *name) { if (l->address) continue; - snprintf(buf, sizeof(buf), "%s", l->name); + pa_snprintf(buf, sizeof(buf), "%s", l->name); if ((e = strrchr(buf, '.'))) *e = 0; @@ -137,7 +138,7 @@ void pa_dump_modules(pa_daemon_conf *c, int argc, char * const argv[]) { if (strlen(l->name) <= sizeof(PREFIX)-1 || strncmp(l->name, PREFIX, sizeof(PREFIX)-1)) continue; - snprintf(buf, sizeof(buf), "%s", l->name); + pa_snprintf(buf, sizeof(buf), "%s", l->name); if ((e = strrchr(buf, '.'))) *e = 0; diff --git a/src/modules/gconf/gconf-helper.c b/src/modules/gconf/gconf-helper.c index 3483b845..abd13287 100644 --- a/src/modules/gconf/gconf-helper.c +++ b/src/modules/gconf/gconf-helper.c @@ -32,6 +32,8 @@ #include #include +#include + #define PA_GCONF_ROOT "/system/pulseaudio" #define PA_GCONF_PATH_MODULES PA_GCONF_ROOT"/modules" @@ -40,13 +42,13 @@ static void handle_module(GConfClient *client, const char *name) { gboolean enabled, locked; int i; - snprintf(p, sizeof(p), PA_GCONF_PATH_MODULES"/%s/locked", name); + pa_snprintf(p, sizeof(p), PA_GCONF_PATH_MODULES"/%s/locked", name); locked = gconf_client_get_bool(client, p, FALSE); if (locked) return; - snprintf(p, sizeof(p), PA_GCONF_PATH_MODULES"/%s/enabled", name); + pa_snprintf(p, sizeof(p), PA_GCONF_PATH_MODULES"/%s/enabled", name); enabled = gconf_client_get_bool(client, p, FALSE); printf("%c%s%c", enabled ? '+' : '-', name, 0); @@ -56,11 +58,11 @@ static void handle_module(GConfClient *client, const char *name) { for (i = 0; i < 10; i++) { gchar *n, *a; - snprintf(p, sizeof(p), PA_GCONF_PATH_MODULES"/%s/name%i", name, i); + pa_snprintf(p, sizeof(p), PA_GCONF_PATH_MODULES"/%s/name%i", name, i); if (!(n = gconf_client_get_string(client, p, NULL)) || !*n) break; - snprintf(p, sizeof(p), PA_GCONF_PATH_MODULES"/%s/args%i", name, i); + pa_snprintf(p, sizeof(p), PA_GCONF_PATH_MODULES"/%s/args%i", name, i); a = gconf_client_get_string(client, p, NULL); printf("%s%c%s%c", n, 0, a ? a : "", 0); diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 716c20b2..b6d718de 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -251,7 +251,7 @@ static struct output *output_new(struct userdata *u, pa_sink *sink, int resample 0, NULL); - snprintf(t, sizeof(t), "Output stream #%u of sink %s", u->n_outputs+1, u->sink->name); + pa_snprintf(t, sizeof(t), "Output stream #%u of sink %s", u->n_outputs+1, u->sink->name); pa_sink_input_new_data_init(&data); data.sink = sink; diff --git a/src/modules/module-detect.c b/src/modules/module-detect.c index 29d6fc27..190cda9d 100644 --- a/src/modules/module-detect.c +++ b/src/modules/module-detect.c @@ -96,7 +96,7 @@ static int detect_alsa(pa_core *c, int just_one) { if (subdevice != 0) continue; - snprintf(args, sizeof(args), "device=hw:%u", device); + pa_snprintf(args, sizeof(args), "device=hw:%u", device); if (!pa_module_load(c, is_sink ? "module-alsa-sink" : "module-alsa-source", args)) continue; @@ -148,16 +148,16 @@ static int detect_oss(pa_core *c, int just_one) { if (sscanf(line, "%u: ", &device) == 1) { if (device == 0) - snprintf(args, sizeof(args), "device=/dev/dsp"); + pa_snprintf(args, sizeof(args), "device=/dev/dsp"); else - snprintf(args, sizeof(args), "device=/dev/dsp%u", device); + pa_snprintf(args, sizeof(args), "device=/dev/dsp%u", device); if (!pa_module_load(c, "module-oss", args)) continue; } else if (sscanf(line, "pcm%u: ", &device) == 1) { /* FreeBSD support, the devices are named /dev/dsp0.0, dsp0.1 and so on */ - snprintf(args, sizeof(args), "device=/dev/dsp%u.0", device); + pa_snprintf(args, sizeof(args), "device=/dev/dsp%u.0", device); if (!pa_module_load(c, "module-oss", args)) continue; @@ -193,7 +193,7 @@ static int detect_solaris(pa_core *c, int just_one) { if (!S_ISCHR(s.st_mode)) return 0; - snprintf(args, sizeof(args), "device=%s", dev); + pa_snprintf(args, sizeof(args), "device=%s", dev); if (!pa_module_load(c, "module-solaris", args)) return 0; diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index 1f48a452..6ae9cd0c 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -182,10 +182,10 @@ static pa_module* hal_device_load_alsa(struct userdata *u, const char *udi, if (type == ALSA_TYPE_SINK) { module_name = "module-alsa-sink"; - snprintf(args, sizeof(args), "device=hw:%u sink_name=alsa_output.%s", card, strip_udi(udi)); + pa_snprintf(args, sizeof(args), "device=hw:%u sink_name=alsa_output.%s", card, strip_udi(udi)); } else { module_name = "module-alsa-source"; - snprintf(args, sizeof(args), "device=hw:%u source_name=alsa_input.%s", card, strip_udi(udi)); + pa_snprintf(args, sizeof(args), "device=hw:%u source_name=alsa_input.%s", card, strip_udi(udi)); } pa_log_debug("Loading %s with arguments '%s'", module_name, args); @@ -244,7 +244,7 @@ static pa_module* hal_device_load_oss(struct userdata *u, const char *udi, if (!device || dbus_error_is_set(error)) return NULL; - snprintf(args, sizeof(args), "device=%s sink_name=oss_output.%s source_name=oss_input.%s", device, strip_udi(udi), strip_udi(udi)); + pa_snprintf(args, sizeof(args), "device=%s sink_name=oss_output.%s source_name=oss_input.%s", device, strip_udi(udi), strip_udi(udi)); libhal_free_string(device); pa_log_debug("Loading module-oss with arguments '%s'", args); diff --git a/src/modules/module-sine.c b/src/modules/module-sine.c index a784f218..797ba440 100644 --- a/src/modules/module-sine.c +++ b/src/modules/module-sine.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "module-sine-symdef.h" @@ -155,7 +156,7 @@ int pa__init(pa_core *c, pa_module*m) { calc_sine(p, pa_memblock_get_length(u->memblock), frequency); pa_memblock_release(u->memblock); - snprintf(t, sizeof(t), "Sine Generator at %u Hz", frequency); + pa_snprintf(t, sizeof(t), "Sine Generator at %u Hz", frequency); pa_sink_input_new_data_init(&data); data.sink = sink; diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c index 288e049e..b96d46b3 100644 --- a/src/modules/module-tunnel.c +++ b/src/modules/module-tunnel.c @@ -596,12 +596,12 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t } #ifdef TUNNEL_SINK - snprintf(name, sizeof(name), "Tunnel from host %s, user %s, sink %s", + pa_snprintf(name, sizeof(name), "Tunnel from host %s, user %s, sink %s", pa_get_host_name(hn, sizeof(hn)), pa_get_user_name(un, sizeof(un)), u->sink->name); #else - snprintf(name, sizeof(name), "Tunnel from host %s, user %s, source %s", + pa_snprintf(name, sizeof(name), "Tunnel from host %s, user %s, source %s", pa_get_host_name(hn, sizeof(hn)), pa_get_user_name(un, sizeof(un)), u->source->name); diff --git a/src/pulse/browser.c b/src/pulse/browser.c index ea2706e4..a35fe810 100644 --- a/src/pulse/browser.c +++ b/src/pulse/browser.c @@ -112,10 +112,10 @@ static void resolve_callback( assert(opcode >= 0); if (aa->proto == AVAHI_PROTO_INET) - snprintf(a, sizeof(a), "tcp:%s:%u", avahi_address_snprint(ip, sizeof(ip), aa), port); + pa_snprintf(a, sizeof(a), "tcp:%s:%u", avahi_address_snprint(ip, sizeof(ip), aa), port); else { assert(aa->proto == AVAHI_PROTO_INET6); - snprintf(a, sizeof(a), "tcp6:%s:%u", avahi_address_snprint(ip, sizeof(ip), aa), port); + pa_snprintf(a, sizeof(a), "tcp6:%s:%u", avahi_address_snprint(ip, sizeof(ip), aa), port); } i.server = a; diff --git a/src/pulse/channelmap.c b/src/pulse/channelmap.c index d5b8f743..5f1fa95f 100644 --- a/src/pulse/channelmap.c +++ b/src/pulse/channelmap.c @@ -370,7 +370,7 @@ char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map) { *(e = s) = 0; for (channel = 0; channel < map->channels && l > 1; channel++) { - l -= snprintf(e, l, "%s%s", + l -= pa_snprintf(e, l, "%s%s", first ? "" : ",", pa_channel_position_to_string(map->map[channel])); diff --git a/src/pulse/context.c b/src/pulse/context.c index 58a5a879..0dba9051 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -535,7 +535,7 @@ static int context_connect_spawn(pa_context *c) { argv[n++] = c->conf->daemon_binary; argv[n++] = "--daemonize=yes"; - snprintf(t, sizeof(t), "-Lmodule-native-protocol-fd fd=%i", fds[1]); + pa_snprintf(t, sizeof(t), "-Lmodule-native-protocol-fd fd=%i", fds[1]); argv[n++] = strdup(t); while (n < MAX_ARGS) { diff --git a/src/pulse/sample.c b/src/pulse/sample.c index ffdeedf7..3d449f53 100644 --- a/src/pulse/sample.c +++ b/src/pulse/sample.c @@ -31,6 +31,7 @@ #include #include +#include #include "sample.h" size_t pa_sample_size(const pa_sample_spec *spec) { @@ -117,22 +118,22 @@ char *pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec) { assert(s && l && spec); if (!pa_sample_spec_valid(spec)) - snprintf(s, l, "Invalid"); + pa_snprintf(s, l, "Invalid"); else - snprintf(s, l, "%s %uch %uHz", pa_sample_format_to_string(spec->format), spec->channels, spec->rate); + pa_snprintf(s, l, "%s %uch %uHz", pa_sample_format_to_string(spec->format), spec->channels, spec->rate); return s; } char* pa_bytes_snprint(char *s, size_t l, unsigned v) { if (v >= ((unsigned) 1024)*1024*1024) - snprintf(s, l, "%0.1f GiB", ((double) v)/1024/1024/1024); + pa_snprintf(s, l, "%0.1f GiB", ((double) v)/1024/1024/1024); else if (v >= ((unsigned) 1024)*1024) - snprintf(s, l, "%0.1f MiB", ((double) v)/1024/1024); + pa_snprintf(s, l, "%0.1f MiB", ((double) v)/1024/1024); else if (v >= (unsigned) 1024) - snprintf(s, l, "%0.1f KiB", ((double) v)/1024); + pa_snprintf(s, l, "%0.1f KiB", ((double) v)/1024); else - snprintf(s, l, "%u B", (unsigned) v); + pa_snprintf(s, l, "%u B", (unsigned) v); return s; } diff --git a/src/pulse/util.c b/src/pulse/util.c index d561329c..c4f2cf78 100644 --- a/src/pulse/util.c +++ b/src/pulse/util.c @@ -90,7 +90,7 @@ char *pa_get_user_name(char *s, size_t l) { * that do not support getpwuid_r. */ if ((r = getpwuid(getuid())) == NULL) { #endif - snprintf(s, l, "%lu", (unsigned long) getuid()); + pa_snprintf(s, l, "%lu", (unsigned long) getuid()); return s; } diff --git a/src/pulse/volume.c b/src/pulse/volume.c index feb33f07..8bba834d 100644 --- a/src/pulse/volume.c +++ b/src/pulse/volume.c @@ -29,6 +29,7 @@ #include #include +#include #include "volume.h" int pa_cvolume_equal(const pa_cvolume *a, const pa_cvolume *b) { @@ -125,7 +126,7 @@ char *pa_cvolume_snprint(char *s, size_t l, const pa_cvolume *c) { *(e = s) = 0; for (channel = 0; channel < c->channels && l > 1; channel++) { - l -= snprintf(e, l, "%s%u: %3u%%", + l -= pa_snprintf(e, l, "%s%u: %3u%%", first ? "" : " ", channel, (c->values[channel]*100)/PA_VOLUME_NORM); diff --git a/src/pulsecore/core-scache.c b/src/pulsecore/core-scache.c index cb272784..d5fe6f20 100644 --- a/src/pulsecore/core-scache.c +++ b/src/pulsecore/core-scache.c @@ -415,7 +415,7 @@ int pa_scache_add_directory_lazy(pa_core *c, const char *pathname) { if (e->d_name[0] == '.') continue; - snprintf(p, sizeof(p), "%s/%s", pathname, e->d_name); + pa_snprintf(p, sizeof(p), "%s/%s", pathname, e->d_name); add_file(c, p); } } diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 98790484..e61be704 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -431,6 +431,8 @@ char *pa_sprintf_malloc(const char *format, ...) { r = vsnprintf(c, size, format, ap); va_end(ap); + c[size-1] = 0; + if (r > -1 && r < size) return c; @@ -453,13 +455,14 @@ char *pa_vsprintf_malloc(const char *format, va_list ap) { int r; va_list aq; - va_copy(aq, ap); - c = pa_xrealloc(c, size); - r = vsnprintf(c, size, format, aq); + va_copy(aq, ap); + r = vsnprintf(c, size, format, aq); va_end(aq); + c[size-1] = 0; + if (r > -1 && r < size) return c; @@ -1146,17 +1149,17 @@ char *pa_runtime_path(const char *fn, char *s, size_t l) { if ((e = getenv("PULSE_RUNTIME_PATH"))) { if (fn) - snprintf(s, l, "%s%c%s", e, PATH_SEP, fn); + pa_snprintf(s, l, "%s%c%s", e, PATH_SEP, fn); else - snprintf(s, l, "%s", e); + pa_snprintf(s, l, "%s", e); } else { char u[256]; if (fn) - snprintf(s, l, "%s%s%c%s", PA_USER_RUNTIME_PATH_PREFIX, pa_get_user_name(u, sizeof(u)), PATH_SEP, fn); + pa_snprintf(s, l, "%s%s%c%s", PA_USER_RUNTIME_PATH_PREFIX, pa_get_user_name(u, sizeof(u)), PATH_SEP, fn); else - snprintf(s, l, "%s%s", PA_USER_RUNTIME_PATH_PREFIX, pa_get_user_name(u, sizeof(u))); + pa_snprintf(s, l, "%s%s", PA_USER_RUNTIME_PATH_PREFIX, pa_get_user_name(u, sizeof(u))); } diff --git a/src/pulsecore/inet_ntop.c b/src/pulsecore/inet_ntop.c index 302369f7..041bc09b 100644 --- a/src/pulsecore/inet_ntop.c +++ b/src/pulsecore/inet_ntop.c @@ -47,7 +47,7 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) { switch (af) { case AF_INET: - snprintf(dst, cnt, "%d.%d.%d.%d", + pa_snprintf(dst, cnt, "%d.%d.%d.%d", #ifdef WORDS_BIGENDIAN (int)(in->s_addr >> 24) & 0xff, (int)(in->s_addr >> 16) & 0xff, @@ -61,7 +61,7 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) { #endif break; case AF_INET6: - snprintf(dst, cnt, "%x:%x:%x:%x:%x:%x:%x:%x", + pa_snprintf(dst, cnt, "%x:%x:%x:%x:%x:%x:%x:%x", in6->s6_addr[ 0] << 8 | in6->s6_addr[ 1], in6->s6_addr[ 2] << 8 | in6->s6_addr[ 3], in6->s6_addr[ 4] << 8 | in6->s6_addr[ 5], diff --git a/src/pulsecore/namereg.c b/src/pulsecore/namereg.c index 7f66af05..5fae3fc3 100644 --- a/src/pulsecore/namereg.c +++ b/src/pulsecore/namereg.c @@ -142,7 +142,7 @@ const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t k = pa_xnew(char, l+4); for (i = 2; i <= 99; i++) { - snprintf(k, l+4, "%s.%u", name, i); + pa_snprintf(k, l+4, "%s.%u", name, i); if (!(e = pa_hashmap_get(c->namereg, k))) break; diff --git a/src/pulsecore/pdispatch.c b/src/pulsecore/pdispatch.c index 10238acb..f5ec1c09 100644 --- a/src/pulsecore/pdispatch.c +++ b/src/pulsecore/pdispatch.c @@ -206,7 +206,7 @@ int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*packet, const pa_creds *creds, char t[256]; char const *p; if (!(p = command_names[command])) - snprintf((char*) (p = t), sizeof(t), "%u", command); + pa_snprintf((char*) (p = t), sizeof(t), "%u", command); pa_log("Recieved opcode <%s>", p); } diff --git a/src/pulsecore/pid.c b/src/pulsecore/pid.c index 5e670e17..efb6e64e 100644 --- a/src/pulsecore/pid.c +++ b/src/pulsecore/pid.c @@ -172,7 +172,7 @@ int pa_pid_file_create(void) { goto fail; } - snprintf(t, sizeof(t), "%lu\n", (unsigned long) getpid()); + pa_snprintf(t, sizeof(t), "%lu\n", (unsigned long) getpid()); l = strlen(t); if (pa_loop_write(fd, t, l, NULL) != (ssize_t) l) { diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c index 6a5c6127..fe0b879b 100644 --- a/src/pulsecore/protocol-esound.c +++ b/src/pulsecore/protocol-esound.c @@ -626,7 +626,7 @@ static int esd_proto_all_info(struct connection *c, esd_proto_t request, const v if (strncmp(ce->name, SCACHE_PREFIX, sizeof(SCACHE_PREFIX)-1) == 0) strncpy(name, ce->name+sizeof(SCACHE_PREFIX)-1, ESD_NAME_MAX); else - snprintf(name, ESD_NAME_MAX, "native.%s", ce->name); + pa_snprintf(name, ESD_NAME_MAX, "native.%s", ce->name); connection_write(c, name, ESD_NAME_MAX); /* rate */ @@ -1194,7 +1194,7 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) pa_iochannel_set_callback(c->io, io_callback, c); pa_iochannel_socket_peer_to_string(io, pname, sizeof(pname)); - snprintf(cname, sizeof(cname), "EsounD client (%s)", pname); + pa_snprintf(cname, sizeof(cname), "EsounD client (%s)", pname); assert(p->core); c->client = pa_client_new(p->core, __FILE__, cname); assert(c->client); diff --git a/src/pulsecore/protocol-http.c b/src/pulsecore/protocol-http.c index 3541721a..eb5bda0d 100644 --- a/src/pulsecore/protocol-http.c +++ b/src/pulsecore/protocol-http.c @@ -69,7 +69,7 @@ static void http_response(struct connection *c, int code, const char *msg, const assert(msg); assert(mime); - snprintf(s, sizeof(s), + pa_snprintf(s, sizeof(s), "HTTP/1.0 %i %s\n" "Connection: close\n" "Content-Type: %s\n" @@ -90,7 +90,7 @@ static void http_message(struct connection *c, int code, const char *msg, const if (!text) text = msg; - snprintf(s, sizeof(s), + pa_snprintf(s, sizeof(s), "\n" "\n" "%s\n" diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 86455693..97345f00 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -2381,7 +2381,7 @@ static void on_connection(PA_GCC_UNUSED pa_socket_server*s, pa_iochannel *io, vo c->version = 8; c->protocol = p; pa_iochannel_socket_peer_to_string(io, pname, sizeof(pname)); - snprintf(cname, sizeof(cname), "Native client (%s)", pname); + pa_snprintf(cname, sizeof(cname), "Native client (%s)", pname); assert(p->core); c->client = pa_client_new(p->core, __FILE__, cname); assert(c->client); diff --git a/src/pulsecore/shm.c b/src/pulsecore/shm.c index 8c7fb4db..8ef02f61 100644 --- a/src/pulsecore/shm.c +++ b/src/pulsecore/shm.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include "shm.h" @@ -53,7 +54,7 @@ #define MAX_SHM_SIZE (1024*1024*20) static char *segment_name(char *fn, size_t l, unsigned id) { - snprintf(fn, l, "/pulse-shm-%u", id); + pa_snprintf(fn, l, "/pulse-shm-%u", id); return fn; } diff --git a/src/pulsecore/socket-client.c b/src/pulsecore/socket-client.c index b83bfead..9e7280dd 100644 --- a/src/pulsecore/socket-client.c +++ b/src/pulsecore/socket-client.c @@ -445,7 +445,7 @@ pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, const char*nam struct addrinfo hints; char port[12]; - snprintf(port, sizeof(port), "%u", (unsigned) a.port); + pa_snprintf(port, sizeof(port), "%u", (unsigned) a.port); memset(&hints, 0, sizeof(hints)); hints.ai_family = a.type == PA_PARSED_ADDRESS_TCP4 ? PF_INET : (a.type == PA_PARSED_ADDRESS_TCP6 ? PF_INET6 : PF_UNSPEC); diff --git a/src/pulsecore/socket-server.c b/src/pulsecore/socket-server.c index b5a6dc31..c900ff32 100644 --- a/src/pulsecore/socket-server.c +++ b/src/pulsecore/socket-server.c @@ -438,14 +438,14 @@ char *pa_socket_server_get_address(pa_socket_server *s, char *c, size_t l) { if (!pa_get_fqdn(fqdn, sizeof(fqdn))) return NULL; - snprintf(c, l, "tcp6:%s:%u", fqdn, (unsigned) ntohs(sa.sin6_port)); + pa_snprintf(c, l, "tcp6:%s:%u", fqdn, (unsigned) ntohs(sa.sin6_port)); } else if (memcmp(&in6addr_loopback, &sa.sin6_addr, sizeof(in6addr_loopback)) == 0) { char hn[256]; if (!pa_get_host_name(hn, sizeof(hn))) return NULL; - snprintf(c, l, "{%s}tcp6:localhost:%u", hn, (unsigned) ntohs(sa.sin6_port)); + pa_snprintf(c, l, "{%s}tcp6:localhost:%u", hn, (unsigned) ntohs(sa.sin6_port)); } else { char ip[INET6_ADDRSTRLEN]; @@ -454,7 +454,7 @@ char *pa_socket_server_get_address(pa_socket_server *s, char *c, size_t l) { return NULL; } - snprintf(c, l, "tcp6:[%s]:%u", ip, (unsigned) ntohs(sa.sin6_port)); + pa_snprintf(c, l, "tcp6:[%s]:%u", ip, (unsigned) ntohs(sa.sin6_port)); } return c; @@ -474,13 +474,13 @@ char *pa_socket_server_get_address(pa_socket_server *s, char *c, size_t l) { if (!pa_get_fqdn(fqdn, sizeof(fqdn))) return NULL; - snprintf(c, l, "tcp:%s:%u", fqdn, (unsigned) ntohs(sa.sin_port)); + pa_snprintf(c, l, "tcp:%s:%u", fqdn, (unsigned) ntohs(sa.sin_port)); } else if (sa.sin_addr.s_addr == INADDR_LOOPBACK) { char hn[256]; if (!pa_get_host_name(hn, sizeof(hn))) return NULL; - snprintf(c, l, "{%s}tcp:localhost:%u", hn, (unsigned) ntohs(sa.sin_port)); + pa_snprintf(c, l, "{%s}tcp:localhost:%u", hn, (unsigned) ntohs(sa.sin_port)); } else { char ip[INET_ADDRSTRLEN]; @@ -489,7 +489,7 @@ char *pa_socket_server_get_address(pa_socket_server *s, char *c, size_t l) { return NULL; } - snprintf(c, l, "tcp:[%s]:%u", ip, (unsigned) ntohs(sa.sin_port)); + pa_snprintf(c, l, "tcp:[%s]:%u", ip, (unsigned) ntohs(sa.sin_port)); } @@ -505,7 +505,7 @@ char *pa_socket_server_get_address(pa_socket_server *s, char *c, size_t l) { if (!pa_get_host_name(hn, sizeof(hn))) return NULL; - snprintf(c, l, "{%s}unix:%s", hn, s->filename); + pa_snprintf(c, l, "{%s}unix:%s", hn, s->filename); return c; } diff --git a/src/pulsecore/socket-util.c b/src/pulsecore/socket-util.c index 05cb3369..511f12ef 100644 --- a/src/pulsecore/socket-util.c +++ b/src/pulsecore/socket-util.c @@ -85,7 +85,7 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) { #ifndef OS_IS_WIN32 if (fstat(fd, &st) < 0) { - snprintf(c, l, "Invalid client fd"); + pa_snprintf(c, l, "Invalid client fd"); return; } #endif @@ -108,7 +108,7 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) { if (sa.sa.sa_family == AF_INET) { uint32_t ip = ntohl(sa.in.sin_addr.s_addr); - snprintf(c, l, "TCP/IP client from %i.%i.%i.%i:%u", + pa_snprintf(c, l, "TCP/IP client from %i.%i.%i.%i:%u", ip >> 24, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, @@ -121,27 +121,27 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) { res = inet_ntop(AF_INET6, &sa.in6.sin6_addr, buf, sizeof(buf)); if (res) { - snprintf(c, l, "TCP/IP client from [%s]:%u", buf, ntohs(sa.in6.sin6_port)); + pa_snprintf(c, l, "TCP/IP client from [%s]:%u", buf, ntohs(sa.in6.sin6_port)); return; } #ifdef HAVE_SYS_UN_H } else if (sa.sa.sa_family == AF_UNIX) { - snprintf(c, l, "UNIX socket client"); + pa_snprintf(c, l, "UNIX socket client"); return; #endif } } #ifndef OS_IS_WIN32 - snprintf(c, l, "Unknown network client"); + pa_snprintf(c, l, "Unknown network client"); return; } else if (S_ISCHR(st.st_mode) && (fd == 0 || fd == 1)) { - snprintf(c, l, "STDIN/STDOUT client"); + pa_snprintf(c, l, "STDIN/STDOUT client"); return; } #endif /* OS_IS_WIN32 */ - snprintf(c, l, "Unknown client"); + pa_snprintf(c, l, "Unknown client"); } int pa_socket_low_delay(int fd) { diff --git a/src/pulsecore/strbuf.c b/src/pulsecore/strbuf.c index a3ddc114..2c66f5fa 100644 --- a/src/pulsecore/strbuf.c +++ b/src/pulsecore/strbuf.c @@ -153,6 +153,7 @@ int pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) { va_start(ap, format); r = vsnprintf(CHUNK_TO_TEXT(c), size, format, ap); + CHUNK_TO_TEXT(c)[size-1] = 0; va_end(ap); if (r > -1 && r < size) { diff --git a/src/pulsecore/x11wrap.c b/src/pulsecore/x11wrap.c index 6a6a2692..067b7df0 100644 --- a/src/pulsecore/x11wrap.c +++ b/src/pulsecore/x11wrap.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "x11wrap.h" @@ -198,7 +199,7 @@ pa_x11_wrapper* pa_x11_wrapper_get(pa_core *c, const char *name) { pa_x11_wrapper *w; assert(c); - snprintf(t, sizeof(t), "x11-wrapper%s%s", name ? "-" : "", name ? name : ""); + pa_snprintf(t, sizeof(t), "x11-wrapper%s%s", name ? "-" : "", name ? name : ""); if ((w = pa_property_get(c, t))) return pa_x11_wrapper_ref(w); -- cgit From 98d36efa82f87a900d4fb83a3ac9f4224651be56 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jul 2007 16:33:56 +0000 Subject: fix some alignment issues and modernize file a little bit git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1535 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/strbuf.c | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/pulsecore/strbuf.c b/src/pulsecore/strbuf.c index 2c66f5fa..ca88c59f 100644 --- a/src/pulsecore/strbuf.c +++ b/src/pulsecore/strbuf.c @@ -27,12 +27,12 @@ #include #include -#include #include #include #include #include +#include #include "strbuf.h" @@ -42,7 +42,7 @@ struct chunk { size_t length; }; -#define CHUNK_TO_TEXT(c) ((char*) (c) + sizeof(struct chunk)) +#define CHUNK_TO_TEXT(c) ((char*) (c) + PA_ALIGN(sizeof(struct chunk))) struct pa_strbuf { size_t length; @@ -50,14 +50,17 @@ struct pa_strbuf { }; pa_strbuf *pa_strbuf_new(void) { - pa_strbuf *sb = pa_xmalloc(sizeof(pa_strbuf)); + + pa_strbuf *sb = pa_xnew(pa_strbuf, 1); sb->length = 0; sb->head = sb->tail = NULL; + return sb; } void pa_strbuf_free(pa_strbuf *sb) { - assert(sb); + pa_assert(sb); + while (sb->head) { struct chunk *c = sb->head; sb->head = sb->head->next; @@ -72,9 +75,10 @@ void pa_strbuf_free(pa_strbuf *sb) { char *pa_strbuf_tostring(pa_strbuf *sb) { char *t, *e; struct chunk *c; - assert(sb); + + pa_assert(sb); - e = t = pa_xmalloc(sb->length+1); + e = t = pa_xnew(char, sb->length+1); for (c = sb->head; c; c = c->next) { assert((size_t) (e-t) <= sb->length); @@ -93,27 +97,33 @@ char *pa_strbuf_tostring(pa_strbuf *sb) { /* Combination of pa_strbuf_free() and pa_strbuf_tostring() */ char *pa_strbuf_tostring_free(pa_strbuf *sb) { char *t; - assert(sb); + + pa_assert(sb); t = pa_strbuf_tostring(sb); pa_strbuf_free(sb); + return t; } /* Append a string to the string buffer */ void pa_strbuf_puts(pa_strbuf *sb, const char *t) { - assert(sb && t); + + pa_assert(sb); + pa_assert(t); + pa_strbuf_putsn(sb, t, strlen(t)); } /* Append a new chunk to the linked list */ static void append(pa_strbuf *sb, struct chunk *c) { - assert(sb && c); + pa_assert(sb); + pa_assert(c); if (sb->tail) { - assert(sb->head); + pa_assert(sb->head); sb->tail->next = c; } else { - assert(!sb->head); + pa_assert(!sb->head); sb->head = c; } @@ -125,12 +135,14 @@ static void append(pa_strbuf *sb, struct chunk *c) { /* Append up to l bytes of a string to the string buffer */ void pa_strbuf_putsn(pa_strbuf *sb, const char *t, size_t l) { struct chunk *c; - assert(sb && t); + + pa_assert(sb); + pa_assert(t); if (!l) return; - c = pa_xmalloc(sizeof(struct chunk)+l); + c = pa_xmalloc(PA_ALIGN(sizeof(struct chunk)) + l); c->length = l; memcpy(CHUNK_TO_TEXT(c), t, l); @@ -143,13 +155,14 @@ int pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) { int size = 100; struct chunk *c = NULL; - assert(sb); + pa_assert(sb); + pa_assert(format); for(;;) { va_list ap; int r; - c = pa_xrealloc(c, sizeof(struct chunk)+size); + c = pa_xrealloc(c, PA_ALIGN(sizeof(struct chunk)) + size); va_start(ap, format); r = vsnprintf(CHUNK_TO_TEXT(c), size, format, ap); -- cgit From 8836396c77de2bf05914ca4d9aaa6d72d0589ecd Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Jul 2007 21:28:56 +0000 Subject: Store strings directly in strlst elements, other modernizations git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1536 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/strlist.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/pulsecore/strlist.c b/src/pulsecore/strlist.c index 955b78e4..1fcb0451 100644 --- a/src/pulsecore/strlist.c +++ b/src/pulsecore/strlist.c @@ -26,26 +26,31 @@ #endif #include -#include #include #include +#include #include #include "strlist.h" struct pa_strlist { pa_strlist *next; - char *str; }; +#define ITEM_TO_TEXT(c) ((char*) (c) + PA_ALIGN(sizeof(pa_strlist))) + pa_strlist* pa_strlist_prepend(pa_strlist *l, const char *s) { pa_strlist *n; - assert(s); - n = pa_xmalloc(sizeof(pa_strlist)); - n->str = pa_xstrdup(s); + size_t size; + + pa_assert(s); + size = strlen(s); + n = pa_xmalloc(PA_ALIGN(sizeof(pa_strlist)) + size + 1); + memcpy(ITEM_TO_TEXT(n), s, size + 1); n->next = l; + return n; } @@ -58,7 +63,7 @@ char *pa_strlist_tostring(pa_strlist *l) { if (!first) pa_strbuf_puts(b, " "); first = 0; - pa_strbuf_puts(b, l->str); + pa_strbuf_puts(b, ITEM_TO_TEXT(l)); } return pa_strbuf_tostring_free(b); @@ -66,19 +71,20 @@ char *pa_strlist_tostring(pa_strlist *l) { pa_strlist* pa_strlist_remove(pa_strlist *l, const char *s) { pa_strlist *ret = l, *prev = NULL; - assert(l && s); + + pa_assert(l); + pa_assert(s); while (l) { - if (!strcmp(l->str, s)) { + if (!strcmp(ITEM_TO_TEXT(l), s)) { pa_strlist *n = l->next; if (!prev) { - assert(ret == l); + pa_assert(ret == l); ret = n; } else prev->next = n; - pa_xfree(l->str); pa_xfree(l); l = n; @@ -96,22 +102,21 @@ void pa_strlist_free(pa_strlist *l) { while (l) { pa_strlist *c = l; l = l->next; - - pa_xfree(c->str); pa_xfree(c); } } pa_strlist* pa_strlist_pop(pa_strlist *l, char **s) { pa_strlist *r; - assert(s); + + pa_assert(s); if (!l) { *s = NULL; return NULL; } - *s = l->str; + *s = pa_xstrdup(ITEM_TO_TEXT(l)); r = l->next; pa_xfree(l); return r; @@ -124,10 +129,12 @@ pa_strlist* pa_strlist_parse(const char *s) { while ((r = pa_split_spaces(s, &state))) { pa_strlist *n; + size_t size = strlen(r); - n = pa_xmalloc(sizeof(pa_strlist)); - n->str = r; + n = pa_xmalloc(PA_ALIGN(sizeof(pa_strlist)) + size + 1); n->next = NULL; + memcpy(ITEM_TO_TEXT(n), r, size+1); + pa_xfree(r); if (p) p->next = n; -- cgit From 6ad165c68615bacc10213e99a2dd485b5d1f8ed1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Jul 2007 13:14:26 +0000 Subject: add abstracted file descriptor based semaphore object that is lock-free in the best cases git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1537 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/fdsem.c | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/pulsecore/fdsem.h | 49 +++++++++++++ 2 files changed, 238 insertions(+) create mode 100644 src/pulsecore/fdsem.c create mode 100644 src/pulsecore/fdsem.h diff --git a/src/pulsecore/fdsem.c b/src/pulsecore/fdsem.c new file mode 100644 index 00000000..4de531ae --- /dev/null +++ b/src/pulsecore/fdsem.c @@ -0,0 +1,189 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "fdsem.h" + +struct pa_fdsem { + int fds[2]; + pa_atomic_t waiting; + pa_atomic_t signalled; + pa_atomic_t in_pipe; +}; + +pa_fdsem *pa_fdsem_new(void) { + pa_fdsem *f; + + f = pa_xnew(pa_fdsem, 1); + + if (pipe(f->fds) < 0) { + pa_xfree(f); + return NULL; + } + + pa_atomic_store(&f->waiting, 0); + pa_atomic_store(&f->signalled, 0); + pa_atomic_store(&f->in_pipe, 0); + + return f; +} + +void pa_fdsem_free(pa_fdsem *f) { + pa_assert(f); + + pa_assert(pa_atomic_load(&f->waiting) == 0); + + close(f->fds[0]); + close(f->fds[1]); + + pa_xfree(f); +} + +static void flush(pa_fdsem *f) { + ssize_t r; + pa_assert(f); + + if (pa_atomic_load(&f->in_pipe) <= 0) + return; + + do { + char x[10]; + + if ((r = read(f->fds[0], &x, sizeof(x))) <= 0) { + pa_assert(r < 0 && errno == EINTR); + continue; + } + + } while (pa_atomic_sub(&f->in_pipe, r) > r); +} + +void pa_fdsem_post(pa_fdsem *f) { + pa_assert(f); + + if (pa_atomic_cmpxchg(&f->signalled, 0, 1)) { + + if (pa_atomic_load(&f->waiting)) { + ssize_t r; + char x = 'x'; + + pa_atomic_inc(&f->in_pipe); + + for (;;) { + + if ((r = write(f->fds[1], &x, 1)) != 1) { + pa_assert(r < 0 && errno == EINTR); + continue; + } + + break; + } + } + } +} + +void pa_fdsem_wait(pa_fdsem *f) { + pa_assert(f); + + flush(f); + + if (pa_atomic_cmpxchg(&f->signalled, 1, 0)) + return; + + pa_atomic_inc(&f->waiting); + + while (!pa_atomic_cmpxchg(&f->signalled, 1, 0)) { + char x[10]; + ssize_t r; + + if ((r = read(f->fds[0], &x, sizeof(x))) <= 0) { + pa_assert(r < 0 && errno == EINTR); + continue; + } + + pa_atomic_sub(&f->in_pipe, r); + } + + pa_atomic_dec(&f->waiting); +} + +int pa_fdsem_try(pa_fdsem *f) { + pa_assert(f); + + flush(f); + + if (pa_atomic_cmpxchg(&f->signalled, 1, 0)) + return 1; + + return 0; +} + + +int pa_fdsem_get(pa_fdsem *f) { + pa_assert(f); + + return f->fds[0]; +} + +int pa_fdsem_before_poll(pa_fdsem *f) { + pa_assert(f); + + flush(f); + + if (pa_atomic_cmpxchg(&f->signalled, 1, 0)) + return -1; + + pa_atomic_inc(&f->waiting); + + if (pa_atomic_cmpxchg(&f->signalled, 1, 0)) { + pa_atomic_dec(&f->waiting); + return -1; + } + + return 0; +} + +int pa_fdsem_after_poll(pa_fdsem *f) { + pa_assert(f); + + pa_atomic_dec(&f->waiting); + + flush(f); + + if (pa_atomic_cmpxchg(&f->signalled, 1, 0)) + return 1; + + return 0; +} diff --git a/src/pulsecore/fdsem.h b/src/pulsecore/fdsem.h new file mode 100644 index 00000000..f38ef205 --- /dev/null +++ b/src/pulsecore/fdsem.h @@ -0,0 +1,49 @@ +#ifndef foopulsefdsemhfoo +#define foopulsefdsemhfoo + +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include +#include + +/* A simple, asynchronous semaphore which uses fds for sleeping. In + * the best case all functions are lock-free unless sleeping is + * required. */ + +typedef struct pa_fdsem pa_fdsem; + +pa_fdsem *pa_fdsem_new(void); +void pa_fdsem_free(pa_fdsem *f); + +void pa_fdsem_post(pa_fdsem *f); +void pa_fdsem_wait(pa_fdsem *f); +int pa_fdsem_try(pa_fdsem *f); + +int pa_fdsem_get(pa_fdsem *f); + +int pa_fdsem_before_poll(pa_fdsem *f); +int pa_fdsem_after_poll(pa_fdsem *f); + + +#endif -- cgit From bc3693261fa2922ff55133432b212dc03589ba50 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Jul 2007 13:15:05 +0000 Subject: port asyncq to make use of new fdsem object git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1538 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/asyncq.c | 207 +++++++++---------------------------------------- 1 file changed, 36 insertions(+), 171 deletions(-) diff --git a/src/pulsecore/asyncq.c b/src/pulsecore/asyncq.c index 025c695e..22381248 100644 --- a/src/pulsecore/asyncq.c +++ b/src/pulsecore/asyncq.c @@ -36,12 +36,15 @@ #include #include "asyncq.h" +#include "fdsem.h" #define ASYNCQ_SIZE 128 /* For debugging purposes we can define _Y to put and extra thread * yield between each operation. */ +/* #define PROFILE */ + #ifdef PROFILE #define _Y pa_thread_yield() #else @@ -52,10 +55,7 @@ struct pa_asyncq { unsigned size; unsigned read_idx; unsigned write_idx; - pa_atomic_t read_waiting; /* a bool */ - pa_atomic_t write_waiting; /* a bool */ - int read_fds[2], write_fds[2]; - pa_atomic_t in_read_fifo, in_write_fifo; + pa_fdsem *read_fdsem, *write_fdsem; }; #define PA_ASYNCQ_CELLS(x) ((pa_atomic_ptr_t*) ((uint8_t*) (x) + PA_ALIGN(sizeof(struct pa_asyncq)))) @@ -79,26 +79,18 @@ pa_asyncq *pa_asyncq_new(unsigned size) { l = pa_xmalloc0(PA_ALIGN(sizeof(pa_asyncq)) + (sizeof(pa_atomic_ptr_t) * size)); l->size = size; - pa_atomic_store(&l->read_waiting, 0); - pa_atomic_store(&l->write_waiting, 0); - pa_atomic_store(&l->in_read_fifo, 0); - pa_atomic_store(&l->in_write_fifo, 0); - if (pipe(l->read_fds) < 0) { + if (!(l->read_fdsem = pa_fdsem_new())) { pa_xfree(l); return NULL; } - if (pipe(l->write_fds) < 0) { - pa_close(l->read_fds[0]); - pa_close(l->read_fds[1]); + if (!(l->write_fdsem = pa_fdsem_new())) { + pa_fdsem_free(l->read_fdsem); pa_xfree(l); return NULL; } - pa_make_nonblock_fd(l->read_fds[1]); - pa_make_nonblock_fd(l->write_fds[1]); - return l; } @@ -112,11 +104,8 @@ void pa_asyncq_free(pa_asyncq *l, pa_free_cb_t free_cb) { free_cb(p); } - pa_close(l->read_fds[0]); - pa_close(l->read_fds[1]); - pa_close(l->write_fds[0]); - pa_close(l->write_fds[1]); - + pa_fdsem_free(l->read_fdsem); + pa_fdsem_free(l->write_fdsem); pa_xfree(l); } @@ -134,80 +123,20 @@ int pa_asyncq_push(pa_asyncq*l, void *p, int wait) { if (!pa_atomic_ptr_cmpxchg(&cells[idx], NULL, p)) { - /* Let's empty the FIFO from old notifications, before we return */ - - while (pa_atomic_load(&l->in_write_fifo) > 0) { - ssize_t r; - int x[20]; - - if ((r = read(l->write_fds[0], x, sizeof(x))) < 0) { - - if (errno == EINTR) - continue; - - return -1; - } - - pa_assert(r > 0); - - if (pa_atomic_sub(&l->in_write_fifo, r) <= r) - break; - - } - - /* Now let's make sure that we didn't lose any events */ - if (!pa_atomic_ptr_cmpxchg(&cells[idx], NULL, p)) { - - if (!wait) - return -1; - - /* Let's wait for changes. */ - - _Y; - - pa_assert_se(pa_atomic_cmpxchg(&l->write_waiting, 0, 1)); - - for (;;) { - char x[20]; - ssize_t r; - - _Y; - - if (pa_atomic_ptr_cmpxchg(&cells[idx], NULL, p)) - break; - - _Y; - - if ((r = read(l->write_fds[0], x, sizeof(x))) < 0) { - - if (errno == EINTR) - continue; - - pa_assert_se(pa_atomic_cmpxchg(&l->write_waiting, 1, 0)); - return -1; - } - - pa_assert(r > 0); - pa_atomic_sub(&l->in_write_fifo, r); - } - - _Y; - - pa_assert_se(pa_atomic_cmpxchg(&l->write_waiting, 1, 0)); - } + if (!wait) + return -1; + +/* pa_log("sleeping on push"); */ + + do { + pa_fdsem_wait(l->read_fdsem); + } while (!pa_atomic_ptr_cmpxchg(&cells[idx], NULL, p)); } _Y; l->write_idx++; - if (pa_atomic_load(&l->read_waiting) > 0) { - char x = 'x'; - _Y; - if (write(l->read_fds[1], &x, sizeof(x)) > 0) { - pa_atomic_inc(&l->in_read_fifo); -/* pa_log("increasing %p by 1", l); */ - } - } + pa_fdsem_post(l->write_fdsem); return 0; } @@ -226,95 +155,33 @@ void* pa_asyncq_pop(pa_asyncq*l, int wait) { if (!(ret = pa_atomic_ptr_load(&cells[idx]))) { -/* pa_log("pop failed wait=%i", wait); */ - - /* Hmm, nothing, here, so let's drop all queued events. */ - while (pa_atomic_load(&l->in_read_fifo) > 0) { - ssize_t r; - int x[20]; - - if ((r = read(l->read_fds[0], x, sizeof(x))) < 0) { - - if (errno == EINTR) - continue; - - return NULL; - } - - pa_assert(r > 0); - -/* pa_log("decreasing %p by %i", l, r); */ - - if (pa_atomic_sub(&l->in_read_fifo, r) <= r) - break; - } - - /* Now let's make sure that we didn't lose any events */ - if (!(ret = pa_atomic_ptr_load(&cells[idx]))) { - - if (!wait) - return NULL; - - /* Let's wait for changes. */ - - _Y; - - pa_assert_se(pa_atomic_cmpxchg(&l->read_waiting, 0, 1)); - - for (;;) { - char x[20]; - ssize_t r; - - _Y; - - if ((ret = pa_atomic_ptr_load(&cells[idx]))) - break; - - _Y; - - if ((r = read(l->read_fds[0], x, sizeof(x))) < 0) { - - if (errno == EINTR) - continue; - - pa_assert_se(pa_atomic_cmpxchg(&l->read_waiting, 1, 0)); - return NULL; - } - -/* pa_log("decreasing %p by %i", l, r); */ - - pa_assert(r > 0); - pa_atomic_sub(&l->in_read_fifo, r); - } - - _Y; - - pa_assert_se(pa_atomic_cmpxchg(&l->read_waiting, 1, 0)); - } + if (!wait) + return NULL; + +/* pa_log("sleeping on pop"); */ + + do { + pa_fdsem_wait(l->write_fdsem); + } while (!(ret = pa_atomic_ptr_load(&cells[idx]))); } pa_assert(ret); - /* Guaranteed if we only have a single reader */ + /* Guaranteed to succeed if we only have a single reader */ pa_assert_se(pa_atomic_ptr_cmpxchg(&cells[idx], ret, NULL)); _Y; l->read_idx++; - if (pa_atomic_load(&l->write_waiting) > 0) { - char x = 'x'; - _Y; - if (write(l->write_fds[1], &x, sizeof(x)) >= 0) - pa_atomic_inc(&l->in_write_fifo); - } - + pa_fdsem_post(l->read_fdsem); + return ret; } int pa_asyncq_get_fd(pa_asyncq *q) { pa_assert(q); - return q->read_fds[0]; + return pa_fdsem_get(q->write_fdsem); } int pa_asyncq_before_poll(pa_asyncq *l) { @@ -328,14 +195,12 @@ int pa_asyncq_before_poll(pa_asyncq *l) { _Y; idx = reduce(l, l->read_idx); - if (pa_atomic_ptr_load(&cells[idx]) || pa_atomic_load(&l->in_read_fifo) > 0) - return -1; - - pa_assert_se(pa_atomic_cmpxchg(&l->read_waiting, 0, 1)); + for (;;) { + if (pa_atomic_ptr_load(&cells[idx])) + return -1; - if (pa_atomic_ptr_load(&cells[idx]) || pa_atomic_load(&l->in_read_fifo) > 0) { - pa_assert_se(pa_atomic_cmpxchg(&l->read_waiting, 1, 0)); - return -1; + if (pa_fdsem_before_poll(l->write_fdsem) >= 0) + return 0; } return 0; @@ -344,5 +209,5 @@ int pa_asyncq_before_poll(pa_asyncq *l) { void pa_asyncq_after_poll(pa_asyncq *l) { pa_assert(l); - pa_assert_se(pa_atomic_cmpxchg(&l->read_waiting, 1, 0)); + pa_fdsem_after_poll(l->write_fdsem); } -- cgit From 8cdde282e8caacabe6f31c0931d1b4b4f1f8a6b1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Jul 2007 13:15:58 +0000 Subject: reverse order of printf and push to make output more readable git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1539 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/tests/asyncq-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/asyncq-test.c b/src/tests/asyncq-test.c index 600d9d07..2e4b66cc 100644 --- a/src/tests/asyncq-test.c +++ b/src/tests/asyncq-test.c @@ -40,8 +40,8 @@ static void producer(void *_q) { int i; for (i = 0; i < 1000; i++) { + printf("pushing %i\n", i); pa_asyncq_push(q, (void*) (i+1), 1); - printf("pushed %i\n", i); } pa_asyncq_push(q, (void*) -1, 1); -- cgit From 58af737ebba2f9563deb92da0e0eae77b4e3b319 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Jul 2007 13:16:37 +0000 Subject: Add fdsem to makefile git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1540 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile.am b/src/Makefile.am index cda35733..be0e584e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -655,6 +655,7 @@ libpulsecore_la_SOURCES += \ pulsecore/flist.c pulsecore/flist.h \ pulsecore/asyncmsgq.c pulsecore/asyncmsgqq.h \ pulsecore/asyncq.c pulsecore/asyncq.h \ + pulsecore/fdsem.c pulsecore/fdsem.h \ pulsecore/object.c pulsecore/object.h \ pulsecore/msgobject.c pulsecore/msgobject.h \ $(PA_THREAD_OBJS) -- cgit From d80fd10a67e2764d301e8ff41cc271c0eee2399f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Jul 2007 13:17:34 +0000 Subject: properly deref sink_input/source_output objects when removing them from a sink/source git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1541 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink.c | 3 ++- src/pulsecore/source.c | 14 ++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index a66097bc..015cf4d5 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -671,7 +671,8 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk * case PA_SINK_MESSAGE_REMOVE_INPUT: { pa_sink_input *i = userdata; - pa_hashmap_remove(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index)); + if (pa_hashmap_remove(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index))) + pa_sink_input_unref(i); return 0; } diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index ce1ee987..6ca81727 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -384,20 +384,22 @@ unsigned pa_source_used_by(pa_source *s) { return pa_idxset_size(s->outputs); } -int pa_source_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk) { - pa_source *s = PA_SOURCE(o); +int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, pa_memchunk *chunk) { + pa_source *s = PA_SOURCE(object); pa_source_assert_ref(s); switch ((pa_source_message_t) code) { case PA_SOURCE_MESSAGE_ADD_OUTPUT: { - pa_source_output *i = userdata; - pa_hashmap_put(s->thread_info.outputs, PA_UINT32_TO_PTR(i->index), pa_source_output_ref(i)); + pa_source_output *o = userdata; + pa_hashmap_put(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index), pa_source_output_ref(o)); return 0; } case PA_SOURCE_MESSAGE_REMOVE_OUTPUT: { - pa_source_output *i = userdata; - pa_hashmap_remove(s->thread_info.outputs, PA_UINT32_TO_PTR(i->index)); + pa_source_output *o = userdata; + if (pa_hashmap_remove(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index))) + pa_source_output_unref(o); + return 0; } -- cgit From 222a6d270ed49d50d0ab73590d45449a77c17ff2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Jul 2007 13:18:50 +0000 Subject: Increase ref counter of sink input as long as it is included in the sink idxset git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1542 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink-input.c | 3 ++- src/pulsecore/source-output.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index db98dd54..96836610 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -198,7 +198,7 @@ pa_sink_input* pa_sink_input_new( i->thread_info.volume = i->volume; i->thread_info.muted = i->muted; - pa_assert_se(pa_idxset_put(core->sink_inputs, i, &i->index) == 0); + pa_assert_se(pa_idxset_put(core->sink_inputs, pa_sink_input_ref(i), &i->index) == 0); pa_assert_se(pa_idxset_put(i->sink->inputs, i, NULL) == 0); pa_log_info("Created input %u \"%s\" on %s with sample spec %s", @@ -235,6 +235,7 @@ void pa_sink_input_disconnect(pa_sink_input *i) { pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, NULL); pa_idxset_remove_by_data(i->sink->core->sink_inputs, i, NULL); pa_idxset_remove_by_data(i->sink->inputs, i, NULL); + pa_sink_input_unref(i); pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE, i->index); diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index defb7797..ee76a6e0 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -157,7 +157,7 @@ pa_source_output* pa_source_output_new( o->thread_info.resampler = resampler; pa_assert_se(pa_idxset_put(core->source_outputs, o, &o->index) == 0); - pa_assert_se( pa_idxset_put(o->source->outputs, o, NULL) == 0); + pa_assert_se(pa_idxset_put(o->source->outputs, pa_source_output_ref(o), NULL) == 0); pa_log_info("Created output %u \"%s\" on %s with sample spec %s", o->index, @@ -191,6 +191,7 @@ void pa_source_output_disconnect(pa_source_output*o) { pa_idxset_remove_by_data(o->source->core->source_outputs, o, NULL); pa_idxset_remove_by_data(o->source->outputs, o, NULL); + pa_source_output_unref(o); pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_REMOVE, o->index); -- cgit From bc17b8ea2d772e5069fbef4dde24ef9c63f1cfa1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Jul 2007 13:20:11 +0000 Subject: reverse order flist destruction and mempool allocation warning git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1543 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/memblock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index c39147d1..f3e400ee 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -669,12 +669,13 @@ void pa_mempool_free(pa_mempool *p) { pa_mutex_unlock(p->mutex); + pa_flist_free(p->free_slots, NULL); + if (pa_atomic_load(&p->stat.n_allocated) > 0) { /* raise(SIGTRAP); */ pa_log_warn("WARNING! Memory pool destroyed but not all memory blocks freed! %u remain.", pa_atomic_load(&p->stat.n_allocated)); } - pa_flist_free(p->free_slots, NULL); pa_shm_free(&p->memory); pa_mutex_free(p->mutex); -- cgit From 042cb0939431b47e7d6ac91b89d8ef9ab0ce7744 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Jul 2007 13:55:52 +0000 Subject: make valgrind shut up regarding non-freed ident strings. other modernizations git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1544 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/log.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/pulsecore/log.c b/src/pulsecore/log.c index a1197eb5..53f8974c 100644 --- a/src/pulsecore/log.c +++ b/src/pulsecore/log.c @@ -26,7 +26,6 @@ #include #endif -#include #include #include #include @@ -40,6 +39,7 @@ #include #include +#include #include #include "log.h" @@ -79,13 +79,22 @@ void pa_log_set_ident(const char *p) { log_ident_local = pa_xstrdup(log_ident); } +/* To make valgrind shut up. */ +static void ident_destructor(void) PA_GCC_DESTRUCTOR; +static void ident_destructor(void) { + pa_xfree(log_ident); + pa_xfree(log_ident_local); +} + void pa_log_set_maximal_level(pa_log_level_t l) { - assert(l < PA_LOG_LEVEL_MAX); + pa_assert(l < PA_LOG_LEVEL_MAX); + maximal_level = l; } void pa_log_set_target(pa_log_target_t t, void (*func)(pa_log_level_t l, const char*s)) { - assert(t == PA_LOG_USER || !func); + pa_assert(t == PA_LOG_USER || !func); + log_target = t; user_log_func = func; } @@ -101,8 +110,8 @@ void pa_log_levelv_meta( const char *e; char *text, *t, *n, *location; - assert(level < PA_LOG_LEVEL_MAX); - assert(format); + pa_assert(level < PA_LOG_LEVEL_MAX); + pa_assert(format); if ((e = getenv(ENV_LOGLEVEL))) maximal_level = atoi(e); @@ -218,6 +227,7 @@ void pa_log_levelv(pa_log_level_t level, const char *format, va_list ap) { void pa_log_level(pa_log_level_t level, const char *format, ...) { va_list ap; + va_start(ap, format); pa_log_levelv_meta(level, NULL, 0, NULL, format, ap); va_end(ap); -- cgit From bbb347fa912a5891c18b93d886e3143ca0545a82 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Jul 2007 13:58:50 +0000 Subject: properly free memblocks when skipping over them git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1545 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink-input.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 96836610..44d00ef8 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -475,8 +475,11 @@ void pa_sink_input_drop(pa_sink_input *i, size_t length) { pa_cvolume volume; if (pa_sink_input_peek(i, &chunk, &volume) >= 0) { - size_t l = chunk.length; + size_t l; + pa_memblock_unref(chunk.memblock); + + l = chunk.length; if (l > length) l = length; -- cgit From 86abfbf9e858e434330375f711a12f2cbdd3c453 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Jul 2007 14:40:17 +0000 Subject: remove debug messages; don't queue request messages like nothing when send file is finished git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1546 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sound-file-stream.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index c31187c5..946af3e6 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -62,8 +62,6 @@ static void file_stream_free(pa_object *o) { file_stream *u = FILE_STREAM(o); pa_assert(u); - pa_log("xxxx ffreee"); - if (u->memchunk.memblock) pa_memblock_unref(u->memchunk.memblock); @@ -76,11 +74,9 @@ static void file_stream_free(pa_object *o) { static void file_stream_drop(file_stream *u) { file_stream_assert_ref(u); - pa_log("xxxx drop"); - - if (u->sink_input) { pa_sink_input_disconnect(u->sink_input); + pa_sink_input_unref(u->sink_input); u->sink_input = NULL; @@ -116,6 +112,9 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { u = FILE_STREAM(i->userdata); file_stream_assert_ref(u); + if (!u->sndfile) + return -1; + for (;;) { if (!u->memchunk.memblock) { @@ -132,11 +131,6 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { n = u->readf_function(u->sndfile, p, BUF_SIZE/fs); pa_memblock_release(u->memchunk.memblock); - pa_log("%u/%u = data: %02x %02x %02x %02x %02x %02x %02x %02x", - (unsigned int) n, BUF_SIZE/fs, - ((uint8_t*)p)[0], ((uint8_t*)p)[1], ((uint8_t*)p)[2], ((uint8_t*)p)[3], - ((uint8_t*)p)[4], ((uint8_t*)p)[5], ((uint8_t*)p)[6], ((uint8_t*)p)[7]); - if (n <= 0) n = 0; @@ -161,6 +155,10 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { pa_memchunk_reset(&u->memchunk); pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u), MESSAGE_DROP_FILE_STREAM, NULL, NULL, NULL); + + sf_close(u->sndfile); + u->sndfile = NULL; + return -1; } } @@ -293,7 +291,7 @@ int pa_play_file( /* The reference to u is dangling here, because we want to keep * this stream around until it is fully played. */ - + return 0; fail: -- cgit From 4cc0d0a18f7f4ffd553f0ab40045bcdeda0e590b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Jul 2007 19:19:42 +0000 Subject: remove some log messages git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1547 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink-input.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 44d00ef8..e4e931f4 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -440,16 +440,12 @@ void pa_sink_input_drop(pa_sink_input *i, size_t length) { /* return; */ /* } */ - pa_log("dropping %u", length); - if (i->thread_info.resampled_chunk.memblock) { size_t l = length; if (l > i->thread_info.resampled_chunk.length) l = i->thread_info.resampled_chunk.length; - pa_log("really dropping %u", l); - i->thread_info.resampled_chunk.index += l; i->thread_info.resampled_chunk.length -= l; @@ -461,8 +457,6 @@ void pa_sink_input_drop(pa_sink_input *i, size_t length) { length -= l; } - pa_log("really remaining %u", length); - if (length > 0) { if (i->thread_info.resampler) { -- cgit From c936e53fa28381123bf3381f9c9c7d253082451f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Jul 2007 19:30:51 +0000 Subject: Fix channel remapping in resample; other modernizations git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1548 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/resampler.c | 155 +++++++++++++++++++++++----------------------- 1 file changed, 78 insertions(+), 77 deletions(-) diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index a8c90050..1405d7e1 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -25,7 +25,6 @@ #include #endif -#include #include #include @@ -33,9 +32,9 @@ #include #include - #include #include +#include #include "resampler.h" @@ -83,12 +82,12 @@ pa_resampler* pa_resampler_new( pa_resampler *r = NULL; - assert(pool); - assert(a); - assert(b); - assert(pa_sample_spec_valid(a)); - assert(pa_sample_spec_valid(b)); - assert(resample_method != PA_RESAMPLER_INVALID); + pa_assert(pool); + pa_assert(a); + pa_assert(b); + pa_assert(pa_sample_spec_valid(a)); + pa_assert(pa_sample_spec_valid(b)); + pa_assert(resample_method != PA_RESAMPLER_INVALID); r = pa_xnew(pa_resampler, 1); r->impl_data = NULL; @@ -145,7 +144,7 @@ fail: } void pa_resampler_free(pa_resampler *r) { - assert(r); + pa_assert(r); if (r->impl_free) r->impl_free(r); @@ -154,8 +153,8 @@ void pa_resampler_free(pa_resampler *r) { } void pa_resampler_set_input_rate(pa_resampler *r, uint32_t rate) { - assert(r); - assert(rate > 0); + pa_assert(r); + pa_assert(rate > 0); if (r->i_ss.rate == rate) return; @@ -167,8 +166,8 @@ void pa_resampler_set_input_rate(pa_resampler *r, uint32_t rate) { } void pa_resampler_set_output_rate(pa_resampler *r, uint32_t rate) { - assert(r); - assert(rate > 0); + pa_assert(r); + pa_assert(rate > 0); if (r->o_ss.rate == rate) return; @@ -180,19 +179,19 @@ void pa_resampler_set_output_rate(pa_resampler *r, uint32_t rate) { } void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) { - assert(r && in && out && r->impl_run); + pa_assert(r && in && out && r->impl_run); r->impl_run(r, in, out); } size_t pa_resampler_request(pa_resampler *r, size_t out_length) { - assert(r); + pa_assert(r); return (((out_length / r->o_fz)*r->i_ss.rate)/r->o_ss.rate) * r->i_fz; } pa_resample_method_t pa_resampler_get_method(pa_resampler *r) { - assert(r); + pa_assert(r); return r->resample_method; } @@ -216,7 +215,7 @@ const char *pa_resample_method_to_string(pa_resample_method_t m) { pa_resample_method_t pa_parse_resample_method(const char *string) { pa_resample_method_t m; - assert(string); + pa_assert(string); for (m = 0; m < PA_RESAMPLER_MAX; m++) if (!strcmp(string, resample_methods[m])) @@ -231,8 +230,8 @@ pa_resample_method_t pa_parse_resample_method(const char *string) { static void libsamplerate_free(pa_resampler *r) { struct impl_libsamplerate *u; - assert(r); - assert(r->impl_data); + pa_assert(r); + pa_assert(r->impl_data); u = r->impl_data; @@ -253,12 +252,13 @@ static void libsamplerate_free(pa_resampler *r) { static void calc_map_table(pa_resampler *r) { struct impl_libsamplerate *u; unsigned oc; - assert(r); - assert(r->impl_data); + + pa_assert(r); + pa_assert(r->impl_data); u = r->impl_data; - if (!(u->map_required = (!pa_channel_map_equal(&r->i_cm, &r->o_cm) || r->i_ss.channels != r->o_ss.channels))) + if (!(u->map_required = (r->i_ss.channels != r->o_ss.channels || !pa_channel_map_equal(&r->i_cm, &r->o_cm)))) return; for (oc = 0; oc < r->o_ss.channels; oc++) { @@ -290,11 +290,11 @@ static pa_memchunk* convert_to_float(pa_resampler *r, pa_memchunk *input) { unsigned n_samples; void *src, *dst; - assert(r); - assert(input); - assert(input->memblock); + pa_assert(r); + pa_assert(input); + pa_assert(input->memblock); - assert(r->impl_data); + pa_assert(r->impl_data); u = r->impl_data; /* Convert the incoming sample into floats and place them in buf1 */ @@ -328,16 +328,16 @@ static pa_memchunk* convert_to_float(pa_resampler *r, pa_memchunk *input) { static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) { struct impl_libsamplerate *u; - unsigned n_samples, n_frames; + unsigned in_n_samples, out_n_samples, n_frames; int i_skip, o_skip; unsigned oc; float *src, *dst; - assert(r); - assert(input); - assert(input->memblock); + pa_assert(r); + pa_assert(input); + pa_assert(input->memblock); - assert(r->impl_data); + pa_assert(r->impl_data); u = r->impl_data; /* Remap channels and place the result int buf2 */ @@ -345,22 +345,23 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) { if (!u->map_required || !input->length) return input; - n_samples = input->length / sizeof(float); - n_frames = n_samples / r->o_ss.channels; + in_n_samples = input->length / sizeof(float); + n_frames = in_n_samples / r->i_ss.channels; + out_n_samples = n_frames * r->o_ss.channels; - if (!u->buf2.memblock || u->buf2_samples < n_samples) { + if (!u->buf2.memblock || u->buf2_samples < out_n_samples) { if (u->buf2.memblock) pa_memblock_unref(u->buf2.memblock); - u->buf2_samples = n_samples; - u->buf2.memblock = pa_memblock_new(r->mempool, u->buf2.length = sizeof(float) * n_samples); + u->buf2_samples = out_n_samples; + u->buf2.memblock = pa_memblock_new(r->mempool, u->buf2.length = sizeof(float) * out_n_samples); u->buf2.index = 0; } src = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); dst = (float*) pa_memblock_acquire(u->buf2.memblock); - memset(dst, 0, n_samples * sizeof(float)); + memset(dst, 0, u->buf2.length); o_skip = sizeof(float) * r->o_ss.channels; i_skip = sizeof(float) * r->i_ss.channels; @@ -381,7 +382,7 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) { pa_memblock_release(input->memblock); pa_memblock_release(u->buf2.memblock); - u->buf2.length = n_frames * sizeof(float) * r->o_ss.channels; + u->buf2.length = out_n_samples * sizeof(float); return &u->buf2; } @@ -393,9 +394,9 @@ static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) { unsigned out_n_frames, out_n_samples; int ret; - assert(r); - assert(input); - assert(r->impl_data); + pa_assert(r); + pa_assert(input); + pa_assert(r->impl_data); u = r->impl_data; /* Resample the data and place the result in buf3 */ @@ -428,8 +429,8 @@ static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) { data.end_of_input = 0; ret = src_process(u->src_state, &data); - assert(ret == 0); - assert((unsigned) data.input_frames_used == in_n_frames); + pa_assert(ret == 0); + pa_assert((unsigned) data.input_frames_used == in_n_frames); pa_memblock_release(input->memblock); pa_memblock_release(u->buf3.memblock); @@ -444,9 +445,9 @@ static pa_memchunk *convert_from_float(pa_resampler *r, pa_memchunk *input) { unsigned n_samples, n_frames; void *src, *dst; - assert(r); - assert(input); - assert(r->impl_data); + pa_assert(r); + pa_assert(input); + pa_assert(r->impl_data); u = r->impl_data; /* Convert the data into the correct sample type and place the result in buf4 */ @@ -481,13 +482,13 @@ static void libsamplerate_run(pa_resampler *r, const pa_memchunk *in, pa_memchun struct impl_libsamplerate *u; pa_memchunk *buf; - assert(r); - assert(in); - assert(out); - assert(in->length); - assert(in->memblock); - assert(in->length % r->i_fz == 0); - assert(r->impl_data); + pa_assert(r); + pa_assert(in); + pa_assert(out); + pa_assert(in->length); + pa_assert(in->memblock); + pa_assert(in->length % r->i_fz == 0); + pa_assert(r->impl_data); u = r->impl_data; @@ -511,36 +512,36 @@ static void libsamplerate_run(pa_resampler *r, const pa_memchunk *in, pa_memchun static void libsamplerate_update_input_rate(pa_resampler *r, uint32_t rate) { struct impl_libsamplerate *u; - assert(r); - assert(rate > 0); - assert(r->impl_data); + pa_assert(r); + pa_assert(rate > 0); + pa_assert(r->impl_data); u = r->impl_data; if (!u->src_state) { int err; u->src_state = src_new(r->resample_method, r->o_ss.channels, &err); - assert(u->src_state); + pa_assert(u->src_state); } else { int ret = src_set_ratio(u->src_state, (double) r->o_ss.rate / rate); - assert(ret == 0); + pa_assert(ret == 0); } } static void libsamplerate_update_output_rate(pa_resampler *r, uint32_t rate) { struct impl_libsamplerate *u; - assert(r); - assert(rate > 0); - assert(r->impl_data); + pa_assert(r); + pa_assert(rate > 0); + pa_assert(r->impl_data); u = r->impl_data; if (!u->src_state) { int err; u->src_state = src_new(r->resample_method, r->o_ss.channels, &err); - assert(u->src_state); + pa_assert(u->src_state); } else { int ret = src_set_ratio(u->src_state, (double) rate / r->i_ss.rate); - assert(ret == 0); + pa_assert(ret == 0); } } @@ -592,15 +593,15 @@ static void trivial_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out unsigned n_frames; struct impl_trivial *u; - assert(r); - assert(in); - assert(out); - assert(r->impl_data); + pa_assert(r); + pa_assert(in); + pa_assert(out); + pa_assert(r->impl_data); u = r->impl_data; fz = r->i_fz; - assert(fz == r->o_fz); + pa_assert(fz == r->o_fz); n_frames = in->length/fz; @@ -635,7 +636,7 @@ static void trivial_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out if (j >= n_frames) break; - assert(o_index*fz < pa_memblock_get_length(out->memblock)); + pa_assert(o_index*fz < pa_memblock_get_length(out->memblock)); memcpy((uint8_t*) dst + fz*o_index, (uint8_t*) src + fz*j, fz); @@ -653,13 +654,13 @@ static void trivial_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out /* Normalize counters */ while (u->i_counter >= r->i_ss.rate) { u->i_counter -= r->i_ss.rate; - assert(u->o_counter >= r->o_ss.rate); + pa_assert(u->o_counter >= r->o_ss.rate); u->o_counter -= r->o_ss.rate; } } static void trivial_free(pa_resampler *r) { - assert(r); + pa_assert(r); pa_xfree(r->impl_data); } @@ -667,9 +668,9 @@ static void trivial_free(pa_resampler *r) { static void trivial_update_rate(pa_resampler *r, uint32_t rate) { struct impl_trivial *u; - assert(r); - assert(rate > 0); - assert(r->impl_data); + pa_assert(r); + pa_assert(rate > 0); + pa_assert(r->impl_data); u = r->impl_data; u->i_counter = 0; @@ -679,9 +680,9 @@ static void trivial_update_rate(pa_resampler *r, uint32_t rate) { static int trivial_init(pa_resampler*r) { struct impl_trivial *u; - assert(r); - assert(r->i_ss.format == r->o_ss.format); - assert(r->i_ss.channels == r->o_ss.channels); + pa_assert(r); + pa_assert(r->i_ss.format == r->o_ss.format); + pa_assert(r->i_ss.channels == r->o_ss.channels); r->impl_data = u = pa_xnew(struct impl_trivial, 1); u->o_counter = u->i_counter = 0; -- cgit From 8e4660a0b5b34ae465fa3765c68dd8f2d276956f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 26 Jul 2007 19:55:51 +0000 Subject: Disable memory mapping if we open the device in O_WRONLY. Unfortunately we cannot do mmap() in Linux without opening the device for reading as well. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1549 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-oss.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index b210c17c..96e0c3ce 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -1078,10 +1078,15 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; if (use_mmap && (!(caps & DSP_CAP_MMAP) || !(caps & DSP_CAP_TRIGGER))) { - pa_log("OSS device not mmap capable, falling back to UNIX read/write mode"); + pa_log_info("OSS device not mmap capable, falling back to UNIX read/write mode."); use_mmap = 0; } + if (use_mmap && mode == O_WRONLY) { + pa_log_info("Device opened for write only, cannot do memory mapping, falling back to UNIX read/write mode."); + use_mmap = 0; + } + if (pa_oss_get_hw_description(p, hwdesc, sizeof(hwdesc)) >= 0) pa_log_info("Hardware name is '%s'.", hwdesc); else -- cgit From c7df4ba6c3f9b0f63e45505c53879cab11c0d696 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 28 Jul 2007 17:16:05 +0000 Subject: minor modernizations git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1550 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/utf8.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/pulse/utf8.c b/src/pulse/utf8.c index 923e021d..a179b3fc 100644 --- a/src/pulse/utf8.c +++ b/src/pulse/utf8.c @@ -50,7 +50,6 @@ #include #endif -#include #include #include #include @@ -60,6 +59,8 @@ #include #endif +#include + #include "utf8.h" #include "xmalloc.h" @@ -207,10 +208,9 @@ static char* iconv_simple(const char *str, const char *to, const char *from) { inlen = len = strlen(str) + 1; new_str = pa_xmalloc(len); - assert(new_str); - while (1) { - inbuf = (ICONV_CONST char*)str; /* Brain dead prototype for iconv() */ + for (;;) { + inbuf = (ICONV_CONST char*) str; /* Brain dead prototype for iconv() */ inbytes = inlen; outbuf = new_str; outbytes = len; @@ -226,11 +226,10 @@ static char* iconv_simple(const char *str, const char *to, const char *from) { break; } - assert(inbytes != 0); + pa_assert(inbytes != 0); len += inbytes; new_str = pa_xrealloc(new_str, len); - assert(new_str); } iconv_close(cd); -- cgit From 787f93533c6f0974d83185e2df1f8071dcce48ee Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 28 Jul 2007 17:24:28 +0000 Subject: port module-alsa-sink to new lock-free core. also add mmmap'ing support while doing so. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1551 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 26 +- src/modules/alsa-util.c | 228 +--------- src/modules/alsa-util.h | 10 +- src/modules/module-alsa-sink.c | 967 ++++++++++++++++++++++++++++------------- src/modules/module-oss.c | 61 ++- 5 files changed, 718 insertions(+), 574 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index be0e584e..ec1bbd02 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -934,12 +934,12 @@ modlibexec_LTLIBRARIES += \ module-oss.la endif -#if HAVE_ALSA -#modlibexec_LTLIBRARIES += \ -# libalsa-util.la \ -# module-alsa-sink.la \ +if HAVE_ALSA +modlibexec_LTLIBRARIES += \ + libalsa-util.la \ + module-alsa-sink.la # module-alsa-source.la -#endif +endif if HAVE_SOLARIS modlibexec_LTLIBRARIES += \ @@ -1185,15 +1185,15 @@ module_oss_la_LIBADD = $(AM_LIBADD) libiochannel.la liboss-util.la # ALSA -#libalsa_util_la_SOURCES = modules/alsa-util.c modules/alsa-util.h -#libalsa_util_la_LDFLAGS = -avoid-version -#libalsa_util_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libpulsecore.la -#libalsa_util_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) +libalsa_util_la_SOURCES = modules/alsa-util.c modules/alsa-util.h +libalsa_util_la_LDFLAGS = -avoid-version +libalsa_util_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libpulsecore.la +libalsa_util_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) -#module_alsa_sink_la_SOURCES = modules/module-alsa-sink.c -#module_alsa_sink_la_LDFLAGS = -module -avoid-version -#module_alsa_sink_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la libpulsecore.la -#module_alsa_sink_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) +module_alsa_sink_la_SOURCES = modules/module-alsa-sink.c +module_alsa_sink_la_LDFLAGS = -module -avoid-version +module_alsa_sink_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la libpulsecore.la +module_alsa_sink_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) #module_alsa_source_la_SOURCES = modules/module-alsa-source.c #module_alsa_source_la_LDFLAGS = -module -avoid-version diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c index 0a518025..520215fa 100644 --- a/src/modules/alsa-util.c +++ b/src/modules/alsa-util.c @@ -36,219 +36,6 @@ #include "alsa-util.h" -struct pa_alsa_fdlist { - int num_fds; - struct pollfd *fds; - /* This is a temporary buffer used to avoid lots of mallocs */ - struct pollfd *work_fds; - - snd_pcm_t *pcm; - snd_mixer_t *mixer; - - pa_mainloop_api *m; - pa_defer_event *defer; - pa_io_event **ios; - - int polled; - - void (*cb)(void *userdata); - void *userdata; -}; - -static void io_cb(pa_mainloop_api*a, pa_io_event* e, PA_GCC_UNUSED int fd, pa_io_event_flags_t events, void *userdata) { - struct pa_alsa_fdlist *fdl = (struct pa_alsa_fdlist*)userdata; - int err, i; - unsigned short revents; - - assert(a && fdl && (fdl->pcm || fdl->mixer) && fdl->fds && fdl->work_fds); - - if (fdl->polled) - return; - - fdl->polled = 1; - - memcpy(fdl->work_fds, fdl->fds, sizeof(struct pollfd) * fdl->num_fds); - - for (i = 0;i < fdl->num_fds;i++) { - if (e == fdl->ios[i]) { - if (events & PA_IO_EVENT_INPUT) - fdl->work_fds[i].revents |= POLLIN; - if (events & PA_IO_EVENT_OUTPUT) - fdl->work_fds[i].revents |= POLLOUT; - if (events & PA_IO_EVENT_ERROR) - fdl->work_fds[i].revents |= POLLERR; - if (events & PA_IO_EVENT_HANGUP) - fdl->work_fds[i].revents |= POLLHUP; - break; - } - } - - assert(i != fdl->num_fds); - - if (fdl->pcm) - err = snd_pcm_poll_descriptors_revents(fdl->pcm, fdl->work_fds, fdl->num_fds, &revents); - else - err = snd_mixer_poll_descriptors_revents(fdl->mixer, fdl->work_fds, fdl->num_fds, &revents); - - if (err < 0) { - pa_log_error("Unable to get poll revent: %s", - snd_strerror(err)); - return; - } - - a->defer_enable(fdl->defer, 1); - - if (revents) { - if (fdl->pcm) - fdl->cb(fdl->userdata); - else - snd_mixer_handle_events(fdl->mixer); - } -} - -static void defer_cb(pa_mainloop_api*a, PA_GCC_UNUSED pa_defer_event* e, void *userdata) { - struct pa_alsa_fdlist *fdl = (struct pa_alsa_fdlist*)userdata; - int num_fds, i, err; - struct pollfd *temp; - - assert(a && fdl && (fdl->pcm || fdl->mixer)); - - a->defer_enable(fdl->defer, 0); - - if (fdl->pcm) - num_fds = snd_pcm_poll_descriptors_count(fdl->pcm); - else - num_fds = snd_mixer_poll_descriptors_count(fdl->mixer); - assert(num_fds > 0); - - if (num_fds != fdl->num_fds) { - if (fdl->fds) - pa_xfree(fdl->fds); - if (fdl->work_fds) - pa_xfree(fdl->work_fds); - fdl->fds = pa_xmalloc0(sizeof(struct pollfd) * num_fds); - fdl->work_fds = pa_xmalloc(sizeof(struct pollfd) * num_fds); - } - - memset(fdl->work_fds, 0, sizeof(struct pollfd) * num_fds); - - if (fdl->pcm) - err = snd_pcm_poll_descriptors(fdl->pcm, fdl->work_fds, num_fds); - else - err = snd_mixer_poll_descriptors(fdl->mixer, fdl->work_fds, num_fds); - - if (err < 0) { - pa_log_error("Unable to get poll descriptors: %s", - snd_strerror(err)); - return; - } - - fdl->polled = 0; - - if (memcmp(fdl->fds, fdl->work_fds, sizeof(struct pollfd) * num_fds) == 0) - return; - - if (fdl->ios) { - for (i = 0;i < fdl->num_fds;i++) - a->io_free(fdl->ios[i]); - if (num_fds != fdl->num_fds) { - pa_xfree(fdl->ios); - fdl->ios = pa_xmalloc(sizeof(pa_io_event*) * num_fds); - assert(fdl->ios); - } - } else { - fdl->ios = pa_xmalloc(sizeof(pa_io_event*) * num_fds); - assert(fdl->ios); - } - - /* Swap pointers */ - temp = fdl->work_fds; - fdl->work_fds = fdl->fds; - fdl->fds = temp; - - fdl->num_fds = num_fds; - - for (i = 0;i < num_fds;i++) { - fdl->ios[i] = a->io_new(a, fdl->fds[i].fd, - ((fdl->fds[i].events & POLLIN) ? PA_IO_EVENT_INPUT : 0) | - ((fdl->fds[i].events & POLLOUT) ? PA_IO_EVENT_OUTPUT : 0), - io_cb, fdl); - assert(fdl->ios[i]); - } -} - -struct pa_alsa_fdlist *pa_alsa_fdlist_new(void) { - struct pa_alsa_fdlist *fdl; - - fdl = pa_xmalloc(sizeof(struct pa_alsa_fdlist)); - - fdl->num_fds = 0; - fdl->fds = NULL; - fdl->work_fds = NULL; - - fdl->pcm = NULL; - fdl->mixer = NULL; - - fdl->m = NULL; - fdl->defer = NULL; - fdl->ios = NULL; - - fdl->polled = 0; - - return fdl; -} - -void pa_alsa_fdlist_free(struct pa_alsa_fdlist *fdl) { - assert(fdl); - - if (fdl->defer) { - assert(fdl->m); - fdl->m->defer_free(fdl->defer); - } - - if (fdl->ios) { - int i; - assert(fdl->m); - for (i = 0;i < fdl->num_fds;i++) - fdl->m->io_free(fdl->ios[i]); - pa_xfree(fdl->ios); - } - - if (fdl->fds) - pa_xfree(fdl->fds); - if (fdl->work_fds) - pa_xfree(fdl->work_fds); - - pa_xfree(fdl); -} - -int pa_alsa_fdlist_init_pcm(struct pa_alsa_fdlist *fdl, snd_pcm_t *pcm_handle, pa_mainloop_api* m, void (*cb)(void *userdata), void *userdata) { - assert(fdl && pcm_handle && m && !fdl->m && cb); - - fdl->pcm = pcm_handle; - fdl->m = m; - - fdl->defer = m->defer_new(m, defer_cb, fdl); - assert(fdl->defer); - - fdl->cb = cb; - fdl->userdata = userdata; - - return 0; -} - -int pa_alsa_fdlist_init_mixer(struct pa_alsa_fdlist *fdl, snd_mixer_t *mixer_handle, pa_mainloop_api* m) { - assert(fdl && mixer_handle && m && !fdl->m); - - fdl->mixer = mixer_handle; - fdl->m = m; - - fdl->defer = m->defer_new(m, defer_cb, fdl); - assert(fdl->defer); - - return 0; -} - static int set_format(snd_pcm_t *pcm_handle, snd_pcm_hw_params_t *hwparams, pa_sample_format_t *f) { static const snd_pcm_format_t format_trans[] = { @@ -308,7 +95,7 @@ try_auto: /* Set the hardware parameters of the given ALSA device. Returns the * selected fragment settings in *period and *period_size */ -int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *periods, snd_pcm_uframes_t *period_size) { +int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *periods, snd_pcm_uframes_t *period_size, int *use_mmap) { int ret = -1; snd_pcm_uframes_t buffer_size; unsigned int r = ss->rate; @@ -325,10 +112,19 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *p if ((ret = snd_pcm_hw_params_malloc(&hwparams)) < 0 || (ret = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0 || - (ret = snd_pcm_hw_params_set_rate_resample(pcm_handle, hwparams, 0)) < 0 || - (ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) + (ret = snd_pcm_hw_params_set_rate_resample(pcm_handle, hwparams, 0)) < 0) goto finish; + if (use_mmap && *use_mmap) { + if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0) + if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) + goto finish; + + } else if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) + goto finish; + else if (*use_mmap) + *use_mmap = 0; + if ((ret = set_format(pcm_handle, hwparams, &f)) < 0) goto finish; diff --git a/src/modules/alsa-util.h b/src/modules/alsa-util.h index ea6c7e1d..0cde087f 100644 --- a/src/modules/alsa-util.h +++ b/src/modules/alsa-util.h @@ -32,15 +32,7 @@ #include -struct pa_alsa_fdlist; - -struct pa_alsa_fdlist *pa_alsa_fdlist_new(void); -void pa_alsa_fdlist_free(struct pa_alsa_fdlist *fdl); - -int pa_alsa_fdlist_init_pcm(struct pa_alsa_fdlist *fdl, snd_pcm_t *pcm_handle, pa_mainloop_api* m, void (*cb)(void *userdata), void *userdata); -int pa_alsa_fdlist_init_mixer(struct pa_alsa_fdlist *fdl, snd_mixer_t *mixer_handle, pa_mainloop_api* m); - -int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *periods, snd_pcm_uframes_t *period_size); +int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *periods, snd_pcm_uframes_t *period_size, int *use_mmap); int pa_alsa_prepare_mixer(snd_mixer_t *mixer, const char *dev); snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name, const char *fallback); diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index f9c4efd4..4fc2f3a2 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -26,7 +26,6 @@ #include #endif -#include #include #ifdef HAVE_SYS_POLL_H @@ -38,6 +37,7 @@ #include #include +#include #include #include @@ -47,6 +47,9 @@ #include #include #include +#include +#include +#include #include "alsa-util.h" #include "module-alsa-sink-symdef.h" @@ -62,20 +65,36 @@ PA_MODULE_USAGE( "rate= " "fragments= " "fragment_size= " - "channel_map=") + "channel_map= " + "mmap=") + +#define DEFAULT_DEVICE "default" + +#define DEFAULT_NFRAGS 4 +#define DEFAULT_FRAGSIZE_MSEC 25 struct userdata { - snd_pcm_t *pcm_handle; - snd_mixer_t *mixer_handle; - snd_mixer_elem_t *mixer_elem; + pa_core *core; + pa_module *module; pa_sink *sink; - struct pa_alsa_fdlist *pcm_fdl; - struct pa_alsa_fdlist *mixer_fdl; - long hw_volume_max, hw_volume_min; + pa_thread *thread; + pa_asyncmsgq *asyncmsgq; + + snd_pcm_t *pcm_handle; - size_t frame_size, fragment_size; - pa_memchunk memchunk, silence; - pa_module *module; +/* snd_mixer_t *mixer_handle; */ +/* snd_mixer_elem_t *mixer_elem; */ +/* long hw_volume_max, hw_volume_min; */ + + size_t frame_size, fragment_size, hwbuf_size; + unsigned nfragments; + pa_memchunk memchunk; + + char *device_name; + + int use_mmap; + + int first; }; static const char* const valid_modargs[] = { @@ -87,327 +106,601 @@ static const char* const valid_modargs[] = { "fragments", "fragment_size", "channel_map", + "mmap", NULL }; -#define DEFAULT_DEVICE "default" +static int mmap_write(struct userdata *u) { + snd_pcm_sframes_t n; + int err; + const snd_pcm_channel_area_t *areas; + snd_pcm_uframes_t offset, frames; + + pa_assert(u); + pa_assert(u->sink); -static void update_usage(struct userdata *u) { - pa_module_set_used(u->module, u->sink ? pa_sink_used_by(u->sink) : 0); -} + for (;;) { + pa_memchunk chunk; + void *p; + + if ((n = snd_pcm_avail_update(u->pcm_handle)) < 0) { -static void clear_up(struct userdata *u) { - assert(u); + if (n == -EPIPE) { + pa_log_debug("snd_pcm_avail_update: Buffer underrun!"); + u->first = 1; + } + + if ((err = snd_pcm_recover(u->pcm_handle, n, 1)) == 0) + continue; - if (u->sink) { - pa_sink_disconnect(u->sink); - pa_sink_unref(u->sink); - u->sink = NULL; - } + if (err == EAGAIN) + return 0; + + pa_log("snd_pcm_avail_update: %s", snd_strerror(n)); + return -1; + } - if (u->pcm_fdl) - pa_alsa_fdlist_free(u->pcm_fdl); - if (u->mixer_fdl) - pa_alsa_fdlist_free(u->mixer_fdl); +/* pa_log("Got request for %i samples", (int) n); */ + + if (n <= 0) + return 0; + + frames = n; + + if ((err = snd_pcm_mmap_begin(u->pcm_handle, &areas, &offset, &frames)) < 0) { + + if (err == -EPIPE) { + pa_log_debug("snd_pcm_mmap_begin: Buffer underrun!"); + u->first = 1; + } - u->pcm_fdl = u->mixer_fdl = NULL; + if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0) + continue; - if (u->mixer_handle) { - snd_mixer_close(u->mixer_handle); - u->mixer_handle = NULL; - } + if (err == EAGAIN) + return 0; - if (u->pcm_handle) { - snd_pcm_drop(u->pcm_handle); - snd_pcm_close(u->pcm_handle); - u->pcm_handle = NULL; + pa_log("Failed to write data to DSP: %s", snd_strerror(err)); + return -1; + } + + /* Check these are multiples of 8 bit */ + pa_assert((areas[0].first & 7) == 0); + pa_assert((areas[0].step & 7)== 0); + + /* We assume a single interleaved memory buffer */ + pa_assert((areas[0].first >> 3) == 0); + pa_assert((areas[0].step >> 3) == u->frame_size); + + p = (uint8_t*) areas[0].addr + (offset * u->frame_size); + + chunk.memblock = pa_memblock_new_fixed(u->core->mempool, p, frames * u->frame_size, 1); + chunk.length = pa_memblock_get_length(chunk.memblock); + chunk.index = 0; + + pa_sink_render_into_full(u->sink, &chunk); + + /* FIXME: Maybe we can do something to keep this memory block + * a little bit longer around? */ + pa_memblock_unref_fixed(chunk.memblock); + + if ((err = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0) { + + if (err == -EPIPE) { + pa_log_debug("snd_pcm_mmap_commit: Buffer underrun!"); + u->first = 1; + } + + if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0) + continue; + + if (err == EAGAIN) + return 0; + + pa_log("Failed to write data to DSP: %s", snd_strerror(err)); + return -1; + } + +/* pa_log("wrote %i samples", (int) frames); */ } } -static int xrun_recovery(struct userdata *u) { - int ret; - assert(u); - - pa_log_info("*** ALSA-XRUN (playback) ***"); +static pa_usec_t sink_get_latency(struct userdata *u) { + pa_usec_t r = 0; + snd_pcm_sframes_t frames = 0; + int err; + + pa_assert(u); - if ((ret = snd_pcm_prepare(u->pcm_handle)) < 0) { - pa_log("snd_pcm_prepare() failed: %s", snd_strerror(-ret)); + snd_pcm_avail_update(u->pcm_handle); - clear_up(u); - pa_module_unload_request(u->module); - return -1; + if ((err = snd_pcm_delay(u->pcm_handle, &frames)) < 0) { + pa_log("Failed to get delay: %s", snd_strerror(err)); + return 0; } - return ret; + if (frames > 0) + r = pa_bytes_to_usec(frames * u->frame_size, &u->sink->sample_spec); + + if (u->memchunk.memblock) + r += pa_bytes_to_usec(u->memchunk.length, &u->sink->sample_spec); + + return r; } -static int suspend_recovery(struct userdata *u) { - int ret; - assert(u); +static int suspend(struct userdata *u) { + pa_assert(u); + pa_assert(u->pcm_handle); - pa_log_info("*** ALSA-SUSPEND (playback) ***"); + snd_pcm_drain(u->pcm_handle); /* Let's suspend */ + snd_pcm_close(u->pcm_handle); + u->pcm_handle = NULL; - if ((ret = snd_pcm_resume(u->pcm_handle)) < 0) { - if (ret == -EAGAIN) - return -1; + pa_log_debug("Device suspended..."); + + return 0; +} - if (ret != -ENOSYS) - pa_log("snd_pcm_resume() failed: %s", snd_strerror(-ret)); - else { - if ((ret = snd_pcm_prepare(u->pcm_handle)) < 0) - pa_log("snd_pcm_prepare() failed: %s", snd_strerror(-ret)); - } +static int unsuspend(struct userdata *u) { + pa_sample_spec ss; + int err, b; + unsigned nfrags; + snd_pcm_uframes_t period_size; - if (ret < 0) { - clear_up(u); - pa_module_unload_request(u->module); - return -1; - } + pa_assert(u); + pa_assert(!u->pcm_handle); + + pa_log_debug("Trying resume..."); + + snd_config_update_free_global(); + if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { + pa_log("Error opening PCM device %s: %s", u->device_name, snd_strerror(err)); + goto fail; } - return ret; -} + ss = u->sink->sample_spec; + nfrags = u->nfragments; + period_size = u->fragment_size / u->frame_size; + b = u->use_mmap; + + if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) { + pa_log("Failed to set hardware parameters: %s", snd_strerror(err)); + goto fail; + } -static void do_write(struct userdata *u) { - assert(u); + if (b != u->use_mmap) { + pa_log_warn("Resume failed, couldn't get original access mode."); + goto fail; + } - update_usage(u); + if (!pa_sample_spec_equal(&ss, &u->sink->sample_spec)) { + pa_log_warn("Resume failed, couldn't restore original sample settings."); + goto fail; + } - for (;;) { - void *p; - pa_memchunk *memchunk = NULL; - snd_pcm_sframes_t frames; - - if (u->memchunk.memblock) - memchunk = &u->memchunk; - else { - if (pa_sink_render(u->sink, u->fragment_size, &u->memchunk) < 0) - memchunk = &u->silence; - else - memchunk = &u->memchunk; - } - assert(memchunk->memblock); - assert(memchunk->length); - assert((memchunk->length % u->frame_size) == 0); + if (!nfrags != u->nfragments || period_size*u->frame_size != u->fragment_size) { + pa_log_warn("Resume failed, couldn't restore original fragment settings."); + goto fail; + } - p = pa_memblock_acquire(memchunk->memblock); + u->first = 1; + + pa_log_debug("Resumed successfully..."); - if ((frames = snd_pcm_writei(u->pcm_handle, (uint8_t*) p + memchunk->index, memchunk->length / u->frame_size)) < 0) { - pa_memblock_release(memchunk->memblock); + return 0; - if (frames == -EAGAIN) - return; +fail: + snd_pcm_close(u->pcm_handle); + u->pcm_handle = NULL; - if (frames == -EPIPE) { - if (xrun_recovery(u) < 0) - return; + return -1; +} - continue; - } +static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk *chunk) { + struct userdata *u = PA_SINK(o)->userdata; - if (frames == -ESTRPIPE) { - if (suspend_recovery(u) < 0) - return; + switch (code) { - continue; - } + case PA_SINK_MESSAGE_GET_LATENCY: { + pa_usec_t r = 0; + + if (u->pcm_handle) + r = sink_get_latency(u); - pa_log("snd_pcm_writei() failed: %s", snd_strerror(-frames)); + *((pa_usec_t*) data) = r; - clear_up(u); - pa_module_unload_request(u->module); - return; + break; } - pa_memblock_release(memchunk->memblock); + case PA_SINK_MESSAGE_SET_STATE: + + if (PA_PTR_TO_UINT(data) == PA_SINK_SUSPENDED) { + pa_assert(u->sink->thread_info.state != PA_SINK_SUSPENDED); - if (memchunk == &u->memchunk) { - size_t l = frames * u->frame_size; - memchunk->index += l; - memchunk->length -= l; + if (suspend(u) < 0) + return -1; + + } else if (u->sink->thread_info.state == PA_SINK_SUSPENDED) { + pa_assert(PA_PTR_TO_UINT(data) != PA_SINK_SUSPENDED); - if (memchunk->length == 0) { - pa_memblock_unref(memchunk->memblock); - memchunk->memblock = NULL; - memchunk->index = memchunk->length = 0; + if (unsuspend(u) < 0) + return -1; } - } + + break; + +/* case PA_SINK_MESSAGE_SET_VOLUME: */ + +/* if (u->use_pcm_volume && u->fd >= 0) { */ - break; +/* if (pa_oss_set_pcm_volume(u->fd, &u->sink->sample_spec, ((pa_cvolume*) data)) < 0) { */ +/* pa_log_info("Device doesn't support setting mixer settings: %s", pa_cstrerror(errno)); */ +/* u->use_pcm_volume = 0; */ +/* } else */ +/* return 0; */ +/* } */ + +/* break; */ + +/* case PA_SINK_MESSAGE_GET_VOLUME: */ + +/* if (u->use_pcm_volume && u->fd >= 0) { */ + +/* if (pa_oss_get_pcm_volume(u->fd, &u->sink->sample_spec, ((pa_cvolume*) data)) < 0) { */ +/* pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno)); */ +/* u->use_pcm_volume = 0; */ +/* } else */ +/* return 0; */ +/* } */ + +/* break; */ } + + return pa_sink_process_msg(o, code, data, chunk); } -static void fdl_callback(void *userdata) { - struct userdata *u = userdata; - assert(u); - if (snd_pcm_state(u->pcm_handle) == SND_PCM_STATE_XRUN) - if (xrun_recovery(u) < 0) - return; +/* static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) { */ +/* struct userdata *u = snd_mixer_elem_get_callback_private(elem); */ - if (snd_pcm_state(u->pcm_handle) == SND_PCM_STATE_SUSPENDED) - if (suspend_recovery(u) < 0) - return; +/* pa_assert(u && u->mixer_handle); */ - do_write(u); -} +/* if (mask == SND_CTL_EVENT_MASK_REMOVE) */ +/* return 0; */ -static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) { - struct userdata *u = snd_mixer_elem_get_callback_private(elem); +/* if (mask & SND_CTL_EVENT_MASK_VALUE) { */ +/* if (u->sink->get_hw_volume) */ +/* u->sink->get_hw_volume(u->sink); */ +/* if (u->sink->get_hw_mute) */ +/* u->sink->get_hw_mute(u->sink); */ +/* pa_subscription_post(u->sink->core, */ +/* PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, */ +/* u->sink->index); */ +/* } */ - assert(u && u->mixer_handle); +/* return 0; */ +/* } */ - if (mask == SND_CTL_EVENT_MASK_REMOVE) - return 0; +/* static int sink_get_hw_volume_cb(pa_sink *s) { */ +/* struct userdata *u = s->userdata; */ +/* int err; */ +/* int i; */ - if (mask & SND_CTL_EVENT_MASK_VALUE) { - if (u->sink->get_hw_volume) - u->sink->get_hw_volume(u->sink); - if (u->sink->get_hw_mute) - u->sink->get_hw_mute(u->sink); - pa_subscription_post(u->sink->core, - PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, - u->sink->index); - } +/* pa_assert(u); */ +/* pa_assert(u->mixer_elem); */ - return 0; -} +/* for (i = 0; i < s->hw_volume.channels; i++) { */ +/* long set_vol, vol; */ -static pa_usec_t sink_get_latency_cb(pa_sink *s) { - pa_usec_t r = 0; - struct userdata *u = s->userdata; - snd_pcm_sframes_t frames; - int err; +/* pa_assert(snd_mixer_selem_has_playback_channel(u->mixer_elem, i)); */ - assert(s && u && u->sink); +/* if ((err = snd_mixer_selem_get_playback_volume(u->mixer_elem, i, &vol)) < 0) */ +/* goto fail; */ - if ((err = snd_pcm_delay(u->pcm_handle, &frames)) < 0) { - pa_log("failed to get delay: %s", snd_strerror(err)); - s->get_latency = NULL; - return 0; - } +/* set_vol = (long) roundf(((float) s->hw_volume.values[i] * (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min; */ - if (frames < 0) - frames = 0; +/* /\* Try to avoid superfluous volume changes *\/ */ +/* if (set_vol != vol) */ +/* s->hw_volume.values[i] = (pa_volume_t) roundf(((float) (vol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min)); */ +/* } */ - r += pa_bytes_to_usec(frames * u->frame_size, &s->sample_spec); +/* return 0; */ - if (u->memchunk.memblock) - r += pa_bytes_to_usec(u->memchunk.length, &s->sample_spec); +/* fail: */ +/* pa_log_error("Unable to read volume: %s", snd_strerror(err)); */ +/* s->get_hw_volume = NULL; */ +/* s->set_hw_volume = NULL; */ +/* return -1; */ +/* } */ - return r; -} +/* static int sink_set_hw_volume_cb(pa_sink *s) { */ +/* struct userdata *u = s->userdata; */ +/* int err; */ +/* int i; */ +/* pa_volume_t vol; */ -static int sink_get_hw_volume_cb(pa_sink *s) { - struct userdata *u = s->userdata; - int err; - int i; +/* pa_assert(u); */ +/* pa_assert(u->mixer_elem); */ - assert(u); - assert(u->mixer_elem); +/* for (i = 0; i < s->hw_volume.channels; i++) { */ +/* long alsa_vol; */ - for (i = 0; i < s->hw_volume.channels; i++) { - long set_vol, vol; +/* pa_assert(snd_mixer_selem_has_playback_channel(u->mixer_elem, i)); */ - assert(snd_mixer_selem_has_playback_channel(u->mixer_elem, i)); +/* vol = s->hw_volume.values[i]; */ - if ((err = snd_mixer_selem_get_playback_volume(u->mixer_elem, i, &vol)) < 0) - goto fail; +/* if (vol > PA_VOLUME_NORM) */ +/* vol = PA_VOLUME_NORM; */ - set_vol = (long) roundf(((float) s->hw_volume.values[i] * (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min; +/* alsa_vol = (long) roundf(((float) vol * (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min; */ - /* Try to avoid superfluous volume changes */ - if (set_vol != vol) - s->hw_volume.values[i] = (pa_volume_t) roundf(((float) (vol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min)); - } +/* if ((err = snd_mixer_selem_set_playback_volume(u->mixer_elem, i, alsa_vol)) < 0) */ +/* goto fail; */ +/* } */ - return 0; +/* return 0; */ -fail: - pa_log_error("Unable to read volume: %s", snd_strerror(err)); - s->get_hw_volume = NULL; - s->set_hw_volume = NULL; - return -1; -} +/* fail: */ +/* pa_log_error("Unable to set volume: %s", snd_strerror(err)); */ +/* s->get_hw_volume = NULL; */ +/* s->set_hw_volume = NULL; */ +/* return -1; */ +/* } */ -static int sink_set_hw_volume_cb(pa_sink *s) { - struct userdata *u = s->userdata; - int err; - int i; - pa_volume_t vol; +/* static int sink_get_hw_mute_cb(pa_sink *s) { */ +/* struct userdata *u = s->userdata; */ +/* int err, sw; */ - assert(u); - assert(u->mixer_elem); +/* pa_assert(u && u->mixer_elem); */ - for (i = 0; i < s->hw_volume.channels; i++) { - long alsa_vol; +/* err = snd_mixer_selem_get_playback_switch(u->mixer_elem, 0, &sw); */ +/* if (err) { */ +/* pa_log_error("Unable to get switch: %s", snd_strerror(err)); */ +/* s->get_hw_mute = NULL; */ +/* s->set_hw_mute = NULL; */ +/* return -1; */ +/* } */ - assert(snd_mixer_selem_has_playback_channel(u->mixer_elem, i)); +/* s->hw_muted = !sw; */ - vol = s->hw_volume.values[i]; +/* return 0; */ +/* } */ - if (vol > PA_VOLUME_NORM) - vol = PA_VOLUME_NORM; +/* static int sink_set_hw_mute_cb(pa_sink *s) { */ +/* struct userdata *u = s->userdata; */ +/* int err; */ - alsa_vol = (long) roundf(((float) vol * (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min; +/* pa_assert(u && u->mixer_elem); */ - if ((err = snd_mixer_selem_set_playback_volume(u->mixer_elem, i, alsa_vol)) < 0) - goto fail; - } +/* err = snd_mixer_selem_set_playback_switch_all(u->mixer_elem, !s->hw_muted); */ +/* if (err) { */ +/* pa_log_error("Unable to set switch: %s", snd_strerror(err)); */ +/* s->get_hw_mute = NULL; */ +/* s->set_hw_mute = NULL; */ +/* return -1; */ +/* } */ - return 0; +/* return 0; */ +/* } */ -fail: - pa_log_error("Unable to set volume: %s", snd_strerror(err)); - s->get_hw_volume = NULL; - s->set_hw_volume = NULL; - return -1; -} +static void thread_func(void *userdata) { + enum { + POLLFD_ASYNCQ, + POLLFD_ALSA_BASE + }; + + struct userdata *u = userdata; + struct pollfd *pollfd = NULL; + int n_alsa_fds, err; + unsigned short revents = 0; + snd_pcm_status_t *status; -static int sink_get_hw_mute_cb(pa_sink *s) { - struct userdata *u = s->userdata; - int err, sw; + pa_assert(u); + snd_pcm_status_alloca(&status); - assert(u && u->mixer_elem); + pa_log_debug("Thread starting up"); - err = snd_mixer_selem_get_playback_switch(u->mixer_elem, 0, &sw); - if (err) { - pa_log_error("Unable to get switch: %s", snd_strerror(err)); - s->get_hw_mute = NULL; - s->set_hw_mute = NULL; - return -1; + if ((n_alsa_fds = snd_pcm_poll_descriptors_count(u->pcm_handle)) < 0) { + pa_log("snd_pcm_poll_descriptors_count() failed: %s", snd_strerror(n_alsa_fds)); + goto fail; } - s->hw_muted = !sw; + pollfd = pa_xnew0(struct pollfd, POLLFD_ALSA_BASE + n_alsa_fds); - return 0; -} + pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq); + pollfd[POLLFD_ASYNCQ].events = POLLIN; -static int sink_set_hw_mute_cb(pa_sink *s) { - struct userdata *u = s->userdata; - int err; + if ((err = snd_pcm_poll_descriptors(u->pcm_handle, pollfd+POLLFD_ALSA_BASE, n_alsa_fds)) < 0) { + pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err)); + goto fail; + } + + for (;;) { + pa_msgobject *object; + int code; + void *data; + pa_memchunk chunk; + int r; + +/* pa_log("loop"); */ + + /* Check whether there is a message for us to process */ + if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { + int ret; + +/* pa_log("processing msg"); */ + + if (!object && code == PA_MESSAGE_SHUTDOWN) { + pa_asyncmsgq_done(u->asyncmsgq, 0); + goto finish; + } + + ret = pa_asyncmsgq_dispatch(object, code, data, &chunk); + pa_asyncmsgq_done(u->asyncmsgq, ret); + continue; + } + +/* pa_log("loop2"); */ + + /* Render some data and write it to the dsp */ + + if (u->sink->thread_info.state != PA_SINK_SUSPENDED && ((revents & POLLOUT) || u->first == 1)) { + + if (u->use_mmap) { + int ret; + + if ((ret = mmap_write(u)) < 0) + goto fail; + + revents &= ~POLLOUT; + + if (ret > 0) + continue; + + } else { + ssize_t l; + + snd_pcm_hwsync(u->pcm_handle); + if ((err = snd_pcm_status(u->pcm_handle, status)) >= 0) + l = snd_pcm_status_get_avail(status) * u->frame_size; + else + l = u->fragment_size; + + do { + void *p; + snd_pcm_sframes_t t; + + pa_assert(l > 0); + + if (u->memchunk.length <= 0) + pa_sink_render(u->sink, l, &u->memchunk); + + pa_assert(u->memchunk.length > 0); + + p = pa_memblock_acquire(u->memchunk.memblock); + t = snd_pcm_writei(u->pcm_handle, (uint8_t*) p + u->memchunk.index, u->memchunk.length / u->frame_size); + pa_memblock_release(u->memchunk.memblock); + +/* pa_log("wrote %i bytes of %u", t, l); */ + + pa_assert(t != 0); + + if (t < 0) { + + if (t == -EPIPE) { + pa_log_debug("Buffer underrun!"); + u->first = 1; + } + + if ((t = snd_pcm_recover(u->pcm_handle, t, 1)) == 0) + continue; + + if (t == EAGAIN) { + pa_log_debug("EAGAIN"); + + revents &= ~POLLOUT; + break; + + } else { + pa_log("Failed to write data to DSP: %s", snd_strerror(t)); + goto fail; + } + + } else { + + u->memchunk.index += t * u->frame_size; + u->memchunk.length -= t * u->frame_size; + + if (u->memchunk.length <= 0) { + pa_memblock_unref(u->memchunk.memblock); + pa_memchunk_reset(&u->memchunk); + } + + l -= t * u->frame_size; + + revents &= ~POLLOUT; + } + + } while (l > 0); + + continue; + } + + if (u->first) { + pa_log_info("Starting playback."); + + if ((err = snd_pcm_start(u->pcm_handle)) < 0) { + pa_log("Failed to start PCM playback: %s", snd_strerror(err)); + goto fail; + } + + u->first = 0; + } + } - assert(u && u->mixer_elem); + /* Hmm, nothing to do. Let's sleep */ + if (pa_asyncmsgq_before_poll(u->asyncmsgq) < 0) + continue; - err = snd_mixer_selem_set_playback_switch_all(u->mixer_elem, !s->hw_muted); - if (err) { - pa_log_error("Unable to set switch: %s", snd_strerror(err)); - s->get_hw_mute = NULL; - s->set_hw_mute = NULL; - return -1; +/* pa_log("polling for %i", POLLFD_ALSA_BASE + (u->sink->thread_info.state != PA_SINK_SUSPENDED ? n_alsa_fds : 0)); */ + r = poll(pollfd, POLLFD_ALSA_BASE + (u->sink->thread_info.state != PA_SINK_SUSPENDED ? n_alsa_fds : 0), -1); + /*pa_log("polling got dsp=%i amq=%i (%i)", r > 0 ? pollfd[POLLFD_DSP].revents : 0, r > 0 ? pollfd[POLLFD_ASYNCQ].revents : 0, r); */ +/* pa_log("poll end"); */ + + pa_asyncmsgq_after_poll(u->asyncmsgq); + + if (r < 0) { + if (errno == EINTR) { + pollfd[POLLFD_ASYNCQ].revents = 0; + revents = 0; + continue; + } + + pa_log("poll() failed: %s", pa_cstrerror(errno)); + goto fail; + } + + pa_assert(r > 0); + + if (u->sink->thread_info.state != PA_SINK_SUSPENDED) { + if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, pollfd + POLLFD_ALSA_BASE, n_alsa_fds, &revents)) < 0) { + pa_log("snd_pcm_poll_descriptors_revents() failed: %s", snd_strerror(err)); + goto fail; + } + +/* pa_log("got alsa event"); */ + } else + revents = 0; + + if (revents & ~(POLLOUT|POLLERR)) { + pa_log("DSP shutdown."); + goto fail; + } + + pa_assert((pollfd[POLLFD_ASYNCQ].revents & ~POLLIN) == 0); } - return 0; +fail: + /* We have to continue processing messages until we receive the + * SHUTDOWN message */ + pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, NULL, NULL); + pa_asyncmsgq_wait_for(u->asyncmsgq, PA_MESSAGE_SHUTDOWN); + +finish: + pa_log_debug("Thread shutting down"); + + pa_xfree(pollfd); } int pa__init(pa_core *c, pa_module*m) { + pa_modargs *ma = NULL; int ret = -1; struct userdata *u = NULL; const char *dev; pa_sample_spec ss; pa_channel_map map; - uint32_t periods, fragsize; + uint32_t nfrags, frag_size; snd_pcm_uframes_t period_size; size_t frame_size; snd_pcm_info_t *pcm_info = NULL; @@ -416,6 +709,10 @@ int pa__init(pa_core *c, pa_module*m) { const char *name; char *name_buf = NULL; int namereg_fail; + int use_mmap = 1, b; + + pa_assert(c); + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("failed to parse module arguments"); @@ -430,19 +727,29 @@ int pa__init(pa_core *c, pa_module*m) { frame_size = pa_frame_size(&ss); - /* Fix latency to 100ms */ - periods = 8; - fragsize = pa_bytes_per_second(&ss)/128; + nfrags = DEFAULT_NFRAGS; + frag_size = pa_usec_to_bytes(DEFAULT_FRAGSIZE_MSEC*1000, &ss); + if (frag_size <= 0) + frag_size = frame_size; - if (pa_modargs_get_value_u32(ma, "fragments", &periods) < 0 || pa_modargs_get_value_u32(ma, "fragment_size", &fragsize) < 0) { + if (pa_modargs_get_value_u32(ma, "fragments", &nfrags) < 0 || pa_modargs_get_value_u32(ma, "fragment_size", &frag_size) < 0) { pa_log("failed to parse buffer metrics"); goto fail; } - period_size = fragsize/frame_size; + period_size = frag_size/frame_size; + if (pa_modargs_get_value_boolean(ma, "mmap", &use_mmap) < 0) { + pa_log("Failed to parse mmap argument."); + goto fail; + } + u = pa_xnew0(struct userdata, 1); - m->userdata = u; + u->core = c; u->module = m; + m->userdata = u; + u->use_mmap = use_mmap; + u->first = 1; + pa_assert_se(u->asyncmsgq = pa_asyncmsgq_new(0)); snd_config_update_free_global(); if ((err = snd_pcm_open(&u->pcm_handle, dev = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { @@ -450,17 +757,25 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } + u->device_name = pa_xstrdup(dev); + if ((err = snd_pcm_info_malloc(&pcm_info)) < 0 || (err = snd_pcm_info(u->pcm_handle, pcm_info)) < 0) { pa_log("Error fetching PCM info: %s", snd_strerror(err)); goto fail; } - if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &periods, &period_size)) < 0) { + b = use_mmap; + if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) { pa_log("Failed to set hardware parameters: %s", snd_strerror(err)); goto fail; } + if (use_mmap && !b) { + pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode."); + u->use_mmap = use_mmap = b; + } + /* ALSA might tweak the sample spec, so recalculate the frame size */ frame_size = pa_frame_size(&ss); @@ -468,16 +783,16 @@ int pa__init(pa_core *c, pa_module*m) { /* Seems ALSA didn't like the channel number, so let's fix the channel map */ pa_channel_map_init_auto(&map, ss.channels, PA_CHANNEL_MAP_ALSA); - if ((err = snd_mixer_open(&u->mixer_handle, 0)) < 0) { - pa_log("Error opening mixer: %s", snd_strerror(err)); - goto fail; - } +/* if ((err = snd_mixer_open(&u->mixer_handle, 0)) < 0) */ +/* pa_log_warn("Error opening mixer: %s", snd_strerror(err)); */ +/* else { */ - if ((pa_alsa_prepare_mixer(u->mixer_handle, dev) < 0) || - !(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "PCM", "Master"))) { - snd_mixer_close(u->mixer_handle); - u->mixer_handle = NULL; - } +/* if ((pa_alsa_prepare_mixer(u->mixer_handle, dev) < 0) || */ +/* !(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "PCM", "Master"))) { */ +/* snd_mixer_close(u->mixer_handle); */ +/* u->mixer_handle = NULL; */ +/* } */ +/* } */ if ((name = pa_modargs_get_value(ma, "sink_name", NULL))) namereg_fail = 1; @@ -486,84 +801,86 @@ int pa__init(pa_core *c, pa_module*m) { namereg_fail = 0; } - if (!(u->sink = pa_sink_new(c, __FILE__, name, namereg_fail, &ss, &map))) { + u->sink = pa_sink_new(c, __FILE__, name, namereg_fail, &ss, &map); + pa_xfree(name_buf); + + if (!u->sink) { pa_log("Failed to create sink object"); goto fail; } - u->sink->is_hardware = 1; - u->sink->get_latency = sink_get_latency_cb; - if (u->mixer_handle) { - assert(u->mixer_elem); - if (snd_mixer_selem_has_playback_volume(u->mixer_elem)) { - int i; - - for (i = 0;i < ss.channels;i++) { - if (!snd_mixer_selem_has_playback_channel(u->mixer_elem, i)) - break; - } - - if (i == ss.channels) { - u->sink->get_hw_volume = sink_get_hw_volume_cb; - u->sink->set_hw_volume = sink_set_hw_volume_cb; - snd_mixer_selem_get_playback_volume_range( - u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max); - } - } - if (snd_mixer_selem_has_playback_switch(u->mixer_elem)) { - u->sink->get_hw_mute = sink_get_hw_mute_cb; - u->sink->set_hw_mute = sink_set_hw_mute_cb; - } - } + u->sink->parent.process_msg = sink_process_msg; u->sink->userdata = u; - pa_sink_set_owner(u->sink, m); - pa_sink_set_description(u->sink, t = pa_sprintf_malloc("ALSA PCM on %s (%s)", dev, snd_pcm_info_get_name(pcm_info))); - pa_xfree(t); - u->pcm_fdl = pa_alsa_fdlist_new(); - assert(u->pcm_fdl); - if (pa_alsa_fdlist_init_pcm(u->pcm_fdl, u->pcm_handle, c->mainloop, fdl_callback, u) < 0) { - pa_log("failed to initialise file descriptor monitoring"); - goto fail; - } - - if (u->mixer_handle) { - u->mixer_fdl = pa_alsa_fdlist_new(); - assert(u->mixer_fdl); - if (pa_alsa_fdlist_init_mixer(u->mixer_fdl, u->mixer_handle, c->mainloop) < 0) { - pa_log("failed to initialise file descriptor monitoring"); - goto fail; - } - snd_mixer_elem_set_callback(u->mixer_elem, mixer_callback); - snd_mixer_elem_set_callback_private(u->mixer_elem, u); - } else - u->mixer_fdl = NULL; + pa_sink_set_module(u->sink, m); + pa_sink_set_asyncmsgq(u->sink, u->asyncmsgq); + pa_sink_set_description(u->sink, t = pa_sprintf_malloc( + "ALSA PCM on %s (%s)", + dev, + snd_pcm_info_get_name(pcm_info))); + pa_xfree(t); + + u->sink->is_hardware = 1; + +/* if (u->mixer_handle) { */ +/* pa_assert(u->mixer_elem); */ +/* if (snd_mixer_selem_has_playback_volume(u->mixer_elem)) { */ +/* int i; */ + +/* for (i = 0;i < ss.channels;i++) { */ +/* if (!snd_mixer_selem_has_playback_channel(u->mixer_elem, i)) */ +/* break; */ +/* } */ + +/* if (i == ss.channels) { */ +/* u->sink->get_hw_volume = sink_get_hw_volume_cb; */ +/* u->sink->set_hw_volume = sink_set_hw_volume_cb; */ +/* snd_mixer_selem_get_playback_volume_range( */ +/* u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max); */ +/* } */ +/* } */ +/* if (snd_mixer_selem_has_playback_switch(u->mixer_elem)) { */ +/* u->sink->get_hw_mute = sink_get_hw_mute_cb; */ +/* u->sink->set_hw_mute = sink_set_hw_mute_cb; */ +/* } */ +/* } */ + +/* if (u->mixer_handle) { */ +/* u->mixer_fdl = pa_alsa_fdlist_new(); */ +/* pa_assert(u->mixer_fdl); */ +/* if (pa_alsa_fdlist_init_mixer(u->mixer_fdl, u->mixer_handle, c->mainloop) < 0) { */ +/* pa_log("failed to initialise file descriptor monitoring"); */ +/* goto fail; */ +/* } */ +/* snd_mixer_elem_set_callback(u->mixer_elem, mixer_callback); */ +/* snd_mixer_elem_set_callback_private(u->mixer_elem, u); */ +/* } else */ +/* u->mixer_fdl = NULL; */ u->frame_size = frame_size; u->fragment_size = period_size * frame_size; + u->nfragments = nfrags; + u->hwbuf_size = u->fragment_size * nfrags; - pa_log_info("using %u fragments of size %lu bytes.", periods, (long unsigned)u->fragment_size); + pa_log_info("Using %u fragments of size %lu bytes.", nfrags, (long unsigned) u->fragment_size); - u->silence.memblock = pa_memblock_new(c->mempool, u->silence.length = u->fragment_size); - assert(u->silence.memblock); - pa_silence_memblock(u->silence.memblock, &ss); - u->silence.index = 0; + pa_memchunk_reset(&u->memchunk); - u->memchunk.memblock = NULL; - u->memchunk.index = u->memchunk.length = 0; + if (!(u->thread = pa_thread_new(thread_func, u))) { + pa_log("Failed to create thread."); + goto fail; + } + + /* Get initial mixer settings */ + if (u->sink->get_volume) + u->sink->get_volume(u->sink); + if (u->sink->get_mute) + u->sink->get_mute(u->sink); ret = 0; - /* Get initial mixer settings */ - if (u->sink->get_hw_volume) - u->sink->get_hw_volume(u->sink); - if (u->sink->get_hw_mute) - u->sink->get_hw_mute(u->sink); - finish: - pa_xfree(name_buf); - if (ma) pa_modargs_free(ma); @@ -582,18 +899,42 @@ fail: void pa__done(pa_core *c, pa_module*m) { struct userdata *u; - assert(c && m); + + pa_assert(c); + pa_assert(m); if (!(u = m->userdata)) return; - clear_up(u); + if (u->sink) + pa_sink_disconnect(u->sink); + + if (u->thread) { + pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, NULL); + pa_thread_free(u->thread); + } + + if (u->asyncmsgq) + pa_asyncmsgq_free(u->asyncmsgq); + if (u->sink) + pa_sink_unref(u->sink); + if (u->memchunk.memblock) pa_memblock_unref(u->memchunk.memblock); - if (u->silence.memblock) - pa_memblock_unref(u->silence.memblock); + +/* if (u->mixer_handle) */ +/* snd_mixer_close(u->mixer_handle); */ + if (u->pcm_handle) { + snd_pcm_drop(u->pcm_handle); + snd_pcm_close(u->pcm_handle); + } + + pa_xfree(u->device_name); + + snd_config_update_free_global(); + pa_xfree(u); } diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 96e0c3ce..4db1ed02 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -48,9 +48,14 @@ #include #endif +#ifdef HAVE_SYS_POLL_H +#include +#else +#include "poll.h" +#endif + #include #include -#include #include #include #include @@ -73,6 +78,7 @@ #include #include #include +#include #include "oss-util.h" #include "module-oss-symdef.h" @@ -805,7 +811,6 @@ static void thread_func(void *userdata) { } else { ssize_t l; - void *p; int loop = 0; l = u->out_fragment_size; @@ -825,6 +830,7 @@ static void thread_func(void *userdata) { } do { + void *p; ssize_t t; pa_assert(l > 0); @@ -1019,9 +1025,10 @@ finish: } int pa__init(pa_core *c, pa_module*m) { + struct audio_buf_info info; struct userdata *u = NULL; - const char *p; + const char *dev; int fd = -1; int nfrags, frag_size; int mode, caps; @@ -1074,7 +1081,7 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - if ((fd = pa_oss_open(p = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), &mode, &caps)) < 0) + if ((fd = pa_oss_open(dev = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), &mode, &caps)) < 0) goto fail; if (use_mmap && (!(caps & DSP_CAP_MMAP) || !(caps & DSP_CAP_TRIGGER))) { @@ -1087,7 +1094,7 @@ int pa__init(pa_core *c, pa_module*m) { use_mmap = 0; } - if (pa_oss_get_hw_description(p, hwdesc, sizeof(hwdesc)) >= 0) + if (pa_oss_get_hw_description(dev, hwdesc, sizeof(hwdesc)) >= 0) pa_log_info("Hardware name is '%s'.", hwdesc); else hwdesc[0] = 0; @@ -1111,11 +1118,12 @@ int pa__init(pa_core *c, pa_module*m) { u->core = c; u->module = m; m->userdata = u; + u->fd = fd; u->use_getospace = u->use_getispace = 1; u->use_getodelay = 1; u->use_input_volume = u->use_pcm_volume = 1; u->mode = mode; - u->device_name = pa_xstrdup(p); + u->device_name = pa_xstrdup(dev); u->in_nfrags = u->out_nfrags = u->nfrags = nfrags; u->out_fragment_size = u->in_fragment_size = u->frag_size = frag_size; u->use_mmap = use_mmap; @@ -1159,25 +1167,28 @@ int pa__init(pa_core *c, pa_module*m) { if ((name = pa_modargs_get_value(ma, "source_name", NULL))) namereg_fail = 1; else { - name = name_buf = pa_sprintf_malloc("oss_input.%s", pa_path_get_filename(p)); + name = name_buf = pa_sprintf_malloc("oss_input.%s", pa_path_get_filename(dev)); namereg_fail = 0; } u->source = pa_source_new(c, __FILE__, name, namereg_fail, &ss, &map); pa_xfree(name_buf); - if (!u->source) + if (!u->source) { + pa_log("Failed to create source object"); goto fail; + } u->source->parent.process_msg = source_process_msg; u->source->userdata = u; pa_source_set_module(u->source, m); pa_source_set_asyncmsgq(u->source, u->asyncmsgq); - pa_source_set_description(u->source, t = pa_sprintf_malloc("OSS PCM on %s%s%s%s", - p, - hwdesc[0] ? " (" : "", - hwdesc[0] ? hwdesc : "", - hwdesc[0] ? ")" : "")); + pa_source_set_description(u->source, t = pa_sprintf_malloc( + "OSS PCM on %s%s%s%s", + dev, + hwdesc[0] ? " (" : "", + hwdesc[0] ? hwdesc : "", + hwdesc[0] ? ")" : "")); pa_xfree(t); u->source->is_hardware = 1; u->source->refresh_volume = 1; @@ -1210,25 +1221,28 @@ try_write: if ((name = pa_modargs_get_value(ma, "sink_name", NULL))) namereg_fail = 1; else { - name = name_buf = pa_sprintf_malloc("oss_output.%s", pa_path_get_filename(p)); + name = name_buf = pa_sprintf_malloc("oss_output.%s", pa_path_get_filename(dev)); namereg_fail = 0; } u->sink = pa_sink_new(c, __FILE__, name, namereg_fail, &ss, &map); pa_xfree(name_buf); - if (!u->sink) + if (!u->sink) { + pa_log("Failed to create sink object"); goto fail; + } u->sink->parent.process_msg = sink_process_msg; u->sink->userdata = u; pa_sink_set_module(u->sink, m); pa_sink_set_asyncmsgq(u->sink, u->asyncmsgq); - pa_sink_set_description(u->sink, t = pa_sprintf_malloc("OSS PCM on %s%s%s%s", - p, - hwdesc[0] ? " (" : "", - hwdesc[0] ? hwdesc : "", - hwdesc[0] ? ")" : "")); + pa_sink_set_description(u->sink, t = pa_sprintf_malloc( + "OSS PCM on %s%s%s%s", + dev, + hwdesc[0] ? " (" : "", + hwdesc[0] ? hwdesc : "", + hwdesc[0] ? ")" : "")); pa_xfree(t); u->sink->is_hardware = 1; u->sink->refresh_volume = 1; @@ -1241,8 +1255,6 @@ go_on: pa_assert(u->source || u->sink); - u->fd = fd; - pa_memchunk_reset(&u->memchunk); if (!(u->thread = pa_thread_new(thread_func, u))) { @@ -1261,7 +1273,10 @@ go_on: return 0; fail: - if (fd >= 0) + + if (u) + pa__done(c, m); + else if (fd >= 0) close(fd); if (ma) -- cgit From dd40020057a1452ed75a682e8b07032e5a35aa9c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 28 Jul 2007 19:26:40 +0000 Subject: bring back alsa fd list managemet, since we need it for proper mixer change notification git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1552 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/alsa-util.c | 207 +++++++++++++++++++++++++++++++++++++++++++++--- src/modules/alsa-util.h | 6 ++ 2 files changed, 201 insertions(+), 12 deletions(-) diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c index 520215fa..dd9ac79e 100644 --- a/src/modules/alsa-util.c +++ b/src/modules/alsa-util.c @@ -33,9 +33,190 @@ #include #include +#include #include "alsa-util.h" +struct pa_alsa_fdlist { + int num_fds; + struct pollfd *fds; + /* This is a temporary buffer used to avoid lots of mallocs */ + struct pollfd *work_fds; + + snd_mixer_t *mixer; + + pa_mainloop_api *m; + pa_defer_event *defer; + pa_io_event **ios; + + int polled; + + void (*cb)(void *userdata); + void *userdata; +}; + +static void io_cb(pa_mainloop_api*a, pa_io_event* e, PA_GCC_UNUSED int fd, pa_io_event_flags_t events, void *userdata) { + + struct pa_alsa_fdlist *fdl = userdata; + int err, i; + unsigned short revents; + + pa_assert(a); + pa_assert(fdl); + pa_assert(fdl->mixer); + pa_assert(fdl->fds); + pa_assert(fdl->work_fds); + + if (fdl->polled) + return; + + fdl->polled = 1; + + memcpy(fdl->work_fds, fdl->fds, sizeof(struct pollfd) * fdl->num_fds); + + for (i = 0;i < fdl->num_fds; i++) { + if (e == fdl->ios[i]) { + if (events & PA_IO_EVENT_INPUT) + fdl->work_fds[i].revents |= POLLIN; + if (events & PA_IO_EVENT_OUTPUT) + fdl->work_fds[i].revents |= POLLOUT; + if (events & PA_IO_EVENT_ERROR) + fdl->work_fds[i].revents |= POLLERR; + if (events & PA_IO_EVENT_HANGUP) + fdl->work_fds[i].revents |= POLLHUP; + break; + } + } + + assert(i != fdl->num_fds); + + if ((err = snd_mixer_poll_descriptors_revents(fdl->mixer, fdl->work_fds, fdl->num_fds, &revents)) < 0) { + pa_log_error("Unable to get poll revent: %s", snd_strerror(err)); + return; + } + + a->defer_enable(fdl->defer, 1); + + if (revents) + snd_mixer_handle_events(fdl->mixer); +} + +static void defer_cb(pa_mainloop_api*a, PA_GCC_UNUSED pa_defer_event* e, void *userdata) { + struct pa_alsa_fdlist *fdl = userdata; + int num_fds, i, err; + struct pollfd *temp; + + pa_assert(a); + pa_assert(fdl); + pa_assert(fdl->mixer); + + a->defer_enable(fdl->defer, 0); + + num_fds = snd_mixer_poll_descriptors_count(fdl->mixer); + pa_assert(num_fds > 0); + + if (num_fds != fdl->num_fds) { + if (fdl->fds) + pa_xfree(fdl->fds); + if (fdl->work_fds) + pa_xfree(fdl->work_fds); + fdl->fds = pa_xnew0(struct pollfd, num_fds); + fdl->work_fds = pa_xnew(struct pollfd, num_fds); + } + + memset(fdl->work_fds, 0, sizeof(struct pollfd) * num_fds); + + if ((err = snd_mixer_poll_descriptors(fdl->mixer, fdl->work_fds, num_fds)) < 0) { + pa_log_error("Unable to get poll descriptors: %s", snd_strerror(err)); + return; + } + + fdl->polled = 0; + + if (memcmp(fdl->fds, fdl->work_fds, sizeof(struct pollfd) * num_fds) == 0) + return; + + if (fdl->ios) { + for (i = 0; i < fdl->num_fds; i++) + a->io_free(fdl->ios[i]); + + if (num_fds != fdl->num_fds) { + pa_xfree(fdl->ios); + fdl->ios = NULL; + } + } + + if (!fdl->ios) + fdl->ios = pa_xnew(pa_io_event*, num_fds); + + /* Swap pointers */ + temp = fdl->work_fds; + fdl->work_fds = fdl->fds; + fdl->fds = temp; + + fdl->num_fds = num_fds; + + for (i = 0;i < num_fds;i++) + fdl->ios[i] = a->io_new(a, fdl->fds[i].fd, + ((fdl->fds[i].events & POLLIN) ? PA_IO_EVENT_INPUT : 0) | + ((fdl->fds[i].events & POLLOUT) ? PA_IO_EVENT_OUTPUT : 0), + io_cb, fdl); +} + +struct pa_alsa_fdlist *pa_alsa_fdlist_new(void) { + struct pa_alsa_fdlist *fdl; + + fdl = pa_xnew0(struct pa_alsa_fdlist, 1); + + fdl->num_fds = 0; + fdl->fds = NULL; + fdl->work_fds = NULL; + fdl->mixer = NULL; + fdl->m = NULL; + fdl->defer = NULL; + fdl->ios = NULL; + fdl->polled = 0; + + return fdl; +} + +void pa_alsa_fdlist_free(struct pa_alsa_fdlist *fdl) { + pa_assert(fdl); + + if (fdl->defer) { + pa_assert(fdl->m); + fdl->m->defer_free(fdl->defer); + } + + if (fdl->ios) { + int i; + pa_assert(fdl->m); + for (i = 0;i < fdl->num_fds;i++) + fdl->m->io_free(fdl->ios[i]); + pa_xfree(fdl->ios); + } + + if (fdl->fds) + pa_xfree(fdl->fds); + if (fdl->work_fds) + pa_xfree(fdl->work_fds); + + pa_xfree(fdl); +} + +int pa_alsa_fdlist_set_mixer(struct pa_alsa_fdlist *fdl, snd_mixer_t *mixer_handle, pa_mainloop_api* m) { + pa_assert(fdl); + pa_assert(mixer_handle); + pa_assert(m); + pa_assert(!fdl->m); + + fdl->mixer = mixer_handle; + fdl->m = m; + fdl->defer = m->defer_new(m, defer_cb, fdl); + + return 0; +} + static int set_format(snd_pcm_t *pcm_handle, snd_pcm_hw_params_t *hwparams, pa_sample_format_t *f) { static const snd_pcm_format_t format_trans[] = { @@ -61,8 +242,8 @@ static int set_format(snd_pcm_t *pcm_handle, snd_pcm_hw_params_t *hwparams, pa_s int i, ret; - assert(pcm_handle); - assert(f); + pa_assert(pcm_handle); + pa_assert(f); if ((ret = snd_pcm_hw_params_set_format(pcm_handle, hwparams, format_trans[*f])) >= 0) return ret; @@ -103,10 +284,10 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *p pa_sample_format_t f = ss->format; snd_pcm_hw_params_t *hwparams; - assert(pcm_handle); - assert(ss); - assert(periods); - assert(period_size); + pa_assert(pcm_handle); + pa_assert(ss); + pa_assert(periods); + pa_assert(period_size); buffer_size = *periods * *period_size; @@ -166,10 +347,10 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *p (ret = snd_pcm_hw_params_get_period_size(hwparams, period_size, NULL)) < 0) goto finish; - assert(buffer_size > 0); - assert(*period_size > 0); + pa_assert(buffer_size > 0); + pa_assert(*period_size > 0); *periods = buffer_size / *period_size; - assert(*periods > 0); + pa_assert(*periods > 0); ret = 0; @@ -183,7 +364,8 @@ finish: int pa_alsa_prepare_mixer(snd_mixer_t *mixer, const char *dev) { int err; - assert(mixer && dev); + pa_assert(mixer); + pa_assert(dev); if ((err = snd_mixer_attach(mixer, dev)) < 0) { pa_log_warn("Unable to attach to mixer %s: %s", dev, snd_strerror(err)); @@ -206,10 +388,11 @@ int pa_alsa_prepare_mixer(snd_mixer_t *mixer, const char *dev) { snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name, const char *fallback) { snd_mixer_elem_t *elem; snd_mixer_selem_id_t *sid = NULL; + snd_mixer_selem_id_alloca(&sid); - assert(mixer); - assert(name); + pa_assert(mixer); + pa_assert(name); snd_mixer_selem_id_set_name(sid, name); diff --git a/src/modules/alsa-util.h b/src/modules/alsa-util.h index 0cde087f..f79325c6 100644 --- a/src/modules/alsa-util.h +++ b/src/modules/alsa-util.h @@ -32,6 +32,12 @@ #include +typedef struct pa_alsa_fdlist pa_alsa_fdlist; + +struct pa_alsa_fdlist *pa_alsa_fdlist_new(void); +void pa_alsa_fdlist_free(struct pa_alsa_fdlist *fdl); +int pa_alsa_fdlist_set_mixer(struct pa_alsa_fdlist *fdl, snd_mixer_t *mixer_handle, pa_mainloop_api* m); + int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *periods, snd_pcm_uframes_t *period_size, int *use_mmap); int pa_alsa_prepare_mixer(snd_mixer_t *mixer, const char *dev); -- cgit From 9dac60c80e9990a5f9d316233ba2c5b98d68acae Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 28 Jul 2007 19:27:01 +0000 Subject: reload OSS volume after unsuspend git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1553 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-oss.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 4db1ed02..7ead6784 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -559,6 +559,11 @@ static int unsuspend(struct userdata *u) { u->out_mmap_current = u->in_mmap_current = 0; u->out_mmap_saved_nfrags = u->in_mmap_saved_nfrags = 0; + + if (u->sink) + pa_sink_get_volume(u->sink); + if (u->source) + pa_source_get_volume(u->source); /* Now, start only what we need */ trigger(u, 0); -- cgit From 10cb0483d943f37da0851a665f5a17fa2dc92522 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 28 Jul 2007 19:30:10 +0000 Subject: restore proper mixer volume control git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1554 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 317 ++++++++++++++++++++--------------------- 1 file changed, 152 insertions(+), 165 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 4fc2f3a2..1350090e 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -82,9 +82,10 @@ struct userdata { snd_pcm_t *pcm_handle; -/* snd_mixer_t *mixer_handle; */ -/* snd_mixer_elem_t *mixer_elem; */ -/* long hw_volume_max, hw_volume_min; */ + pa_alsa_fdlist *mixer_fdl; + snd_mixer_t *mixer_handle; + snd_mixer_elem_t *mixer_elem; + long hw_volume_max, hw_volume_min; size_t frame_size, fragment_size, hwbuf_size; unsigned nfragments; @@ -283,6 +284,9 @@ static int unsuspend(struct userdata *u) { goto fail; } + pa_sink_get_volume(u->sink); + pa_sink_get_mute(u->sink); + u->first = 1; pa_log_debug("Resumed successfully..."); @@ -328,160 +332,133 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk * } break; - -/* case PA_SINK_MESSAGE_SET_VOLUME: */ - -/* if (u->use_pcm_volume && u->fd >= 0) { */ - -/* if (pa_oss_set_pcm_volume(u->fd, &u->sink->sample_spec, ((pa_cvolume*) data)) < 0) { */ -/* pa_log_info("Device doesn't support setting mixer settings: %s", pa_cstrerror(errno)); */ -/* u->use_pcm_volume = 0; */ -/* } else */ -/* return 0; */ -/* } */ - -/* break; */ - -/* case PA_SINK_MESSAGE_GET_VOLUME: */ - -/* if (u->use_pcm_volume && u->fd >= 0) { */ - -/* if (pa_oss_get_pcm_volume(u->fd, &u->sink->sample_spec, ((pa_cvolume*) data)) < 0) { */ -/* pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno)); */ -/* u->use_pcm_volume = 0; */ -/* } else */ -/* return 0; */ -/* } */ - -/* break; */ } return pa_sink_process_msg(o, code, data, chunk); } +static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) { + struct userdata *u = snd_mixer_elem_get_callback_private(elem); -/* static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) { */ -/* struct userdata *u = snd_mixer_elem_get_callback_private(elem); */ + pa_assert(u); + pa_assert(u->mixer_handle); -/* pa_assert(u && u->mixer_handle); */ + if (mask == SND_CTL_EVENT_MASK_REMOVE) + return 0; -/* if (mask == SND_CTL_EVENT_MASK_REMOVE) */ -/* return 0; */ + if (mask & SND_CTL_EVENT_MASK_VALUE) { + pa_sink_get_volume(u->sink); + pa_sink_get_mute(u->sink); + } -/* if (mask & SND_CTL_EVENT_MASK_VALUE) { */ -/* if (u->sink->get_hw_volume) */ -/* u->sink->get_hw_volume(u->sink); */ -/* if (u->sink->get_hw_mute) */ -/* u->sink->get_hw_mute(u->sink); */ -/* pa_subscription_post(u->sink->core, */ -/* PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, */ -/* u->sink->index); */ -/* } */ + return 0; +} -/* return 0; */ -/* } */ +static int sink_get_volume_cb(pa_sink *s) { + struct userdata *u = s->userdata; + int err; + int i; -/* static int sink_get_hw_volume_cb(pa_sink *s) { */ -/* struct userdata *u = s->userdata; */ -/* int err; */ -/* int i; */ + pa_assert(u); + pa_assert(u->mixer_elem); -/* pa_assert(u); */ -/* pa_assert(u->mixer_elem); */ + for (i = 0; i < s->sample_spec.channels; i++) { + long set_vol, vol; -/* for (i = 0; i < s->hw_volume.channels; i++) { */ -/* long set_vol, vol; */ + pa_assert(snd_mixer_selem_has_playback_channel(u->mixer_elem, i)); -/* pa_assert(snd_mixer_selem_has_playback_channel(u->mixer_elem, i)); */ + if ((err = snd_mixer_selem_get_playback_volume(u->mixer_elem, i, &vol)) < 0) + goto fail; -/* if ((err = snd_mixer_selem_get_playback_volume(u->mixer_elem, i, &vol)) < 0) */ -/* goto fail; */ + set_vol = (long) roundf(((float) s->volume.values[i] * (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min; -/* set_vol = (long) roundf(((float) s->hw_volume.values[i] * (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min; */ + /* Try to avoid superfluous volume changes */ + if (set_vol != vol) + s->volume.values[i] = (pa_volume_t) roundf(((float) (vol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min)); + } -/* /\* Try to avoid superfluous volume changes *\/ */ -/* if (set_vol != vol) */ -/* s->hw_volume.values[i] = (pa_volume_t) roundf(((float) (vol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min)); */ -/* } */ + return 0; -/* return 0; */ +fail: + pa_log_error("Unable to read volume: %s", snd_strerror(err)); + + s->get_volume = NULL; + s->set_volume = NULL; + return -1; +} -/* fail: */ -/* pa_log_error("Unable to read volume: %s", snd_strerror(err)); */ -/* s->get_hw_volume = NULL; */ -/* s->set_hw_volume = NULL; */ -/* return -1; */ -/* } */ +static int sink_set_volume_cb(pa_sink *s) { + struct userdata *u = s->userdata; + int err; + int i; -/* static int sink_set_hw_volume_cb(pa_sink *s) { */ -/* struct userdata *u = s->userdata; */ -/* int err; */ -/* int i; */ -/* pa_volume_t vol; */ + pa_assert(u); + pa_assert(u->mixer_elem); -/* pa_assert(u); */ -/* pa_assert(u->mixer_elem); */ + for (i = 0; i < s->sample_spec.channels; i++) { + long alsa_vol; + pa_volume_t vol; -/* for (i = 0; i < s->hw_volume.channels; i++) { */ -/* long alsa_vol; */ + pa_assert(snd_mixer_selem_has_playback_channel(u->mixer_elem, i)); -/* pa_assert(snd_mixer_selem_has_playback_channel(u->mixer_elem, i)); */ + vol = s->volume.values[i]; -/* vol = s->hw_volume.values[i]; */ + if (vol > PA_VOLUME_NORM) + vol = PA_VOLUME_NORM; -/* if (vol > PA_VOLUME_NORM) */ -/* vol = PA_VOLUME_NORM; */ + alsa_vol = (long) roundf(((float) vol * (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min; -/* alsa_vol = (long) roundf(((float) vol * (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min; */ + if ((err = snd_mixer_selem_set_playback_volume(u->mixer_elem, i, alsa_vol)) < 0) + goto fail; + } -/* if ((err = snd_mixer_selem_set_playback_volume(u->mixer_elem, i, alsa_vol)) < 0) */ -/* goto fail; */ -/* } */ + return 0; -/* return 0; */ +fail: + pa_log_error("Unable to set volume: %s", snd_strerror(err)); + + s->get_volume = NULL; + s->set_volume = NULL; + return -1; +} -/* fail: */ -/* pa_log_error("Unable to set volume: %s", snd_strerror(err)); */ -/* s->get_hw_volume = NULL; */ -/* s->set_hw_volume = NULL; */ -/* return -1; */ -/* } */ +static int sink_get_mute_cb(pa_sink *s) { + struct userdata *u = s->userdata; + int err, sw; -/* static int sink_get_hw_mute_cb(pa_sink *s) { */ -/* struct userdata *u = s->userdata; */ -/* int err, sw; */ + pa_assert(u); + pa_assert(u->mixer_elem); -/* pa_assert(u && u->mixer_elem); */ + if ((err = snd_mixer_selem_get_playback_switch(u->mixer_elem, 0, &sw)) < 0) { + pa_log_error("Unable to get switch: %s", snd_strerror(err)); -/* err = snd_mixer_selem_get_playback_switch(u->mixer_elem, 0, &sw); */ -/* if (err) { */ -/* pa_log_error("Unable to get switch: %s", snd_strerror(err)); */ -/* s->get_hw_mute = NULL; */ -/* s->set_hw_mute = NULL; */ -/* return -1; */ -/* } */ + s->get_mute = NULL; + s->set_mute = NULL; + return -1; + } -/* s->hw_muted = !sw; */ + s->muted = !sw; -/* return 0; */ -/* } */ + return 0; +} -/* static int sink_set_hw_mute_cb(pa_sink *s) { */ -/* struct userdata *u = s->userdata; */ -/* int err; */ +static int sink_set_mute_cb(pa_sink *s) { + struct userdata *u = s->userdata; + int err; -/* pa_assert(u && u->mixer_elem); */ + pa_assert(u); + pa_assert(u->mixer_elem); -/* err = snd_mixer_selem_set_playback_switch_all(u->mixer_elem, !s->hw_muted); */ -/* if (err) { */ -/* pa_log_error("Unable to set switch: %s", snd_strerror(err)); */ -/* s->get_hw_mute = NULL; */ -/* s->set_hw_mute = NULL; */ -/* return -1; */ -/* } */ + if ((err = snd_mixer_selem_set_playback_switch_all(u->mixer_elem, !s->muted)) < 0) { + pa_log_error("Unable to set switch: %s", snd_strerror(err)); + + s->get_mute = NULL; + s->set_mute = NULL; + return -1; + } -/* return 0; */ -/* } */ + return 0; +} static void thread_func(void *userdata) { enum { @@ -776,6 +753,9 @@ int pa__init(pa_core *c, pa_module*m) { u->use_mmap = use_mmap = b; } + if (u->use_mmap) + pa_log_info("Successfully enabled mmap() mode."); + /* ALSA might tweak the sample spec, so recalculate the frame size */ frame_size = pa_frame_size(&ss); @@ -783,16 +763,17 @@ int pa__init(pa_core *c, pa_module*m) { /* Seems ALSA didn't like the channel number, so let's fix the channel map */ pa_channel_map_init_auto(&map, ss.channels, PA_CHANNEL_MAP_ALSA); -/* if ((err = snd_mixer_open(&u->mixer_handle, 0)) < 0) */ -/* pa_log_warn("Error opening mixer: %s", snd_strerror(err)); */ -/* else { */ + if ((err = snd_mixer_open(&u->mixer_handle, 0)) < 0) + pa_log_warn("Error opening mixer: %s", snd_strerror(err)); + else { -/* if ((pa_alsa_prepare_mixer(u->mixer_handle, dev) < 0) || */ -/* !(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "PCM", "Master"))) { */ -/* snd_mixer_close(u->mixer_handle); */ -/* u->mixer_handle = NULL; */ -/* } */ -/* } */ + if ((pa_alsa_prepare_mixer(u->mixer_handle, dev) < 0) || + !(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "PCM", "Master"))) { + + snd_mixer_close(u->mixer_handle); + u->mixer_handle = NULL; + } + } if ((name = pa_modargs_get_value(ma, "sink_name", NULL))) namereg_fail = 1; @@ -821,41 +802,6 @@ int pa__init(pa_core *c, pa_module*m) { pa_xfree(t); u->sink->is_hardware = 1; - -/* if (u->mixer_handle) { */ -/* pa_assert(u->mixer_elem); */ -/* if (snd_mixer_selem_has_playback_volume(u->mixer_elem)) { */ -/* int i; */ - -/* for (i = 0;i < ss.channels;i++) { */ -/* if (!snd_mixer_selem_has_playback_channel(u->mixer_elem, i)) */ -/* break; */ -/* } */ - -/* if (i == ss.channels) { */ -/* u->sink->get_hw_volume = sink_get_hw_volume_cb; */ -/* u->sink->set_hw_volume = sink_set_hw_volume_cb; */ -/* snd_mixer_selem_get_playback_volume_range( */ -/* u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max); */ -/* } */ -/* } */ -/* if (snd_mixer_selem_has_playback_switch(u->mixer_elem)) { */ -/* u->sink->get_hw_mute = sink_get_hw_mute_cb; */ -/* u->sink->set_hw_mute = sink_set_hw_mute_cb; */ -/* } */ -/* } */ - -/* if (u->mixer_handle) { */ -/* u->mixer_fdl = pa_alsa_fdlist_new(); */ -/* pa_assert(u->mixer_fdl); */ -/* if (pa_alsa_fdlist_init_mixer(u->mixer_fdl, u->mixer_handle, c->mainloop) < 0) { */ -/* pa_log("failed to initialise file descriptor monitoring"); */ -/* goto fail; */ -/* } */ -/* snd_mixer_elem_set_callback(u->mixer_elem, mixer_callback); */ -/* snd_mixer_elem_set_callback_private(u->mixer_elem, u); */ -/* } else */ -/* u->mixer_fdl = NULL; */ u->frame_size = frame_size; u->fragment_size = period_size * frame_size; @@ -866,6 +812,44 @@ int pa__init(pa_core *c, pa_module*m) { pa_memchunk_reset(&u->memchunk); + if (u->mixer_handle) { + /* Initialize mixer code */ + + pa_assert(u->mixer_elem); + + if (snd_mixer_selem_has_playback_volume(u->mixer_elem)) { + int i; + + for (i = 0;i < ss.channels; i++) { + if (!snd_mixer_selem_has_playback_channel(u->mixer_elem, i)) + break; + } + + if (i == ss.channels) { + u->sink->get_volume = sink_get_volume_cb; + u->sink->set_volume = sink_set_volume_cb; + snd_mixer_selem_get_playback_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max); + } + } + if (snd_mixer_selem_has_playback_switch(u->mixer_elem)) { + u->sink->get_mute = sink_get_mute_cb; + u->sink->set_mute = sink_set_mute_cb; + } + + u->mixer_fdl = pa_alsa_fdlist_new(); + pa_assert(u->mixer_fdl); + + if (pa_alsa_fdlist_set_mixer(u->mixer_fdl, u->mixer_handle, c->mainloop) < 0) { + pa_log("failed to initialise file descriptor monitoring"); + goto fail; + } + + snd_mixer_elem_set_callback(u->mixer_elem, mixer_callback); + snd_mixer_elem_set_callback_private(u->mixer_elem, u); + } else + u->mixer_fdl = NULL; + + if (!(u->thread = pa_thread_new(thread_func, u))) { pa_log("Failed to create thread."); goto fail; @@ -922,9 +906,12 @@ void pa__done(pa_core *c, pa_module*m) { if (u->memchunk.memblock) pa_memblock_unref(u->memchunk.memblock); + + if (u->mixer_fdl) + pa_alsa_fdlist_free(u->mixer_fdl); -/* if (u->mixer_handle) */ -/* snd_mixer_close(u->mixer_handle); */ + if (u->mixer_handle) + snd_mixer_close(u->mixer_handle); if (u->pcm_handle) { snd_pcm_drop(u->pcm_handle); -- cgit From 5fbb8e12d6d7a881100f53ea77f646b2bb32fc08 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 28 Jul 2007 20:58:33 +0000 Subject: add PA_SINK_OPENED/PA_SOURCE_OPENED macros for easier checking for _IDLE or _RUNNING states git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1555 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink.h | 6 +++++- src/pulsecore/source.h | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index dab97453..958279c5 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -157,5 +157,9 @@ void pa_sink_render_into(pa_sink*s, pa_memchunk *target); void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target); int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk); - + +static inline int PA_SINK_OPENED(pa_sink_state_t x) { + return x == PA_SINK_RUNNING || x == PA_SINK_IDLE; +} + #endif diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index 4db2dedf..e2b02ceb 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -148,4 +148,8 @@ unsigned pa_source_used_by(pa_source *s); void pa_source_post(pa_source*s, const pa_memchunk *b); int pa_source_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk); +static inline int PA_SOURCE_OPENED(pa_source_state_t x) { + return x == PA_SOURCE_RUNNING || x == PA_SOURCE_IDLE; +} + #endif -- cgit From 8aee345ccb8292fe2acf354dc9419eb2208eeef8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 28 Jul 2007 21:00:16 +0000 Subject: Fix suspending/resuming git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1556 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 110 ++++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 52 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 1350090e..05fb90bb 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -116,6 +116,7 @@ static int mmap_write(struct userdata *u) { int err; const snd_pcm_channel_area_t *areas; snd_pcm_uframes_t offset, frames; + int work_done = 0; pa_assert(u); pa_assert(u->sink); @@ -134,8 +135,8 @@ static int mmap_write(struct userdata *u) { if ((err = snd_pcm_recover(u->pcm_handle, n, 1)) == 0) continue; - if (err == EAGAIN) - return 0; + if (err == -EAGAIN) + return work_done; pa_log("snd_pcm_avail_update: %s", snd_strerror(n)); return -1; @@ -144,7 +145,7 @@ static int mmap_write(struct userdata *u) { /* pa_log("Got request for %i samples", (int) n); */ if (n <= 0) - return 0; + return work_done; frames = n; @@ -158,8 +159,8 @@ static int mmap_write(struct userdata *u) { if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0) continue; - if (err == EAGAIN) - return 0; + if (err == -EAGAIN) + return work_done; pa_log("Failed to write data to DSP: %s", snd_strerror(err)); return -1; @@ -195,13 +196,15 @@ static int mmap_write(struct userdata *u) { if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0) continue; - if (err == EAGAIN) - return 0; + if (err == -EAGAIN) + return work_done; pa_log("Failed to write data to DSP: %s", snd_strerror(err)); return -1; } + work_done = 1; + /* pa_log("wrote %i samples", (int) frames); */ } } @@ -279,7 +282,7 @@ static int unsuspend(struct userdata *u) { goto fail; } - if (!nfrags != u->nfragments || period_size*u->frame_size != u->fragment_size) { + if (nfrags != u->nfragments || period_size*u->frame_size != u->fragment_size) { pa_log_warn("Resume failed, couldn't restore original fragment settings."); goto fail; } @@ -318,17 +321,28 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk * case PA_SINK_MESSAGE_SET_STATE: - if (PA_PTR_TO_UINT(data) == PA_SINK_SUSPENDED) { - pa_assert(u->sink->thread_info.state != PA_SINK_SUSPENDED); - - if (suspend(u) < 0) - return -1; + switch ((pa_sink_state_t) PA_PTR_TO_UINT(data)) { - } else if (u->sink->thread_info.state == PA_SINK_SUSPENDED) { - pa_assert(PA_PTR_TO_UINT(data) != PA_SINK_SUSPENDED); + case PA_SINK_SUSPENDED: + pa_assert(PA_SINK_OPENED(u->sink->thread_info.state)); + + if (suspend(u) < 0) + return -1; + + break; + + case PA_SINK_IDLE: + case PA_SINK_RUNNING: + + if (u->sink->thread_info.state == PA_SINK_SUSPENDED) { + if (unsuspend(u) < 0) + return -1; + } + + break; - if (unsuspend(u) < 0) - return -1; + case PA_SINK_DISCONNECTED: + ; } break; @@ -499,7 +513,7 @@ static void thread_func(void *userdata) { pa_memchunk chunk; int r; -/* pa_log("loop"); */ +/* pa_log("loop"); */ /* Check whether there is a message for us to process */ if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { @@ -521,19 +535,15 @@ static void thread_func(void *userdata) { /* Render some data and write it to the dsp */ - if (u->sink->thread_info.state != PA_SINK_SUSPENDED && ((revents & POLLOUT) || u->first == 1)) { + if (PA_SINK_OPENED(u->sink->thread_info.state) && ((revents & POLLOUT) || u->first == 1)) { + int work_done = 0; + pa_assert(u->pcm_handle); if (u->use_mmap) { - int ret; - if ((ret = mmap_write(u)) < 0) + if ((work_done = mmap_write(u)) < 0) goto fail; - revents &= ~POLLOUT; - - if (ret > 0) - continue; - } else { ssize_t l; @@ -542,11 +552,11 @@ static void thread_func(void *userdata) { l = snd_pcm_status_get_avail(status) * u->frame_size; else l = u->fragment_size; - - do { + + while (l > 0) { void *p; snd_pcm_sframes_t t; - + pa_assert(l > 0); if (u->memchunk.length <= 0) @@ -558,7 +568,7 @@ static void thread_func(void *userdata) { t = snd_pcm_writei(u->pcm_handle, (uint8_t*) p + u->memchunk.index, u->memchunk.length / u->frame_size); pa_memblock_release(u->memchunk.memblock); -/* pa_log("wrote %i bytes of %u", t, l); */ +/* pa_log("wrote %i bytes of %u (%u)", t*u->frame_size, u->memchunk.length, l); */ pa_assert(t != 0); @@ -572,12 +582,9 @@ static void thread_func(void *userdata) { if ((t = snd_pcm_recover(u->pcm_handle, t, 1)) == 0) continue; - if (t == EAGAIN) { - pa_log_debug("EAGAIN"); - - revents &= ~POLLOUT; + if (t == -EAGAIN) { + pa_log_debug("EAGAIN"); break; - } else { pa_log("Failed to write data to DSP: %s", snd_strerror(t)); goto fail; @@ -594,24 +601,23 @@ static void thread_func(void *userdata) { } l -= t * u->frame_size; - - revents &= ~POLLOUT; + + work_done = 1; } - - } while (l > 0); - - continue; + } } - if (u->first) { - pa_log_info("Starting playback."); - - if ((err = snd_pcm_start(u->pcm_handle)) < 0) { - pa_log("Failed to start PCM playback: %s", snd_strerror(err)); - goto fail; - } + revents &= ~POLLOUT; + + if (work_done) { - u->first = 0; + if (u->first) { + pa_log_info("Starting playback."); + snd_pcm_start(u->pcm_handle); + u->first = 0; + } + + continue; } } @@ -619,8 +625,8 @@ static void thread_func(void *userdata) { if (pa_asyncmsgq_before_poll(u->asyncmsgq) < 0) continue; -/* pa_log("polling for %i", POLLFD_ALSA_BASE + (u->sink->thread_info.state != PA_SINK_SUSPENDED ? n_alsa_fds : 0)); */ - r = poll(pollfd, POLLFD_ALSA_BASE + (u->sink->thread_info.state != PA_SINK_SUSPENDED ? n_alsa_fds : 0), -1); +/* pa_log("polling for %i", POLLFD_ALSA_BASE + (PA_SINK_OPENED(u->sink->thread_info.state) ? n_alsa_fds : 0)); */ + r = poll(pollfd, POLLFD_ALSA_BASE + (PA_SINK_OPENED(u->sink->thread_info.state) ? n_alsa_fds : 0), -1); /*pa_log("polling got dsp=%i amq=%i (%i)", r > 0 ? pollfd[POLLFD_DSP].revents : 0, r > 0 ? pollfd[POLLFD_ASYNCQ].revents : 0, r); */ /* pa_log("poll end"); */ @@ -639,7 +645,7 @@ static void thread_func(void *userdata) { pa_assert(r > 0); - if (u->sink->thread_info.state != PA_SINK_SUSPENDED) { + if (PA_SINK_OPENED(u->sink->thread_info.state)) { if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, pollfd + POLLFD_ALSA_BASE, n_alsa_fds, &revents)) < 0) { pa_log("snd_pcm_poll_descriptors_revents() failed: %s", snd_strerror(err)); goto fail; -- cgit From 16154507675ba7fa37f5478ecd6717d9c616439d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 28 Jul 2007 22:55:12 +0000 Subject: It is now allowed to call pa_sink_get_volume() from thread context git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1557 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 05fb90bb..cf56d8cf 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -287,9 +287,8 @@ static int unsuspend(struct userdata *u) { goto fail; } - pa_sink_get_volume(u->sink); - pa_sink_get_mute(u->sink); - + /* FIXME: We need to reload the volume somehow */ + u->first = 1; pa_log_debug("Resumed successfully..."); -- cgit From 81aa8ea37c8cc974246d580d25a604a6e309e472 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 28 Jul 2007 22:55:44 +0000 Subject: drop data from inputs only when in running state git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1558 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 015cf4d5..7f2a8b39 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -408,7 +408,8 @@ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) { result->index = 0; } - inputs_drop(s, info, n, result->length); + if (s->thread_info.state == PA_SINK_RUNNING) + inputs_drop(s, info, n, result->length); if (s->monitor_source) pa_source_post(s->monitor_source, result); @@ -472,7 +473,8 @@ void pa_sink_render_into(pa_sink*s, pa_memchunk *target) { pa_memblock_release(target->memblock); } - inputs_drop(s, info, n, target->length); + if (s->thread_info.state == PA_SINK_RUNNING) + inputs_drop(s, info, n, target->length); if (s->monitor_source) pa_source_post(s->monitor_source, target); -- cgit From 6afbbba1025d04ee5ebeadba563c138e1d7b2aed Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 28 Jul 2007 22:56:39 +0000 Subject: fix suspending logic git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1559 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-oss.c | 149 ++++++++++++++++++++++++++++------------------- 1 file changed, 89 insertions(+), 60 deletions(-) diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 7ead6784..63f4d40e 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -158,18 +158,20 @@ static const char* const valid_modargs[] = { static void trigger(struct userdata *u, int quick) { int enable_bits = 0, zero = 0; -/* pa_log_debug("trigger"); */ + if (u->fd < 0) + return; + + pa_log_debug("trigger"); - if (u->source && u->source->thread_info.state != PA_SOURCE_SUSPENDED) + if (u->source && PA_SOURCE_OPENED(u->source->thread_info.state)) enable_bits |= PCM_ENABLE_INPUT; - if (u->sink && u->sink->thread_info.state != PA_SINK_SUSPENDED) + if (u->sink && PA_SINK_OPENED(u->sink->thread_info.state)) enable_bits |= PCM_ENABLE_OUTPUT; if (u->use_mmap) { if (!quick) - /* First, let's stop all playback, capturing */ ioctl(u->fd, SNDCTL_DSP_SETTRIGGER, &zero); #ifdef SNDCTL_DSP_HALT @@ -199,7 +201,7 @@ static void trigger(struct userdata *u, int quick) { * register the fd as ready. */ - if (u->source && u->source->thread_info.state != PA_SOURCE_SUSPENDED) { + if (u->source && PA_SOURCE_OPENED(u->source->thread_info.state)) { uint8_t *buf = pa_xnew(uint8_t, u->in_fragment_size); pa_read(u->fd, buf, u->in_fragment_size, NULL); pa_xfree(buf); @@ -212,6 +214,8 @@ static void mmap_fill_memblocks(struct userdata *u, unsigned n) { pa_assert(u); pa_assert(u->out_mmap_memblocks); +/* pa_log("Mmmap writing %u blocks", n); */ + while (n > 0) { pa_memchunk chunk; @@ -241,10 +245,11 @@ static void mmap_fill_memblocks(struct userdata *u, unsigned n) { static int mmap_write(struct userdata *u) { struct count_info info; - pa_assert(u); pa_assert(u->sink); +/* pa_log("Mmmap writing..."); */ + if (ioctl(u->fd, SNDCTL_DSP_GETOPTR, &info) < 0) { pa_log("SNDCTL_DSP_GETOPTR: %s", pa_cstrerror(errno)); return -1; @@ -263,6 +268,8 @@ static void mmap_post_memblocks(struct userdata *u, unsigned n) { pa_assert(u); pa_assert(u->in_mmap_memblocks); +/* pa_log("Mmmap reading %u blocks", n); */ + while (n > 0) { pa_memchunk chunk; @@ -317,6 +324,8 @@ static int mmap_read(struct userdata *u) { pa_assert(u); pa_assert(u->source); +/* pa_log("Mmmap reading..."); */ + if (ioctl(u->fd, SNDCTL_DSP_GETIPTR, &info) < 0) { pa_log("SNDCTL_DSP_GETIPTR: %s", pa_cstrerror(errno)); return -1; @@ -437,6 +446,8 @@ static int suspend(struct userdata *u) { pa_assert(u); pa_assert(u->fd >= 0); + pa_log_debug("Suspending..."); + if (u->out_mmap_memblocks) { unsigned i; for (i = 0; i < u->out_nfrags; i++) @@ -559,15 +570,7 @@ static int unsuspend(struct userdata *u) { u->out_mmap_current = u->in_mmap_current = 0; u->out_mmap_saved_nfrags = u->in_mmap_saved_nfrags = 0; - - if (u->sink) - pa_sink_get_volume(u->sink); - if (u->source) - pa_source_get_volume(u->source); - /* Now, start only what we need */ - trigger(u, 0); - pa_log_debug("Resumed successfully..."); return 0; @@ -580,7 +583,7 @@ fail: static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk *chunk) { struct userdata *u = PA_SINK(o)->userdata; - int do_trigger = 0, ret; + int do_trigger = 0, ret, quick = 1; switch (code) { @@ -601,30 +604,44 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk * case PA_SINK_MESSAGE_SET_STATE: - if (PA_PTR_TO_UINT(data) == PA_SINK_SUSPENDED) { - pa_assert(u->sink->thread_info.state != PA_SINK_SUSPENDED); + switch ((pa_sink_state_t) PA_PTR_TO_UINT(data)) { - if (u->source_suspended) { - if (suspend(u) < 0) - return -1; - } else - do_trigger = 1; + case PA_SINK_SUSPENDED: + pa_assert(PA_SINK_OPENED(u->sink->thread_info.state)); - u->sink_suspended = 1; - - } else if (u->sink->thread_info.state == PA_SINK_SUSPENDED) { - pa_assert(PA_PTR_TO_UINT(data) != PA_SINK_SUSPENDED); + if (!u->source || u->source_suspended) { + if (suspend(u) < 0) + return -1; + } - if (u->source_suspended) { - if (unsuspend(u) < 0) - return -1; - } else do_trigger = 1; - u->out_mmap_current = 0; - u->out_mmap_saved_nfrags = 0; + u->sink_suspended = 1; + break; + + case PA_SINK_IDLE: + case PA_SINK_RUNNING: + + if (u->sink->thread_info.state == PA_SINK_SUSPENDED) { + + if (!u->source || u->source_suspended) { + if (unsuspend(u) < 0) + return -1; + quick = 0; + } + + do_trigger = 1; + + u->out_mmap_current = 0; + u->out_mmap_saved_nfrags = 0; + + u->sink_suspended = 0; + } + + break; - u->sink_suspended = 0; + case PA_SINK_DISCONNECTED: + ; } break; @@ -659,14 +676,14 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk * ret = pa_sink_process_msg(o, code, data, chunk); if (do_trigger) - trigger(u, 1); + trigger(u, quick); return ret; } static int source_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk *chunk) { struct userdata *u = PA_SOURCE(o)->userdata; - int do_trigger = 0, ret; + int do_trigger = 0, ret, quick = 1; switch (code) { @@ -686,32 +703,44 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk case PA_SOURCE_MESSAGE_SET_STATE: - if (PA_PTR_TO_UINT(data) == PA_SOURCE_SUSPENDED) { - pa_assert(u->source->thread_info.state != PA_SOURCE_SUSPENDED); + switch ((pa_source_state_t) PA_PTR_TO_UINT(data)) { + case PA_SOURCE_SUSPENDED: + pa_assert(PA_SOURCE_OPENED(u->source->thread_info.state)); + + if (!u->sink || u->sink_suspended) { + if (suspend(u) < 0) + return -1; + } - if (u->sink_suspended) { - if (suspend(u) < 0) - return -1; - } else do_trigger = 1; + + u->source_suspended = 1; + break; - u->source_suspended = 1; + case PA_SOURCE_IDLE: + case PA_SOURCE_RUNNING: + + if (u->source->thread_info.state == PA_SOURCE_SUSPENDED) { - } else if (u->source->thread_info.state == PA_SOURCE_SUSPENDED) { - pa_assert(PA_PTR_TO_UINT(data) != PA_SOURCE_SUSPENDED); + if (!u->sink || u->sink_suspended) { + if (unsuspend(u) < 0) + return -1; + quick = 0; + } - if (u->sink_suspended) { - if (unsuspend(u) < 0) - return -1; - } else - do_trigger = 1; - - u->in_mmap_current = 0; - u->in_mmap_saved_nfrags = 0; + do_trigger = 1; + + u->in_mmap_current = 0; + u->in_mmap_saved_nfrags = 0; + + u->source_suspended = 0; + } + break; - u->source_suspended = 0; - } + case PA_SOURCE_DISCONNECTED: + ; + } break; case PA_SOURCE_MESSAGE_SET_VOLUME: @@ -744,7 +773,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk ret = pa_source_process_msg(o, code, data, chunk); if (do_trigger) - trigger(u, 1); + trigger(u, quick); return ret; } @@ -779,7 +808,7 @@ static void thread_func(void *userdata) { pa_memchunk chunk; int r; -/* pa_log("loop"); */ +/* pa_log("loop"); */ /* Check whether there is a message for us to process */ if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { @@ -801,7 +830,7 @@ static void thread_func(void *userdata) { /* Render some data and write it to the dsp */ - if (u->sink && u->sink->thread_info.state != PA_SINK_SUSPENDED && (pollfd[POLLFD_DSP].revents & POLLOUT)) { + if (u->sink && u->sink->thread_info.state != PA_SINK_DISCONNECTED && u->fd >= 0 && (pollfd[POLLFD_DSP].revents & POLLOUT)) { if (u->use_mmap) { int ret; @@ -892,7 +921,7 @@ static void thread_func(void *userdata) { /* Try to read some data and pass it on to the source driver */ - if (u->source && u->source->thread_info.state != PA_SOURCE_SUSPENDED && ((pollfd[POLLFD_DSP].revents & POLLIN))) { + if (u->source && u->source->thread_info.state != PA_SOURCE_DISCONNECTED && u->fd >= 0 && ((pollfd[POLLFD_DSP].revents & POLLIN))) { if (u->use_mmap) { int ret; @@ -980,8 +1009,8 @@ static void thread_func(void *userdata) { if (u->fd >= 0) { pollfd[POLLFD_DSP].fd = u->fd; pollfd[POLLFD_DSP].events = - ((u->source && u->source->thread_info.state != PA_SOURCE_SUSPENDED) ? POLLIN : 0) | - ((u->sink && u->sink->thread_info.state != PA_SINK_SUSPENDED) ? POLLOUT : 0); + ((u->source && PA_SOURCE_OPENED(u->source->thread_info.state)) ? POLLIN : 0) | + ((u->sink && PA_SINK_OPENED(u->sink->thread_info.state)) ? POLLOUT : 0); } /* Hmm, nothing to do. Let's sleep */ -- cgit From 13a4327c1f36239a08892f8c24cc7f60befcad02 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 28 Jul 2007 23:49:39 +0000 Subject: minor cleanups git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1560 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index cf56d8cf..9ca881d1 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -564,7 +564,7 @@ static void thread_func(void *userdata) { pa_assert(u->memchunk.length > 0); p = pa_memblock_acquire(u->memchunk.memblock); - t = snd_pcm_writei(u->pcm_handle, (uint8_t*) p + u->memchunk.index, u->memchunk.length / u->frame_size); + t = snd_pcm_writei(u->pcm_handle, (const uint8_t*) p + u->memchunk.index, u->memchunk.length / u->frame_size); pa_memblock_release(u->memchunk.memblock); /* pa_log("wrote %i bytes of %u (%u)", t*u->frame_size, u->memchunk.length, l); */ @@ -654,11 +654,6 @@ static void thread_func(void *userdata) { } else revents = 0; - if (revents & ~(POLLOUT|POLLERR)) { - pa_log("DSP shutdown."); - goto fail; - } - pa_assert((pollfd[POLLFD_ASYNCQ].revents & ~POLLIN) == 0); } @@ -697,13 +692,13 @@ int pa__init(pa_core *c, pa_module*m) { pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { - pa_log("failed to parse module arguments"); + pa_log("Failed to parse module arguments"); goto fail; } ss = c->default_sample_spec; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_ALSA) < 0) { - pa_log("failed to parse sample specification and channel map"); + pa_log("Failed to parse sample specification and channel map"); goto fail; } @@ -715,7 +710,7 @@ int pa__init(pa_core *c, pa_module*m) { frag_size = frame_size; if (pa_modargs_get_value_u32(ma, "fragments", &nfrags) < 0 || pa_modargs_get_value_u32(ma, "fragment_size", &frag_size) < 0) { - pa_log("failed to parse buffer metrics"); + pa_log("Failed to parse buffer metrics"); goto fail; } period_size = frag_size/frame_size; @@ -809,7 +804,7 @@ int pa__init(pa_core *c, pa_module*m) { u->sink->is_hardware = 1; u->frame_size = frame_size; - u->fragment_size = period_size * frame_size; + u->fragment_size = frag_size = period_size * frame_size; u->nfragments = nfrags; u->hwbuf_size = u->fragment_size * nfrags; @@ -836,13 +831,13 @@ int pa__init(pa_core *c, pa_module*m) { snd_mixer_selem_get_playback_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max); } } + if (snd_mixer_selem_has_playback_switch(u->mixer_elem)) { u->sink->get_mute = sink_get_mute_cb; u->sink->set_mute = sink_set_mute_cb; } u->mixer_fdl = pa_alsa_fdlist_new(); - pa_assert(u->mixer_fdl); if (pa_alsa_fdlist_set_mixer(u->mixer_fdl, u->mixer_handle, c->mainloop) < 0) { pa_log("failed to initialise file descriptor monitoring"); @@ -854,7 +849,6 @@ int pa__init(pa_core *c, pa_module*m) { } else u->mixer_fdl = NULL; - if (!(u->thread = pa_thread_new(thread_func, u))) { pa_log("Failed to create thread."); goto fail; @@ -872,9 +866,9 @@ finish: if (ma) pa_modargs_free(ma); - - if (pcm_info) - snd_pcm_info_free(pcm_info); + + if (pcm_info) + snd_pcm_info_free(pcm_info); return ret; @@ -924,9 +918,8 @@ void pa__done(pa_core *c, pa_module*m) { } pa_xfree(u->device_name); - - snd_config_update_free_global(); - pa_xfree(u); + + snd_config_update_free_global(); } -- cgit From a82505e72f6680258b8162b846c98c64bea45c37 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 28 Jul 2007 23:50:20 +0000 Subject: port module-alsa-source to new lock-free core git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1561 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 12 +- src/modules/module-alsa-source.c | 794 +++++++++++++++++++++++++++------------ 2 files changed, 559 insertions(+), 247 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index ec1bbd02..1afe6d6e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -937,8 +937,8 @@ endif if HAVE_ALSA modlibexec_LTLIBRARIES += \ libalsa-util.la \ - module-alsa-sink.la -# module-alsa-source.la + module-alsa-sink.la \ + module-alsa-source.la endif if HAVE_SOLARIS @@ -1195,10 +1195,10 @@ module_alsa_sink_la_LDFLAGS = -module -avoid-version module_alsa_sink_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la libpulsecore.la module_alsa_sink_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) -#module_alsa_source_la_SOURCES = modules/module-alsa-source.c -#module_alsa_source_la_LDFLAGS = -module -avoid-version -#module_alsa_source_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la libpulsecore.la -#module_alsa_source_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) +module_alsa_source_la_SOURCES = modules/module-alsa-source.c +module_alsa_source_la_LDFLAGS = -module -avoid-version +module_alsa_source_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la libpulsecore.la +module_alsa_source_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) # Solaris diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 6d7e09e6..59414d33 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -48,6 +48,9 @@ #include #include #include +#include +#include +#include #include "alsa-util.h" #include "module-alsa-source-symdef.h" @@ -63,20 +66,33 @@ PA_MODULE_USAGE( "rate= " "fragments= " "fragment_size= " - "channel_map=") + "channel_map= " + "mmap=") + +#define DEFAULT_DEVICE "default" +#define DEFAULT_NFRAGS 4 +#define DEFAULT_FRAGSIZE_MSEC 25 struct userdata { + pa_core *core; + pa_module *module; + pa_source *source; + pa_thread *thread; + pa_asyncmsgq *asyncmsgq; + snd_pcm_t *pcm_handle; + + pa_alsa_fdlist *mixer_fdl; snd_mixer_t *mixer_handle; snd_mixer_elem_t *mixer_elem; - pa_source *source; - struct pa_alsa_fdlist *pcm_fdl; - struct pa_alsa_fdlist *mixer_fdl; long hw_volume_max, hw_volume_min; - size_t frame_size, fragment_size; - pa_memchunk memchunk; - pa_module *module; + size_t frame_size, fragment_size, hwbuf_size; + unsigned nfragments; + + char *device_name; + + int use_mmap; }; static const char* const valid_modargs[] = { @@ -88,261 +104,312 @@ static const char* const valid_modargs[] = { "fragments", "fragment_size", "channel_map", + "mmap", NULL }; -#define DEFAULT_DEVICE "default" +static int mmap_read(struct userdata *u) { + snd_pcm_sframes_t n; + int err; + const snd_pcm_channel_area_t *areas; + snd_pcm_uframes_t offset, frames; + int work_done = 0; + + pa_assert(u); + pa_assert(u->source); -static void update_usage(struct userdata *u) { - pa_module_set_used(u->module, u->source ? pa_source_used_by(u->source) : 0); -} + for (;;) { + pa_memchunk chunk; + void *p; + + if ((n = snd_pcm_avail_update(u->pcm_handle)) < 0) { -static void clear_up(struct userdata *u) { - assert(u); + if (n == -EPIPE) + pa_log_debug("snd_pcm_avail_update: Buffer underrun!"); + + if ((err = snd_pcm_recover(u->pcm_handle, n, 1)) == 0) + continue; - if (u->source) { - pa_source_disconnect(u->source); - pa_source_unref(u->source); - u->source = NULL; - } + if (err == -EAGAIN) + return work_done; + + pa_log("snd_pcm_avail_update: %s", snd_strerror(n)); + return -1; + } - if (u->pcm_fdl) - pa_alsa_fdlist_free(u->pcm_fdl); - if (u->mixer_fdl) - pa_alsa_fdlist_free(u->mixer_fdl); +/* pa_log("Got request for %i samples", (int) n); */ + + if (n <= 0) + return work_done; - u->pcm_fdl = u->mixer_fdl = NULL; + frames = n; + + if ((err = snd_pcm_mmap_begin(u->pcm_handle, &areas, &offset, &frames)) < 0) { + + if (err == -EPIPE) + pa_log_debug("snd_pcm_mmap_begin: Buffer underrun!"); - if (u->mixer_handle) { - snd_mixer_close(u->mixer_handle); - u->mixer_handle = NULL; - } + if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0) + continue; - if (u->pcm_handle) { - snd_pcm_drop(u->pcm_handle); - snd_pcm_close(u->pcm_handle); - u->pcm_handle = NULL; - } -} + if (err == -EAGAIN) + return work_done; -static int xrun_recovery(struct userdata *u) { - int ret; - assert(u); + pa_log("Failed to write data to DSP: %s", snd_strerror(err)); + return -1; + } - pa_log_info("*** ALSA-XRUN (capture) ***"); + /* Check these are multiples of 8 bit */ + pa_assert((areas[0].first & 7) == 0); + pa_assert((areas[0].step & 7)== 0); - if ((ret = snd_pcm_prepare(u->pcm_handle)) < 0) { - pa_log("snd_pcm_prepare() failed: %s", snd_strerror(-ret)); + /* We assume a single interleaved memory buffer */ + pa_assert((areas[0].first >> 3) == 0); + pa_assert((areas[0].step >> 3) == u->frame_size); - clear_up(u); - pa_module_unload_request(u->module); + p = (uint8_t*) areas[0].addr + (offset * u->frame_size); + + chunk.memblock = pa_memblock_new_fixed(u->core->mempool, p, frames * u->frame_size, 1); + chunk.length = pa_memblock_get_length(chunk.memblock); + chunk.index = 0; - return -1; - } + pa_source_post(u->source, &chunk); - return 0; -} + /* FIXME: Maybe we can do something to keep this memory block + * a little bit longer around? */ + pa_memblock_unref_fixed(chunk.memblock); + if ((err = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0) { -static int suspend_recovery(struct userdata *u) { - int ret; - assert(u); + if (err == -EPIPE) + pa_log_debug("snd_pcm_mmap_commit: Buffer underrun!"); + + if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0) + continue; + + if (err == -EAGAIN) + return work_done; + + pa_log("Failed to write data to DSP: %s", snd_strerror(err)); + return -1; + } - pa_log_info("*** ALSA-SUSPEND (capture) ***"); + work_done = 1; - if ((ret = snd_pcm_resume(u->pcm_handle)) < 0) { - if (ret == -EAGAIN) - return -1; +/* pa_log("wrote %i samples", (int) frames); */ + } +} - if (ret != -ENOSYS) - pa_log("snd_pcm_resume() failed: %s", snd_strerror(-ret)); - else { - if ((ret = snd_pcm_prepare(u->pcm_handle)) < 0) - pa_log("snd_pcm_prepare() failed: %s", snd_strerror(-ret)); - } +static pa_usec_t source_get_latency(struct userdata *u) { + pa_usec_t r = 0; + snd_pcm_sframes_t frames = 0; + int err; + + pa_assert(u); - if (ret < 0) { - clear_up(u); - pa_module_unload_request(u->module); - return -1; - } + snd_pcm_avail_update(u->pcm_handle); + + if ((err = snd_pcm_delay(u->pcm_handle, &frames)) < 0) { + pa_log("Failed to get delay: %s", snd_strerror(err)); + return 0; } - return ret; + if (frames > 0) + r = pa_bytes_to_usec(frames * u->frame_size, &u->source->sample_spec); + + return r; } -static void do_read(struct userdata *u) { - assert(u); +static int suspend(struct userdata *u) { + pa_assert(u); + pa_assert(u->pcm_handle); - update_usage(u); + /* Let's suspend */ + snd_pcm_close(u->pcm_handle); + u->pcm_handle = NULL; - for (;;) { - pa_memchunk post_memchunk; - snd_pcm_sframes_t frames; - size_t l; - void *p; + pa_log_debug("Device suspended..."); + + return 0; +} - if (!u->memchunk.memblock) { - u->memchunk.memblock = pa_memblock_new(u->source->core->mempool, u->memchunk.length = u->fragment_size); - u->memchunk.index = 0; - } +static int unsuspend(struct userdata *u) { + pa_sample_spec ss; + int err, b; + unsigned nfrags; + snd_pcm_uframes_t period_size; - assert(u->memchunk.memblock); - assert(u->memchunk.length); - assert(u->memchunk.length % u->frame_size == 0); + pa_assert(u); + pa_assert(!u->pcm_handle); - p = pa_memblock_acquire(u->memchunk.memblock); + pa_log_debug("Trying resume..."); - if ((frames = snd_pcm_readi(u->pcm_handle, (uint8_t*) p + u->memchunk.index, u->memchunk.length / u->frame_size)) < 0) { - pa_memblock_release(u->memchunk.memblock); + snd_config_update_free_global(); + if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) { + pa_log("Error opening PCM device %s: %s", u->device_name, snd_strerror(err)); + goto fail; + } - if (frames == -EAGAIN) - return; + ss = u->source->sample_spec; + nfrags = u->nfragments; + period_size = u->fragment_size / u->frame_size; + b = u->use_mmap; + + if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) { + pa_log("Failed to set hardware parameters: %s", snd_strerror(err)); + goto fail; + } - if (frames == -EPIPE) { - if (xrun_recovery(u) < 0) - return; + if (b != u->use_mmap) { + pa_log_warn("Resume failed, couldn't get original access mode."); + goto fail; + } - continue; - } + if (!pa_sample_spec_equal(&ss, &u->source->sample_spec)) { + pa_log_warn("Resume failed, couldn't restore original sample settings."); + goto fail; + } - if (frames == -ESTRPIPE) { - if (suspend_recovery(u) < 0) - return; + if (nfrags != u->nfragments || period_size*u->frame_size != u->fragment_size) { + pa_log_warn("Resume failed, couldn't restore original fragment settings."); + goto fail; + } - continue; - } + snd_pcm_start(u->pcm_handle); + + /* FIXME: We need to reload the volume somehow */ + + pa_log_debug("Resumed successfully..."); - pa_log("snd_pcm_readi() failed: %s", snd_strerror(-frames)); + return 0; - clear_up(u); - pa_module_unload_request(u->module); - return; - } - pa_memblock_release(u->memchunk.memblock); +fail: + snd_pcm_close(u->pcm_handle); + u->pcm_handle = NULL; + + return -1; +} + +static int source_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk *chunk) { + struct userdata *u = PA_SOURCE(o)->userdata; - l = frames * u->frame_size; + switch (code) { - post_memchunk = u->memchunk; - post_memchunk.length = l; + case PA_SOURCE_MESSAGE_GET_LATENCY: { + pa_usec_t r = 0; - pa_source_post(u->source, &post_memchunk); + if (u->pcm_handle) + r = source_get_latency(u); - u->memchunk.index += l; - u->memchunk.length -= l; + *((pa_usec_t*) data) = r; - if (u->memchunk.length == 0) { - pa_memblock_unref(u->memchunk.memblock); - u->memchunk.memblock = NULL; - u->memchunk.index = u->memchunk.length = 0; + break; } - break; - } -} + case PA_SOURCE_MESSAGE_SET_STATE: -static void fdl_callback(void *userdata) { - struct userdata *u = userdata; - assert(u); + switch ((pa_source_state_t) PA_PTR_TO_UINT(data)) { + + case PA_SOURCE_SUSPENDED: + pa_assert(PA_SOURCE_OPENED(u->source->thread_info.state)); - if (snd_pcm_state(u->pcm_handle) == SND_PCM_STATE_XRUN) - if (xrun_recovery(u) < 0) - return; + if (suspend(u) < 0) + return -1; + + break; + + case PA_SOURCE_IDLE: + case PA_SOURCE_RUNNING: - if (snd_pcm_state(u->pcm_handle) == SND_PCM_STATE_SUSPENDED) - if (suspend_recovery(u) < 0) - return; + if (u->source->thread_info.state == PA_SOURCE_SUSPENDED) { + if (unsuspend(u) < 0) + return -1; + } + + break; - do_read(u); + case PA_SOURCE_DISCONNECTED: + ; + } + + break; + } + + return pa_source_process_msg(o, code, data, chunk); } static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) { struct userdata *u = snd_mixer_elem_get_callback_private(elem); - assert(u && u->mixer_handle); + pa_assert(u); + pa_assert(u->mixer_handle); if (mask == SND_CTL_EVENT_MASK_REMOVE) return 0; if (mask & SND_CTL_EVENT_MASK_VALUE) { - if (u->source->get_hw_volume) - u->source->get_hw_volume(u->source); - if (u->source->get_hw_mute) - u->source->get_hw_mute(u->source); - - pa_subscription_post(u->source->core, - PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, - u->source->index); + pa_source_get_volume(u->source); + pa_source_get_mute(u->source); } return 0; } -static pa_usec_t source_get_latency_cb(pa_source *s) { - struct userdata *u = s->userdata; - snd_pcm_sframes_t frames; - assert(s && u && u->source); - - if (snd_pcm_delay(u->pcm_handle, &frames) < 0) { - pa_log("failed to get delay"); - s->get_latency = NULL; - return 0; - } - - return pa_bytes_to_usec(frames * u->frame_size, &s->sample_spec); -} - -static int source_get_hw_volume_cb(pa_source *s) { +static int source_get_volume_cb(pa_source *s) { struct userdata *u = s->userdata; - long vol; int err; int i; - assert(u && u->mixer_elem); + pa_assert(u); + pa_assert(u->mixer_elem); - for (i = 0;i < s->hw_volume.channels;i++) { - long set_vol; + for (i = 0; i < s->sample_spec.channels; i++) { + long set_vol, vol; - assert(snd_mixer_selem_has_capture_channel(u->mixer_elem, i)); + pa_assert(snd_mixer_selem_has_capture_channel(u->mixer_elem, i)); if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, i, &vol)) < 0) goto fail; - set_vol = (long) roundf(((float) s->hw_volume.values[i] * (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min; + set_vol = (long) roundf(((float) s->volume.values[i] * (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min; /* Try to avoid superfluous volume changes */ if (set_vol != vol) - s->hw_volume.values[i] = (pa_volume_t) roundf(((float) (vol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min)); + s->volume.values[i] = (pa_volume_t) roundf(((float) (vol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min)); } return 0; fail: pa_log_error("Unable to read volume: %s", snd_strerror(err)); - s->get_hw_volume = NULL; - s->set_hw_volume = NULL; + + s->get_volume = NULL; + s->set_volume = NULL; return -1; } -static int source_set_hw_volume_cb(pa_source *s) { +static int source_set_volume_cb(pa_source *s) { struct userdata *u = s->userdata; int err; - pa_volume_t vol; int i; - assert(u && u->mixer_elem); + pa_assert(u); + pa_assert(u->mixer_elem); + + for (i = 0; i < s->sample_spec.channels; i++) { + long alsa_vol; + pa_volume_t vol; - for (i = 0;i < s->hw_volume.channels;i++) { - assert(snd_mixer_selem_has_capture_channel(u->mixer_elem, i)); + pa_assert(snd_mixer_selem_has_capture_channel(u->mixer_elem, i)); - vol = s->hw_volume.values[i]; + vol = s->volume.values[i]; if (vol > PA_VOLUME_NORM) vol = PA_VOLUME_NORM; - vol = (long) roundf(((float) vol * (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min; + alsa_vol = (long) roundf(((float) vol * (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min; - if ((err = snd_mixer_selem_set_capture_volume(u->mixer_elem, i, vol)) < 0) + if ((err = snd_mixer_selem_set_capture_volume(u->mixer_elem, i, alsa_vol)) < 0) goto fail; } @@ -350,55 +417,242 @@ static int source_set_hw_volume_cb(pa_source *s) { fail: pa_log_error("Unable to set volume: %s", snd_strerror(err)); - s->get_hw_volume = NULL; - s->set_hw_volume = NULL; + + s->get_volume = NULL; + s->set_volume = NULL; return -1; } -static int source_get_hw_mute_cb(pa_source *s) { +static int source_get_mute_cb(pa_source *s) { struct userdata *u = s->userdata; int err, sw; - assert(u && u->mixer_elem); + pa_assert(u); + pa_assert(u->mixer_elem); - err = snd_mixer_selem_get_capture_switch(u->mixer_elem, 0, &sw); - if (err) { + if ((err = snd_mixer_selem_get_capture_switch(u->mixer_elem, 0, &sw)) < 0) { pa_log_error("Unable to get switch: %s", snd_strerror(err)); - s->get_hw_mute = NULL; - s->set_hw_mute = NULL; + + s->get_mute = NULL; + s->set_mute = NULL; return -1; } - s->hw_muted = !sw; + s->muted = !sw; return 0; } -static int source_set_hw_mute_cb(pa_source *s) { +static int source_set_mute_cb(pa_source *s) { struct userdata *u = s->userdata; int err; - assert(u && u->mixer_elem); + pa_assert(u); + pa_assert(u->mixer_elem); - err = snd_mixer_selem_set_capture_switch_all(u->mixer_elem, !s->hw_muted); - if (err) { + if ((err = snd_mixer_selem_set_capture_switch_all(u->mixer_elem, !s->muted)) < 0) { pa_log_error("Unable to set switch: %s", snd_strerror(err)); - s->get_hw_mute = NULL; - s->set_hw_mute = NULL; + + s->get_mute = NULL; + s->set_mute = NULL; return -1; } return 0; } +static void thread_func(void *userdata) { + enum { + POLLFD_ASYNCQ, + POLLFD_ALSA_BASE + }; + + struct userdata *u = userdata; + struct pollfd *pollfd = NULL; + int n_alsa_fds, err; + unsigned short revents = 0; + snd_pcm_status_t *status; + + pa_assert(u); + snd_pcm_status_alloca(&status); + + pa_log_debug("Thread starting up"); + + if ((n_alsa_fds = snd_pcm_poll_descriptors_count(u->pcm_handle)) < 0) { + pa_log("snd_pcm_poll_descriptors_count() failed: %s", snd_strerror(n_alsa_fds)); + goto fail; + } + + pollfd = pa_xnew0(struct pollfd, POLLFD_ALSA_BASE + n_alsa_fds); + + pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq); + pollfd[POLLFD_ASYNCQ].events = POLLIN; + + if ((err = snd_pcm_poll_descriptors(u->pcm_handle, pollfd+POLLFD_ALSA_BASE, n_alsa_fds)) < 0) { + pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err)); + goto fail; + } + + for (;;) { + pa_msgobject *object; + int code; + void *data; + int r; + pa_memchunk chunk; + +/* pa_log("loop"); */ + + /* Check whether there is a message for us to process */ + if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { + int ret; + +/* pa_log("processing msg"); */ + + if (!object && code == PA_MESSAGE_SHUTDOWN) { + pa_asyncmsgq_done(u->asyncmsgq, 0); + goto finish; + } + + ret = pa_asyncmsgq_dispatch(object, code, data, &chunk); + pa_asyncmsgq_done(u->asyncmsgq, ret); + continue; + } + +/* pa_log("loop2"); */ + + /* Render some data and write it to the dsp */ + + if (PA_SOURCE_OPENED(u->source->thread_info.state) && (revents & POLLIN)) { + int work_done = 0; + pa_assert(u->pcm_handle); + + if (u->use_mmap) { + + if ((work_done = mmap_read(u)) < 0) + goto fail; + + } else { + ssize_t l; + + snd_pcm_hwsync(u->pcm_handle); + if ((err = snd_pcm_status(u->pcm_handle, status)) >= 0) + l = snd_pcm_status_get_avail(status) * u->frame_size; + else + l = u->fragment_size; + + while (l > 0) { + void *p; + snd_pcm_sframes_t t; + + pa_assert(l > 0); + + chunk.memblock = pa_memblock_new(u->core->mempool, l); + + p = pa_memblock_acquire(chunk.memblock); + t = snd_pcm_readi(u->pcm_handle, (uint8_t*) p, l / u->frame_size); + pa_memblock_release(chunk.memblock); + +/* pa_log("wrote %i bytes of %u (%u)", t*u->frame_size, u->memchunk.length, l); */ + + pa_assert(t != 0); + + if (t < 0) { + pa_memblock_unref(chunk.memblock); + + if (t == -EPIPE) + pa_log_debug("Buffer underrun!"); + + if ((t = snd_pcm_recover(u->pcm_handle, t, 1)) == 0) + continue; + + if (t == -EAGAIN) { + pa_log_debug("EAGAIN"); + break; + } else { + pa_log("Failed to read data from DSP: %s", snd_strerror(t)); + goto fail; + } + + } else { + + chunk.index = 0; + chunk.length = t * u->frame_size; + + pa_source_post(u->source, &chunk); + pa_memblock_unref(chunk.memblock); + + l -= t * u->frame_size; + + work_done = 1; + } + } + } + + revents &= ~POLLIN; + + if (work_done) + continue; + } + + /* Hmm, nothing to do. Let's sleep */ + if (pa_asyncmsgq_before_poll(u->asyncmsgq) < 0) + continue; + +/* pa_log("polling for %i", POLLFD_ALSA_BASE + (PA_SOURCE_OPENED(u->source->thread_info.state) ? n_alsa_fds : 0)); */ + r = poll(pollfd, POLLFD_ALSA_BASE + (PA_SOURCE_OPENED(u->source->thread_info.state) ? n_alsa_fds : 0), -1); + /*pa_log("polling got dsp=%i amq=%i (%i)", r > 0 ? pollfd[POLLFD_DSP].revents : 0, r > 0 ? pollfd[POLLFD_ASYNCQ].revents : 0, r); */ +/* pa_log("poll end"); */ + + pa_asyncmsgq_after_poll(u->asyncmsgq); + + if (r < 0) { + if (errno == EINTR) { + pollfd[POLLFD_ASYNCQ].revents = 0; + revents = 0; + continue; + } + + pa_log("poll() failed: %s", pa_cstrerror(errno)); + goto fail; + } + + pa_assert(r > 0); + + if (PA_SOURCE_OPENED(u->source->thread_info.state)) { + if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, pollfd + POLLFD_ALSA_BASE, n_alsa_fds, &revents)) < 0) { + pa_log("snd_pcm_poll_descriptors_revents() failed: %s", snd_strerror(err)); + goto fail; + } + +/* pa_log("got alsa event"); */ + } else + revents = 0; + + pa_assert((pollfd[POLLFD_ASYNCQ].revents & ~POLLIN) == 0); + } + +fail: + /* We have to continue processing messages until we receive the + * SHUTDOWN message */ + pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, NULL, NULL); + pa_asyncmsgq_wait_for(u->asyncmsgq, PA_MESSAGE_SHUTDOWN); + +finish: + pa_log_debug("Thread shutting down"); + + pa_xfree(pollfd); +} + + int pa__init(pa_core *c, pa_module*m) { + pa_modargs *ma = NULL; int ret = -1; struct userdata *u = NULL; const char *dev; pa_sample_spec ss; pa_channel_map map; - unsigned periods, fragsize; + unsigned nfrags, frag_size; snd_pcm_uframes_t period_size; size_t frame_size; snd_pcm_info_t *pcm_info = NULL; @@ -407,33 +661,47 @@ int pa__init(pa_core *c, pa_module*m) { const char *name; char *name_buf = NULL; int namereg_fail; + int use_mmap = 1, b; + pa_assert(c); + pa_assert(m); + if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { - pa_log("failed to parse module arguments"); + pa_log("Failed to parse module arguments"); goto fail; } ss = c->default_sample_spec; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_ALSA) < 0) { - pa_log("failed to parse sample specification"); + pa_log("Failed to parse sample specification"); goto fail; } frame_size = pa_frame_size(&ss); /* Fix latency to 100ms */ - periods = 12; - fragsize = pa_bytes_per_second(&ss)/128; + nfrags = DEFAULT_NFRAGS; + frag_size = pa_usec_to_bytes(DEFAULT_FRAGSIZE_MSEC*1000, &ss); + if (frag_size <= 0) + frag_size = frame_size; - if (pa_modargs_get_value_u32(ma, "fragments", &periods) < 0 || pa_modargs_get_value_u32(ma, "fragment_size", &fragsize) < 0) { - pa_log("failed to parse buffer metrics"); + if (pa_modargs_get_value_u32(ma, "fragments", &nfrags) < 0 || pa_modargs_get_value_u32(ma, "fragment_size", &frag_size) < 0) { + pa_log("Failed to parse buffer metrics"); goto fail; } - period_size = fragsize/frame_size; + period_size = frag_size/frame_size; + if (pa_modargs_get_value_boolean(ma, "mmap", &use_mmap) < 0) { + pa_log("Failed to parse mmap argument."); + goto fail; + } + u = pa_xnew0(struct userdata, 1); - m->userdata = u; + u->core = c; u->module = m; + m->userdata = u; + u->use_mmap = use_mmap; + pa_assert_se(u->asyncmsgq = pa_asyncmsgq_new(0)); snd_config_update_free_global(); if ((err = snd_pcm_open(&u->pcm_handle, dev = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) { @@ -441,30 +709,44 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } + u->device_name = pa_xstrdup(dev); + if ((err = snd_pcm_info_malloc(&pcm_info)) < 0 || (err = snd_pcm_info(u->pcm_handle, pcm_info)) < 0) { pa_log("Error fetching PCM info: %s", snd_strerror(err)); goto fail; } - if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &periods, &period_size)) < 0) { + b = use_mmap; + if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) { pa_log("Failed to set hardware parameters: %s", snd_strerror(err)); goto fail; } + if (use_mmap && !b) { + pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode."); + u->use_mmap = use_mmap = b; + } + + if (u->use_mmap) + pa_log_info("Successfully enabled mmap() mode."); + + /* ALSA might tweak the sample spec, so recalculate the frame size */ + frame_size = pa_frame_size(&ss); + if (ss.channels != map.channels) /* Seems ALSA didn't like the channel number, so let's fix the channel map */ pa_channel_map_init_auto(&map, ss.channels, PA_CHANNEL_MAP_ALSA); - if ((err = snd_mixer_open(&u->mixer_handle, 0)) < 0) { + if ((err = snd_mixer_open(&u->mixer_handle, 0)) < 0) pa_log("Error opening mixer: %s", snd_strerror(err)); - goto fail; - } - - if ((pa_alsa_prepare_mixer(u->mixer_handle, dev) < 0) || - !(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Capture", "Mic"))) { - snd_mixer_close(u->mixer_handle); - u->mixer_handle = NULL; + else { + + if ((pa_alsa_prepare_mixer(u->mixer_handle, dev) < 0) || + !(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Capture", "Mic"))) { + snd_mixer_close(u->mixer_handle); + u->mixer_handle = NULL; + } } if ((name = pa_modargs_get_value(ma, "source_name", NULL))) @@ -474,16 +756,37 @@ int pa__init(pa_core *c, pa_module*m) { namereg_fail = 0; } - if (!(u->source = pa_source_new(c, __FILE__, name, namereg_fail, &ss, &map))) { + u->source = pa_source_new(c, __FILE__, name, namereg_fail, &ss, &map); + pa_xfree(name_buf); + + if (!u->source) { pa_log("Failed to create source object"); goto fail; } - u->source->is_hardware = 1; + u->source->parent.process_msg = source_process_msg; u->source->userdata = u; - u->source->get_latency = source_get_latency_cb; + + pa_source_set_module(u->source, m); + pa_source_set_asyncmsgq(u->source, u->asyncmsgq); + pa_source_set_description(u->source, t = pa_sprintf_malloc( + "ALSA PCM on %s (%s)", + dev, + snd_pcm_info_get_name(pcm_info))); + pa_xfree(t); + + u->source->is_hardware = 1; + + u->frame_size = frame_size; + u->fragment_size = frag_size = period_size * frame_size; + u->nfragments = nfrags; + u->hwbuf_size = u->fragment_size * nfrags; + + pa_log_info("Using %u fragments of size %lu bytes.", nfrags, (long unsigned) u->fragment_size); + if (u->mixer_handle) { assert(u->mixer_elem); + if (snd_mixer_selem_has_capture_volume(u->mixer_elem)) { int i; @@ -493,64 +796,48 @@ int pa__init(pa_core *c, pa_module*m) { } if (i == ss.channels) { - u->source->get_hw_volume = source_get_hw_volume_cb; - u->source->set_hw_volume = source_set_hw_volume_cb; - snd_mixer_selem_get_capture_volume_range( - u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max); + u->source->get_volume = source_get_volume_cb; + u->source->set_volume = source_set_volume_cb; + snd_mixer_selem_get_capture_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max); } } + if (snd_mixer_selem_has_capture_switch(u->mixer_elem)) { - u->source->get_hw_mute = source_get_hw_mute_cb; - u->source->set_hw_mute = source_set_hw_mute_cb; + u->source->get_mute = source_get_mute_cb; + u->source->set_mute = source_set_mute_cb; } - } - pa_source_set_owner(u->source, m); - pa_source_set_description(u->source, t = pa_sprintf_malloc("ALSA PCM on %s (%s)", dev, snd_pcm_info_get_name(pcm_info))); - pa_xfree(t); - - u->pcm_fdl = pa_alsa_fdlist_new(); - assert(u->pcm_fdl); - if (pa_alsa_fdlist_init_pcm(u->pcm_fdl, u->pcm_handle, c->mainloop, fdl_callback, u) < 0) { - pa_log("failed to initialise file descriptor monitoring"); - goto fail; - } - if (u->mixer_handle) { u->mixer_fdl = pa_alsa_fdlist_new(); - assert(u->mixer_fdl); - if (pa_alsa_fdlist_init_mixer(u->mixer_fdl, u->mixer_handle, c->mainloop) < 0) { + + if (pa_alsa_fdlist_set_mixer(u->mixer_fdl, u->mixer_handle, c->mainloop) < 0) { pa_log("failed to initialise file descriptor monitoring"); goto fail; } + snd_mixer_elem_set_callback(u->mixer_elem, mixer_callback); snd_mixer_elem_set_callback_private(u->mixer_elem, u); } else u->mixer_fdl = NULL; - u->frame_size = frame_size; - u->fragment_size = period_size * frame_size; - - pa_log_info("using %u fragments of size %lu bytes.", periods, (long unsigned) u->fragment_size); - - u->memchunk.memblock = NULL; - u->memchunk.index = u->memchunk.length = 0; + if (!(u->thread = pa_thread_new(thread_func, u))) { + pa_log("Failed to create thread."); + goto fail; + } + /* Get initial mixer settings */ + if (u->source->get_volume) + u->source->get_volume(u->source); + if (u->source->get_mute) + u->source->get_mute(u->source); snd_pcm_start(u->pcm_handle); - + ret = 0; - /* Get initial mixer settings */ - if (u->source->get_hw_volume) - u->source->get_hw_volume(u->source); - if (u->source->get_hw_mute) - u->source->get_hw_mute(u->source); - finish: - pa_xfree(name_buf); if (ma) - pa_modargs_free(ma); - + pa_modargs_free(ma); + if (pcm_info) snd_pcm_info_free(pcm_info); @@ -566,16 +853,41 @@ fail: void pa__done(pa_core *c, pa_module*m) { struct userdata *u; - assert(c && m); + + pa_assert(c); + pa_assert(m); if (!(u = m->userdata)) return; - clear_up(u); + if (u->source) + pa_source_disconnect(u->source); + + if (u->thread) { + pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, NULL); + pa_thread_free(u->thread); + } + + if (u->asyncmsgq) + pa_asyncmsgq_free(u->asyncmsgq); - if (u->memchunk.memblock) - pa_memblock_unref(u->memchunk.memblock); + if (u->source) + pa_source_unref(u->source); + if (u->mixer_fdl) + pa_alsa_fdlist_free(u->mixer_fdl); + + if (u->mixer_handle) + snd_mixer_close(u->mixer_handle); + + if (u->pcm_handle) { + snd_pcm_drop(u->pcm_handle); + snd_pcm_close(u->pcm_handle); + } + + pa_xfree(u->device_name); pa_xfree(u); + + snd_config_update_free_global(); } -- cgit From 0defdfb5607889c35fdefff4af31eb8b0ae0cbcf Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 31 Jul 2007 22:44:53 +0000 Subject: A lot of updates, all necessary to get the native protocol ported: * add an int64_t argument to pa_asyncmsgq because it is very difficult to pass 64 values otherwise * simplify subclassing in pa_object * s/drop/unlink/ at some places * port the native protocol to the lock-free core (not tested, compiles fine) * move synchronisation of playback streams into pa_sink_input * add "start_corked" field to pa_sink_input_new_data * allow casting of NULL values in pa_object git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1562 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 43 +- src/modules/module-alsa-sink.c | 13 +- src/modules/module-alsa-source.c | 13 +- src/modules/module-null-sink.c | 13 +- src/modules/module-oss.c | 21 +- src/modules/module-pipe-sink.c | 13 +- src/modules/module-pipe-source.c | 9 +- src/pulsecore/asyncmsgq.c | 20 +- src/pulsecore/asyncmsgq.h | 8 +- src/pulsecore/core.c | 11 +- src/pulsecore/msgobject.c | 13 +- src/pulsecore/msgobject.h | 8 +- src/pulsecore/native-common.h | 2 + src/pulsecore/object.c | 13 +- src/pulsecore/object.h | 25 +- src/pulsecore/protocol-native.c | 1451 +++++++++++++++++++++++-------------- src/pulsecore/protocol-simple.c | 114 +-- src/pulsecore/sink-input.c | 64 +- src/pulsecore/sink-input.h | 9 +- src/pulsecore/sink.c | 58 +- src/pulsecore/sink.h | 2 +- src/pulsecore/sound-file-stream.c | 8 +- src/pulsecore/source-output.c | 18 +- src/pulsecore/source-output.h | 4 +- src/pulsecore/source.c | 20 +- src/pulsecore/source.h | 2 +- src/tests/asyncmsgq-test.c | 10 +- 27 files changed, 1222 insertions(+), 763 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 1afe6d6e..4083ea55 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -722,10 +722,10 @@ modlibexec_LTLIBRARIES = \ libauthkey-prop.la \ libstrlist.la \ libprotocol-simple.la \ - libprotocol-http.la + libprotocol-http.la \ + libprotocol-native.la # libprotocol-esound.la -# libprotocol-native.la # We need to emulate sendmsg/recvmsg to support this on Win32 if !OS_IS_WIN32 @@ -879,11 +879,10 @@ modlibexec_LTLIBRARIES += \ module-volume-restore.la \ module-rescue-streams.la \ module-http-protocol-tcp.la \ - module-sine.la - + module-sine.la \ + module-native-protocol-tcp.la \ + module-native-protocol-fd.la # module-esound-protocol-tcp.la \ -# module-native-protocol-tcp.la \ -# module-native-protocol-fd.la \ # module-combine.la \ # module-tunnel-sink.la \ # module-tunnel-source.la \ @@ -899,10 +898,10 @@ modlibexec_LTLIBRARIES += \ if HAVE_AF_UNIX modlibexec_LTLIBRARIES += \ module-cli-protocol-unix.la \ - module-simple-protocol-unix.la - module-http-protocol-unix.la -# module-esound-protocol-unix.la \ -# module-native-protocol-unix.la + module-simple-protocol-unix.la \ + module-http-protocol-unix.la \ + module-native-protocol-unix.la +# module-esound-protocol-unix.la endif if HAVE_MKFIFO @@ -1083,20 +1082,20 @@ module_http_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-h # Native protocol -#module_native_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c -#module_native_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_NATIVE $(AM_CFLAGS) -#module_native_protocol_tcp_la_LDFLAGS = -module -avoid-version -#module_native_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-native.la libsocket-server.la +module_native_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c +module_native_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_NATIVE $(AM_CFLAGS) +module_native_protocol_tcp_la_LDFLAGS = -module -avoid-version +module_native_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-native.la libsocket-server.la -#module_native_protocol_unix_la_SOURCES = modules/module-protocol-stub.c -#module_native_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_NATIVE $(AM_CFLAGS) -#module_native_protocol_unix_la_LDFLAGS = -module -avoid-version -#module_native_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-native.la libsocket-server.la libsocket-util.la +module_native_protocol_unix_la_SOURCES = modules/module-protocol-stub.c +module_native_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_NATIVE $(AM_CFLAGS) +module_native_protocol_unix_la_LDFLAGS = -module -avoid-version +module_native_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-native.la libsocket-server.la libsocket-util.la -#module_native_protocol_fd_la_SOURCES = modules/module-native-protocol-fd.c -#module_native_protocol_fd_la_CFLAGS = $(AM_CFLAGS) -#module_native_protocol_fd_la_LDFLAGS = -module -avoid-version -#module_native_protocol_fd_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-native.la libsocket-server.la libsocket-util.la libiochannel.la +module_native_protocol_fd_la_SOURCES = modules/module-native-protocol-fd.c +module_native_protocol_fd_la_CFLAGS = $(AM_CFLAGS) +module_native_protocol_fd_la_LDFLAGS = -module -avoid-version +module_native_protocol_fd_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-native.la libsocket-server.la libsocket-util.la libiochannel.la # EsounD protocol diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 9ca881d1..551bad89 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -302,7 +302,7 @@ fail: return -1; } -static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk *chunk) { +static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { struct userdata *u = PA_SINK(o)->userdata; switch (code) { @@ -347,7 +347,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk * break; } - return pa_sink_process_msg(o, code, data, chunk); + return pa_sink_process_msg(o, code, data, offset, chunk); } static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) { @@ -510,12 +510,13 @@ static void thread_func(void *userdata) { int code; void *data; pa_memchunk chunk; + int64_t offset; int r; /* pa_log("loop"); */ /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { + if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; /* pa_log("processing msg"); */ @@ -525,7 +526,7 @@ static void thread_func(void *userdata) { goto finish; } - ret = pa_asyncmsgq_dispatch(object, code, data, &chunk); + ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); pa_asyncmsgq_done(u->asyncmsgq, ret); continue; } @@ -660,7 +661,7 @@ static void thread_func(void *userdata) { fail: /* We have to continue processing messages until we receive the * SHUTDOWN message */ - pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, NULL, NULL); + pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); pa_asyncmsgq_wait_for(u->asyncmsgq, PA_MESSAGE_SHUTDOWN); finish: @@ -893,7 +894,7 @@ void pa__done(pa_core *c, pa_module*m) { pa_sink_disconnect(u->sink); if (u->thread) { - pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, NULL); + pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); pa_thread_free(u->thread); } diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 59414d33..c2dad6f9 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -290,7 +290,7 @@ fail: return -1; } -static int source_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk *chunk) { +static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { struct userdata *u = PA_SOURCE(o)->userdata; switch (code) { @@ -335,7 +335,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk break; } - return pa_source_process_msg(o, code, data, chunk); + return pa_source_process_msg(o, code, data, offset, chunk); } static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) { @@ -498,12 +498,13 @@ static void thread_func(void *userdata) { int code; void *data; int r; + int64_t offset; pa_memchunk chunk; /* pa_log("loop"); */ /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { + if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; /* pa_log("processing msg"); */ @@ -513,7 +514,7 @@ static void thread_func(void *userdata) { goto finish; } - ret = pa_asyncmsgq_dispatch(object, code, data, &chunk); + ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); pa_asyncmsgq_done(u->asyncmsgq, ret); continue; } @@ -634,7 +635,7 @@ static void thread_func(void *userdata) { fail: /* We have to continue processing messages until we receive the * SHUTDOWN message */ - pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, NULL, NULL); + pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); pa_asyncmsgq_wait_for(u->asyncmsgq, PA_MESSAGE_SHUTDOWN); finish: @@ -864,7 +865,7 @@ void pa__done(pa_core *c, pa_module*m) { pa_source_disconnect(u->source); if (u->thread) { - pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, NULL); + pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); pa_thread_free(u->thread); } diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index bb0a5045..f0e3a061 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -83,7 +83,7 @@ static const char* const valid_modargs[] = { NULL }; -static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk *chunk) { +static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { struct userdata *u = PA_SINK(o)->userdata; switch (code) { @@ -107,7 +107,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk * } } - return pa_sink_process_msg(o, code, data, chunk); + return pa_sink_process_msg(o, code, data, offset, chunk); } static void thread_func(void *userdata) { @@ -131,9 +131,10 @@ static void thread_func(void *userdata) { pa_memchunk chunk; int r, timeout; struct timeval now; + int64_t offset; /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { + if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; if (!object && code == PA_MESSAGE_SHUTDOWN) { @@ -141,7 +142,7 @@ static void thread_func(void *userdata) { goto finish; } - ret = pa_asyncmsgq_dispatch(object, code, data, &chunk); + ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); pa_asyncmsgq_done(u->asyncmsgq, ret); continue; } @@ -190,7 +191,7 @@ static void thread_func(void *userdata) { fail: /* We have to continue processing messages until we receive the * SHUTDOWN message */ - pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, NULL, NULL); + pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); pa_asyncmsgq_wait_for(u->asyncmsgq, PA_MESSAGE_SHUTDOWN); finish: @@ -271,7 +272,7 @@ void pa__done(pa_core *c, pa_module*m) { pa_sink_disconnect(u->sink); if (u->thread) { - pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, NULL); + pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); pa_thread_free(u->thread); } diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 63f4d40e..a43bdb3c 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -581,7 +581,7 @@ fail: return -1; } -static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk *chunk) { +static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { struct userdata *u = PA_SINK(o)->userdata; int do_trigger = 0, ret, quick = 1; @@ -673,7 +673,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk * break; } - ret = pa_sink_process_msg(o, code, data, chunk); + ret = pa_sink_process_msg(o, code, data, offset, chunk); if (do_trigger) trigger(u, quick); @@ -681,7 +681,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk * return ret; } -static int source_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk *chunk) { +static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { struct userdata *u = PA_SOURCE(o)->userdata; int do_trigger = 0, ret, quick = 1; @@ -770,7 +770,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk break; } - ret = pa_source_process_msg(o, code, data, chunk); + ret = pa_source_process_msg(o, code, data, offset, chunk); if (do_trigger) trigger(u, quick); @@ -807,11 +807,12 @@ static void thread_func(void *userdata) { void *data; pa_memchunk chunk; int r; + int64_t offset; /* pa_log("loop"); */ /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { + if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; /* pa_log("processing msg"); */ @@ -821,7 +822,7 @@ static void thread_func(void *userdata) { goto finish; } - ret = pa_asyncmsgq_dispatch(object, code, data, &chunk); + ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); pa_asyncmsgq_done(u->asyncmsgq, ret); continue; } @@ -1051,7 +1052,7 @@ static void thread_func(void *userdata) { fail: /* We have to continue processing messages until we receive the * SHUTDOWN message */ - pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, NULL, NULL); + pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); pa_asyncmsgq_wait_for(u->asyncmsgq, PA_MESSAGE_SHUTDOWN); finish: @@ -1300,9 +1301,9 @@ go_on: /* Read mixer settings */ if (u->source) - pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->source), PA_SOURCE_MESSAGE_GET_VOLUME, &u->source->volume, NULL, NULL); + pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->source), PA_SOURCE_MESSAGE_GET_VOLUME, &u->source->volume, 0, NULL, NULL); if (u->sink) - pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_GET_VOLUME, &u->sink->volume, NULL, NULL); + pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_GET_VOLUME, &u->sink->volume, 0, NULL, NULL); return 0; @@ -1335,7 +1336,7 @@ void pa__done(pa_core *c, pa_module*m) { pa_source_disconnect(u->source); if (u->thread) { - pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, NULL); + pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); pa_thread_free(u->thread); } diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index db8b2e10..83ee06b7 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -84,7 +84,7 @@ static const char* const valid_modargs[] = { NULL }; -static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk *chunk) { +static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { struct userdata *u = PA_SINK(o)->userdata; switch (code) { @@ -103,7 +103,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, pa_memchunk * } } - return pa_sink_process_msg(o, code, data, chunk); + return pa_sink_process_msg(o, code, data, offset, chunk); } static void thread_func(void *userdata) { @@ -133,9 +133,10 @@ static void thread_func(void *userdata) { void *data; pa_memchunk chunk; int r; + int64_t offset; /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { + if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; if (!object && code == PA_MESSAGE_SHUTDOWN) { @@ -143,7 +144,7 @@ static void thread_func(void *userdata) { goto finish; } - ret = pa_asyncmsgq_dispatch(object, code, data, &chunk); + ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); pa_asyncmsgq_done(u->asyncmsgq, ret); continue; } @@ -224,7 +225,7 @@ static void thread_func(void *userdata) { fail: /* We have to continue processing messages until we receive the * SHUTDOWN message */ - pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, NULL, NULL); + pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); pa_asyncmsgq_wait_for(u->asyncmsgq, PA_MESSAGE_SHUTDOWN); finish: @@ -326,7 +327,7 @@ void pa__done(pa_core *c, pa_module*m) { pa_sink_disconnect(u->sink); if (u->thread) { - pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, NULL); + pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); pa_thread_free(u->thread); } diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index 5dbb1e7b..a5f95f9a 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -111,9 +111,10 @@ static void thread_func(void *userdata) { void *data; pa_memchunk chunk; int r; + int64_t offset; /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { + if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; if (!object && code == PA_MESSAGE_SHUTDOWN) { @@ -121,7 +122,7 @@ static void thread_func(void *userdata) { goto finish; } - ret = pa_asyncmsgq_dispatch(object, code, data, &chunk); + ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); pa_asyncmsgq_done(u->asyncmsgq, ret); continue; } @@ -202,7 +203,7 @@ static void thread_func(void *userdata) { fail: /* We have to continue processing messages until we receive the * SHUTDOWN message */ - pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, NULL, NULL); + pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); pa_asyncmsgq_wait_for(u->asyncmsgq, PA_MESSAGE_SHUTDOWN); finish: @@ -303,7 +304,7 @@ void pa__done(pa_core *c, pa_module*m) { pa_source_disconnect(u->source); if (u->thread) { - pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, NULL); + pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); pa_thread_free(u->thread); } diff --git a/src/pulsecore/asyncmsgq.c b/src/pulsecore/asyncmsgq.c index 1b6d8025..ed71d374 100644 --- a/src/pulsecore/asyncmsgq.c +++ b/src/pulsecore/asyncmsgq.c @@ -46,6 +46,7 @@ struct asyncmsgq_item { pa_msgobject *object; void *userdata; pa_free_cb_t free_cb; + int64_t offset; pa_memchunk memchunk; pa_semaphore *semaphore; int ret; @@ -96,7 +97,7 @@ void pa_asyncmsgq_free(pa_asyncmsgq *a) { pa_xfree(a); } -void pa_asyncmsgq_post(pa_asyncmsgq *a, pa_msgobject *object, int code, const void *userdata, const pa_memchunk *chunk, pa_free_cb_t free_cb) { +void pa_asyncmsgq_post(pa_asyncmsgq *a, pa_msgobject *object, int code, const void *userdata, int64_t offset, const pa_memchunk *chunk, pa_free_cb_t free_cb) { struct asyncmsgq_item *i; pa_assert(a); @@ -107,6 +108,7 @@ void pa_asyncmsgq_post(pa_asyncmsgq *a, pa_msgobject *object, int code, const vo i->object = object ? pa_msgobject_ref(object) : NULL; i->userdata = (void*) userdata; i->free_cb = free_cb; + i->offset = offset; if (chunk) { pa_assert(chunk->memblock); i->memchunk = *chunk; @@ -121,7 +123,7 @@ void pa_asyncmsgq_post(pa_asyncmsgq *a, pa_msgobject *object, int code, const vo pa_mutex_unlock(a->mutex); } -int pa_asyncmsgq_send(pa_asyncmsgq *a, pa_msgobject *object, int code, const void *userdata, const pa_memchunk *chunk) { +int pa_asyncmsgq_send(pa_asyncmsgq *a, pa_msgobject *object, int code, const void *userdata, int64_t offset, const pa_memchunk *chunk) { struct asyncmsgq_item i; pa_assert(a); @@ -130,6 +132,7 @@ int pa_asyncmsgq_send(pa_asyncmsgq *a, pa_msgobject *object, int code, const voi i.userdata = (void*) userdata; i.free_cb = NULL; i.ret = -1; + i.offset = offset; if (chunk) { pa_assert(chunk->memblock); i.memchunk = *chunk; @@ -148,7 +151,7 @@ int pa_asyncmsgq_send(pa_asyncmsgq *a, pa_msgobject *object, int code, const voi return i.ret; } -int pa_asyncmsgq_get(pa_asyncmsgq *a, pa_msgobject **object, int *code, void **userdata, pa_memchunk *chunk, int wait) { +int pa_asyncmsgq_get(pa_asyncmsgq *a, pa_msgobject **object, int *code, void **userdata, int64_t *offset, pa_memchunk *chunk, int wait) { pa_assert(a); pa_assert(code); pa_assert(!a->current); @@ -163,6 +166,8 @@ int pa_asyncmsgq_get(pa_asyncmsgq *a, pa_msgobject **object, int *code, void **u *code = a->current->code; if (userdata) *userdata = a->current->userdata; + if (offset) + *offset = a->current->offset; if (object) { if ((*object = a->current->object)) pa_msgobject_assert_ref(*object); @@ -207,13 +212,14 @@ int pa_asyncmsgq_wait_for(pa_asyncmsgq *a, int code) { do { pa_msgobject *o; void *data; + int64_t offset; pa_memchunk chunk; int ret; - if (pa_asyncmsgq_get(a, &o, &c, &data, &chunk, 1) < 0) + if (pa_asyncmsgq_get(a, &o, &c, &data, &offset, &chunk, 1) < 0) return -1; - ret = pa_asyncmsgq_dispatch(o, c, data, &chunk); + ret = pa_asyncmsgq_dispatch(o, c, data, offset, &chunk); pa_asyncmsgq_done(a, ret); } while (c != code); @@ -239,10 +245,10 @@ void pa_asyncmsgq_after_poll(pa_asyncmsgq *a) { pa_asyncq_after_poll(a->asyncq); } -int pa_asyncmsgq_dispatch(pa_msgobject *object, int code, void *userdata, pa_memchunk *memchunk) { +int pa_asyncmsgq_dispatch(pa_msgobject *object, int code, void *userdata, int64_t offset, pa_memchunk *memchunk) { if (object) - return object->process_msg(object, code, userdata, memchunk); + return object->process_msg(object, code, userdata, offset, memchunk); return 0; } diff --git a/src/pulsecore/asyncmsgq.h b/src/pulsecore/asyncmsgq.h index 17b37e4b..b0f1a6e4 100644 --- a/src/pulsecore/asyncmsgq.h +++ b/src/pulsecore/asyncmsgq.h @@ -57,11 +57,11 @@ typedef struct pa_asyncmsgq pa_asyncmsgq; pa_asyncmsgq* pa_asyncmsgq_new(size_t size); void pa_asyncmsgq_free(pa_asyncmsgq* q); -void pa_asyncmsgq_post(pa_asyncmsgq *q, pa_msgobject *object, int code, const void *userdata, const pa_memchunk *memchunk, pa_free_cb_t userdata_free_cb); -int pa_asyncmsgq_send(pa_asyncmsgq *q, pa_msgobject *object, int code, const void *userdata, const pa_memchunk *memchunk); +void pa_asyncmsgq_post(pa_asyncmsgq *q, pa_msgobject *object, int code, const void *userdata, int64_t offset, const pa_memchunk *memchunk, pa_free_cb_t userdata_free_cb); +int pa_asyncmsgq_send(pa_asyncmsgq *q, pa_msgobject *object, int code, const void *userdata, int64_t offset, const pa_memchunk *memchunk); -int pa_asyncmsgq_get(pa_asyncmsgq *q, pa_msgobject **object, int *code, void **userdata, pa_memchunk *memchunk, int wait); -int pa_asyncmsgq_dispatch(pa_msgobject *object, int code, void *userdata, pa_memchunk *memchunk); +int pa_asyncmsgq_get(pa_asyncmsgq *q, pa_msgobject **object, int *code, void **userdata, int64_t *offset, pa_memchunk *memchunk, int wait); +int pa_asyncmsgq_dispatch(pa_msgobject *object, int code, void *userdata, int64_t offset, pa_memchunk *memchunk); void pa_asyncmsgq_done(pa_asyncmsgq *q, int ret); int pa_asyncmsgq_wait_for(pa_asyncmsgq *a, int code); diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c index a940bfc0..1a0e50bb 100644 --- a/src/pulsecore/core.c +++ b/src/pulsecore/core.c @@ -49,9 +49,9 @@ #include "core.h" -static PA_DEFINE_CHECK_TYPE(pa_core, core_check_type, pa_msgobject_check_type); +static PA_DEFINE_CHECK_TYPE(pa_core, pa_msgobject); -static int core_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk) { +static int core_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) { pa_core *c = PA_CORE(o); pa_core_assert_ref(c); @@ -79,13 +79,14 @@ static void asyncmsgq_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_even pa_msgobject *object; int code; void *data; + int64_t offset; pa_memchunk chunk; /* Check whether there is a message for us to process */ - while (pa_asyncmsgq_get(c->asyncmsgq, &object, &code, &data, &chunk, 0) == 0) { + while (pa_asyncmsgq_get(c->asyncmsgq, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; - ret = pa_asyncmsgq_dispatch(object, code, data, &chunk); + ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); pa_asyncmsgq_done(c->asyncmsgq, ret); } @@ -116,7 +117,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { } } - c = pa_msgobject_new(pa_core, core_check_type); + c = pa_msgobject_new(pa_core); c->parent.parent.free = core_free; c->parent.process_msg = core_process_msg; diff --git a/src/pulsecore/msgobject.c b/src/pulsecore/msgobject.c index 6db630c5..f54e69f2 100644 --- a/src/pulsecore/msgobject.c +++ b/src/pulsecore/msgobject.c @@ -28,15 +28,22 @@ #include "msgobject.h" -PA_DEFINE_CHECK_TYPE(pa_msgobject, pa_msgobject_check_type, pa_object_check_type); +PA_DEFINE_CHECK_TYPE(pa_msgobject, pa_object); -pa_msgobject *pa_msgobject_new_internal(size_t size, const char *type_name, int (*check_type)(pa_object *o, const char *type_name)) { +pa_msgobject *pa_msgobject_new_internal(size_t size, const char *type_name, int (*check_type)(const char *type_name)) { pa_msgobject *o; pa_assert(size > sizeof(pa_msgobject)); pa_assert(type_name); - o = PA_MSGOBJECT(pa_object_new_internal(size, type_name, check_type ? check_type : pa_msgobject_check_type)); + if (!check_type) + check_type = pa_msgobject_check_type; + + pa_assert(check_type(type_name)); + pa_assert(check_type("pa_object")); + pa_assert(check_type("pa_msgobject")); + + o = PA_MSGOBJECT(pa_object_new_internal(size, type_name, check_type)); o->process_msg = NULL; return o; } diff --git a/src/pulsecore/msgobject.h b/src/pulsecore/msgobject.h index 65761aea..8221cc33 100644 --- a/src/pulsecore/msgobject.h +++ b/src/pulsecore/msgobject.h @@ -37,14 +37,14 @@ typedef struct pa_msgobject pa_msgobject; struct pa_msgobject { pa_object parent; - int (*process_msg)(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk); + int (*process_msg)(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk); }; -pa_msgobject *pa_msgobject_new_internal(size_t size, const char *type_name, int (*check_type)(pa_object *o, const char *type_name)); +pa_msgobject *pa_msgobject_new_internal(size_t size, const char *type_name, int (*check_type)(const char *type_name)); -int pa_msgobject_check_type(pa_object *o, const char *type); +int pa_msgobject_check_type(const char *type); -#define pa_msgobject_new(type, check_type) ((type*) pa_msgobject_new_internal(sizeof(type), #type, check_type)) +#define pa_msgobject_new(type) ((type*) pa_msgobject_new_internal(sizeof(type), #type, type##_check_type)) #define pa_msgobject_free ((void (*) (pa_msgobject* o)) pa_object_free) #define PA_MSGOBJECT(o) pa_msgobject_cast(o) diff --git a/src/pulsecore/native-common.h b/src/pulsecore/native-common.h index f7a7da1d..d22c8d12 100644 --- a/src/pulsecore/native-common.h +++ b/src/pulsecore/native-common.h @@ -115,6 +115,8 @@ enum { PA_COMMAND_MOVE_SINK_INPUT, PA_COMMAND_MOVE_SOURCE_OUTPUT, + PA_COMMAND_SET_SINK_INPUT_MUTE, + PA_COMMAND_MAX }; diff --git a/src/pulsecore/object.c b/src/pulsecore/object.c index a983c5ae..23a45754 100644 --- a/src/pulsecore/object.c +++ b/src/pulsecore/object.c @@ -28,17 +28,23 @@ #include "object.h" -pa_object *pa_object_new_internal(size_t size, const char *type_name, int (*check_type)(pa_object *o, const char *type_name)) { +pa_object *pa_object_new_internal(size_t size, const char *type_name, int (*check_type)(const char *type_name)) { pa_object *o; pa_assert(size > sizeof(pa_object)); pa_assert(type_name); + if (!check_type) + check_type = pa_object_check_type; + + pa_assert(check_type(type_name)); + pa_assert(check_type("pa_object")); + o = pa_xmalloc(size); PA_REFCNT_INIT(o); o->type_name = type_name; o->free = pa_object_free; - o->check_type = check_type ? check_type : pa_object_check_type; + o->check_type = check_type; return o; } @@ -59,8 +65,7 @@ void pa_object_unref(pa_object *o) { } } -int pa_object_check_type(pa_object *o, const char *type_name) { - pa_assert(o); +int pa_object_check_type(const char *type_name) { pa_assert(type_name); return type_name == "pa_object" || strcmp(type_name, "pa_object") == 0; diff --git a/src/pulsecore/object.h b/src/pulsecore/object.h index 270f289d..9c62f74a 100644 --- a/src/pulsecore/object.h +++ b/src/pulsecore/object.h @@ -38,20 +38,19 @@ struct pa_object { PA_REFCNT_DECLARE; const char *type_name; void (*free)(pa_object *o); - int (*check_type)(pa_object *o, const char *type_name); + int (*check_type)(const char *type_name); }; -pa_object *pa_object_new_internal(size_t size, const char *type_name, int (*check_type)(pa_object *o, const char *type_name)); -#define pa_object_new(type, check_type) ((type*) pa_object_new_internal(sizeof(type), #type, check_type) +pa_object *pa_object_new_internal(size_t size, const char *type_name, int (*check_type)(const char *type_name)); +#define pa_object_new(type) ((type*) pa_object_new_internal(sizeof(type), #type, type##_check_type) #define pa_object_free ((void (*) (pa_object* o)) pa_xfree) -int pa_object_check_type(pa_object *o, const char *type); +int pa_object_check_type(const char *type); static inline int pa_object_isinstance(void *o) { pa_object *obj = (pa_object*) o; - pa_assert(obj); - return obj->check_type(obj, "pa_object"); + return obj ? obj->check_type("pa_object") : 0; } pa_object *pa_object_ref(pa_object *o); @@ -63,19 +62,18 @@ static inline int pa_object_refcnt(pa_object *o) { static inline pa_object* pa_object_cast(void *o) { pa_object *obj = (pa_object*) o; - pa_assert(obj->check_type(obj, "pa_object")); + pa_assert(!obj || obj->check_type("pa_object")); return obj; } -#define pa_object_assert_ref(o) pa_assert(pa_object_refcnt(o)) +#define pa_object_assert_ref(o) pa_assert(pa_object_refcnt(o) > 0) #define PA_OBJECT(o) pa_object_cast(o) #define PA_DECLARE_CLASS(c) \ static inline int c##_isinstance(void *o) { \ pa_object *obj = (pa_object*) o; \ - pa_assert(obj); \ - return obj->check_type(obj, #c); \ + return obj ? obj->check_type(#c) : 1; \ } \ static inline c* c##_cast(void *o) { \ pa_assert(c##_isinstance(o)); \ @@ -95,14 +93,13 @@ static inline pa_object* pa_object_cast(void *o) { } \ struct __stupid_useless_struct_to_allow_trailing_semicolon -#define PA_DEFINE_CHECK_TYPE(c, func, parent) \ - int func(pa_object *o, const char *type) { \ - pa_assert(o); \ +#define PA_DEFINE_CHECK_TYPE(c, parent) \ + int c##_check_type(const char *type) { \ pa_assert(type); \ if (type == #c || \ strcmp(type, #c) == 0) \ return 1; \ - return parent(o, type); \ + return parent##_check_type(type); \ } \ struct __stupid_useless_struct_to_allow_trailing_semicolon diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 97345f00..3be5eae8 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -28,7 +28,6 @@ #include #include -#include #include #include @@ -72,54 +71,57 @@ #define MAX_MEMBLOCKQ_LENGTH (4*1024*1024) /* 4MB */ -struct connection; +typedef struct connection connection; struct pa_protocol_native; -struct record_stream { - struct connection *connection; +typedef struct record_stream { + pa_msgobject parent; + + connection *connection; uint32_t index; + pa_source_output *source_output; pa_memblockq *memblockq; size_t fragment_size; -}; +} record_stream; + +typedef struct output_stream { + pa_msgobject parent; +} output_stream; -struct playback_stream { - int type; - struct connection *connection; +typedef struct playback_stream { + output_stream parent; + + connection *connection; uint32_t index; + pa_sink_input *sink_input; pa_memblockq *memblockq; - size_t requested_bytes; int drain_request; uint32_t drain_tag; uint32_t syncid; int underrun; - /* Sync group members */ - PA_LLIST_FIELDS(struct playback_stream); -}; + pa_atomic_t missing; + size_t last_missing; +} playback_stream; -struct upload_stream { - int type; - struct connection *connection; +typedef struct upload_stream { + output_stream parent; + + connection *connection; uint32_t index; + pa_memchunk memchunk; size_t length; char *name; pa_sample_spec sample_spec; pa_channel_map channel_map; -}; - -struct output_stream { - int type; -}; - -enum { - UPLOAD_STREAM, - PLAYBACK_STREAM -}; +} upload_stream; struct connection { + pa_msgobject parent; + int authorized; uint32_t version; pa_protocol_native *protocol; @@ -132,10 +134,31 @@ struct connection { pa_time_event *auth_timeout_event; }; + +PA_DECLARE_CLASS(record_stream); +#define RECORD_STREAM(o) (record_stream_cast(o)) +static PA_DEFINE_CHECK_TYPE(record_stream, pa_msgobject); + +PA_DECLARE_CLASS(output_stream); +#define OUTPUT_STREAM(o) (output_stream_cast(o)) +static PA_DEFINE_CHECK_TYPE(output_stream, pa_msgobject); + +PA_DECLARE_CLASS(playback_stream); +#define PLAYBACK_STREAM(o) (playback_stream_cast(o)) +static PA_DEFINE_CHECK_TYPE(playback_stream, output_stream); + +PA_DECLARE_CLASS(upload_stream); +#define UPLOAD_STREAM(o) (upload_stream_cast(o)) +static PA_DEFINE_CHECK_TYPE(upload_stream, output_stream); + +PA_DECLARE_CLASS(connection); +#define CONNECTION(o) (connection_cast(o)) +static PA_DEFINE_CHECK_TYPE(connection, pa_msgobject); + struct pa_protocol_native { pa_module *module; - int public; pa_core *core; + int public; pa_socket_server *server; pa_idxset *connections; uint8_t auth_cookie[PA_NATIVE_COOKIE_LENGTH]; @@ -146,17 +169,39 @@ struct pa_protocol_native { pa_ip_acl *auth_ip_acl; }; +enum { + SINK_INPUT_MESSAGE_POST_DATA = PA_SINK_INPUT_MESSAGE_MAX, /* data from main loop to sink input */ + SINK_INPUT_MESSAGE_DRAIN, /* disabled prebuf, get playback started. */ + SINK_INPUT_MESSAGE_FLUSH, + SINK_INPUT_MESSAGE_TRIGGER, + SINK_INPUT_MESSAGE_SEEK, + SINK_INPUT_MESSAGE_PREBUF_FORCE +}; + +enum { + PLAYBACK_STREAM_MESSAGE_REQUEST_DATA, /* data requested from sink input from the main loop */ + PLAYBACK_STREAM_MESSAGE_UNDERFLOW, + PLAYBACK_STREAM_MESSAGE_OVERFLOW, + PLAYBACK_STREAM_MESSAGE_DRAIN_ACK +}; + +enum { + RECORD_STREAM_MESSAGE_POST_DATA /* data from source output to main loop */ +}; + static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk); -static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_t length); +static void sink_input_drop_cb(pa_sink_input *i, size_t length); static void sink_input_kill_cb(pa_sink_input *i); -static pa_usec_t sink_input_get_latency_cb(pa_sink_input *i); +static void send_memblock(connection *c); static void request_bytes(struct playback_stream*s); static void source_output_kill_cb(pa_source_output *o); static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk); static pa_usec_t source_output_get_latency_cb(pa_source_output *o); +static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk); + static void command_exit(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); static void command_drain_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); @@ -179,8 +224,7 @@ static void command_subscribe(pa_pdispatch *pd, uint32_t command, uint32_t tag, static void command_set_volume(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); static void command_set_mute(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); static void command_cork_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_flush_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_trigger_or_prebuf_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); +static void command_trigger_or_flush_or_prebuf_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); static void command_set_default_sink_or_source(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); static void command_set_stream_name(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); static void command_kill(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); @@ -239,12 +283,13 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = { [PA_COMMAND_SET_SOURCE_VOLUME] = command_set_volume, [PA_COMMAND_SET_SINK_MUTE] = command_set_mute, + [PA_COMMAND_SET_SINK_INPUT_MUTE] = command_set_mute, [PA_COMMAND_SET_SOURCE_MUTE] = command_set_mute, [PA_COMMAND_CORK_PLAYBACK_STREAM] = command_cork_playback_stream, - [PA_COMMAND_FLUSH_PLAYBACK_STREAM] = command_flush_playback_stream, - [PA_COMMAND_TRIGGER_PLAYBACK_STREAM] = command_trigger_or_prebuf_playback_stream, - [PA_COMMAND_PREBUF_PLAYBACK_STREAM] = command_trigger_or_prebuf_playback_stream, + [PA_COMMAND_FLUSH_PLAYBACK_STREAM] = command_trigger_or_flush_or_prebuf_playback_stream, + [PA_COMMAND_TRIGGER_PLAYBACK_STREAM] = command_trigger_or_flush_or_prebuf_playback_stream, + [PA_COMMAND_PREBUF_PLAYBACK_STREAM] = command_trigger_or_flush_or_prebuf_playback_stream, [PA_COMMAND_CORK_RECORD_STREAM] = command_cork_record_stream, [PA_COMMAND_FLUSH_RECORD_STREAM] = command_flush_record_stream, @@ -269,74 +314,145 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = { /* structure management */ -static struct upload_stream* upload_stream_new( - struct connection *c, - const pa_sample_spec *ss, - const pa_channel_map *map, - const char *name, size_t length) { +static void upload_stream_unlink(upload_stream *s) { + pa_assert(s); + + if (!s->connection) + return; + + pa_assert_se(pa_idxset_remove_by_data(s->connection->output_streams, s, NULL) == s); + upload_stream_unref(s); + s->connection = NULL; +} + +static void upload_stream_free(pa_object *o) { + upload_stream *s = UPLOAD_STREAM(o); + pa_assert(s); - struct upload_stream *s; - assert(c && ss && name && length); + upload_stream_unlink(s); - s = pa_xnew(struct upload_stream, 1); - s->type = UPLOAD_STREAM; + pa_xfree(s->name); + + if (s->memchunk.memblock) + pa_memblock_unref(s->memchunk.memblock); + + pa_xfree(s); +} + +static upload_stream* upload_stream_new( + connection *c, + const pa_sample_spec *ss, + const pa_channel_map *map, + const char *name, size_t length) { + + upload_stream *s; + + pa_assert(c); + pa_assert(ss); + pa_assert(name); + pa_assert(length > 0); + + s = pa_msgobject_new(upload_stream); + c->parent.parent.free = upload_stream_free; s->connection = c; s->sample_spec = *ss; s->channel_map = *map; s->name = pa_xstrdup(name); - - s->memchunk.memblock = NULL; - s->memchunk.index = 0; - s->memchunk.length = 0; - + pa_memchunk_reset(&s->memchunk); s->length = length; pa_idxset_put(c->output_streams, s, &s->index); + return s; } -static void upload_stream_free(struct upload_stream *o) { - assert(o && o->connection); +static void record_stream_unlink(record_stream *s) { + pa_assert(s); - pa_idxset_remove_by_data(o->connection->output_streams, o, NULL); + if (!s->connection) + return; - pa_xfree(o->name); + if (s->source_output) { + pa_source_output_disconnect(s->source_output); + pa_source_output_unref(s->source_output); + s->source_output = NULL; + } + + pa_assert_se(pa_idxset_remove_by_data(s->connection->record_streams, s, NULL) == s); + record_stream_unref(s); + s->connection = NULL; +} + +static void record_stream_free(pa_object *o) { + record_stream *s = RECORD_STREAM(o); + pa_assert(s); + + record_stream_unlink(s); + + pa_memblockq_free(s->memblockq); + pa_xfree(s); +} - if (o->memchunk.memblock) - pa_memblock_unref(o->memchunk.memblock); +static int record_stream_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) { + record_stream *s = RECORD_STREAM(o); + record_stream_assert_ref(s); + + switch (code) { + + case RECORD_STREAM_MESSAGE_POST_DATA: + + if (pa_memblockq_push_align(s->memblockq, chunk) < 0) { + pa_log_warn("Failed to push data into output queue."); + return -1; + } + + if (!pa_pstream_is_pending(s->connection->pstream)) + send_memblock(s->connection); + + pa_pstream_send_memblock(s->connection->pstream, s->index, 0, PA_SEEK_RELATIVE, chunk); + break; + } - pa_xfree(o); + return 0; } -static struct record_stream* record_stream_new( - struct connection *c, - pa_source *source, - const pa_sample_spec *ss, - const pa_channel_map *map, - const char *name, - size_t maxlength, - size_t fragment_size) { +static record_stream* record_stream_new( + connection *c, + pa_source *source, + const pa_sample_spec *ss, + const pa_channel_map *map, + const char *name, + size_t *maxlength, + size_t fragment_size, + int corked) { - struct record_stream *s; + record_stream *s; pa_source_output *source_output; size_t base; pa_source_output_new_data data; - assert(c && ss && name && maxlength); + pa_assert(c); + pa_assert(ss); + pa_assert(name); + pa_assert(maxlength); + pa_assert(*maxlength > 0); pa_source_output_new_data_init(&data); + data.module = c->protocol->module; + data.client = c->client; data.source = source; data.driver = __FILE__; data.name = name; + data.corked = corked; pa_source_output_new_data_set_sample_spec(&data, ss); pa_source_output_new_data_set_channel_map(&data, map); - data.module = c->protocol->module; - data.client = c->client; if (!(source_output = pa_source_output_new(c->protocol->core, &data, 0))) return NULL; - s = pa_xnew(struct record_stream, 1); + s = pa_msgobject_new(record_stream); + c->parent.parent.free = record_stream_free; + c->parent.process_msg = record_stream_process_msg; s->connection = c; s->source_output = source_output; s->source_output->push = source_output_push_cb; @@ -346,58 +462,143 @@ static struct record_stream* record_stream_new( s->memblockq = pa_memblockq_new( 0, - maxlength, + *maxlength, 0, base = pa_frame_size(ss), 1, 0, NULL); - assert(s->memblockq); s->fragment_size = (fragment_size/base)*base; - if (!s->fragment_size) + if (s->fragment_size <= 0) s->fragment_size = base; + *maxlength = pa_memblockq_get_maxlength(s->memblockq); pa_idxset_put(c->record_streams, s, &s->index); + + pa_source_output_put(s->source_output); return s; } -static void record_stream_free(struct record_stream* r) { - assert(r && r->connection); +static void playback_stream_unlink(playback_stream *s) { + pa_assert(s); + + if (!s->connection) + return; - pa_idxset_remove_by_data(r->connection->record_streams, r, NULL); - pa_source_output_disconnect(r->source_output); - pa_source_output_unref(r->source_output); - pa_memblockq_free(r->memblockq); - pa_xfree(r); + if (s->sink_input) { + pa_sink_input_disconnect(s->sink_input); + pa_sink_input_unref(s->sink_input); + s->sink_input = NULL; + } + + if (s->drain_request) + pa_pstream_send_error(s->connection->pstream, s->drain_tag, PA_ERR_NOENTITY); + + pa_assert_se(pa_idxset_remove_by_data(s->connection->output_streams, s, NULL) == s); + playback_stream_unref(s); + s->connection = NULL; +} + +static void playback_stream_free(pa_object* o) { + playback_stream *s = PLAYBACK_STREAM(o); + pa_assert(s); + + playback_stream_unlink(s); + + pa_memblockq_free(s->memblockq); + pa_xfree(s); } -static struct playback_stream* playback_stream_new( - struct connection *c, +static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) { + playback_stream *s = PLAYBACK_STREAM(o); + playback_stream_assert_ref(s); + + switch (code) { + case PLAYBACK_STREAM_MESSAGE_REQUEST_DATA: { + pa_tagstruct *t; + int32_t l; + + if ((l = pa_atomic_load(&s->missing)) <= 0) + break; + + pa_assert_se(pa_atomic_sub(&s->missing, l) >= l); + + t = pa_tagstruct_new(NULL, 0); + pa_tagstruct_putu32(t, PA_COMMAND_REQUEST); + pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ + pa_tagstruct_putu32(t, s->index); + pa_tagstruct_putu32(t, l); + pa_pstream_send_tagstruct(s->connection->pstream, t); + + /* pa_log("Requesting %u bytes", l); */ + break; + } + + case PLAYBACK_STREAM_MESSAGE_UNDERFLOW: { + pa_tagstruct *t; + + /* Report that we're empty */ + t = pa_tagstruct_new(NULL, 0); + pa_tagstruct_putu32(t, PA_COMMAND_UNDERFLOW); + pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ + pa_tagstruct_putu32(t, s->index); + pa_pstream_send_tagstruct(s->connection->pstream, t); + break; + } + + case PLAYBACK_STREAM_MESSAGE_OVERFLOW: { + pa_tagstruct *t; + + /* Notify the user we're overflowed*/ + t = pa_tagstruct_new(NULL, 0); + pa_tagstruct_putu32(t, PA_COMMAND_OVERFLOW); + pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ + pa_tagstruct_putu32(t, s->index); + pa_pstream_send_tagstruct(s->connection->pstream, t); + break; + } + + case PLAYBACK_STREAM_MESSAGE_DRAIN_ACK: + pa_pstream_send_simple_ack(s->connection->pstream, PA_PTR_TO_UINT(userdata)); + break; + + } + + return 0; +} + +static playback_stream* playback_stream_new( + connection *c, pa_sink *sink, const pa_sample_spec *ss, const pa_channel_map *map, const char *name, - size_t maxlength, - size_t tlength, - size_t prebuf, - size_t minreq, + size_t *maxlength, + size_t *tlength, + size_t *prebuf, + size_t *minreq, pa_cvolume *volume, - uint32_t syncid) { + uint32_t syncid, + int corked, + size_t *missing) { - struct playback_stream *s, *ssync; + playback_stream *s, *ssync; pa_sink_input *sink_input; pa_memblock *silence; uint32_t idx; int64_t start_index; pa_sink_input_new_data data; - assert(c && ss && name && maxlength); + pa_assert(c); + pa_assert(ss); + pa_assert(name); + pa_assert(maxlength); /* Find syncid group */ for (ssync = pa_idxset_first(c->output_streams, &idx); ssync; ssync = pa_idxset_next(c->output_streams, &idx)) { - if (ssync->type != PLAYBACK_STREAM) + if (!playback_stream_isinstance(ssync)) continue; if (ssync->syncid == syncid) @@ -405,8 +606,13 @@ static struct playback_stream* playback_stream_new( } /* Synced streams must connect to the same sink */ - if (ssync) - sink = ssync->sink_input->sink; + if (ssync) { + + if (!sink) + sink = ssync->sink_input->sink; + else if (sink != ssync->sink_input->sink) + return NULL; + } pa_sink_input_new_data_init(&data); data.sink = sink; @@ -417,146 +623,136 @@ static struct playback_stream* playback_stream_new( pa_sink_input_new_data_set_volume(&data, volume); data.module = c->protocol->module; data.client = c->client; + data.start_corked = corked; + data.sync_base = ssync ? ssync->sink_input : NULL; if (!(sink_input = pa_sink_input_new(c->protocol->core, &data, 0))) return NULL; - s = pa_xnew(struct playback_stream, 1); - s->type = PLAYBACK_STREAM; + s = pa_msgobject_new(playback_stream); + c->parent.parent.free = playback_stream_free; + c->parent.process_msg = playback_stream_process_msg; s->connection = c; s->syncid = syncid; s->sink_input = sink_input; s->underrun = 1; + s->sink_input->parent.process_msg = sink_input_process_msg; s->sink_input->peek = sink_input_peek_cb; s->sink_input->drop = sink_input_drop_cb; s->sink_input->kill = sink_input_kill_cb; - s->sink_input->get_latency = sink_input_get_latency_cb; s->sink_input->userdata = s; - if (ssync) { - /* Sync id found, now find head of list */ - PA_LLIST_FIND_HEAD(struct playback_stream, ssync, &ssync); - - /* Prepend ourselves */ - PA_LLIST_PREPEND(struct playback_stream, ssync, s); - - /* Set our start index to the current read index of the other grozp member(s) */ - assert(ssync->next); - start_index = pa_memblockq_get_read_index(ssync->next->memblockq); - } else { - /* This ia a new sync group */ - PA_LLIST_INIT(struct playback_stream, s); - start_index = 0; - } + start_index = ssync ? pa_memblockq_get_read_index(ssync->memblockq) : 0; silence = pa_silence_memblock_new(c->protocol->core->mempool, ss, 0); s->memblockq = pa_memblockq_new( start_index, - maxlength, - tlength, + *maxlength, + *tlength, pa_frame_size(ss), - prebuf, - minreq, + *prebuf, + *minreq, silence); pa_memblock_unref(silence); - s->requested_bytes = 0; + *maxlength = pa_memblockq_get_maxlength(s->memblockq); + *tlength = pa_memblockq_get_tlength(s->memblockq); + *prebuf = pa_memblockq_get_prebuf(s->memblockq); + *minreq = pa_memblockq_get_minreq(s->memblockq); + *missing = pa_memblockq_missing(s->memblockq); + + pa_atomic_store(&s->missing, 0); + s->last_missing = *missing; s->drain_request = 0; pa_idxset_put(c->output_streams, s, &s->index); + pa_sink_input_put(s->sink_input); + return s; } -static void playback_stream_free(struct playback_stream* p) { - struct playback_stream *head; - assert(p && p->connection); +static void connection_unlink(connection *c) { + record_stream *r; + output_stream *o; - if (p->drain_request) - pa_pstream_send_error(p->connection->pstream, p->drain_tag, PA_ERR_NOENTITY); + pa_assert(c); - PA_LLIST_FIND_HEAD(struct playback_stream, p, &head); - PA_LLIST_REMOVE(struct playback_stream, head, p); - - pa_idxset_remove_by_data(p->connection->output_streams, p, NULL); - pa_sink_input_disconnect(p->sink_input); - pa_sink_input_unref(p->sink_input); - pa_memblockq_free(p->memblockq); - pa_xfree(p); -} - -static void connection_free(struct connection *c) { - struct record_stream *r; - struct output_stream *o; - assert(c && c->protocol); + if (!c->protocol) + return; - pa_idxset_remove_by_data(c->protocol->connections, c, NULL); while ((r = pa_idxset_first(c->record_streams, NULL))) - record_stream_free(r); - pa_idxset_free(c->record_streams, NULL, NULL); + record_stream_unlink(r); while ((o = pa_idxset_first(c->output_streams, NULL))) - if (o->type == PLAYBACK_STREAM) - playback_stream_free((struct playback_stream*) o); + if (playback_stream_isinstance(o)) + playback_stream_unlink(PLAYBACK_STREAM(o)); else - upload_stream_free((struct upload_stream*) o); - pa_idxset_free(c->output_streams, NULL, NULL); - - pa_pdispatch_unref(c->pdispatch); - pa_pstream_close(c->pstream); - pa_pstream_unref(c->pstream); - pa_client_free(c->client); + upload_stream_unlink(UPLOAD_STREAM(o)); if (c->subscription) pa_subscription_free(c->subscription); - if (c->auth_timeout_event) + if (c->pstream) + pa_pstream_close(c->pstream); + + if (c->auth_timeout_event) { c->protocol->core->mainloop->time_free(c->auth_timeout_event); + c->auth_timeout_event = NULL; + } + + pa_assert_se(pa_idxset_remove_by_data(c->protocol->connections, c, NULL) == c); + connection_unref(c); + c->protocol = NULL; +} + +static void connection_free(pa_object *o) { + connection *c = CONNECTION(o); + + pa_assert(c); + + connection_unlink(c); + + pa_idxset_free(c->record_streams, NULL, NULL); + pa_idxset_free(c->output_streams, NULL, NULL); + + pa_pdispatch_unref(c->pdispatch); + pa_pstream_unref(c->pstream); + pa_client_free(c->client); pa_xfree(c); } -static void request_bytes(struct playback_stream *s) { - pa_tagstruct *t; - size_t l; - assert(s); +static void request_bytes(playback_stream *s) { + size_t new_missing, delta, previous_missing; - if (!(l = pa_memblockq_missing(s->memblockq))) - return; - - if (l <= s->requested_bytes) - return; + playback_stream_assert_ref(s); - l -= s->requested_bytes; + new_missing = pa_memblockq_missing(s->memblockq); - if (l < pa_memblockq_get_minreq(s->memblockq)) + if (new_missing <= s->last_missing) return; - s->requested_bytes += l; - - t = pa_tagstruct_new(NULL, 0); - assert(t); - pa_tagstruct_putu32(t, PA_COMMAND_REQUEST); - pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ - pa_tagstruct_putu32(t, s->index); - pa_tagstruct_putu32(t, l); - pa_pstream_send_tagstruct(s->connection->pstream, t); + delta = new_missing - s->last_missing; + s->last_missing = new_missing; -/* pa_log("Requesting %u bytes", l); */ + previous_missing = pa_atomic_add(&s->missing, delta); + if (previous_missing < pa_memblockq_get_minreq(s->memblockq) && previous_missing+delta >= pa_memblockq_get_minreq(s->memblockq)) + pa_asyncmsgq_post(s->connection->protocol->core->asyncmsgq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); } -static void send_memblock(struct connection *c) { +static void send_memblock(connection *c) { uint32_t start; - struct record_stream *r; + record_stream *r; start = PA_IDXSET_INVALID; for (;;) { pa_memchunk chunk; - if (!(r = pa_idxset_rrobin(c->record_streams, &c->rrobin_index))) + if (!(r = RECORD_STREAM(pa_idxset_rrobin(c->record_streams, &c->rrobin_index)))) return; if (start == PA_IDXSET_INVALID) @@ -571,7 +767,8 @@ static void send_memblock(struct connection *c) { schunk.length = r->fragment_size; pa_pstream_send_memblock(c->pstream, r->index, 0, PA_SEEK_RELATIVE, &schunk); - pa_memblockq_drop(r->memblockq, &chunk, schunk.length); + + pa_memblockq_drop(r->memblockq, schunk.length); pa_memblock_unref(schunk.memblock); return; @@ -579,9 +776,9 @@ static void send_memblock(struct connection *c) { } } -static void send_playback_stream_killed(struct playback_stream *p) { +static void send_playback_stream_killed(playback_stream *p) { pa_tagstruct *t; - assert(p); + playback_stream_assert_ref(p); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_PLAYBACK_STREAM_KILLED); @@ -590,9 +787,9 @@ static void send_playback_stream_killed(struct playback_stream *p) { pa_pstream_send_tagstruct(p->connection->pstream, t); } -static void send_record_stream_killed(struct record_stream *r) { +static void send_record_stream_killed(record_stream *r) { pa_tagstruct *t; - assert(r); + record_stream_assert_ref(r); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_RECORD_STREAM_KILLED); @@ -603,22 +800,123 @@ static void send_record_stream_killed(struct record_stream *r) { /*** sinkinput callbacks ***/ -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { - struct playback_stream *s; - assert(i && i->userdata && chunk); - s = i->userdata; +static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) { + pa_sink_input *i = PA_SINK_INPUT(o); + playback_stream *s; - if (pa_memblockq_get_length(s->memblockq) <= 0 && !s->underrun) { - pa_tagstruct *t; + pa_sink_input_assert_ref(i); + s = PLAYBACK_STREAM(i->userdata); + playback_stream_assert_ref(s); + + switch (code) { + + case SINK_INPUT_MESSAGE_SEEK: + pa_memblockq_seek(s->memblockq, offset, PA_PTR_TO_UINT(userdata)); + return 0; + + case SINK_INPUT_MESSAGE_POST_DATA: { + pa_assert(chunk); + + if (pa_memblockq_push_align(s->memblockq, chunk) < 0) { + + pa_log_warn("Failed to push data into queue"); + pa_asyncmsgq_post(s->connection->protocol->core->asyncmsgq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_OVERFLOW, NULL, 0, NULL, NULL); + pa_memblockq_seek(s->memblockq, chunk->length, PA_SEEK_RELATIVE); + } + + s->underrun = 0; + return 0; + } + + case SINK_INPUT_MESSAGE_DRAIN: { + + pa_memblockq_prebuf_disable(s->memblockq); + + if (!pa_memblockq_is_readable(s->memblockq)) + pa_asyncmsgq_post(s->connection->protocol->core->asyncmsgq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_DRAIN_ACK, userdata, 0, NULL, NULL); + else { + s->drain_tag = PA_PTR_TO_UINT(userdata); + s->drain_request = 1; + } + + return 0; + } + + case SINK_INPUT_MESSAGE_FLUSH: + case SINK_INPUT_MESSAGE_PREBUF_FORCE: + case SINK_INPUT_MESSAGE_TRIGGER: { + + pa_sink_input *isync; + void (*func)(pa_memblockq *bq); + + switch (code) { + case SINK_INPUT_MESSAGE_FLUSH: + func = pa_memblockq_flush; + break; + + case SINK_INPUT_MESSAGE_PREBUF_FORCE: + func = pa_memblockq_prebuf_force; + break; + + case SINK_INPUT_MESSAGE_TRIGGER: + func = pa_memblockq_prebuf_disable; + break; + + default: + pa_assert_not_reached(); + } + + func(s->memblockq); + s->underrun = 0; + request_bytes(s); + + /* Do the same for all other members in the sync group */ + for (isync = i->sync_prev; isync; isync = isync->sync_prev) { + playback_stream *ssync = PLAYBACK_STREAM(isync->userdata); + func(ssync->memblockq); + ssync->underrun = 0; + request_bytes(ssync); + } + + for (isync = i->sync_next; isync; isync = isync->sync_next) { + playback_stream *ssync = PLAYBACK_STREAM(isync->userdata); + func(ssync->memblockq); + ssync->underrun = 0; + request_bytes(ssync); + } + + return 0; + } + + case PA_SINK_INPUT_MESSAGE_SET_STATE: + + pa_memblockq_prebuf_force(s->memblockq); + break; + + case PA_SINK_INPUT_MESSAGE_GET_LATENCY: { + pa_usec_t *r = userdata; + + *r = pa_bytes_to_usec(pa_memblockq_get_length(s->memblockq), &i->sample_spec); + + /* Fall through, the default handler will add in the extra + * latency added by the resampler */ + break; + } + } - /* Report that we're empty */ + return pa_sink_input_process_msg(o, code, userdata, offset, chunk); +} + +static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { + playback_stream *s; - t = pa_tagstruct_new(NULL, 0); - pa_tagstruct_putu32(t, PA_COMMAND_UNDERFLOW); - pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ - pa_tagstruct_putu32(t, s->index); - pa_pstream_send_tagstruct(s->connection->pstream, t); + pa_sink_input_assert_ref(i); + s = PLAYBACK_STREAM(i->userdata); + playback_stream_assert_ref(s); + pa_assert(chunk); + if (pa_memblockq_get_length(s->memblockq) <= 0 && !s->underrun) { + pa_asyncmsgq_post(s->connection->protocol->core->asyncmsgq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_UNDERFLOW, NULL, 0, NULL, NULL); s->underrun = 1; } @@ -632,65 +930,67 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { return 0; } -static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_t length) { - struct playback_stream *s; - assert(i && i->userdata && length); - s = i->userdata; +static void sink_input_drop_cb(pa_sink_input *i, size_t length) { + playback_stream *s; - pa_memblockq_drop(s->memblockq, chunk, length); + pa_sink_input_assert_ref(i); + s = PLAYBACK_STREAM(i->userdata); + playback_stream_assert_ref(s); + pa_assert(length > 0); - request_bytes(s); + pa_memblockq_drop(s->memblockq, length); if (s->drain_request && !pa_memblockq_is_readable(s->memblockq)) { - pa_pstream_send_simple_ack(s->connection->pstream, s->drain_tag); s->drain_request = 0; + pa_asyncmsgq_post(s->connection->protocol->core->asyncmsgq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_DRAIN_ACK, PA_UINT_TO_PTR(s->drain_tag), 0, NULL, NULL); } + request_bytes(s); + /* pa_log("after_drop: %u %u", pa_memblockq_get_length(s->memblockq), pa_memblockq_is_readable(s->memblockq)); */ } static void sink_input_kill_cb(pa_sink_input *i) { - assert(i && i->userdata); - send_playback_stream_killed((struct playback_stream *) i->userdata); - playback_stream_free((struct playback_stream *) i->userdata); -} + playback_stream *s; -static pa_usec_t sink_input_get_latency_cb(pa_sink_input *i) { - struct playback_stream *s; - assert(i && i->userdata); - s = i->userdata; + pa_sink_input_assert_ref(i); + s = PLAYBACK_STREAM(i->userdata); + playback_stream_assert_ref(s); - /*pa_log("get_latency: %u", pa_memblockq_get_length(s->memblockq));*/ - - return pa_bytes_to_usec(pa_memblockq_get_length(s->memblockq), &s->sink_input->sample_spec); + send_playback_stream_killed(s); + playback_stream_unlink(s); } /*** source_output callbacks ***/ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) { - struct record_stream *s; - assert(o && o->userdata && chunk); - s = o->userdata; + record_stream *s; - if (pa_memblockq_push_align(s->memblockq, chunk) < 0) { - pa_log_warn("Failed to push data into output queue."); - return; - } + pa_source_output_assert_ref(o); + s = RECORD_STREAM(o->userdata); + record_stream_assert_ref(s); + pa_assert(chunk); - if (!pa_pstream_is_pending(s->connection->pstream)) - send_memblock(s->connection); + pa_asyncmsgq_post(s->connection->protocol->core->asyncmsgq, PA_MSGOBJECT(s), RECORD_STREAM_MESSAGE_POST_DATA, NULL, 0, chunk, NULL); } static void source_output_kill_cb(pa_source_output *o) { - assert(o && o->userdata); - send_record_stream_killed((struct record_stream *) o->userdata); - record_stream_free((struct record_stream *) o->userdata); + record_stream *s; + + pa_source_output_assert_ref(o); + s = RECORD_STREAM(o->userdata); + record_stream_assert_ref(s); + + send_record_stream_killed(s); + record_stream_unlink(s); } static pa_usec_t source_output_get_latency_cb(pa_source_output *o) { - struct record_stream *s; - assert(o && o->userdata); - s = o->userdata; + record_stream *s; + + pa_source_output_assert_ref(o); + s = RECORD_STREAM(o->userdata); + record_stream_assert_ref(s); /*pa_log("get_latency: %u", pa_memblockq_get_length(s->memblockq));*/ @@ -699,9 +999,9 @@ static pa_usec_t source_output_get_latency_cb(pa_source_output *o) { /*** pdispatch callbacks ***/ -static void protocol_error(struct connection *c) { +static void protocol_error(connection *c) { pa_log("protocol error, kicking client"); - connection_free(c); + connection_unlink(c); } #define CHECK_VALIDITY(pstream, expression, tag, error) do { \ @@ -721,9 +1021,9 @@ static pa_tagstruct *reply_new(uint32_t tag) { } static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - struct playback_stream *s; - uint32_t maxlength, tlength, prebuf, minreq, sink_index, syncid; + connection *c = CONNECTION(userdata); + playback_stream *s; + uint32_t maxlength, tlength, prebuf, minreq, sink_index, syncid, missing; const char *name, *sink_name; pa_sample_spec ss; pa_channel_map map; @@ -731,8 +1031,9 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC pa_sink *sink = NULL; pa_cvolume volume; int corked; - - assert(c && t && c->protocol && c->protocol->core); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_get( t, @@ -773,34 +1074,33 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC CHECK_VALIDITY(c->pstream, sink, tag, PA_ERR_NOENTITY); } - s = playback_stream_new(c, sink, &ss, &map, name, maxlength, tlength, prebuf, minreq, &volume, syncid); + s = playback_stream_new(c, sink, &ss, &map, name, &maxlength, &tlength, &prebuf, &minreq, &volume, syncid, corked, &missing); CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_INVALID); - pa_sink_input_cork(s->sink_input, corked); - reply = reply_new(tag); pa_tagstruct_putu32(reply, s->index); - assert(s->sink_input); + pa_assert(s->sink_input); pa_tagstruct_putu32(reply, s->sink_input->index); - pa_tagstruct_putu32(reply, s->requested_bytes = pa_memblockq_missing(s->memblockq)); + pa_tagstruct_putu32(reply, missing); if (c->version >= 9) { /* Since 0.9 we support sending the buffer metrics back to the client */ - pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_maxlength(s->memblockq)); - pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_tlength(s->memblockq)); - pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_prebuf(s->memblockq)); - pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_minreq(s->memblockq)); + pa_tagstruct_putu32(reply, (uint32_t) maxlength); + pa_tagstruct_putu32(reply, (uint32_t) tlength); + pa_tagstruct_putu32(reply, (uint32_t) prebuf); + pa_tagstruct_putu32(reply, (uint32_t) minreq); } pa_pstream_send_tagstruct(c->pstream, reply); - request_bytes(s); } static void command_delete_stream(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); uint32_t channel; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_getu32(t, &channel) < 0 || !pa_tagstruct_eof(t)) { @@ -810,39 +1110,52 @@ static void command_delete_stream(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t comma CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - if (command == PA_COMMAND_DELETE_PLAYBACK_STREAM) { - struct playback_stream *s; - if (!(s = pa_idxset_get_by_index(c->output_streams, channel)) || (s->type != PLAYBACK_STREAM)) { - pa_pstream_send_error(c->pstream, tag, PA_ERR_EXIST); - return; + switch (command) { + + case PA_COMMAND_DELETE_PLAYBACK_STREAM: { + playback_stream *s; + if (!(s = pa_idxset_get_by_index(c->output_streams, channel)) || !playback_stream_isinstance(s)) { + pa_pstream_send_error(c->pstream, tag, PA_ERR_EXIST); + return; + } + + playback_stream_unlink(s); + break; } - - playback_stream_free(s); - } else if (command == PA_COMMAND_DELETE_RECORD_STREAM) { - struct record_stream *s; - if (!(s = pa_idxset_get_by_index(c->record_streams, channel))) { - pa_pstream_send_error(c->pstream, tag, PA_ERR_EXIST); - return; + + case PA_COMMAND_DELETE_RECORD_STREAM: { + record_stream *s; + if (!(s = pa_idxset_get_by_index(c->record_streams, channel))) { + pa_pstream_send_error(c->pstream, tag, PA_ERR_EXIST); + return; + } + + record_stream_unlink(s); + break; } - record_stream_free(s); - } else { - struct upload_stream *s; - assert(command == PA_COMMAND_DELETE_UPLOAD_STREAM); - if (!(s = pa_idxset_get_by_index(c->output_streams, channel)) || (s->type != UPLOAD_STREAM)) { - pa_pstream_send_error(c->pstream, tag, PA_ERR_EXIST); - return; + case PA_COMMAND_DELETE_UPLOAD_STREAM: { + upload_stream *s; + + if (!(s = pa_idxset_get_by_index(c->output_streams, channel)) || !upload_stream_isinstance(s)) { + pa_pstream_send_error(c->pstream, tag, PA_ERR_EXIST); + return; + } + + upload_stream_unlink(s); + break; } - upload_stream_free(s); + default: + pa_assert_not_reached(); } pa_pstream_send_simple_ack(c->pstream, tag); } static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - struct record_stream *s; + connection *c = CONNECTION(userdata); + record_stream *s; uint32_t maxlength, fragment_size; uint32_t source_index; const char *name, *source_name; @@ -851,7 +1164,9 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ pa_tagstruct *reply; pa_source *source = NULL; int corked; - assert(c && t && c->protocol && c->protocol->core); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_gets(t, &name) < 0 || pa_tagstruct_get_sample_spec(t, &ss) < 0 || @@ -882,20 +1197,18 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ CHECK_VALIDITY(c->pstream, source, tag, PA_ERR_NOENTITY); } - s = record_stream_new(c, source, &ss, &map, name, maxlength, fragment_size); + s = record_stream_new(c, source, &ss, &map, name, &maxlength, fragment_size, corked); CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_INVALID); - pa_source_output_cork(s->source_output, corked); - reply = reply_new(tag); pa_tagstruct_putu32(reply, s->index); - assert(s->source_output); + pa_assert(s->source_output); pa_tagstruct_putu32(reply, s->source_output->index); if (c->version >= 9) { /* Since 0.9 we support sending the buffer metrics back to the client */ - pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_maxlength(s->memblockq)); + pa_tagstruct_putu32(reply, (uint32_t) maxlength); pa_tagstruct_putu32(reply, (uint32_t) s->fragment_size); } @@ -903,9 +1216,11 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ } static void command_exit(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - assert(c && t); + connection *c = CONNECTION(userdata); + connection_assert_ref(c); + pa_assert(t); + if (!pa_tagstruct_eof(t)) { protocol_error(c); return; @@ -913,16 +1228,17 @@ static void command_exit(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - assert(c->protocol && c->protocol->core && c->protocol->core->mainloop); c->protocol->core->mainloop->quit(c->protocol->core->mainloop, 0); pa_pstream_send_simple_ack(c->pstream, tag); /* nonsense */ } static void command_auth(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); const void*cookie; pa_tagstruct *reply; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_getu32(t, &c->version) < 0 || pa_tagstruct_get_arbitrary(t, &cookie, PA_NATIVE_COOKIE_LENGTH) < 0 || @@ -1015,9 +1331,11 @@ static void command_auth(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t } static void command_set_client_name(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); const char *name; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_gets(t, &name) < 0 || !pa_tagstruct_eof(t)) { @@ -1032,10 +1350,12 @@ static void command_set_client_name(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSE } static void command_lookup(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); const char *name; uint32_t idx = PA_IDXSET_INVALID; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_gets(t, &name) < 0 || !pa_tagstruct_eof(t)) { @@ -1052,7 +1372,7 @@ static void command_lookup(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uin idx = sink->index; } else { pa_source *source; - assert(command == PA_COMMAND_LOOKUP_SOURCE); + pa_assert(command == PA_COMMAND_LOOKUP_SOURCE); if ((source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1))) idx = source->index; } @@ -1068,10 +1388,12 @@ static void command_lookup(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uin } static void command_drain_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); uint32_t idx; - struct playback_stream *s; - assert(c && t); + playback_stream *s; + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || !pa_tagstruct_eof(t)) { @@ -1082,29 +1404,18 @@ static void command_drain_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); s = pa_idxset_get_by_index(c->output_streams, idx); CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - CHECK_VALIDITY(c->pstream, s->type == PLAYBACK_STREAM, tag, PA_ERR_NOENTITY); - - s->drain_request = 0; - - pa_memblockq_prebuf_disable(s->memblockq); + CHECK_VALIDITY(c->pstream, playback_stream_isinstance(s), tag, PA_ERR_NOENTITY); - if (!pa_memblockq_is_readable(s->memblockq)) { -/* pa_log("immediate drain: %u", pa_memblockq_get_length(s->memblockq)); */ - pa_pstream_send_simple_ack(c->pstream, tag); - } else { -/* pa_log("slow drain triggered"); */ - s->drain_request = 1; - s->drain_tag = tag; - - pa_sink_notify(s->sink_input->sink); - } + pa_asyncmsgq_post(s->sink_input->sink->asyncmsgq, PA_MSGOBJECT(s->sink_input), SINK_INPUT_MESSAGE_DRAIN, PA_UINT_TO_PTR(tag), 0, NULL, NULL); } static void command_stat(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); pa_tagstruct *reply; const pa_mempool_stat *stat; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (!pa_tagstruct_eof(t)) { protocol_error(c); @@ -1125,13 +1436,15 @@ static void command_stat(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t } static void command_get_playback_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); pa_tagstruct *reply; - struct playback_stream *s; + playback_stream *s; struct timeval tv, now; uint32_t idx; pa_usec_t latency; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || pa_tagstruct_get_timeval(t, &tv) < 0 || @@ -1143,13 +1456,13 @@ static void command_get_playback_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); s = pa_idxset_get_by_index(c->output_streams, idx); CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - CHECK_VALIDITY(c->pstream, s->type == PLAYBACK_STREAM, tag, PA_ERR_NOENTITY); + CHECK_VALIDITY(c->pstream, playback_stream_isinstance(s), tag, PA_ERR_NOENTITY); reply = reply_new(tag); latency = pa_sink_get_latency(s->sink_input->sink); - if (s->sink_input->resampled_chunk.memblock) - latency += pa_bytes_to_usec(s->sink_input->resampled_chunk.length, &s->sink_input->sample_spec); +/* if (s->sink_input->resampled_chunk.memblock) */ /* FIXME*/ +/* latency += pa_bytes_to_usec(s->sink_input->resampled_chunk.length, &s->sink_input->sample_spec); */ pa_tagstruct_put_usec(reply, latency); pa_tagstruct_put_usec(reply, 0); @@ -1162,12 +1475,14 @@ static void command_get_playback_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ } static void command_get_record_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); pa_tagstruct *reply; - struct record_stream *s; + record_stream *s; struct timeval tv, now; uint32_t idx; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || pa_tagstruct_get_timeval(t, &tv) < 0 || @@ -1192,14 +1507,16 @@ static void command_get_record_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UN } static void command_create_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - struct upload_stream *s; + connection *c = CONNECTION(userdata); + upload_stream *s; uint32_t length; const char *name; pa_sample_spec ss; pa_channel_map map; pa_tagstruct *reply; - assert(c && t && c->protocol && c->protocol->core); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_gets(t, &name) < 0 || pa_tagstruct_get_sample_spec(t, &ss) < 0 || @@ -1228,11 +1545,13 @@ static void command_create_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ } static void command_finish_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); uint32_t channel; - struct upload_stream *s; + upload_stream *s; uint32_t idx; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_getu32(t, &channel) < 0 || !pa_tagstruct_eof(t)) { @@ -1244,23 +1563,25 @@ static void command_finish_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ s = pa_idxset_get_by_index(c->output_streams, channel); CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - CHECK_VALIDITY(c->pstream, s->type == UPLOAD_STREAM, tag, PA_ERR_NOENTITY); + CHECK_VALIDITY(c->pstream, upload_stream_isinstance(s), tag, PA_ERR_NOENTITY); if (pa_scache_add_item(c->protocol->core, s->name, &s->sample_spec, &s->channel_map, &s->memchunk, &idx) < 0) pa_pstream_send_error(c->pstream, tag, PA_ERR_INTERNAL); else pa_pstream_send_simple_ack(c->pstream, tag); - upload_stream_free(s); + upload_stream_unlink(s); } static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); uint32_t sink_index; pa_volume_t volume; pa_sink *sink; const char *name, *sink_name; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_getu32(t, &sink_index) < 0 || pa_tagstruct_gets(t, &sink_name) < 0 || @@ -1291,9 +1612,11 @@ static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED ui } static void command_remove_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); const char *name; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_gets(t, &name) < 0 || !pa_tagstruct_eof(t)) { @@ -1313,7 +1636,9 @@ static void command_remove_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED } static void sink_fill_tagstruct(pa_tagstruct *t, pa_sink *sink) { - assert(t && sink); + pa_assert(t); + pa_sink_assert_ref(sink); + pa_tagstruct_put( t, PA_TAG_U32, sink->index, @@ -1321,22 +1646,24 @@ static void sink_fill_tagstruct(pa_tagstruct *t, pa_sink *sink) { PA_TAG_STRING, sink->description, PA_TAG_SAMPLE_SPEC, &sink->sample_spec, PA_TAG_CHANNEL_MAP, &sink->channel_map, - PA_TAG_U32, sink->owner ? sink->owner->index : PA_INVALID_INDEX, - PA_TAG_CVOLUME, pa_sink_get_volume(sink, PA_MIXER_HARDWARE), - PA_TAG_BOOLEAN, pa_sink_get_mute(sink, PA_MIXER_HARDWARE), + PA_TAG_U32, sink->module ? sink->module->index : PA_INVALID_INDEX, + PA_TAG_CVOLUME, pa_sink_get_volume(sink), + PA_TAG_BOOLEAN, pa_sink_get_mute(sink), PA_TAG_U32, sink->monitor_source ? sink->monitor_source->index : PA_INVALID_INDEX, PA_TAG_STRING, sink->monitor_source ? sink->monitor_source->name : NULL, PA_TAG_USEC, pa_sink_get_latency(sink), PA_TAG_STRING, sink->driver, PA_TAG_U32, - (sink->get_hw_volume ? PA_SINK_HW_VOLUME_CTRL : 0) | - (sink->get_latency ? PA_SINK_LATENCY : 0) | + (sink->get_volume ? PA_SINK_HW_VOLUME_CTRL : 0) | /* FIXME */ + (sink->get_latency ? PA_SINK_LATENCY : 0) | /* FIXME */ (sink->is_hardware ? PA_SINK_HARDWARE : 0), PA_TAG_INVALID); } static void source_fill_tagstruct(pa_tagstruct *t, pa_source *source) { - assert(t && source); + pa_assert(t); + pa_source_assert_ref(source); + pa_tagstruct_put( t, PA_TAG_U32, source->index, @@ -1344,22 +1671,24 @@ static void source_fill_tagstruct(pa_tagstruct *t, pa_source *source) { PA_TAG_STRING, source->description, PA_TAG_SAMPLE_SPEC, &source->sample_spec, PA_TAG_CHANNEL_MAP, &source->channel_map, - PA_TAG_U32, source->owner ? source->owner->index : PA_INVALID_INDEX, - PA_TAG_CVOLUME, pa_source_get_volume(source, PA_MIXER_HARDWARE), - PA_TAG_BOOLEAN, pa_source_get_mute(source, PA_MIXER_HARDWARE), + PA_TAG_U32, source->module ? source->module->index : PA_INVALID_INDEX, + PA_TAG_CVOLUME, pa_source_get_volume(source), + PA_TAG_BOOLEAN, pa_source_get_mute(source), PA_TAG_U32, source->monitor_of ? source->monitor_of->index : PA_INVALID_INDEX, PA_TAG_STRING, source->monitor_of ? source->monitor_of->name : NULL, PA_TAG_USEC, pa_source_get_latency(source), PA_TAG_STRING, source->driver, PA_TAG_U32, - (source->get_hw_volume ? PA_SOURCE_HW_VOLUME_CTRL : 0) | - (source->get_latency ? PA_SOURCE_LATENCY : 0) | + (source->get_volume ? PA_SOURCE_HW_VOLUME_CTRL : 0) | /* FIXME */ + (source->get_latency ? PA_SOURCE_LATENCY : 0) | /* FIXME */ (source->is_hardware ? PA_SOURCE_HARDWARE : 0), PA_TAG_INVALID); } static void client_fill_tagstruct(pa_tagstruct *t, pa_client *client) { - assert(t && client); + pa_assert(t); + pa_assert(client); + pa_tagstruct_putu32(t, client->index); pa_tagstruct_puts(t, client->name); pa_tagstruct_putu32(t, client->owner ? client->owner->index : PA_INVALID_INDEX); @@ -1367,7 +1696,9 @@ static void client_fill_tagstruct(pa_tagstruct *t, pa_client *client) { } static void module_fill_tagstruct(pa_tagstruct *t, pa_module *module) { - assert(t && module); + pa_assert(t); + pa_assert(module); + pa_tagstruct_putu32(t, module->index); pa_tagstruct_puts(t, module->name); pa_tagstruct_puts(t, module->argument); @@ -1376,7 +1707,9 @@ static void module_fill_tagstruct(pa_tagstruct *t, pa_module *module) { } static void sink_input_fill_tagstruct(pa_tagstruct *t, pa_sink_input *s) { - assert(t && s); + pa_assert(t); + pa_sink_input_assert_ref(s); + pa_tagstruct_putu32(t, s->index); pa_tagstruct_puts(t, s->name); pa_tagstruct_putu32(t, s->module ? s->module->index : PA_INVALID_INDEX); @@ -1392,7 +1725,9 @@ static void sink_input_fill_tagstruct(pa_tagstruct *t, pa_sink_input *s) { } static void source_output_fill_tagstruct(pa_tagstruct *t, pa_source_output *s) { - assert(t && s); + pa_assert(t); + pa_source_output_assert_ref(s); + pa_tagstruct_putu32(t, s->index); pa_tagstruct_puts(t, s->name); pa_tagstruct_putu32(t, s->module ? s->module->index : PA_INVALID_INDEX); @@ -1407,7 +1742,9 @@ static void source_output_fill_tagstruct(pa_tagstruct *t, pa_source_output *s) { } static void scache_fill_tagstruct(pa_tagstruct *t, pa_scache_entry *e) { - assert(t && e); + pa_assert(t); + pa_assert(e); + pa_tagstruct_putu32(t, e->index); pa_tagstruct_puts(t, e->name); pa_tagstruct_put_cvolume(t, &e->volume); @@ -1420,7 +1757,7 @@ static void scache_fill_tagstruct(pa_tagstruct *t, pa_scache_entry *e) { } static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); uint32_t idx; pa_sink *sink = NULL; pa_source *source = NULL; @@ -1431,7 +1768,9 @@ static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, u pa_scache_entry *sce = NULL; const char *name; pa_tagstruct *reply; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || (command != PA_COMMAND_GET_CLIENT_INFO && @@ -1466,7 +1805,7 @@ static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, u else if (command == PA_COMMAND_GET_SOURCE_OUTPUT_INFO) so = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx); else { - assert(command == PA_COMMAND_GET_SAMPLE_INFO); + pa_assert(command == PA_COMMAND_GET_SAMPLE_INFO); if (idx != PA_INVALID_INDEX) sce = pa_idxset_get_by_index(c->protocol->core->scache, idx); else @@ -1497,12 +1836,14 @@ static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, u } static void command_get_info_list(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); pa_idxset *i; uint32_t idx; void *p; pa_tagstruct *reply; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (!pa_tagstruct_eof(t)) { protocol_error(c); @@ -1526,7 +1867,7 @@ static void command_get_info_list(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t comma else if (command == PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST) i = c->protocol->core->source_outputs; else { - assert(command == PA_COMMAND_GET_SAMPLE_INFO_LIST); + pa_assert(command == PA_COMMAND_GET_SAMPLE_INFO_LIST); i = c->protocol->core->scache; } @@ -1545,7 +1886,7 @@ static void command_get_info_list(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t comma else if (command == PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST) source_output_fill_tagstruct(reply, p); else { - assert(command == PA_COMMAND_GET_SAMPLE_INFO_LIST); + pa_assert(command == PA_COMMAND_GET_SAMPLE_INFO_LIST); scache_fill_tagstruct(reply, p); } } @@ -1555,11 +1896,13 @@ static void command_get_info_list(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t comma } static void command_get_server_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); pa_tagstruct *reply; char txt[256]; const char *n; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (!pa_tagstruct_eof(t)) { protocol_error(c); @@ -1587,8 +1930,10 @@ static void command_get_server_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSE static void subscription_cb(pa_core *core, pa_subscription_event_type_t e, uint32_t idx, void *userdata) { pa_tagstruct *t; - struct connection *c = userdata; - assert(c && core); + connection *c = CONNECTION(userdata); + + connection_assert_ref(c); + pa_assert(t); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_SUBSCRIBE_EVENT); @@ -1599,9 +1944,11 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t e, uint3 } static void command_subscribe(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); pa_subscription_mask_t m; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_getu32(t, &m) < 0 || !pa_tagstruct_eof(t)) { @@ -1617,7 +1964,7 @@ static void command_subscribe(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint if (m != 0) { c->subscription = pa_subscription_new(c->protocol->core, m, subscription_cb, c); - assert(c->subscription); + pa_assert(c->subscription); } else c->subscription = NULL; @@ -1631,14 +1978,16 @@ static void command_set_volume( pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); uint32_t idx; pa_cvolume volume; pa_sink *sink = NULL; pa_source *source = NULL; pa_sink_input *si = NULL; const char *name = NULL; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || (command == PA_COMMAND_SET_SINK_VOLUME && pa_tagstruct_gets(t, &name) < 0) || @@ -1653,27 +2002,36 @@ static void command_set_volume( CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID); CHECK_VALIDITY(c->pstream, pa_cvolume_valid(&volume), tag, PA_ERR_INVALID); - if (command == PA_COMMAND_SET_SINK_VOLUME) { - if (idx != PA_INVALID_INDEX) - sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx); - else - sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK, 1); - } else if (command == PA_COMMAND_SET_SOURCE_VOLUME) { - if (idx != (uint32_t) -1) - source = pa_idxset_get_by_index(c->protocol->core->sources, idx); - else - source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1); - } else { - assert(command == PA_COMMAND_SET_SINK_INPUT_VOLUME); - si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx); + switch (command) { + + case PA_COMMAND_SET_SINK_VOLUME: + if (idx != PA_INVALID_INDEX) + sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx); + else + sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK, 1); + break; + + case PA_COMMAND_SET_SOURCE_VOLUME: + if (idx != PA_INVALID_INDEX) + source = pa_idxset_get_by_index(c->protocol->core->sources, idx); + else + source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1); + break; + + case PA_COMMAND_SET_SINK_INPUT_VOLUME: + si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx); + break; + + default: + pa_assert_not_reached(); } CHECK_VALIDITY(c->pstream, si || sink || source, tag, PA_ERR_NOENTITY); if (sink) - pa_sink_set_volume(sink, PA_MIXER_HARDWARE, &volume); + pa_sink_set_volume(sink, &volume); else if (source) - pa_source_set_volume(source, PA_MIXER_HARDWARE, &volume); + pa_source_set_volume(source, &volume); else if (si) pa_sink_input_set_volume(si, &volume); @@ -1687,16 +2045,20 @@ static void command_set_mute( pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); uint32_t idx; int mute; pa_sink *sink = NULL; pa_source *source = NULL; + pa_sink_input *si = NULL; const char *name = NULL; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || - pa_tagstruct_gets(t, &name) < 0 || + (command == PA_COMMAND_SET_SINK_MUTE && pa_tagstruct_gets(t, &name) < 0) || + (command == PA_COMMAND_SET_SOURCE_MUTE && pa_tagstruct_gets(t, &name) < 0) || pa_tagstruct_get_boolean(t, &mute) || !pa_tagstruct_eof(t)) { protocol_error(c); @@ -1706,35 +2068,53 @@ static void command_set_mute( CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID); - if (command == PA_COMMAND_SET_SINK_MUTE) { - if (idx != PA_INVALID_INDEX) - sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx); - else - sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK, 1); - } else { - assert(command == PA_COMMAND_SET_SOURCE_MUTE); - if (idx != (uint32_t) -1) - source = pa_idxset_get_by_index(c->protocol->core->sources, idx); - else - source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1); + switch (command) { + + case PA_COMMAND_SET_SINK_MUTE: + + if (idx != PA_INVALID_INDEX) + sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx); + else + sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK, 1); + + break; + + case PA_COMMAND_SET_SOURCE_MUTE: + if (idx != PA_INVALID_INDEX) + source = pa_idxset_get_by_index(c->protocol->core->sources, idx); + else + source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1); + + break; + + case PA_COMMAND_SET_SINK_INPUT_MUTE: + si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx); + break; + + default: + pa_assert_not_reached(); } - CHECK_VALIDITY(c->pstream, sink || source, tag, PA_ERR_NOENTITY); + CHECK_VALIDITY(c->pstream, si || sink || source, tag, PA_ERR_NOENTITY); if (sink) - pa_sink_set_mute(sink, PA_MIXER_HARDWARE, mute); + pa_sink_set_mute(sink, mute); else if (source) - pa_source_set_mute(source, PA_MIXER_HARDWARE, mute); + pa_source_set_mute(source, mute); + else if (si) + pa_sink_input_set_mute(si, mute); pa_pstream_send_simple_ack(c->pstream, tag); } static void command_cork_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); uint32_t idx; int b; - struct playback_stream *s, *ssync; - assert(c && t); + playback_stream *s; + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || pa_tagstruct_get_boolean(t, &b) < 0 || @@ -1747,73 +2127,19 @@ static void command_cork_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX, tag, PA_ERR_INVALID); s = pa_idxset_get_by_index(c->output_streams, idx); CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - CHECK_VALIDITY(c->pstream, s->type == PLAYBACK_STREAM, tag, PA_ERR_NOENTITY); + CHECK_VALIDITY(c->pstream, playback_stream_isinstance(s), tag, PA_ERR_NOENTITY); pa_sink_input_cork(s->sink_input, b); - pa_memblockq_prebuf_force(s->memblockq); - - /* Do the same for all other members in the sync group */ - for (ssync = s->prev; ssync; ssync = ssync->prev) { - pa_sink_input_cork(ssync->sink_input, b); - pa_memblockq_prebuf_force(ssync->memblockq); - } - - for (ssync = s->next; ssync; ssync = ssync->next) { - pa_sink_input_cork(ssync->sink_input, b); - pa_memblockq_prebuf_force(ssync->memblockq); - } - pa_pstream_send_simple_ack(c->pstream, tag); } -static void command_flush_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; +static void command_trigger_or_flush_or_prebuf_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + connection *c = CONNECTION(userdata); uint32_t idx; - struct playback_stream *s, *ssync; - assert(c && t); - - if (pa_tagstruct_getu32(t, &idx) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX, tag, PA_ERR_INVALID); - s = pa_idxset_get_by_index(c->output_streams, idx); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - CHECK_VALIDITY(c->pstream, s->type == PLAYBACK_STREAM, tag, PA_ERR_NOENTITY); - - pa_memblockq_flush(s->memblockq); - s->underrun = 0; + playback_stream *s; - /* Do the same for all other members in the sync group */ - for (ssync = s->prev; ssync; ssync = ssync->prev) { - pa_memblockq_flush(ssync->memblockq); - ssync->underrun = 0; - } - - for (ssync = s->next; ssync; ssync = ssync->next) { - pa_memblockq_flush(ssync->memblockq); - ssync->underrun = 0; - } - - pa_pstream_send_simple_ack(c->pstream, tag); - pa_sink_notify(s->sink_input->sink); - request_bytes(s); - - for (ssync = s->prev; ssync; ssync = ssync->prev) - request_bytes(ssync); - - for (ssync = s->next; ssync; ssync = ssync->next) - request_bytes(ssync); -} - -static void command_trigger_or_prebuf_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - uint32_t idx; - struct playback_stream *s; - assert(c && t); + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || !pa_tagstruct_eof(t)) { @@ -1825,32 +2151,36 @@ static void command_trigger_or_prebuf_playback_stream(PA_GCC_UNUSED pa_pdispatch CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX, tag, PA_ERR_INVALID); s = pa_idxset_get_by_index(c->output_streams, idx); CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - CHECK_VALIDITY(c->pstream, s->type == PLAYBACK_STREAM, tag, PA_ERR_NOENTITY); + CHECK_VALIDITY(c->pstream, playback_stream_isinstance(s), tag, PA_ERR_NOENTITY); switch (command) { + case PA_COMMAND_FLUSH_PLAYBACK_STREAM: + pa_asyncmsgq_send(s->sink_input->sink->asyncmsgq, PA_MSGOBJECT(s->sink_input), SINK_INPUT_MESSAGE_FLUSH, NULL, 0, NULL); + break; + case PA_COMMAND_PREBUF_PLAYBACK_STREAM: - pa_memblockq_prebuf_force(s->memblockq); + pa_asyncmsgq_send(s->sink_input->sink->asyncmsgq, PA_MSGOBJECT(s->sink_input), SINK_INPUT_MESSAGE_TRIGGER, NULL, 0, NULL); break; case PA_COMMAND_TRIGGER_PLAYBACK_STREAM: - pa_memblockq_prebuf_disable(s->memblockq); + pa_asyncmsgq_send(s->sink_input->sink->asyncmsgq, PA_MSGOBJECT(s->sink_input), SINK_INPUT_MESSAGE_PREBUF_FORCE, NULL, 0, NULL); break; default: - abort(); + pa_assert_not_reached(); } - pa_sink_notify(s->sink_input->sink); pa_pstream_send_simple_ack(c->pstream, tag); - request_bytes(s); } static void command_cork_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); uint32_t idx; - struct record_stream *s; + record_stream *s; int b; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || pa_tagstruct_get_boolean(t, &b) < 0 || @@ -1869,11 +2199,13 @@ static void command_cork_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UN } static void command_flush_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); uint32_t idx; - struct record_stream *s; - assert(c && t); + record_stream *s; + connection_assert_ref(c); + pa_assert(t); + if (pa_tagstruct_getu32(t, &idx) < 0 || !pa_tagstruct_eof(t)) { protocol_error(c); @@ -1889,9 +2221,11 @@ static void command_flush_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_U } static void command_set_default_sink_or_source(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); const char *s; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_gets(t, &s) < 0 || !pa_tagstruct_eof(t)) { @@ -1907,10 +2241,12 @@ static void command_set_default_sink_or_source(PA_GCC_UNUSED pa_pdispatch *pd, u } static void command_set_stream_name(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); uint32_t idx; const char *name; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || pa_tagstruct_gets(t, &name) < 0 || @@ -1923,16 +2259,16 @@ static void command_set_stream_name(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t com CHECK_VALIDITY(c->pstream, name && pa_utf8_valid(name), tag, PA_ERR_INVALID); if (command == PA_COMMAND_SET_PLAYBACK_STREAM_NAME) { - struct playback_stream *s; + playback_stream *s; s = pa_idxset_get_by_index(c->output_streams, idx); CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - CHECK_VALIDITY(c->pstream, s->type == PLAYBACK_STREAM, tag, PA_ERR_NOENTITY); + CHECK_VALIDITY(c->pstream, playback_stream_isinstance(s), tag, PA_ERR_NOENTITY); pa_sink_input_set_name(s->sink_input, name); } else { - struct record_stream *s; + record_stream *s; s = pa_idxset_get_by_index(c->record_streams, idx); CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); @@ -1944,9 +2280,11 @@ static void command_set_stream_name(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t com } static void command_kill(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); uint32_t idx; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || !pa_tagstruct_eof(t)) { @@ -1973,7 +2311,7 @@ static void command_kill(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint3 } else { pa_source_output *s; - assert(command == PA_COMMAND_KILL_SOURCE_OUTPUT); + pa_assert(command == PA_COMMAND_KILL_SOURCE_OUTPUT); s = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx); CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); @@ -1985,12 +2323,14 @@ static void command_kill(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint3 } static void command_load_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); pa_module *m; const char *name, *argument; pa_tagstruct *reply; - assert(c && t); + connection_assert_ref(c); + pa_assert(t); + if (pa_tagstruct_gets(t, &name) < 0 || pa_tagstruct_gets(t, &argument) < 0 || !pa_tagstruct_eof(t)) { @@ -2013,10 +2353,12 @@ static void command_load_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED ui } static void command_unload_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); uint32_t idx; pa_module *m; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || !pa_tagstruct_eof(t)) { @@ -2033,12 +2375,14 @@ static void command_unload_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED } static void command_add_autoload(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); const char *name, *module, *argument; uint32_t type; uint32_t idx; pa_tagstruct *reply; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_gets(t, &name) < 0 || pa_tagstruct_getu32(t, &type) < 0 || @@ -2066,11 +2410,13 @@ static void command_add_autoload(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED u } static void command_remove_autoload(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); const char *name = NULL; uint32_t type, idx = PA_IDXSET_INVALID; int r; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if ((pa_tagstruct_getu32(t, &idx) < 0 && (pa_tagstruct_gets(t, &name) < 0 || @@ -2095,7 +2441,7 @@ static void command_remove_autoload(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSE } static void autoload_fill_tagstruct(pa_tagstruct *t, const pa_autoload_entry *e) { - assert(t && e); + pa_assert(t && e); pa_tagstruct_putu32(t, e->index); pa_tagstruct_puts(t, e->name); @@ -2105,12 +2451,14 @@ static void autoload_fill_tagstruct(pa_tagstruct *t, const pa_autoload_entry *e) } static void command_get_autoload_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); const pa_autoload_entry *a = NULL; uint32_t type, idx; const char *name; pa_tagstruct *reply; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if ((pa_tagstruct_getu32(t, &idx) < 0 && (pa_tagstruct_gets(t, &name) < 0 || @@ -2137,9 +2485,11 @@ static void command_get_autoload_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNU } static void command_get_autoload_info_list(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); pa_tagstruct *reply; - assert(c && t); + + connection_assert_ref(c); + pa_assert(t); if (!pa_tagstruct_eof(t)) { protocol_error(c); @@ -2162,12 +2512,12 @@ static void command_get_autoload_info_list(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC } static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; + connection *c = CONNECTION(userdata); uint32_t idx = PA_INVALID_INDEX, idx_device = PA_INVALID_INDEX; const char *name = NULL; - assert(c); - assert(t); + connection_assert_ref(c); + pa_assert(t); if (pa_tagstruct_getu32(t, &idx) < 0 || pa_tagstruct_getu32(t, &idx_device) < 0 || @@ -2218,69 +2568,49 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag } pa_pstream_send_simple_ack(c->pstream, tag); - } /*** pstream callbacks ***/ static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata) { - struct connection *c = userdata; - assert(p && packet && packet->data && c); + connection *c = CONNECTION(userdata); + + pa_assert(p); + pa_assert(packet); + connection_assert_ref(c); if (pa_pdispatch_run(c->pdispatch, packet, creds, c) < 0) { pa_log("invalid packet."); - connection_free(c); + connection_unlink(c); } } static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata) { - struct connection *c = userdata; - struct output_stream *stream; - assert(p && chunk && userdata); - - if (!(stream = pa_idxset_get_by_index(c->output_streams, channel))) { + connection *c = CONNECTION(userdata); + output_stream *stream; + + pa_assert(p); + pa_assert(chunk); + connection_assert_ref(c); + + if (!(stream = OUTPUT_STREAM(pa_idxset_get_by_index(c->output_streams, channel)))) { pa_log("client sent block for invalid stream."); /* Ignoring */ return; } - if (stream->type == PLAYBACK_STREAM) { - struct playback_stream *ps = (struct playback_stream*) stream; - if (chunk->length >= ps->requested_bytes) - ps->requested_bytes = 0; - else - ps->requested_bytes -= chunk->length; - - pa_memblockq_seek(ps->memblockq, offset, seek); - - if (pa_memblockq_push_align(ps->memblockq, chunk) < 0) { - pa_tagstruct *t; - - pa_log_warn("failed to push data into queue"); - - /* Pushing this block into the queue failed, so we simulate - * it by skipping ahead */ - - pa_memblockq_seek(ps->memblockq, chunk->length, PA_SEEK_RELATIVE); - - /* Notify the user */ - t = pa_tagstruct_new(NULL, 0); - pa_tagstruct_putu32(t, PA_COMMAND_OVERFLOW); - pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ - pa_tagstruct_putu32(t, ps->index); - pa_pstream_send_tagstruct(p, t); - } - - ps->underrun = 0; - - pa_sink_notify(ps->sink_input->sink); - + if (playback_stream_isinstance(stream)) { + playback_stream *ps = PLAYBACK_STREAM(stream); + + if (seek != PA_SEEK_RELATIVE || offset != 0) + pa_asyncmsgq_post(ps->sink_input->sink->asyncmsgq, PA_MSGOBJECT(ps->sink_input), SINK_INPUT_MESSAGE_SEEK, PA_UINT_TO_PTR(seek), offset, NULL, NULL); + + pa_asyncmsgq_post(ps->sink_input->sink->asyncmsgq, PA_MSGOBJECT(ps->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, 0, chunk, NULL); + } else { - struct upload_stream *u = (struct upload_stream*) stream; + upload_stream *u = UPLOAD_STREAM(stream); size_t l; - assert(u->type == UPLOAD_STREAM); - if (!u->memchunk.memblock) { if (u->length == chunk->length) { u->memchunk = *chunk; @@ -2292,7 +2622,7 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o } } - assert(u->memchunk.memblock); + pa_assert(u->memchunk.memblock); l = u->length; if (l > chunk->length) @@ -2317,17 +2647,21 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o } static void pstream_die_callback(pa_pstream *p, void *userdata) { - struct connection *c = userdata; - assert(p && c); - connection_free(c); + connection *c = CONNECTION(userdata); + + pa_assert(p); + connection_assert_ref(c); + connection_unlink(c); /* pa_log("connection died.");*/ } static void pstream_drain_callback(pa_pstream *p, void *userdata) { - struct connection *c = userdata; - assert(p && c); + connection *c = CONNECTION(userdata); + + pa_assert(p); + connection_assert_ref(c); send_memblock(c); } @@ -2335,25 +2669,32 @@ static void pstream_drain_callback(pa_pstream *p, void *userdata) { /*** client callbacks ***/ static void client_kill_cb(pa_client *c) { - assert(c && c->userdata); - connection_free(c->userdata); + pa_assert(c); + + connection_unlink(CONNECTION(c->userdata)); } /*** socket server callbacks ***/ static void auth_timeout(pa_mainloop_api*m, pa_time_event *e, const struct timeval *tv, void *userdata) { - struct connection *c = userdata; - assert(m && tv && c && c->auth_timeout_event == e); + connection *c = CONNECTION(userdata); + + pa_assert(m); + pa_assert(tv); + connection_assert_ref(c); + pa_assert(c->auth_timeout_event == e); if (!c->authorized) - connection_free(c); + connection_unlink(c); } static void on_connection(PA_GCC_UNUSED pa_socket_server*s, pa_iochannel *io, void *userdata) { pa_protocol_native *p = userdata; - struct connection *c; + connection *c; char cname[256], pname[128]; - assert(io && p); + + pa_assert(io); + pa_assert(p); if (pa_idxset_size(p->connections)+1 > MAX_CONNECTIONS) { pa_log_warn("Warning! Too many connections (%u), dropping incoming connection.", MAX_CONNECTIONS); @@ -2361,7 +2702,8 @@ static void on_connection(PA_GCC_UNUSED pa_socket_server*s, pa_iochannel *io, vo return; } - c = pa_xmalloc(sizeof(struct connection)); + c = pa_msgobject_new(connection); + c->parent.parent.free = connection_free; c->authorized = !!p->public; @@ -2382,15 +2724,15 @@ static void on_connection(PA_GCC_UNUSED pa_socket_server*s, pa_iochannel *io, vo c->protocol = p; pa_iochannel_socket_peer_to_string(io, pname, sizeof(pname)); pa_snprintf(cname, sizeof(cname), "Native client (%s)", pname); - assert(p->core); + pa_assert(p->core); c->client = pa_client_new(p->core, __FILE__, cname); - assert(c->client); + pa_assert(c->client); c->client->kill = client_kill_cb; c->client->userdata = c; c->client->owner = p->module; c->pstream = pa_pstream_new(p->core->mainloop, io, p->core->mempool); - assert(c->pstream); + pa_assert(c->pstream); pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_callback, c); pa_pstream_set_recieve_memblock_callback(c->pstream, pstream_memblock_callback, c); @@ -2398,11 +2740,11 @@ static void on_connection(PA_GCC_UNUSED pa_socket_server*s, pa_iochannel *io, vo pa_pstream_set_drain_callback(c->pstream, pstream_drain_callback, c); c->pdispatch = pa_pdispatch_new(p->core->mainloop, command_table, PA_COMMAND_MAX); - assert(c->pdispatch); + pa_assert(c->pdispatch); c->record_streams = pa_idxset_new(NULL, NULL); c->output_streams = pa_idxset_new(NULL, NULL); - assert(c->record_streams && c->output_streams); + pa_assert(c->record_streams && c->output_streams); c->rrobin_index = PA_IDXSET_INVALID; c->subscription = NULL; @@ -2420,7 +2762,7 @@ static void on_connection(PA_GCC_UNUSED pa_socket_server*s, pa_iochannel *io, vo /*** module entry points ***/ static int load_key(pa_protocol_native*p, const char*fn) { - assert(p); + pa_assert(p); p->auth_cookie_in_property = 0; @@ -2450,8 +2792,8 @@ static pa_protocol_native* protocol_new_internal(pa_core *c, pa_module *m, pa_mo int public = 0; const char *acl; - assert(c); - assert(ma); + pa_assert(c); + pa_assert(ma); if (pa_modargs_get_value_boolean(ma, "auth-anonymous", &public) < 0) { pa_log("auth-anonymous= expects a boolean argument."); @@ -2492,7 +2834,7 @@ static pa_protocol_native* protocol_new_internal(pa_core *c, pa_module *m, pa_mo goto fail; p->connections = pa_idxset_new(NULL, NULL); - assert(p->connections); + pa_assert(p->connections); return p; @@ -2527,11 +2869,11 @@ pa_protocol_native* pa_protocol_native_new(pa_core *core, pa_socket_server *serv } void pa_protocol_native_free(pa_protocol_native *p) { - struct connection *c; - assert(p); + connection *c; + pa_assert(p); while ((c = pa_idxset_first(p->connections, NULL))) - connection_free(c); + connection_unlink(c); pa_idxset_free(p->connections, NULL, NULL); if (p->server) { @@ -2563,7 +2905,12 @@ void pa_protocol_native_free(pa_protocol_native *p) { pa_xfree(p); } -pa_protocol_native* pa_protocol_native_new_iochannel(pa_core*core, pa_iochannel *io, pa_module *m, pa_modargs *ma) { +pa_protocol_native* pa_protocol_native_new_iochannel( + pa_core*core, + pa_iochannel *io, + pa_module *m, + pa_modargs *ma) { + pa_protocol_native *p; if (!(p = protocol_new_internal(core, m, ma))) diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index 8f9aed58..0ded5d26 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -67,7 +67,7 @@ typedef struct connection { PA_DECLARE_CLASS(connection); #define CONNECTION(o) (connection_cast(o)) -static PA_DEFINE_CHECK_TYPE(connection, connection_check_type, pa_msgobject_check_type); +static PA_DEFINE_CHECK_TYPE(connection, pa_msgobject); struct pa_protocol_simple { pa_module *module; @@ -91,9 +91,9 @@ enum { }; enum { - MESSAGE_REQUEST_DATA, /* data requested from sink input from the main loop */ - MESSAGE_POST_DATA, /* data from source output to main loop */ - MESSAGE_DROP_CONNECTION /* Please drop a aconnection now */ + CONNECTION_MESSAGE_REQUEST_DATA, /* data requested from sink input from the main loop */ + CONNECTION_MESSAGE_POST_DATA, /* data from source output to main loop */ + CONNECTION_MESSAGE_DROP_CONNECTION /* Please drop a aconnection now */ }; @@ -102,29 +102,12 @@ enum { #define RECORD_BUFFER_SECONDS (5) #define RECORD_BUFFER_FRAGMENTS (100) -static void connection_free(pa_object *o) { - connection *c = CONNECTION(o); +static void connection_unlink(connection *c) { pa_assert(c); - if (c->playback.current_memblock) - pa_memblock_unref(c->playback.current_memblock); - - if (c->io) - pa_iochannel_free(c->io); - if (c->input_memblockq) - pa_memblockq_free(c->input_memblockq); - if (c->output_memblockq) - pa_memblockq_free(c->output_memblockq); - - pa_xfree(c); -} - -static void connection_drop(connection *c) { - pa_assert(c); - - if (!pa_idxset_remove_by_data(c->protocol->connections, c, NULL)) + if (!c->protocol) return; - + if (c->sink_input) { pa_sink_input_disconnect(c->sink_input); pa_sink_input_unref(c->sink_input); @@ -142,9 +125,30 @@ static void connection_drop(connection *c) { c->client = NULL; } + pa_assert_se(pa_idxset_remove_by_data(c->protocol->connections, c, NULL) == c); + c->protocol = NULL; connection_unref(c); } +static void connection_free(pa_object *o) { + connection *c = CONNECTION(o); + pa_assert(c); + + connection_unref(c); + + if (c->playback.current_memblock) + pa_memblock_unref(c->playback.current_memblock); + + if (c->io) + pa_iochannel_free(c->io); + if (c->input_memblockq) + pa_memblockq_free(c->input_memblockq); + if (c->output_memblockq) + pa_memblockq_free(c->output_memblockq); + + pa_xfree(c); +} + static int do_read(connection *c) { pa_memchunk chunk; ssize_t r; @@ -190,7 +194,7 @@ static int do_read(connection *c) { c->playback.memblock_index += r; - pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, &chunk, NULL); + pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, 0, &chunk, NULL); pa_atomic_sub(&c->playback.missing, r); return 0; @@ -263,28 +267,28 @@ fail: pa_iochannel_free(c->io); c->io = NULL; - pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_DISABLE_PREBUF, NULL, NULL, NULL); + pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_DISABLE_PREBUF, NULL, 0, NULL, NULL); } else - connection_drop(c); + connection_unlink(c); } -static int connection_process_msg(pa_msgobject *o, int code, void*userdata, pa_memchunk *chunk) { +static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) { connection *c = CONNECTION(o); connection_assert_ref(c); switch (code) { - case MESSAGE_REQUEST_DATA: + case CONNECTION_MESSAGE_REQUEST_DATA: do_work(c); break; - case MESSAGE_POST_DATA: + case CONNECTION_MESSAGE_POST_DATA: /* pa_log("got data %u", chunk->length); */ pa_memblockq_push_align(c->output_memblockq, chunk); do_work(c); break; - case MESSAGE_DROP_CONNECTION: - connection_drop(c); + case CONNECTION_MESSAGE_DROP_CONNECTION: + connection_unlink(c); break; } @@ -294,13 +298,13 @@ static int connection_process_msg(pa_msgobject *o, int code, void*userdata, pa_m /*** sink_input callbacks ***/ /* Called from thread context */ -static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk) { +static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) { pa_sink_input *i = PA_SINK_INPUT(o); connection*c; - pa_assert(i); - c = i->userdata; - pa_assert(c); + pa_sink_input_assert_ref(i); + c = CONNECTION(i->userdata); + connection_assert_ref(c); switch (code) { @@ -330,7 +334,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, pa_ } default: - return pa_sink_input_process_msg(o, code, userdata, chunk); + return pa_sink_input_process_msg(o, code, userdata, offset, chunk); } } @@ -349,7 +353,7 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { /* pa_log("peeked %u %i", r >= 0 ? chunk->length: 0, r); */ if (c->dead && r < 0) - pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), MESSAGE_DROP_CONNECTION, NULL, NULL, NULL); + pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_DROP_CONNECTION, NULL, 0, NULL, NULL); return r; } @@ -369,19 +373,20 @@ static void sink_input_drop_cb(pa_sink_input *i, size_t length) { if (new > old) { if (pa_atomic_add(&c->playback.missing, new - old) <= 0) - pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), MESSAGE_REQUEST_DATA, NULL, NULL, NULL); + pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); } } /* Called from main context */ static void sink_input_kill_cb(pa_sink_input *i) { - pa_assert(i); + pa_sink_input_assert_ref(i); - connection_drop(CONNECTION(i->userdata)); + connection_unlink(CONNECTION(i->userdata)); } /*** source_output callbacks ***/ +/* Called from thread context */ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) { connection *c; @@ -390,24 +395,22 @@ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) pa_assert(c); pa_assert(chunk); - pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), MESSAGE_POST_DATA, NULL, chunk, NULL); + pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_POST_DATA, NULL, 0, chunk, NULL); } +/* Called from main context */ static void source_output_kill_cb(pa_source_output *o) { - connection*c; + pa_source_output_assert_ref(o); - pa_assert(o); - c = o->userdata; - pa_assert(c); - - connection_drop(c); + connection_unlink(CONNECTION(o->userdata)); } +/* Called from main context */ static pa_usec_t source_output_get_latency_cb(pa_source_output *o) { connection*c; pa_assert(o); - c = o->userdata; + c = CONNECTION(o->userdata); pa_assert(c); return pa_bytes_to_usec(pa_memblockq_get_length(c->output_memblockq), &c->source_output->sample_spec); @@ -419,16 +422,16 @@ static void client_kill_cb(pa_client *client) { connection*c; pa_assert(client); - c = client->userdata; + c = CONNECTION(client->userdata); pa_assert(c); - connection_drop(c); + connection_unlink(c); } /*** pa_iochannel callbacks ***/ static void io_callback(pa_iochannel*io, void *userdata) { - connection *c = userdata; + connection *c = CONNECTION(userdata); pa_assert(io); pa_assert(c); @@ -453,7 +456,7 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) return; } - c = pa_msgobject_new(connection, connection_check_type); + c = pa_msgobject_new(connection); c->parent.parent.free = connection_free; c->parent.process_msg = connection_process_msg; c->io = io; @@ -547,7 +550,6 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) pa_source_output_put(c->source_output); } - pa_iochannel_set_callback(c->io, io_callback, c); pa_idxset_put(p->connections, c, NULL); @@ -555,7 +557,7 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) fail: if (c) - connection_drop(c); + connection_unlink(c); } pa_protocol_simple* pa_protocol_simple_new(pa_core *core, pa_socket_server *server, pa_module *m, pa_modargs *ma) { @@ -618,7 +620,7 @@ void pa_protocol_simple_free(pa_protocol_simple *p) { if (p->connections) { while((c = pa_idxset_first(p->connections, NULL))) - connection_drop(c); + connection_unlink(c); pa_idxset_free(p->connections, NULL, NULL); } diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index e4e931f4..0a7033d0 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -45,7 +45,7 @@ #define MOVE_BUFFER_LENGTH (1024*1024) #define SILENCE_BUFFER_LENGTH (64*1024) -static PA_DEFINE_CHECK_TYPE(pa_sink_input, sink_input_check_type, pa_msgobject_check_type); +static PA_DEFINE_CHECK_TYPE(pa_sink_input, pa_msgobject); static void sink_input_free(pa_object *o); @@ -110,6 +110,7 @@ pa_sink_input* pa_sink_input_new( pa_return_null_if_fail(data->sink); pa_return_null_if_fail(pa_sink_get_state(data->sink) != PA_SINK_DISCONNECTED); + pa_return_null_if_fail(!data->sync_base || (data->sync_base->sink == data->sink && pa_sink_input_get_state(data->sync_base) == PA_SINK_INPUT_CORKED)); if (!data->sample_spec_is_set) data->sample_spec = data->sink->sample_spec; @@ -161,12 +162,12 @@ pa_sink_input* pa_sink_input_new( data->resample_method = pa_resampler_get_method(resampler); } - i = pa_msgobject_new(pa_sink_input, sink_input_check_type); + i = pa_msgobject_new(pa_sink_input); i->parent.parent.free = sink_input_free; i->parent.process_msg = pa_sink_input_process_msg; i->core = core; - i->state = PA_SINK_INPUT_RUNNING; + i->state = data->start_corked ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING; i->flags = flags; i->name = pa_xstrdup(data->name); i->driver = pa_xstrdup(data->driver); @@ -181,6 +182,16 @@ pa_sink_input* pa_sink_input_new( i->volume = data->volume; i->muted = data->muted; + if (data->sync_base) { + i->sync_next = data->sync_base->sync_next; + i->sync_prev = data->sync_base; + + if (data->sync_base->sync_next) + data->sync_base->sync_next->sync_prev = i; + data->sync_base->sync_next = i; + } else + i->sync_next = i->sync_prev = NULL; + i->peek = NULL; i->drop = NULL; i->kill = NULL; @@ -213,6 +224,7 @@ pa_sink_input* pa_sink_input_new( } static int sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) { + pa_sink_input *ssync; pa_assert(i); if (state == PA_SINK_INPUT_DRAINED) @@ -221,10 +233,15 @@ static int sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) { if (i->state == state) return 0; - if (pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), NULL) < 0) + if (pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) < 0) return -1; i->state = state; + for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev) + ssync->state = state; + for (ssync = i->sync_next; ssync; ssync = ssync->sync_next) + ssync->state = state; + return 0; } @@ -232,10 +249,16 @@ void pa_sink_input_disconnect(pa_sink_input *i) { pa_assert(i); pa_return_if_fail(i->state != PA_SINK_INPUT_DISCONNECTED); - pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, NULL); + if (i->sync_prev) + i->sync_prev->sync_next = i->sync_next; + if (i->sync_next) + i->sync_next->sync_prev = i->sync_prev; + + i->sync_prev = i->sync_next = NULL; + + pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, 0, NULL); pa_idxset_remove_by_data(i->sink->core->sink_inputs, i, NULL); pa_idxset_remove_by_data(i->sink->inputs, i, NULL); - pa_sink_input_unref(i); pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE, i->index); @@ -248,6 +271,7 @@ void pa_sink_input_disconnect(pa_sink_input *i) { i->kill = NULL; i->get_latency = NULL; i->underrun = NULL; + pa_sink_input_unref(i); } static void sink_input_free(pa_object *o) { @@ -281,7 +305,7 @@ void pa_sink_input_put(pa_sink_input *i) { i->thread_info.volume = i->volume; i->thread_info.muted = i->muted; - pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, pa_sink_input_ref(i), NULL, (pa_free_cb_t) pa_sink_input_unref); + pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, i, 0, NULL); pa_sink_update_status(i->sink); pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index); @@ -299,7 +323,7 @@ pa_usec_t pa_sink_input_get_latency(pa_sink_input *i) { pa_sink_input_assert_ref(i); - if (pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_LATENCY, &r, NULL) < 0) + if (pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_LATENCY, &r, 0, NULL) < 0) r = 0; if (i->get_latency) @@ -509,7 +533,7 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume) { i->volume = *volume; - pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME, pa_xnewdup(struct pa_cvolume, volume, 1), NULL, pa_xfree); + pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME, pa_xnewdup(struct pa_cvolume, volume, 1), 0, NULL, pa_xfree); pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); } @@ -528,7 +552,7 @@ void pa_sink_input_set_mute(pa_sink_input *i, int mute) { i->muted = mute; - pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_MUTE, PA_UINT_TO_PTR(mute), NULL, NULL); + pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_MUTE, PA_UINT_TO_PTR(mute), 0, NULL, NULL); pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); } @@ -553,7 +577,7 @@ int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) { i->sample_spec.rate = rate; - pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), NULL, NULL); + pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), 0, NULL, NULL); pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); return 0; @@ -741,7 +765,7 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { /* return 0; */ } -int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk) { +int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) { pa_sink_input *i = PA_SINK_INPUT(o); pa_sink_input_assert_ref(i); @@ -776,12 +800,28 @@ int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, pa_memc } case PA_SINK_INPUT_MESSAGE_SET_STATE: { + pa_sink_input *ssync; + if ((PA_PTR_TO_UINT(userdata) == PA_SINK_INPUT_DRAINED || PA_PTR_TO_UINT(userdata) == PA_SINK_INPUT_RUNNING) && (i->thread_info.state != PA_SINK_INPUT_DRAINED) && (i->thread_info.state != PA_SINK_INPUT_RUNNING)) pa_atomic_store(&i->thread_info.drained, 1); i->thread_info.state = PA_PTR_TO_UINT(userdata); + for (ssync = i->thread_info.sync_prev; ssync; ssync = ssync->thread_info.sync_prev) { + if ((PA_PTR_TO_UINT(userdata) == PA_SINK_INPUT_DRAINED || PA_PTR_TO_UINT(userdata) == PA_SINK_INPUT_RUNNING) && + (ssync->thread_info.state != PA_SINK_INPUT_DRAINED) && (ssync->thread_info.state != PA_SINK_INPUT_RUNNING)) + pa_atomic_store(&ssync->thread_info.drained, 1); + ssync->thread_info.state = PA_PTR_TO_UINT(userdata); + } + + for (ssync = i->thread_info.sync_next; ssync; ssync = ssync->thread_info.sync_next) { + if ((PA_PTR_TO_UINT(userdata) == PA_SINK_INPUT_DRAINED || PA_PTR_TO_UINT(userdata) == PA_SINK_INPUT_RUNNING) && + (ssync->thread_info.state != PA_SINK_INPUT_DRAINED) && (ssync->thread_info.state != PA_SINK_INPUT_RUNNING)) + pa_atomic_store(&ssync->thread_info.drained, 1); + ssync->thread_info.state = PA_PTR_TO_UINT(userdata); + } + return 0; } } diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index fe62917a..af3db95e 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -71,6 +71,8 @@ struct pa_sink_input { pa_sample_spec sample_spec; pa_channel_map channel_map; + pa_sink_input *sync_prev, *sync_next; + pa_cvolume volume; int muted; @@ -97,6 +99,8 @@ struct pa_sink_input { /* size_t move_silence; */ pa_memblock *silence_memblock; /* may be NULL */ + pa_sink_input *sync_prev, *sync_next; + pa_cvolume volume; int muted; } thread_info; @@ -133,6 +137,9 @@ typedef struct pa_sink_input_new_data { int muted_is_set; pa_resample_method_t resample_method; + + int start_corked; + pa_sink_input *sync_base; } pa_sink_input_new_data; pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data); @@ -179,6 +186,6 @@ pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i); int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume); void pa_sink_input_drop(pa_sink_input *i, size_t length); -int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk); +int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk); #endif diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 7f2a8b39..5ab01cb4 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -48,7 +48,7 @@ #define MAX_MIX_CHANNELS 32 #define SILENCE_BUFFER_LENGTH (64*1024) -static PA_DEFINE_CHECK_TYPE(pa_sink, sink_check_type, pa_msgobject_check_type); +static PA_DEFINE_CHECK_TYPE(pa_sink, pa_msgobject); static void sink_free(pa_object *s); @@ -80,7 +80,7 @@ pa_sink* pa_sink_new( pa_return_null_if_fail(!driver || pa_utf8_valid(driver)); pa_return_null_if_fail(name && pa_utf8_valid(name) && *name); - s = pa_msgobject_new(pa_sink, sink_check_type); + s = pa_msgobject_new(pa_sink); if (!(name = pa_namereg_register(core, name, PA_NAMEREG_SINK, s, fail))) { pa_xfree(s); @@ -161,7 +161,7 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state) { if ((ret = s->set_state(s, state)) < 0) return -1; - if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), NULL) < 0) + if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) < 0) return -1; s->state = state; @@ -264,7 +264,7 @@ int pa_sink_suspend(pa_sink *s, int suspend) { void pa_sink_ping(pa_sink *s) { pa_sink_assert_ref(s); - pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_PING, NULL, NULL, NULL); + pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_PING, NULL, 0, NULL, NULL); } static unsigned fill_mix_info(pa_sink *s, pa_mix_info *info, unsigned maxinfo) { @@ -530,7 +530,7 @@ pa_usec_t pa_sink_get_latency(pa_sink *s) { if (s->get_latency) return s->get_latency(s); - if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY, &usec, NULL) < 0) + if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0) return 0; return usec; @@ -549,7 +549,7 @@ void pa_sink_set_volume(pa_sink *s, const pa_cvolume *volume) { s->set_volume = NULL; if (!s->set_volume) - pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, pa_xnewdup(struct pa_cvolume, volume, 1), NULL, pa_xfree); + pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, pa_xnewdup(struct pa_cvolume, volume, 1), 0, NULL, pa_xfree); if (changed) pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); @@ -566,7 +566,7 @@ const pa_cvolume *pa_sink_get_volume(pa_sink *s) { s->get_volume = NULL; if (!s->get_volume && s->refresh_volume) - pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_VOLUME, &s->volume, NULL); + pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_VOLUME, &s->volume, 0, NULL); if (!pa_cvolume_equal(&old_volume, &s->volume)) pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); @@ -585,7 +585,7 @@ void pa_sink_set_mute(pa_sink *s, int mute) { s->set_mute = NULL; if (!s->set_mute) - pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MUTE, PA_UINT_TO_PTR(mute), NULL, NULL); + pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MUTE, PA_UINT_TO_PTR(mute), 0, NULL, NULL); if (changed) pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); @@ -602,7 +602,7 @@ int pa_sink_get_mute(pa_sink *s) { s->get_mute = NULL; if (!s->get_mute && s->refresh_mute) - pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MUTE, &s->muted, NULL); + pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MUTE, &s->muted, 0, NULL); if (old_muted != s->muted) pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); @@ -660,21 +660,58 @@ unsigned pa_sink_used_by(pa_sink *s) { return ret; } -int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk) { +int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) { pa_sink *s = PA_SINK(o); pa_sink_assert_ref(s); switch ((pa_sink_message_t) code) { + case PA_SINK_MESSAGE_ADD_INPUT: { pa_sink_input *i = userdata; pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), pa_sink_input_ref(i)); + + /* Since the caller sleeps in pa_sink_input_put(), we can + * safely access data outside of thread_info even though + * it is mutable */ + + if ((i->thread_info.sync_prev = i->sync_prev)) { + pa_assert(i->sink == i->thread_info.sync_prev->sink); + pa_assert(i->sync_prev->sync_next == i); + i->thread_info.sync_prev->thread_info.sync_next = i; + } + + if ((i->thread_info.sync_next = i->sync_next)) { + pa_assert(i->sink == i->thread_info.sync_next->sink); + pa_assert(i->sync_next->sync_prev == i); + i->thread_info.sync_next->thread_info.sync_prev = i; + } + return 0; } case PA_SINK_MESSAGE_REMOVE_INPUT: { pa_sink_input *i = userdata; + + /* Since the caller sleeps in pa_sink_input_disconnect(), + * we can safely access data outside of thread_info even + * though it is mutable */ + + pa_assert(!i->thread_info.sync_prev); + pa_assert(!i->thread_info.sync_next); + + if (i->thread_info.sync_prev) { + i->thread_info.sync_prev->thread_info.sync_next = i->thread_info.sync_prev->sync_next; + i->thread_info.sync_prev = NULL; + } + + if (i->thread_info.sync_next) { + i->thread_info.sync_next->thread_info.sync_prev = i->thread_info.sync_next->sync_prev; + i->thread_info.sync_next = NULL; + } + if (pa_hashmap_remove(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index))) pa_sink_input_unref(i); + return 0; } @@ -698,6 +735,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk * return 0; case PA_SINK_MESSAGE_SET_STATE: + s->thread_info.state = PA_PTR_TO_UINT(userdata); return 0; diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index 958279c5..494bb6a9 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -156,7 +156,7 @@ void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result); void pa_sink_render_into(pa_sink*s, pa_memchunk *target); void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target); -int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk); +int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk); static inline int PA_SINK_OPENED(pa_sink_state_t x) { return x == PA_SINK_RUNNING || x == PA_SINK_IDLE; diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index 946af3e6..f2204f26 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -56,7 +56,7 @@ enum { PA_DECLARE_CLASS(file_stream); #define FILE_STREAM(o) (file_stream_cast(o)) -static PA_DEFINE_CHECK_TYPE(file_stream, file_stream_check_type, pa_msgobject_check_type); +static PA_DEFINE_CHECK_TYPE(file_stream, pa_msgobject); static void file_stream_free(pa_object *o) { file_stream *u = FILE_STREAM(o); @@ -85,7 +85,7 @@ static void file_stream_drop(file_stream *u) { } } -static int file_stream_process_msg(pa_msgobject *o, int code, void*userdata, pa_memchunk *chunk) { +static int file_stream_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) { file_stream *u = FILE_STREAM(o); file_stream_assert_ref(u); @@ -154,7 +154,7 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { pa_memblock_unref(u->memchunk.memblock); pa_memchunk_reset(&u->memchunk); - pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u), MESSAGE_DROP_FILE_STREAM, NULL, NULL, NULL); + pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u), MESSAGE_DROP_FILE_STREAM, NULL, 0, NULL, NULL); sf_close(u->sndfile); u->sndfile = NULL; @@ -224,7 +224,7 @@ int pa_play_file( pa_assert(sink); pa_assert(fname); - u = pa_msgobject_new(file_stream, file_stream_check_type); + u = pa_msgobject_new(file_stream); u->parent.parent.free = file_stream_free; u->parent.process_msg = file_stream_process_msg; u->core = sink->core; diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index ee76a6e0..c3ecf3a2 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -38,7 +38,7 @@ #include "source-output.h" -static PA_DEFINE_CHECK_TYPE(pa_source_output, source_output_check_type, pa_msgobject_check_type); +static PA_DEFINE_CHECK_TYPE(pa_source_output, pa_msgobject); static void source_output_free(pa_object* mo); @@ -130,12 +130,12 @@ pa_source_output* pa_source_output_new( data->resample_method = pa_resampler_get_method(resampler); } - o = pa_msgobject_new(pa_source_output, source_output_check_type); + o = pa_msgobject_new(pa_source_output); o->parent.parent.free = source_output_free; o->parent.process_msg = pa_source_output_process_msg; o->core = core; - o->state = PA_SOURCE_OUTPUT_RUNNING; + o->state = data->corked ? PA_SOURCE_OUTPUT_CORKED : PA_SOURCE_OUTPUT_RUNNING; o->flags = flags; o->name = pa_xstrdup(data->name); o->driver = pa_xstrdup(data->driver); @@ -176,7 +176,7 @@ static int source_output_set_state(pa_source_output *o, pa_source_output_state_t if (o->state == state) return 0; - if (pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), NULL) < 0) + if (pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) < 0) return -1; o->state = state; @@ -187,7 +187,7 @@ void pa_source_output_disconnect(pa_source_output*o) { pa_assert(o); pa_return_if_fail(o->state != PA_SOURCE_OUTPUT_DISCONNECTED); - pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, NULL); + pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, 0, NULL); pa_idxset_remove_by_data(o->source->core->source_outputs, o, NULL); pa_idxset_remove_by_data(o->source->outputs, o, NULL); @@ -225,7 +225,7 @@ static void source_output_free(pa_object* mo) { void pa_source_output_put(pa_source_output *o) { pa_source_output_assert_ref(o); - pa_asyncmsgq_post(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_ADD_OUTPUT, pa_source_output_ref(o), NULL, (pa_free_cb_t) pa_source_output_unref); + pa_asyncmsgq_post(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_ADD_OUTPUT, pa_source_output_ref(o), 0, NULL, (pa_free_cb_t) pa_source_output_unref); pa_source_update_status(o->source); pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW, o->index); @@ -243,7 +243,7 @@ pa_usec_t pa_source_output_get_latency(pa_source_output *o) { pa_source_output_assert_ref(o); - if (pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY, &r, NULL) < 0) + if (pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY, &r, 0, NULL) < 0) r = 0; if (o->get_latency) @@ -293,7 +293,7 @@ int pa_source_output_set_rate(pa_source_output *o, uint32_t rate) { o->sample_spec.rate = rate; - pa_asyncmsgq_post(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), NULL, NULL); + pa_asyncmsgq_post(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_RATE, PA_UINT_TO_PTR(rate), 0, NULL, NULL); pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); return 0; @@ -380,7 +380,7 @@ int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { /* return 0; */ } -int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, pa_memchunk* chunk) { +int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, int64_t offset, pa_memchunk* chunk) { pa_source_output *o = PA_SOURCE_OUTPUT(mo); pa_source_output_assert_ref(o); diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h index 7b6afe81..9f982a9a 100644 --- a/src/pulsecore/source-output.h +++ b/src/pulsecore/source-output.h @@ -103,6 +103,8 @@ typedef struct pa_source_output_new_data { int channel_map_is_set; pa_resample_method_t resample_method; + + int corked; } pa_source_output_new_data; pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data); @@ -142,6 +144,6 @@ int pa_source_output_move_to(pa_source_output *o, pa_source *dest); /* To be used exclusively by the source driver thread */ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk); -int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, pa_memchunk *chunk); +int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, int64_t offset, pa_memchunk *chunk); #endif diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 6ca81727..eaf1335e 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -42,7 +42,7 @@ #include "source.h" -static PA_DEFINE_CHECK_TYPE(pa_source, source_check_type, pa_msgobject_check_type); +static PA_DEFINE_CHECK_TYPE(pa_source, pa_msgobject); static void source_free(pa_object *o); @@ -73,7 +73,7 @@ pa_source* pa_source_new( pa_return_null_if_fail(!driver || pa_utf8_valid(driver)); pa_return_null_if_fail(pa_utf8_valid(name) && *name); - s = pa_msgobject_new(pa_source, source_check_type); + s = pa_msgobject_new(pa_source); if (!(name = pa_namereg_register(core, name, PA_NAMEREG_SOURCE, s, fail))) { pa_xfree(s); @@ -140,7 +140,7 @@ static int source_set_state(pa_source *s, pa_source_state_t state) { if ((ret = s->set_state(s, state)) < 0) return -1; - if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), NULL) < 0) + if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) < 0) return -1; s->state = state; @@ -222,7 +222,7 @@ int pa_source_suspend(pa_source *s, int suspend) { void pa_source_ping(pa_source *s) { pa_source_assert_ref(s); - pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_PING, NULL, NULL, NULL); + pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_PING, NULL, 0, NULL, NULL); } void pa_source_post(pa_source*s, const pa_memchunk *chunk) { @@ -266,7 +266,7 @@ pa_usec_t pa_source_get_latency(pa_source *s) { if (s->get_latency) return s->get_latency(s); - if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_LATENCY, &usec, NULL) < 0) + if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0) return 0; return usec; @@ -285,7 +285,7 @@ void pa_source_set_volume(pa_source *s, const pa_cvolume *volume) { s->set_volume = NULL; if (!s->set_volume) - pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME, pa_xnewdup(struct pa_cvolume, volume, 1), NULL, pa_xfree); + pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME, pa_xnewdup(struct pa_cvolume, volume, 1), 0, NULL, pa_xfree); if (changed) pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); @@ -301,7 +301,7 @@ const pa_cvolume *pa_source_get_volume(pa_source *s) { s->get_volume = NULL; if (!s->get_volume && s->refresh_volume) - pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_VOLUME, &s->volume, NULL); + pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_VOLUME, &s->volume, 0, NULL); if (!pa_cvolume_equal(&old_volume, &s->volume)) pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); @@ -320,7 +320,7 @@ void pa_source_set_mute(pa_source *s, int mute) { s->set_mute = NULL; if (!s->set_mute) - pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_MUTE, PA_UINT_TO_PTR(mute), NULL, NULL); + pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_MUTE, PA_UINT_TO_PTR(mute), 0, NULL, NULL); if (changed) pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); @@ -337,7 +337,7 @@ int pa_source_get_mute(pa_source *s) { s->get_mute = NULL; if (!s->get_mute && s->refresh_muted) - pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_MUTE, &s->muted, NULL); + pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_GET_MUTE, &s->muted, 0, NULL); if (old_muted != s->muted) pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); @@ -384,7 +384,7 @@ unsigned pa_source_used_by(pa_source *s) { return pa_idxset_size(s->outputs); } -int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, pa_memchunk *chunk) { +int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_t offset, pa_memchunk *chunk) { pa_source *s = PA_SOURCE(object); pa_source_assert_ref(s); diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index e2b02ceb..fe59e584 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -146,7 +146,7 @@ unsigned pa_source_used_by(pa_source *s); /* To be used exclusively by the source driver thread */ void pa_source_post(pa_source*s, const pa_memchunk *b); -int pa_source_process_msg(pa_msgobject *o, int code, void *userdata, pa_memchunk *chunk); +int pa_source_process_msg(pa_msgobject *o, int code, void *userdata, int64_t, pa_memchunk *chunk); static inline int PA_SOURCE_OPENED(pa_source_state_t x) { return x == PA_SOURCE_RUNNING || x == PA_SOURCE_IDLE; diff --git a/src/tests/asyncmsgq-test.c b/src/tests/asyncmsgq-test.c index 847d5be1..baf93a0c 100644 --- a/src/tests/asyncmsgq-test.c +++ b/src/tests/asyncmsgq-test.c @@ -49,7 +49,7 @@ static void the_thread(void *_q) { do { int code = 0; - pa_assert_se(pa_asyncmsgq_get(q, NULL, &code, NULL, NULL, 1) == 0); + pa_assert_se(pa_asyncmsgq_get(q, NULL, &code, NULL, NULL, NULL, 1) == 0); switch (code) { @@ -85,22 +85,22 @@ int main(int argc, char *argv[]) { pa_assert_se(t = pa_thread_new(the_thread, q)); printf("Operation A post\n"); - pa_asyncmsgq_post(q, NULL, OPERATION_A, NULL, NULL, NULL); + pa_asyncmsgq_post(q, NULL, OPERATION_A, NULL, 0, NULL, NULL); pa_thread_yield(); printf("Operation B post\n"); - pa_asyncmsgq_post(q, NULL, OPERATION_B, NULL, NULL, NULL); + pa_asyncmsgq_post(q, NULL, OPERATION_B, NULL, 0, NULL, NULL); pa_thread_yield(); printf("Operation C send\n"); - pa_asyncmsgq_send(q, NULL, OPERATION_C, NULL, NULL); + pa_asyncmsgq_send(q, NULL, OPERATION_C, NULL, 0, NULL); pa_thread_yield(); printf("Quit post\n"); - pa_asyncmsgq_post(q, NULL, QUIT, NULL, NULL, NULL); + pa_asyncmsgq_post(q, NULL, QUIT, NULL, 0, NULL, NULL); pa_thread_free(t); -- cgit From d3eca287cfc177fc5084ddf72ccfdbe9bee23cae Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 31 Jul 2007 22:56:35 +0000 Subject: rename pa_source_output_new_data::corked to start_corked to match pa_sink_input_new_data::start_corked git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1563 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-native.c | 2 +- src/pulsecore/sink-input.h | 1 + src/pulsecore/source-output.c | 2 +- src/pulsecore/source-output.h | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 3be5eae8..03f2708e 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -443,7 +443,7 @@ static record_stream* record_stream_new( data.source = source; data.driver = __FILE__; data.name = name; - data.corked = corked; + data.start_corked = corked; pa_source_output_new_data_set_sample_spec(&data, ss); pa_source_output_new_data_set_channel_map(&data, map); diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index af3db95e..0168805a 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -131,6 +131,7 @@ typedef struct pa_sink_input_new_data { int sample_spec_is_set; pa_channel_map channel_map; int channel_map_is_set; + pa_cvolume volume; int volume_is_set; int muted; diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index c3ecf3a2..9b828e1a 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -135,7 +135,7 @@ pa_source_output* pa_source_output_new( o->parent.process_msg = pa_source_output_process_msg; o->core = core; - o->state = data->corked ? PA_SOURCE_OUTPUT_CORKED : PA_SOURCE_OUTPUT_RUNNING; + o->state = data->start_corked ? PA_SOURCE_OUTPUT_CORKED : PA_SOURCE_OUTPUT_RUNNING; o->flags = flags; o->name = pa_xstrdup(data->name); o->driver = pa_xstrdup(data->driver); diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h index 9f982a9a..47cc8c40 100644 --- a/src/pulsecore/source-output.h +++ b/src/pulsecore/source-output.h @@ -104,7 +104,7 @@ typedef struct pa_source_output_new_data { pa_resample_method_t resample_method; - int corked; + int start_corked; } pa_source_output_new_data; pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data); -- cgit From 9a4e84ade9b0d5978cd0649ed3adc0d5a94c2e3d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 3 Aug 2007 22:39:18 +0000 Subject: On recommendation of Takashi Iwai prefer Master volume control over PCM and don't control Mic control git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1564 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 2 +- src/modules/module-alsa-source.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 551bad89..9fd01e4d 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -769,7 +769,7 @@ int pa__init(pa_core *c, pa_module*m) { else { if ((pa_alsa_prepare_mixer(u->mixer_handle, dev) < 0) || - !(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "PCM", "Master"))) { + !(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Master", "PCM"))) { snd_mixer_close(u->mixer_handle); u->mixer_handle = NULL; diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index c2dad6f9..b2b0698a 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -744,7 +744,7 @@ int pa__init(pa_core *c, pa_module*m) { else { if ((pa_alsa_prepare_mixer(u->mixer_handle, dev) < 0) || - !(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Capture", "Mic"))) { + !(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Capture", NULL))) { snd_mixer_close(u->mixer_handle); u->mixer_handle = NULL; } -- cgit From a6c44c0e508ede5c25ebac534642d93d101be21e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 3 Aug 2007 22:41:27 +0000 Subject: Remove unnecessary snd_pcm_hwsync() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1565 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 1 - src/modules/module-alsa-source.c | 1 - 2 files changed, 2 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 9fd01e4d..ced42ee3 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -547,7 +547,6 @@ static void thread_func(void *userdata) { } else { ssize_t l; - snd_pcm_hwsync(u->pcm_handle); if ((err = snd_pcm_status(u->pcm_handle, status)) >= 0) l = snd_pcm_status_get_avail(status) * u->frame_size; else diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index b2b0698a..0fd7bca0 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -535,7 +535,6 @@ static void thread_func(void *userdata) { } else { ssize_t l; - snd_pcm_hwsync(u->pcm_handle); if ((err = snd_pcm_status(u->pcm_handle, status)) >= 0) l = snd_pcm_status_get_avail(status) * u->frame_size; else -- cgit From 95fab184d5448bff9f262589390c7374fb1370c8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 3 Aug 2007 23:48:52 +0000 Subject: Don't stop hardware on buffer underruns. Instead continue playing to guarantee that our time function stays as linear as possible. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1566 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/alsa-util.c | 33 ++++++++++++++++++++--- src/modules/alsa-util.h | 1 + src/modules/module-alsa-sink.c | 58 ++++++++++++++++++++++------------------ src/modules/module-alsa-source.c | 48 ++++++++++++++++++++------------- 4 files changed, 91 insertions(+), 49 deletions(-) diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c index dd9ac79e..dd063f3b 100644 --- a/src/modules/alsa-util.c +++ b/src/modules/alsa-util.c @@ -289,10 +289,11 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *p pa_assert(periods); pa_assert(period_size); + snd_pcm_hw_params_alloca(&hwparams); + buffer_size = *periods * *period_size; - if ((ret = snd_pcm_hw_params_malloc(&hwparams)) < 0 || - (ret = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0 || + if ((ret = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0 || (ret = snd_pcm_hw_params_set_rate_resample(pcm_handle, hwparams, 0)) < 0) goto finish; @@ -355,12 +356,36 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *p ret = 0; finish: - if (hwparams) - snd_pcm_hw_params_free(hwparams); return ret; } +int pa_alsa_set_sw_params(snd_pcm_t *pcm) { + snd_pcm_sw_params_t *swparams; + int err; + + pa_assert(pcm); + + snd_pcm_sw_params_alloca(&swparams); + + if ((err = snd_pcm_sw_params_current(pcm, swparams) < 0)) { + pa_log_warn("Unable to determine current swparams: %s\n", snd_strerror(err)); + return err; + } + + if ((err = snd_pcm_sw_params_set_stop_threshold(pcm, swparams, (snd_pcm_uframes_t) -1)) < 0) { + pa_log_warn("Unable to set stop threshold: %s\n", snd_strerror(err)); + return err; + } + + if ((err = snd_pcm_sw_params(pcm, swparams)) < 0) { + pa_log_warn("Unable to set sw params: %s\n", snd_strerror(err)); + return err; + } + + return 0; +} + int pa_alsa_prepare_mixer(snd_mixer_t *mixer, const char *dev) { int err; diff --git a/src/modules/alsa-util.h b/src/modules/alsa-util.h index f79325c6..6f1f927e 100644 --- a/src/modules/alsa-util.h +++ b/src/modules/alsa-util.h @@ -39,6 +39,7 @@ void pa_alsa_fdlist_free(struct pa_alsa_fdlist *fdl); int pa_alsa_fdlist_set_mixer(struct pa_alsa_fdlist *fdl, snd_mixer_t *mixer_handle, pa_mainloop_api* m); int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *periods, snd_pcm_uframes_t *period_size, int *use_mmap); +int pa_alsa_set_sw_params(snd_pcm_t *pcm); int pa_alsa_prepare_mixer(snd_mixer_t *mixer, const char *dev); snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name, const char *fallback); diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index ced42ee3..5765d780 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -545,18 +545,23 @@ static void thread_func(void *userdata) { goto fail; } else { - ssize_t l; - - if ((err = snd_pcm_status(u->pcm_handle, status)) >= 0) - l = snd_pcm_status_get_avail(status) * u->frame_size; - else - l = u->fragment_size; - - while (l > 0) { + for (;;) { void *p; snd_pcm_sframes_t t; + ssize_t l; + + if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) { + pa_log("Failed to query DSP status data: %s", snd_strerror(t)); + goto fail; + } - pa_assert(l > 0); + if (snd_pcm_status_get_avail_max(status)*u->frame_size >= u->hwbuf_size) + pa_log_debug("Buffer underrun!"); + + l = snd_pcm_status_get_avail(status) * u->frame_size; + + if (l <= 0) + break; if (u->memchunk.length <= 0) pa_sink_render(u->sink, l, &u->memchunk); @@ -573,10 +578,7 @@ static void thread_func(void *userdata) { if (t < 0) { - if (t == -EPIPE) { - pa_log_debug("Buffer underrun!"); - u->first = 1; - } + pa_assert(t != -EPIPE); if ((t = snd_pcm_recover(u->pcm_handle, t, 1)) == 0) continue; @@ -588,21 +590,20 @@ static void thread_func(void *userdata) { pa_log("Failed to write data to DSP: %s", snd_strerror(t)); goto fail; } + } - } else { - - u->memchunk.index += t * u->frame_size; - u->memchunk.length -= t * u->frame_size; - - if (u->memchunk.length <= 0) { - pa_memblock_unref(u->memchunk.memblock); - pa_memchunk_reset(&u->memchunk); - } - - l -= t * u->frame_size; - - work_done = 1; + u->memchunk.index += t * u->frame_size; + u->memchunk.length -= t * u->frame_size; + + if (u->memchunk.length <= 0) { + pa_memblock_unref(u->memchunk.memblock); + pa_memchunk_reset(&u->memchunk); } + + work_done = 1; + + if (t * u->frame_size >= (unsigned) l) + break; } } @@ -756,6 +757,11 @@ int pa__init(pa_core *c, pa_module*m) { if (u->use_mmap) pa_log_info("Successfully enabled mmap() mode."); + if ((err = pa_alsa_set_sw_params(u->pcm_handle)) < 0) { + pa_log("Failed to set software parameters: %s", snd_strerror(err)); + goto fail; + } + /* ALSA might tweak the sample spec, so recalculate the frame size */ frame_size = pa_frame_size(&ss); diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 0fd7bca0..9a5d5acb 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -533,19 +533,25 @@ static void thread_func(void *userdata) { goto fail; } else { - ssize_t l; - if ((err = snd_pcm_status(u->pcm_handle, status)) >= 0) - l = snd_pcm_status_get_avail(status) * u->frame_size; - else - l = u->fragment_size; - - while (l > 0) { + for (;;) { void *p; snd_pcm_sframes_t t; + ssize_t l; - pa_assert(l > 0); + if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) { + pa_log("Failed to query DSP status data: %s", snd_strerror(t)); + goto fail; + } + if (snd_pcm_status_get_avail_max(status)*u->frame_size >= u->hwbuf_size) + pa_log_debug("Buffer overrun!"); + + l = snd_pcm_status_get_avail(status) * u->frame_size; + + if (l <= 0) + break; + chunk.memblock = pa_memblock_new(u->core->mempool, l); p = pa_memblock_acquire(chunk.memblock); @@ -559,8 +565,7 @@ static void thread_func(void *userdata) { if (t < 0) { pa_memblock_unref(chunk.memblock); - if (t == -EPIPE) - pa_log_debug("Buffer underrun!"); + pa_assert(t != -EPIPE); if ((t = snd_pcm_recover(u->pcm_handle, t, 1)) == 0) continue; @@ -573,18 +578,18 @@ static void thread_func(void *userdata) { goto fail; } - } else { + } - chunk.index = 0; - chunk.length = t * u->frame_size; + chunk.index = 0; + chunk.length = t * u->frame_size; - pa_source_post(u->source, &chunk); - pa_memblock_unref(chunk.memblock); - - l -= t * u->frame_size; + pa_source_post(u->source, &chunk); + pa_memblock_unref(chunk.memblock); + + work_done = 1; - work_done = 1; - } + if (t * u->frame_size >= (unsigned) l) + break; } } @@ -730,6 +735,11 @@ int pa__init(pa_core *c, pa_module*m) { if (u->use_mmap) pa_log_info("Successfully enabled mmap() mode."); + + if ((err = pa_alsa_set_sw_params(u->pcm_handle)) < 0) { + pa_log("Failed to set software parameters: %s", snd_strerror(err)); + goto fail; + } /* ALSA might tweak the sample spec, so recalculate the frame size */ frame_size = pa_frame_size(&ss); -- cgit From 81760ad897f309e07ba7edc7f6d0ed6a3a71af9b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 4 Aug 2007 20:20:33 +0000 Subject: merge compat changes from trunk git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1569 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 1 + src/Makefile.am | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 9a1e6c51..89fcb062 100644 --- a/configure.ac +++ b/configure.ac @@ -67,6 +67,7 @@ esac # CC AC_PROG_CC +AM_PROG_CC_C_O AC_PROG_GCC_TRADITIONAL AC_GNU_SOURCE diff --git a/src/Makefile.am b/src/Makefile.am index 4083ea55..8fc0f19c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1267,12 +1267,12 @@ module_rtp_recv_la_CFLAGS = $(AM_CFLAGS) #module_jack_sink_la_SOURCES = modules/module-jack-sink.c #module_jack_sink_la_LDFLAGS = -module -avoid-version #module_jack_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la $(JACK_LIBS) -#module_jack_sink_la_CFLAGS = $(AM_LIBADD) $(JACK_CFLAGS) +#module_jack_sink_la_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS) #module_jack_source_la_SOURCES = modules/module-jack-source.c #module_jack_source_la_LDFLAGS = -module -avoid-version #module_jack_source_la_LIBADD = $(AM_LIBADD) libpulsecore.la $(JACK_LIBS) -#module_jack_source_la_CFLAGS = $(AM_LIBADD) $(JACK_CFLAGS) +#module_jack_source_la_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS) # HAL libdbus_util_la_SOURCES = modules/dbus-util.c modules/dbus-util.h -- cgit From 34e41657e714dcd7f862f5cb4776dfb9f9cc2e5c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 5 Aug 2007 00:06:35 +0000 Subject: minor cleanups git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1570 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sound-file-stream.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index f2204f26..433a73b8 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -40,6 +40,8 @@ #define BUF_SIZE (1024*10) +/* FIXME: file access needs to be moved to seperate thread */ + typedef struct file_stream { pa_msgobject parent; pa_core *core; @@ -58,10 +60,27 @@ PA_DECLARE_CLASS(file_stream); #define FILE_STREAM(o) (file_stream_cast(o)) static PA_DEFINE_CHECK_TYPE(file_stream, pa_msgobject); +static void file_stream_unlink(file_stream *u) { + pa_assert(u); + + if (!u->sink_input) + return; + + pa_sink_input_disconnect(u->sink_input); + + pa_sink_input_unref(u->sink_input); + u->sink_input = NULL; + + /* Make sure we don't decrease the ref count twice. */ + file_stream_unref(u); +} + static void file_stream_free(pa_object *o) { file_stream *u = FILE_STREAM(o); pa_assert(u); + file_stream_unlink(u); + if (u->memchunk.memblock) pa_memblock_unref(u->memchunk.memblock); @@ -71,27 +90,13 @@ static void file_stream_free(pa_object *o) { pa_xfree(u); } -static void file_stream_drop(file_stream *u) { - file_stream_assert_ref(u); - - if (u->sink_input) { - pa_sink_input_disconnect(u->sink_input); - - pa_sink_input_unref(u->sink_input); - u->sink_input = NULL; - - /* Make sure we don't decrease the ref count twice. */ - file_stream_unref(u); - } -} - static int file_stream_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) { file_stream *u = FILE_STREAM(o); file_stream_assert_ref(u); switch (code) { case MESSAGE_DROP_FILE_STREAM: - file_stream_drop(u); + file_stream_unlink(u); break; } @@ -99,9 +104,9 @@ static int file_stream_process_msg(pa_msgobject *o, int code, void*userdata, int } static void sink_input_kill_cb(pa_sink_input *i) { - pa_assert(i); + pa_sink_input_assert_ref(i); - file_stream_drop(FILE_STREAM(i->userdata)); + file_stream_unlink(FILE_STREAM(i->userdata)); } static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { -- cgit From 36dd7819da1615ee96b2343246bc7007211a7d0e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 5 Aug 2007 00:07:07 +0000 Subject: modernize play-memchunk and port it to the new core git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1571 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/play-memchunk.c | 164 +++++++++++++++++++++++++++++------------- 1 file changed, 116 insertions(+), 48 deletions(-) diff --git a/src/pulsecore/play-memchunk.c b/src/pulsecore/play-memchunk.c index 7e750baa..a5ba949b 100644 --- a/src/pulsecore/play-memchunk.c +++ b/src/pulsecore/play-memchunk.c @@ -26,7 +26,6 @@ #endif #include -#include #include #include @@ -37,51 +36,105 @@ #include "play-memchunk.h" -static void sink_input_kill_cb(pa_sink_input *i) { - pa_memchunk *c; - assert(i && i->userdata); - c = i->userdata; - - pa_sink_input_disconnect(i); - pa_sink_input_unref(i); - - pa_memblock_unref(c->memblock); - pa_xfree(c); +typedef struct memchunk_stream { + pa_msgobject parent; + pa_core *core; + pa_sink_input *sink_input; + pa_memchunk memchunk; +} memchunk_stream; + +enum { + MEMCHUNK_STREAM_MESSAGE_UNLINK, +}; + +PA_DECLARE_CLASS(memchunk_stream); +#define MEMCHUNK_STREAM(o) (memchunk_stream_cast(o)) +static PA_DEFINE_CHECK_TYPE(memchunk_stream, pa_msgobject); + +static void memchunk_stream_unlink(memchunk_stream *u) { + pa_assert(u); + + if (!u->sink_input) + return; + + pa_sink_input_disconnect(u->sink_input); + + pa_sink_input_unref(u->sink_input); + u->sink_input = NULL; + + /* Make sure we don't decrease the ref count twice. */ + memchunk_stream_unref(u); } -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { - pa_memchunk *c; - assert(i && chunk && i->userdata); - c = i->userdata; +static void memchunk_stream_free(pa_object *o) { + memchunk_stream *u = MEMCHUNK_STREAM(o); + pa_assert(u); - if (c->length <= 0) - return -1; + memchunk_stream_unlink(u); + + if (u->memchunk.memblock) + pa_memblock_unref(u->memchunk.memblock); + + pa_xfree(u); +} - assert(c->memblock); - *chunk = *c; - pa_memblock_ref(c->memblock); +static int memchunk_stream_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) { + memchunk_stream *u = MEMCHUNK_STREAM(o); + memchunk_stream_assert_ref(u); + + switch (code) { + case MEMCHUNK_STREAM_MESSAGE_UNLINK: + memchunk_stream_unlink(u); + break; + } return 0; } -static void si_kill_cb(PA_GCC_UNUSED pa_mainloop_api *m, void *i) { - sink_input_kill_cb(i); -} +static void sink_input_kill_cb(pa_sink_input *i) { + pa_sink_input_assert_ref(i); -static void sink_input_drop_cb(pa_sink_input *i, size_t length) { - pa_memchunk *c; - assert(i && length && i->userdata); - c = i->userdata; + memchunk_stream_unlink(MEMCHUNK_STREAM(i->userdata)); +} - if (length >= c->length) { - c->length -= length; - c->index += length; - } else { +static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { + memchunk_stream *u; - c->length = 0; + pa_assert(i); + pa_assert(chunk); + u = MEMCHUNK_STREAM(i->userdata); + memchunk_stream_assert_ref(u); - pa_mainloop_api_once(i->sink->core->mainloop, si_kill_cb, i); + if (!u->memchunk.memblock) + return -1; + + if (u->memchunk.length <= 0) { + pa_memblock_unref(u->memchunk.memblock); + u->memchunk.memblock = NULL; + pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u), MEMCHUNK_STREAM_MESSAGE_UNLINK, NULL, 0, NULL, NULL); + return -1; } + + pa_assert(u->memchunk.memblock); + *chunk = u->memchunk; + pa_memblock_ref(chunk->memblock); + + return 0; +} + +static void sink_input_drop_cb(pa_sink_input *i, size_t length) { + memchunk_stream *u; + + pa_assert(i); + pa_assert(length > 0); + u = MEMCHUNK_STREAM(i->userdata); + memchunk_stream_assert_ref(u); + + if (length >= u->memchunk.length) { + u->memchunk.length -= length; + u->memchunk.index += length; + } else + u->memchunk.length = 0; } int pa_play_memchunk( @@ -92,36 +145,51 @@ int pa_play_memchunk( const pa_memchunk *chunk, pa_cvolume *volume) { - pa_sink_input *si; - pa_memchunk *nchunk; + memchunk_stream *u = NULL; pa_sink_input_new_data data; - assert(sink); - assert(ss); - assert(chunk); + pa_assert(sink); + pa_assert(ss); + pa_assert(chunk); if (volume && pa_cvolume_is_muted(volume)) return 0; + u = pa_msgobject_new(memchunk_stream); + u->parent.parent.free = memchunk_stream_free; + u->parent.process_msg = memchunk_stream_process_msg; + u->core = sink->core; + u->sink_input = NULL; + u->memchunk = *chunk; + pa_memblock_ref(u->memchunk.memblock); + pa_sink_input_new_data_init(&data); data.sink = sink; - data.name = name; data.driver = __FILE__; + data.name = name; pa_sink_input_new_data_set_sample_spec(&data, ss); pa_sink_input_new_data_set_channel_map(&data, map); pa_sink_input_new_data_set_volume(&data, volume); - if (!(si = pa_sink_input_new(sink->core, &data, 0))) - return -1; + if (!(u->sink_input = pa_sink_input_new(sink->core, &data, 0))) + goto fail; + + u->sink_input->peek = sink_input_peek_cb; + u->sink_input->drop = sink_input_drop_cb; + u->sink_input->kill = sink_input_kill_cb; + u->sink_input->userdata = u; - si->peek = sink_input_peek_cb; - si->drop = sink_input_drop_cb; - si->kill = sink_input_kill_cb; + pa_sink_input_put(u->sink_input); - si->userdata = nchunk = pa_xnew(pa_memchunk, 1); - *nchunk = *chunk; + /* The reference to u is dangling here, because we want to keep + * this stream around until it is fully played. */ + + return 0; - pa_memblock_ref(chunk->memblock); +fail: + if (u) + memchunk_stream_unref(u); - return 0; + return -1; } + -- cgit From 23d01bb75db12ceaa263fa830b74cf8669ef2dd9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 5 Aug 2007 00:07:58 +0000 Subject: Modernize pstream.[ch], reintroduce defer event to make things actually work git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1572 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/pstream.c | 154 ++++++++++++++++++++++++++++-------------------- src/pulsecore/pstream.h | 2 +- 2 files changed, 90 insertions(+), 66 deletions(-) diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c index f4aab1c2..0ffa583a 100644 --- a/src/pulsecore/pstream.c +++ b/src/pulsecore/pstream.c @@ -28,7 +28,6 @@ #include #include -#include #include #ifdef HAVE_SYS_SOCKET_H @@ -168,8 +167,8 @@ static int do_write(pa_pstream *p); static int do_read(pa_pstream *p); static void do_something(pa_pstream *p) { - assert(p); - assert(PA_REFCNT_VALUE(p) > 0); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); pa_pstream_ref(p); @@ -191,31 +190,42 @@ static void do_something(pa_pstream *p) { fail: - p->dead = 1; - if (p->die_callback) p->die_callback(p, p->die_callback_userdata); + pa_pstream_unlink(p); pa_pstream_unref(p); } static void io_callback(pa_iochannel*io, void *userdata) { pa_pstream *p = userdata; - assert(p); - assert(p->io == io); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); + pa_assert(p->io == io); do_something(p); } +static void defer_callback(pa_mainloop_api *m, pa_defer_event *e, void*userdata) { + pa_pstream *p = userdata; + + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); + pa_assert(p->defer_event == e); + pa_assert(p->mainloop == m); + + do_something(p); +} + static void memimport_release_cb(pa_memimport *i, uint32_t block_id, void *userdata); pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_mempool *pool) { pa_pstream *p; - assert(m); - assert(io); - assert(pool); + pa_assert(m); + pa_assert(io); + pa_assert(pool); p = pa_xnew(pa_pstream, 1); PA_REFCNT_INIT(p); @@ -224,9 +234,11 @@ pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_mempool *poo p->dead = 0; p->mainloop = m; - + p->defer_event = m->defer_new(m, defer_callback, p); + m->defer_enable(p->defer_event, 0); + p->send_queue = pa_queue_new(); - assert(p->send_queue); + pa_assert(p->send_queue); p->write.current = NULL; p->write.index = 0; @@ -264,13 +276,13 @@ pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_mempool *poo static void item_free(void *item, PA_GCC_UNUSED void *p) { struct item_info *i = item; - assert(i); + pa_assert(i); if (i->type == PA_PSTREAM_ITEM_MEMBLOCK) { - assert(i->chunk.memblock); + pa_assert(i->chunk.memblock); pa_memblock_unref(i->chunk.memblock); } else if (i->type == PA_PSTREAM_ITEM_PACKET) { - assert(i->packet); + pa_assert(i->packet); pa_packet_unref(i->packet); } @@ -278,9 +290,9 @@ static void item_free(void *item, PA_GCC_UNUSED void *p) { } static void pstream_free(pa_pstream *p) { - assert(p); + pa_assert(p); - pa_pstream_close(p); + pa_pstream_unlink(p); pa_queue_free(p->send_queue, item_free, NULL); @@ -302,9 +314,9 @@ static void pstream_free(pa_pstream *p) { void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const pa_creds *creds) { struct item_info *i; - assert(p); - assert(PA_REFCNT_VALUE(p) > 0); - assert(packet); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); + pa_assert(packet); if (p->dead) return; @@ -319,15 +331,17 @@ void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const pa_creds *cre #endif pa_queue_push(p->send_queue, i); + + p->mainloop->defer_enable(p->defer_event, 1); } void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa_seek_mode_t seek_mode, const pa_memchunk *chunk) { size_t length, idx; - assert(p); - assert(PA_REFCNT_VALUE(p) > 0); - assert(channel != (uint32_t) -1); - assert(chunk); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); + pa_assert(channel != (uint32_t) -1); + pa_assert(chunk); if (p->dead) return; @@ -366,8 +380,8 @@ static void memimport_release_cb(pa_memimport *i, uint32_t block_id, void *userd struct item_info *item; pa_pstream *p = userdata; - assert(p); - assert(PA_REFCNT_VALUE(p) > 0); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); if (p->dead) return; @@ -382,14 +396,15 @@ static void memimport_release_cb(pa_memimport *i, uint32_t block_id, void *userd #endif pa_queue_push(p->send_queue, item); + p->mainloop->defer_enable(p->defer_event, 1); } static void memexport_revoke_cb(pa_memexport *e, uint32_t block_id, void *userdata) { struct item_info *item; pa_pstream *p = userdata; - assert(p); - assert(PA_REFCNT_VALUE(p) > 0); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); if (p->dead) return; @@ -403,11 +418,12 @@ static void memexport_revoke_cb(pa_memexport *e, uint32_t block_id, void *userda #endif pa_queue_push(p->send_queue, item); + p->mainloop->defer_enable(p->defer_event, 1); } static void prepare_next_write_item(pa_pstream *p) { - assert(p); - assert(PA_REFCNT_VALUE(p) > 0); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); p->write.current = pa_queue_pop(p->send_queue); @@ -426,7 +442,7 @@ static void prepare_next_write_item(pa_pstream *p) { if (p->write.current->type == PA_PSTREAM_ITEM_PACKET) { - assert(p->write.current->packet); + pa_assert(p->write.current->packet); p->write.data = p->write.current->packet->data; p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl(p->write.current->packet->length); @@ -444,8 +460,8 @@ static void prepare_next_write_item(pa_pstream *p) { uint32_t flags; int send_payload = 1; - assert(p->write.current->type == PA_PSTREAM_ITEM_MEMBLOCK); - assert(p->write.current->chunk.memblock); + pa_assert(p->write.current->type == PA_PSTREAM_ITEM_MEMBLOCK); + pa_assert(p->write.current->chunk.memblock); p->write.descriptor[PA_PSTREAM_DESCRIPTOR_CHANNEL] = htonl(p->write.current->channel); p->write.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI] = htonl((uint32_t) (((uint64_t) p->write.current->offset) >> 32)); @@ -457,7 +473,7 @@ static void prepare_next_write_item(pa_pstream *p) { uint32_t block_id, shm_id; size_t offset, length; - assert(p->export); + pa_assert(p->export); if (pa_memexport_put(p->export, p->write.current->chunk.memblock, @@ -503,8 +519,8 @@ static int do_write(pa_pstream *p) { ssize_t r; pa_memblock *release_memblock = NULL; - assert(p); - assert(PA_REFCNT_VALUE(p) > 0); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); if (!p->write.current) prepare_next_write_item(p); @@ -516,7 +532,7 @@ static int do_write(pa_pstream *p) { d = (uint8_t*) p->write.descriptor + p->write.index; l = PA_PSTREAM_DESCRIPTOR_SIZE - p->write.index; } else { - assert(p->write.data || p->write.memchunk.memblock); + pa_assert(p->write.data || p->write.memchunk.memblock); if (p->write.data) d = p->write.data; @@ -529,7 +545,7 @@ static int do_write(pa_pstream *p) { l = ntohl(p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]) - (p->write.index - PA_PSTREAM_DESCRIPTOR_SIZE); } - assert(l > 0); + pa_assert(l > 0); #ifdef HAVE_CREDS if (p->send_creds_now) { @@ -550,7 +566,7 @@ static int do_write(pa_pstream *p) { p->write.index += r; if (p->write.index >= PA_PSTREAM_DESCRIPTOR_SIZE + ntohl(p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH])) { - assert(p->write.current); + pa_assert(p->write.current); item_free(p->write.current, (void *) 1); p->write.current = NULL; @@ -573,14 +589,14 @@ static int do_read(pa_pstream *p) { size_t l; ssize_t r; pa_memblock *release_memblock = NULL; - assert(p); - assert(PA_REFCNT_VALUE(p) > 0); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); if (p->read.index < PA_PSTREAM_DESCRIPTOR_SIZE) { d = (uint8_t*) p->read.descriptor + p->read.index; l = PA_PSTREAM_DESCRIPTOR_SIZE - p->read.index; } else { - assert(p->read.data || p->read.memblock); + pa_assert(p->read.data || p->read.memblock); if (p->read.data) d = p->read.data; @@ -629,7 +645,7 @@ static int do_read(pa_pstream *p) { /* pa_log("Got release frame for %u", ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI])); */ - assert(p->export); + pa_assert(p->export); pa_memexport_process_release(p->export, ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI])); goto frame_done; @@ -640,7 +656,7 @@ static int do_read(pa_pstream *p) { /* pa_log("Got revoke frame for %u", ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI])); */ - assert(p->import); + pa_assert(p->import); pa_memimport_process_revoke(p->import, ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI])); goto frame_done; @@ -653,7 +669,7 @@ static int do_read(pa_pstream *p) { return -1; } - assert(!p->read.packet && !p->read.memblock); + pa_assert(!p->read.packet && !p->read.memblock); channel = ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_CHANNEL]); @@ -757,9 +773,9 @@ static int do_read(pa_pstream *p) { } else { pa_memblock *b; - assert((ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_FLAGS]) & PA_FLAG_SHMMASK) == PA_FLAG_SHMDATA); + pa_assert((ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_FLAGS]) & PA_FLAG_SHMMASK) == PA_FLAG_SHMDATA); - assert(p->import); + pa_assert(p->import); if (!(b = pa_memimport_get(p->import, ntohl(p->read.shm_info[PA_PSTREAM_SHM_BLOCKID]), @@ -821,32 +837,32 @@ fail: } void pa_pstream_set_die_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata) { - assert(p); - assert(PA_REFCNT_VALUE(p) > 0); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); p->die_callback = cb; p->die_callback_userdata = userdata; } void pa_pstream_set_drain_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata) { - assert(p); - assert(PA_REFCNT_VALUE(p) > 0); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); p->drain_callback = cb; p->drain_callback_userdata = userdata; } void pa_pstream_set_recieve_packet_callback(pa_pstream *p, pa_pstream_packet_cb_t cb, void *userdata) { - assert(p); - assert(PA_REFCNT_VALUE(p) > 0); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); p->recieve_packet_callback = cb; p->recieve_packet_callback_userdata = userdata; } void pa_pstream_set_recieve_memblock_callback(pa_pstream *p, pa_pstream_memblock_cb_t cb, void *userdata) { - assert(p); - assert(PA_REFCNT_VALUE(p) > 0); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); p->recieve_memblock_callback = cb; p->recieve_memblock_callback_userdata = userdata; @@ -855,8 +871,8 @@ void pa_pstream_set_recieve_memblock_callback(pa_pstream *p, pa_pstream_memblock int pa_pstream_is_pending(pa_pstream *p) { int b; - assert(p); - assert(PA_REFCNT_VALUE(p) > 0); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); if (p->dead) b = 0; @@ -867,24 +883,27 @@ int pa_pstream_is_pending(pa_pstream *p) { } void pa_pstream_unref(pa_pstream*p) { - assert(p); - assert(PA_REFCNT_VALUE(p) > 0); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); if (PA_REFCNT_DEC(p) <= 0) pstream_free(p); } pa_pstream* pa_pstream_ref(pa_pstream*p) { - assert(p); - assert(PA_REFCNT_VALUE(p) > 0); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); PA_REFCNT_INC(p); return p; } -void pa_pstream_close(pa_pstream *p) { - assert(p); +void pa_pstream_unlink(pa_pstream *p) { + pa_assert(p); + if (p->dead) + return; + p->dead = 1; if (p->import) { @@ -902,6 +921,11 @@ void pa_pstream_close(pa_pstream *p) { p->io = NULL; } + if (p->defer_event) { + p->mainloop->defer_free(p->defer_event); + p->defer_event = NULL; + } + p->die_callback = NULL; p->drain_callback = NULL; p->recieve_packet_callback = NULL; @@ -909,8 +933,8 @@ void pa_pstream_close(pa_pstream *p) { } void pa_pstream_use_shm(pa_pstream *p, int enable) { - assert(p); - assert(PA_REFCNT_VALUE(p) > 0); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); p->use_shm = enable; diff --git a/src/pulsecore/pstream.h b/src/pulsecore/pstream.h index 5900ecea..544cba4d 100644 --- a/src/pulsecore/pstream.h +++ b/src/pulsecore/pstream.h @@ -59,6 +59,6 @@ int pa_pstream_is_pending(pa_pstream *p); void pa_pstream_use_shm(pa_pstream *p, int enable); -void pa_pstream_close(pa_pstream *p); +void pa_pstream_unlink(pa_pstream *p); #endif -- cgit From 55e0866297fb1169a06b2cb6cc7188629b315ad0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 5 Aug 2007 00:08:27 +0000 Subject: typesafe casts git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1573 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink.c | 4 ++-- src/pulsecore/source.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 5ab01cb4..150e4cb9 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -667,7 +667,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse switch ((pa_sink_message_t) code) { case PA_SINK_MESSAGE_ADD_INPUT: { - pa_sink_input *i = userdata; + pa_sink_input *i = PA_SINK_INPUT(userdata); pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), pa_sink_input_ref(i)); /* Since the caller sleeps in pa_sink_input_put(), we can @@ -690,7 +690,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse } case PA_SINK_MESSAGE_REMOVE_INPUT: { - pa_sink_input *i = userdata; + pa_sink_input *i = PA_SINK_INPUT(userdata); /* Since the caller sleeps in pa_sink_input_disconnect(), * we can safely access data outside of thread_info even diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index eaf1335e..241e1fb5 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -390,13 +390,13 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_ switch ((pa_source_message_t) code) { case PA_SOURCE_MESSAGE_ADD_OUTPUT: { - pa_source_output *o = userdata; + pa_source_output *o = PA_SOURCE_OUTPUT(userdata); pa_hashmap_put(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index), pa_source_output_ref(o)); return 0; } case PA_SOURCE_MESSAGE_REMOVE_OUTPUT: { - pa_source_output *o = userdata; + pa_source_output *o = PA_SOURCE_OUTPUT(userdata); if (pa_hashmap_remove(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index))) pa_source_output_unref(o); -- cgit From 241a9e10f15d8e20dc140cfdbd86b19b691f99ac Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 5 Aug 2007 00:09:02 +0000 Subject: follow rename of pstream_close() to pstream_unlink() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1574 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/context.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pulse/context.c b/src/pulse/context.c index 0dba9051..8125c64f 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -183,7 +183,7 @@ static void context_free(pa_context *c) { if (c->pdispatch) pa_pdispatch_unref(c->pdispatch); if (c->pstream) { - pa_pstream_close(c->pstream); + pa_pstream_unlink(c->pstream); pa_pstream_unref(c->pstream); } @@ -250,7 +250,7 @@ void pa_context_set_state(pa_context *c, pa_context_state_t st) { c->pdispatch = NULL; if (c->pstream) { - pa_pstream_close(c->pstream); + pa_pstream_unlink(c->pstream); pa_pstream_unref(c->pstream); } c->pstream = NULL; -- cgit From bd0782eb068bb6d5f407376fb79c689e157c371f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 5 Aug 2007 00:09:48 +0000 Subject: initialize method pointers properly git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1575 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-native.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 03f2708e..2396a38d 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -353,7 +353,7 @@ static upload_stream* upload_stream_new( pa_assert(length > 0); s = pa_msgobject_new(upload_stream); - c->parent.parent.free = upload_stream_free; + s->parent.parent.parent.free = upload_stream_free; s->connection = c; s->sample_spec = *ss; s->channel_map = *map; @@ -451,8 +451,8 @@ static record_stream* record_stream_new( return NULL; s = pa_msgobject_new(record_stream); - c->parent.parent.free = record_stream_free; - c->parent.process_msg = record_stream_process_msg; + s->parent.parent.free = record_stream_free; + s->parent.process_msg = record_stream_process_msg; s->connection = c; s->source_output = source_output; s->source_output->push = source_output_push_cb; @@ -630,8 +630,8 @@ static playback_stream* playback_stream_new( return NULL; s = pa_msgobject_new(playback_stream); - c->parent.parent.free = playback_stream_free; - c->parent.process_msg = playback_stream_process_msg; + s->parent.parent.parent.free = playback_stream_free; + s->parent.parent.process_msg = playback_stream_process_msg; s->connection = c; s->syncid = syncid; s->sink_input = sink_input; @@ -697,7 +697,7 @@ static void connection_unlink(connection *c) { pa_subscription_free(c->subscription); if (c->pstream) - pa_pstream_close(c->pstream); + pa_pstream_unlink(c->pstream); if (c->auth_timeout_event) { c->protocol->core->mainloop->time_free(c->auth_timeout_event); @@ -705,8 +705,8 @@ static void connection_unlink(connection *c) { } pa_assert_se(pa_idxset_remove_by_data(c->protocol->connections, c, NULL) == c); - connection_unref(c); c->protocol = NULL; + connection_unref(c); } static void connection_free(pa_object *o) { @@ -1933,7 +1933,6 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t e, uint3 connection *c = CONNECTION(userdata); connection_assert_ref(c); - pa_assert(t); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_SUBSCRIBE_EVENT); @@ -2653,10 +2652,9 @@ static void pstream_die_callback(pa_pstream *p, void *userdata) { connection_assert_ref(c); connection_unlink(c); -/* pa_log("connection died.");*/ + pa_log_info("connection died."); } - static void pstream_drain_callback(pa_pstream *p, void *userdata) { connection *c = CONNECTION(userdata); @@ -2732,7 +2730,6 @@ static void on_connection(PA_GCC_UNUSED pa_socket_server*s, pa_iochannel *io, vo c->client->owner = p->module; c->pstream = pa_pstream_new(p->core->mainloop, io, p->core->mempool); - pa_assert(c->pstream); pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_callback, c); pa_pstream_set_recieve_memblock_callback(c->pstream, pstream_memblock_callback, c); @@ -2740,18 +2737,15 @@ static void on_connection(PA_GCC_UNUSED pa_socket_server*s, pa_iochannel *io, vo pa_pstream_set_drain_callback(c->pstream, pstream_drain_callback, c); c->pdispatch = pa_pdispatch_new(p->core->mainloop, command_table, PA_COMMAND_MAX); - pa_assert(c->pdispatch); c->record_streams = pa_idxset_new(NULL, NULL); c->output_streams = pa_idxset_new(NULL, NULL); - pa_assert(c->record_streams && c->output_streams); c->rrobin_index = PA_IDXSET_INVALID; c->subscription = NULL; pa_idxset_put(p->connections, c, NULL); - #ifdef HAVE_CREDS if (pa_iochannel_creds_supported(io)) pa_iochannel_creds_enable(io); @@ -2834,7 +2828,6 @@ static pa_protocol_native* protocol_new_internal(pa_core *c, pa_module *m, pa_mo goto fail; p->connections = pa_idxset_new(NULL, NULL); - pa_assert(p->connections); return p; -- cgit From 9d1eb1bbda22a7648c7e216c98d63cfbcb8829e6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 5 Aug 2007 11:22:03 +0000 Subject: play memchunks completely git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1576 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/play-memchunk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/play-memchunk.c b/src/pulsecore/play-memchunk.c index a5ba949b..419d523f 100644 --- a/src/pulsecore/play-memchunk.c +++ b/src/pulsecore/play-memchunk.c @@ -130,7 +130,7 @@ static void sink_input_drop_cb(pa_sink_input *i, size_t length) { u = MEMCHUNK_STREAM(i->userdata); memchunk_stream_assert_ref(u); - if (length >= u->memchunk.length) { + if (length < u->memchunk.length) { u->memchunk.length -= length; u->memchunk.index += length; } else -- cgit From 872951cca18d9c595706b3543570cc764d886cf4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 5 Aug 2007 13:51:32 +0000 Subject: use posix_fadvise to avoid page faults when reading audio files from disk git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1577 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sound-file-stream.c | 42 +++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index 433a73b8..4e0e91e0 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -28,19 +28,21 @@ #include #include #include +#include +#include +#include #include #include +#include #include #include #include "sound-file-stream.h" -#define BUF_SIZE (1024*10) - -/* FIXME: file access needs to be moved to seperate thread */ +#define BUF_SIZE (1024*16) typedef struct file_stream { pa_msgobject parent; @@ -53,7 +55,7 @@ typedef struct file_stream { } file_stream; enum { - MESSAGE_DROP_FILE_STREAM + FILE_STREAM_MESSAGE_UNLINK }; PA_DECLARE_CLASS(file_stream); @@ -95,7 +97,7 @@ static int file_stream_process_msg(pa_msgobject *o, int code, void*userdata, int file_stream_assert_ref(u); switch (code) { - case MESSAGE_DROP_FILE_STREAM: + case FILE_STREAM_MESSAGE_UNLINK: file_stream_unlink(u); break; } @@ -159,7 +161,7 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { pa_memblock_unref(u->memchunk.memblock); pa_memchunk_reset(&u->memchunk); - pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u), MESSAGE_DROP_FILE_STREAM, NULL, 0, NULL, NULL); + pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u), FILE_STREAM_MESSAGE_UNLINK, NULL, 0, NULL, NULL); sf_close(u->sndfile); u->sndfile = NULL; @@ -225,7 +227,8 @@ int pa_play_file( SF_INFO sfinfo; pa_sample_spec ss; pa_sink_input_new_data data; - + int fd; + pa_assert(sink); pa_assert(fname); @@ -241,8 +244,31 @@ int pa_play_file( memset(&sfinfo, 0, sizeof(sfinfo)); - if (!(u->sndfile = sf_open(fname, SFM_READ, &sfinfo))) { + if ((fd = open(fname, O_RDONLY|O_NOCTTY)) < 0) { + pa_log("Failed to open file %s: %s", fname, pa_cstrerror(errno)); + goto fail; + } + + /* FIXME: For now we just use posix_fadvise to avoid page faults + * when accessing the file data. Eventually we should move the + * file reader into the main event loop and pass the data over the + * asyncmsgq. */ + + if (posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL) < 0) { + pa_log_warn("POSIX_FADV_SEQUENTIAL failed: %s", pa_cstrerror(errno)); + goto fail; + } else + pa_log_debug("POSIX_FADV_SEQUENTIAL succeeded."); + + if (posix_fadvise(fd, 0, 0, POSIX_FADV_WILLNEED) < 0) { + pa_log_warn("POSIX_FADV_WILLNEED failed: %s", pa_cstrerror(errno)); + goto fail; + } else + pa_log_debug("POSIX_FADV_WILLNEED succeeded."); + + if (!(u->sndfile = sf_open_fd(fd, SFM_READ, &sfinfo, 1))) { pa_log("Failed to open file %s", fname); + close(fd); goto fail; } -- cgit From 41d67c40d9603228f3bd1a748fa774e49ff50c3e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 5 Aug 2007 13:52:01 +0000 Subject: minor optimization for cacheing in of samples by using posix_fadvise git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1578 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sound-file.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/sound-file.c b/src/pulsecore/sound-file.c index 416ae93e..7c8b5970 100644 --- a/src/pulsecore/sound-file.c +++ b/src/pulsecore/sound-file.c @@ -26,12 +26,16 @@ #endif #include +#include +#include +#include #include #include #include #include +#include #include "sound-file.h" #include "core-scache.h" @@ -49,6 +53,7 @@ int pa_sound_file_load( size_t l; sf_count_t (*readf_function)(SNDFILE *sndfile, void *ptr, sf_count_t frames) = NULL; void *ptr = NULL; + int fd; pa_assert(fname); pa_assert(ss); @@ -57,8 +62,20 @@ int pa_sound_file_load( pa_memchunk_reset(chunk); memset(&sfinfo, 0, sizeof(sfinfo)); - if (!(sf = sf_open(fname, SFM_READ, &sfinfo))) { + if ((fd = open(fname, O_RDONLY|O_NOCTTY)) < 0) { + pa_log("Failed to open file %s: %s", fname, pa_cstrerror(errno)); + goto finish; + } + + if (posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL) < 0) { + pa_log_warn("POSIX_FADV_SEQUENTIAL failed: %s", pa_cstrerror(errno)); + goto finish; + } else + pa_log_debug("POSIX_FADV_SEQUENTIAL succeeded."); + + if (!(sf = sf_open_fd(fd, SFM_READ, &sfinfo, 1))) { pa_log("Failed to open file %s", fname); + close(fd); goto finish; } -- cgit From 67753869830914f6a25a11460405929741776b61 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 5 Aug 2007 14:06:47 +0000 Subject: make sure to handle disconnecting our own connection properly git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1579 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-native.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 2396a38d..89849858 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -2298,6 +2298,8 @@ static void command_kill(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint3 client = pa_idxset_get_by_index(c->protocol->core->clients, idx); CHECK_VALIDITY(c->pstream, client, tag, PA_ERR_NOENTITY); + + connection_ref(c); pa_client_kill(client); } else if (command == PA_COMMAND_KILL_SINK_INPUT) { @@ -2306,6 +2308,7 @@ static void command_kill(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint3 s = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx); CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); + connection_ref(c); pa_sink_input_kill(s); } else { pa_source_output *s; @@ -2315,10 +2318,12 @@ static void command_kill(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint3 s = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx); CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); + connection_ref(c); pa_source_output_kill(s); } pa_pstream_send_simple_ack(c->pstream, tag); + connection_unref(c); } static void command_load_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { -- cgit From c306b835255e576e46194c47782939b6f915ae3a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 6 Aug 2007 16:12:54 +0000 Subject: initialize 'length' properly git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1580 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/pstream.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c index 0ffa583a..c88f9aad 100644 --- a/src/pulsecore/pstream.c +++ b/src/pulsecore/pstream.c @@ -347,7 +347,8 @@ void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa return; idx = 0; - + length = chunk->length; + while (length > 0) { struct item_info *i; size_t n; -- cgit From 62790ccdb4ee529974315c45e11714d56f2a9afa Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 6 Aug 2007 16:13:32 +0000 Subject: fix playback over native protocol git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1581 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-native.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 89849858..4d7dd634 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -321,8 +321,8 @@ static void upload_stream_unlink(upload_stream *s) { return; pa_assert_se(pa_idxset_remove_by_data(s->connection->output_streams, s, NULL) == s); - upload_stream_unref(s); s->connection = NULL; + upload_stream_unref(s); } static void upload_stream_free(pa_object *o) { @@ -379,8 +379,8 @@ static void record_stream_unlink(record_stream *s) { } pa_assert_se(pa_idxset_remove_by_data(s->connection->record_streams, s, NULL) == s); - record_stream_unref(s); s->connection = NULL; + record_stream_unref(s); } static void record_stream_free(pa_object *o) { @@ -496,8 +496,8 @@ static void playback_stream_unlink(playback_stream *s) { pa_pstream_send_error(s->connection->pstream, s->drain_tag, PA_ERR_NOENTITY); pa_assert_se(pa_idxset_remove_by_data(s->connection->output_streams, s, NULL) == s); - playback_stream_unref(s); s->connection = NULL; + playback_stream_unref(s); } static void playback_stream_free(pa_object* o) { @@ -531,7 +531,7 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata, pa_tagstruct_putu32(t, l); pa_pstream_send_tagstruct(s->connection->pstream, t); - /* pa_log("Requesting %u bytes", l); */ +/* pa_log("Requesting %u bytes", l); */ break; } @@ -729,16 +729,22 @@ static void connection_free(pa_object *o) { static void request_bytes(playback_stream *s) { size_t new_missing, delta, previous_missing; + +/* pa_log("request_bytes()"); */ playback_stream_assert_ref(s); new_missing = pa_memblockq_missing(s->memblockq); - - if (new_missing <= s->last_missing) + + if (new_missing <= s->last_missing) { + s->last_missing = new_missing; return; + } delta = new_missing - s->last_missing; s->last_missing = new_missing; +/* pa_log("request_bytes(%u)", delta); */ + previous_missing = pa_atomic_add(&s->missing, delta); if (previous_missing < pa_memblockq_get_minreq(s->memblockq) && previous_missing+delta >= pa_memblockq_get_minreq(s->memblockq)) pa_asyncmsgq_post(s->connection->protocol->core->asyncmsgq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); @@ -812,6 +818,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int case SINK_INPUT_MESSAGE_SEEK: pa_memblockq_seek(s->memblockq, offset, PA_PTR_TO_UINT(userdata)); + request_bytes(s); return 0; case SINK_INPUT_MESSAGE_POST_DATA: { @@ -824,6 +831,8 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int pa_memblockq_seek(s->memblockq, chunk->length, PA_SEEK_RELATIVE); } + request_bytes(s); + s->underrun = 0; return 0; } @@ -838,6 +847,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int s->drain_tag = PA_PTR_TO_UINT(userdata); s->drain_request = 1; } + request_bytes(s); return 0; } @@ -891,6 +901,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int case PA_SINK_INPUT_MESSAGE_SET_STATE: pa_memblockq_prebuf_force(s->memblockq); + request_bytes(s); break; case PA_SINK_INPUT_MESSAGE_GET_LATENCY: { @@ -921,11 +932,13 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { } if (pa_memblockq_peek(s->memblockq, chunk) < 0) { -/* pa_log("peek: failure"); */ +/* pa_log("peek: failure"); */ return -1; } -/* pa_log("peek: %u", chunk->length); */ +/* pa_log("peek: %u", chunk->length); */ + + request_bytes(s); return 0; } @@ -1083,6 +1096,8 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC pa_tagstruct_putu32(reply, s->sink_input->index); pa_tagstruct_putu32(reply, missing); +/* pa_log("initial request is %u", missing); */ + if (c->version >= 9) { /* Since 0.9 we support sending the buffer metrics back to the client */ @@ -2158,11 +2173,11 @@ static void command_trigger_or_flush_or_prebuf_playback_stream(PA_GCC_UNUSED pa_ break; case PA_COMMAND_PREBUF_PLAYBACK_STREAM: - pa_asyncmsgq_send(s->sink_input->sink->asyncmsgq, PA_MSGOBJECT(s->sink_input), SINK_INPUT_MESSAGE_TRIGGER, NULL, 0, NULL); + pa_asyncmsgq_send(s->sink_input->sink->asyncmsgq, PA_MSGOBJECT(s->sink_input), SINK_INPUT_MESSAGE_PREBUF_FORCE, NULL, 0, NULL); break; case PA_COMMAND_TRIGGER_PLAYBACK_STREAM: - pa_asyncmsgq_send(s->sink_input->sink->asyncmsgq, PA_MSGOBJECT(s->sink_input), SINK_INPUT_MESSAGE_PREBUF_FORCE, NULL, 0, NULL); + pa_asyncmsgq_send(s->sink_input->sink->asyncmsgq, PA_MSGOBJECT(s->sink_input), SINK_INPUT_MESSAGE_TRIGGER, NULL, 0, NULL); break; default: -- cgit From 455ff8d342a914f29971dfc7b2c48f9cf09c0f1b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 6 Aug 2007 17:37:59 +0000 Subject: fix a memory leak git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1582 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/pstream.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c index c88f9aad..ea238805 100644 --- a/src/pulsecore/pstream.c +++ b/src/pulsecore/pstream.c @@ -274,7 +274,7 @@ pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_mempool *poo return p; } -static void item_free(void *item, PA_GCC_UNUSED void *p) { +static void item_free(void *item, PA_GCC_UNUSED void *q) { struct item_info *i = item; pa_assert(i); @@ -299,15 +299,15 @@ static void pstream_free(pa_pstream *p) { if (p->write.current) item_free(p->write.current, NULL); + if (p->write.memchunk.memblock) + pa_memblock_unref(p->write.memchunk.memblock); + if (p->read.memblock) pa_memblock_unref(p->read.memblock); if (p->read.packet) pa_packet_unref(p->read.packet); - if (p->write.memchunk.memblock) - pa_memblock_unref(p->write.memchunk.memblock); - pa_xfree(p); } @@ -568,9 +568,14 @@ static int do_write(pa_pstream *p) { if (p->write.index >= PA_PSTREAM_DESCRIPTOR_SIZE + ntohl(p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH])) { pa_assert(p->write.current); - item_free(p->write.current, (void *) 1); + item_free(p->write.current, NULL); p->write.current = NULL; + if (p->write.memchunk.memblock) + pa_memblock_unref(p->write.memchunk.memblock); + + pa_memchunk_reset(&p->write.memchunk); + if (p->drain_callback && !pa_pstream_is_pending(p)) p->drain_callback(p, p->drain_callback_userdata); } -- cgit From 74b3b6d4538e46655d09a08041a5626b0a71d3a6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 6 Aug 2007 19:42:15 +0000 Subject: fix playback status querying git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1583 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-native.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 4d7dd634..d75815fa 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -1481,7 +1481,7 @@ static void command_get_playback_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ pa_tagstruct_put_usec(reply, latency); pa_tagstruct_put_usec(reply, 0); - pa_tagstruct_put_boolean(reply, s->sink_input->state == PA_SINK_INPUT_RUNNING); + pa_tagstruct_put_boolean(reply, pa_sink_input_get_state(s->sink_input) == PA_SINK_INPUT_RUNNING); pa_tagstruct_put_timeval(reply, &tv); pa_tagstruct_put_timeval(reply, pa_gettimeofday(&now)); pa_tagstruct_puts64(reply, pa_memblockq_get_write_index(s->memblockq)); -- cgit From 243f2fc20a4a69739b347a7da6ae4bf10fc3450b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 6 Aug 2007 21:47:29 +0000 Subject: minor fixes and cleanups git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1584 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-native.c | 5 ++--- src/pulsecore/protocol-simple.c | 35 +++++++++++++++++++---------------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index d75815fa..bd1605b1 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -2710,7 +2710,8 @@ static void on_connection(PA_GCC_UNUSED pa_socket_server*s, pa_iochannel *io, vo pa_protocol_native *p = userdata; connection *c; char cname[256], pname[128]; - + + pa_assert(s); pa_assert(io); pa_assert(p); @@ -2742,9 +2743,7 @@ static void on_connection(PA_GCC_UNUSED pa_socket_server*s, pa_iochannel *io, vo c->protocol = p; pa_iochannel_socket_peer_to_string(io, pname, sizeof(pname)); pa_snprintf(cname, sizeof(cname), "Native client (%s)", pname); - pa_assert(p->core); c->client = pa_client_new(p->core, __FILE__, cname); - pa_assert(c->client); c->client->kill = client_kill_cb; c->client->userdata = c; c->client->owner = p->module; diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index 0ded5d26..dd61c7ee 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -93,7 +93,7 @@ enum { enum { CONNECTION_MESSAGE_REQUEST_DATA, /* data requested from sink input from the main loop */ CONNECTION_MESSAGE_POST_DATA, /* data from source output to main loop */ - CONNECTION_MESSAGE_DROP_CONNECTION /* Please drop a aconnection now */ + CONNECTION_MESSAGE_UNLINK_CONNECTION /* Please drop a aconnection now */ }; @@ -125,6 +125,11 @@ static void connection_unlink(connection *c) { c->client = NULL; } + if (c->io) { + pa_iochannel_free(c->io); + c->io = NULL; + } + pa_assert_se(pa_idxset_remove_by_data(c->protocol->connections, c, NULL) == c); c->protocol = NULL; connection_unref(c); @@ -139,8 +144,6 @@ static void connection_free(pa_object *o) { if (c->playback.current_memblock) pa_memblock_unref(c->playback.current_memblock); - if (c->io) - pa_iochannel_free(c->io); if (c->input_memblockq) pa_memblockq_free(c->input_memblockq); if (c->output_memblockq) @@ -155,7 +158,7 @@ static int do_read(connection *c) { size_t l; void *p; - pa_assert(c); + connection_assert_ref(c); if (!c->sink_input || (l = pa_atomic_load(&c->playback.missing)) <= 0) return 0; @@ -205,7 +208,7 @@ static int do_write(connection *c) { ssize_t r; void *p; - pa_assert(c); + connection_assert_ref(c); if (!c->source_output) return 0; @@ -239,7 +242,7 @@ static int do_write(connection *c) { } static void do_work(connection *c) { - pa_assert(c); + connection_assert_ref(c); if (c->dead) return; @@ -287,7 +290,7 @@ static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int6 do_work(c); break; - case CONNECTION_MESSAGE_DROP_CONNECTION: + case CONNECTION_MESSAGE_UNLINK_CONNECTION: connection_unlink(c); break; } @@ -340,12 +343,12 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int /* Called from thread context */ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { - connection*c; + connection *c; int r; pa_assert(i); - c = i->userdata; - pa_assert(c); + c = CONNECTION(i->userdata); + connection_assert_ref(c); pa_assert(chunk); r = pa_memblockq_peek(c->input_memblockq, chunk); @@ -353,18 +356,19 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { /* pa_log("peeked %u %i", r >= 0 ? chunk->length: 0, r); */ if (c->dead && r < 0) - pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_DROP_CONNECTION, NULL, 0, NULL, NULL); + pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_UNLINK_CONNECTION, NULL, 0, NULL, NULL); return r; } /* Called from thread context */ static void sink_input_drop_cb(pa_sink_input *i, size_t length) { - connection*c = i->userdata; + connection *c; size_t old, new; pa_assert(i); - pa_assert(c); + c = CONNECTION(i->userdata); + connection_assert_ref(c); pa_assert(length); old = pa_memblockq_missing(c->input_memblockq); @@ -391,7 +395,7 @@ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) connection *c; pa_assert(o); - c = o->userdata; + c = CONNECTION(o->userdata); pa_assert(c); pa_assert(chunk); @@ -433,8 +437,8 @@ static void client_kill_cb(pa_client *client) { static void io_callback(pa_iochannel*io, void *userdata) { connection *c = CONNECTION(userdata); + connection_assert_ref(c); pa_assert(io); - pa_assert(c); do_work(c); } @@ -507,7 +511,6 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) (size_t) -1, l/PLAYBACK_BUFFER_FRAGMENTS, NULL); - pa_assert(c->input_memblockq); pa_iochannel_socket_set_rcvbuf(io, l/PLAYBACK_BUFFER_FRAGMENTS*5); c->playback.fragment_size = l/PLAYBACK_BUFFER_FRAGMENTS; -- cgit From 1f9ce59969e5e778f3baa287fa9c7918fde1b0c9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 6 Aug 2007 21:47:53 +0000 Subject: port esound protocol to new lock-free core git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1585 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 81 +++--- src/pulsecore/protocol-esound.c | 555 +++++++++++++++++++++++++--------------- 2 files changed, 392 insertions(+), 244 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 8fc0f19c..0f2cdecc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -723,9 +723,8 @@ modlibexec_LTLIBRARIES = \ libstrlist.la \ libprotocol-simple.la \ libprotocol-http.la \ - libprotocol-native.la - -# libprotocol-esound.la + libprotocol-native.la \ + libprotocol-esound.la # We need to emulate sendmsg/recvmsg to support this on Win32 if !OS_IS_WIN32 @@ -881,8 +880,8 @@ modlibexec_LTLIBRARIES += \ module-http-protocol-tcp.la \ module-sine.la \ module-native-protocol-tcp.la \ - module-native-protocol-fd.la -# module-esound-protocol-tcp.la \ + module-native-protocol-fd.la \ + module-esound-protocol-tcp.la # module-combine.la \ # module-tunnel-sink.la \ # module-tunnel-source.la \ @@ -900,8 +899,8 @@ modlibexec_LTLIBRARIES += \ module-cli-protocol-unix.la \ module-simple-protocol-unix.la \ module-http-protocol-unix.la \ - module-native-protocol-unix.la -# module-esound-protocol-unix.la + module-native-protocol-unix.la \ + module-esound-protocol-unix.la endif if HAVE_MKFIFO @@ -910,11 +909,11 @@ modlibexec_LTLIBRARIES += \ module-pipe-source.la endif -#if !OS_IS_WIN32 -#modlibexec_LTLIBRARIES += \ -# module-esound-compat-spawnfd.la \ -# module-esound-compat-spawnpid.la -#endif +if !OS_IS_WIN32 +modlibexec_LTLIBRARIES += \ + module-esound-compat-spawnfd.la \ + module-esound-compat-spawnpid.la +endif if HAVE_REGEX modlibexec_LTLIBRARIES += \ @@ -940,10 +939,10 @@ modlibexec_LTLIBRARIES += \ module-alsa-source.la endif -if HAVE_SOLARIS -modlibexec_LTLIBRARIES += \ - module-solaris.la -endif +#if HAVE_SOLARIS +#modlibexec_LTLIBRARIES += \ +# module-solaris.la +#endif if HAVE_AVAHI modlibexec_LTLIBRARIES += \ @@ -974,10 +973,10 @@ pulselibexec_PROGRAMS = \ gconf-helper endif -if OS_IS_WIN32 -modlibexec_LTLIBRARIES += \ - module-waveout.la -endif +#if OS_IS_WIN32 +#modlibexec_LTLIBRARIES += \ +# module-waveout.la +#endif if HAVE_HAL modlibexec_LTLIBRARIES += \ @@ -1099,23 +1098,23 @@ module_native_protocol_fd_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-n # EsounD protocol -#module_esound_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c -#module_esound_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_ESOUND $(AM_CFLAGS) -#module_esound_protocol_tcp_la_LDFLAGS = -module -avoid-version -#module_esound_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-esound.la libsocket-server.la +module_esound_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c +module_esound_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_ESOUND $(AM_CFLAGS) +module_esound_protocol_tcp_la_LDFLAGS = -module -avoid-version +module_esound_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-esound.la libsocket-server.la -#module_esound_protocol_unix_la_SOURCES = modules/module-protocol-stub.c -#module_esound_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_ESOUND $(AM_CFLAGS) -#module_esound_protocol_unix_la_LDFLAGS = -module -avoid-version -#module_esound_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-esound.la libsocket-server.la libsocket-util.la +module_esound_protocol_unix_la_SOURCES = modules/module-protocol-stub.c +module_esound_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_ESOUND $(AM_CFLAGS) +module_esound_protocol_unix_la_LDFLAGS = -module -avoid-version +module_esound_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-esound.la libsocket-server.la libsocket-util.la -#module_esound_compat_spawnfd_la_SOURCES = modules/module-esound-compat-spawnfd.c -#module_esound_compat_spawnfd_la_LDFLAGS = -module -avoid-version -#module_esound_compat_spawnfd_la_LIBADD = $(AM_LIBADD) libpulsecore.la +module_esound_compat_spawnfd_la_SOURCES = modules/module-esound-compat-spawnfd.c +module_esound_compat_spawnfd_la_LDFLAGS = -module -avoid-version +module_esound_compat_spawnfd_la_LIBADD = $(AM_LIBADD) libpulsecore.la -#module_esound_compat_spawnpid_la_SOURCES = modules/module-esound-compat-spawnpid.c -#module_esound_compat_spawnpid_la_LDFLAGS = -module -avoid-version -#module_esound_compat_spawnpid_la_LIBADD = $(AM_LIBADD) libpulsecore.la +module_esound_compat_spawnpid_la_SOURCES = modules/module-esound-compat-spawnpid.c +module_esound_compat_spawnpid_la_LDFLAGS = -module -avoid-version +module_esound_compat_spawnpid_la_LIBADD = $(AM_LIBADD) libpulsecore.la #module_esound_sink_la_SOURCES = modules/module-esound-sink.c #module_esound_sink_la_LDFLAGS = -module -avoid-version @@ -1201,9 +1200,9 @@ module_alsa_source_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) # Solaris -module_solaris_la_SOURCES = modules/module-solaris.c -module_solaris_la_LDFLAGS = -module -avoid-version -module_solaris_la_LIBADD = $(AM_LIBADD) libiochannel.la +#module_solaris_la_SOURCES = modules/module-solaris.c +#module_solaris_la_LDFLAGS = -module -avoid-version +#module_solaris_la_LIBADD = $(AM_LIBADD) libiochannel.la # Avahi @@ -1228,10 +1227,10 @@ module_mmkbd_evdev_la_CFLAGS = $(AM_CFLAGS) # Windows waveout -module_waveout_la_SOURCES = modules/module-waveout.c -module_waveout_la_LDFLAGS = -module -avoid-version -module_waveout_la_LIBADD = $(AM_LIBADD) libpulsecore.la -lwinmm -module_waveout_la_CFLAGS = $(AM_CFLAGS) +#module_waveout_la_SOURCES = modules/module-waveout.c +#module_waveout_la_LDFLAGS = -module -avoid-version +#module_waveout_la_LIBADD = $(AM_LIBADD) libpulsecore.la -lwinmm +#module_waveout_la_CFLAGS = $(AM_CFLAGS) # Hardware autodetection module module_detect_la_SOURCES = modules/module-detect.c diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c index fe0b879b..74607146 100644 --- a/src/pulsecore/protocol-esound.c +++ b/src/pulsecore/protocol-esound.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -53,6 +52,7 @@ #include #include #include +#include #include "endianmacros.h" @@ -77,7 +77,9 @@ /* This is heavily based on esound's code */ -struct connection { +typedef struct connection { + pa_msgobject parent; + uint32_t index; int dead; pa_protocol_esound *protocol; @@ -100,6 +102,7 @@ struct connection { struct { pa_memblock *current_memblock; size_t memblock_index, fragment_size; + pa_atomic_t missing; } playback; struct { @@ -109,46 +112,62 @@ struct connection { } scache; pa_time_event *auth_timeout_event; -}; +} connection; + +PA_DECLARE_CLASS(connection); +#define CONNECTION(o) (connection_cast(o)) +static PA_DEFINE_CHECK_TYPE(connection, pa_msgobject); struct pa_protocol_esound { - int public; pa_module *module; pa_core *core; + int public; pa_socket_server *server; pa_idxset *connections; + char *sink_name, *source_name; unsigned n_player; uint8_t esd_key[ESD_KEY_LEN]; pa_ip_acl *auth_ip_acl; }; +enum { + SINK_INPUT_MESSAGE_POST_DATA = PA_SINK_INPUT_MESSAGE_MAX, /* data from main loop to sink input */ + SINK_INPUT_MESSAGE_DISABLE_PREBUF +}; + +enum { + CONNECTION_MESSAGE_REQUEST_DATA, + CONNECTION_MESSAGE_POST_DATA, + CONNECTION_MESSAGE_UNLINK_CONNECTION +}; + typedef struct proto_handler { size_t data_length; - int (*proc)(struct connection *c, esd_proto_t request, const void *data, size_t length); + int (*proc)(connection *c, esd_proto_t request, const void *data, size_t length); const char *description; } esd_proto_handler_info_t; -static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_t length); +static void sink_input_drop_cb(pa_sink_input *i, size_t length); static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk); static void sink_input_kill_cb(pa_sink_input *i); -static pa_usec_t sink_input_get_latency_cb(pa_sink_input *i); +static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk); static pa_usec_t source_output_get_latency_cb(pa_source_output *o); static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk); static void source_output_kill_cb(pa_source_output *o); -static int esd_proto_connect(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_stream_play(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_stream_record(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_get_latency(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_server_info(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_all_info(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_stream_pan(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_sample_cache(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_sample_free_or_play(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_sample_get_id(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_standby_or_resume(struct connection *c, esd_proto_t request, const void *data, size_t length); +static int esd_proto_connect(connection *c, esd_proto_t request, const void *data, size_t length); +static int esd_proto_stream_play(connection *c, esd_proto_t request, const void *data, size_t length); +static int esd_proto_stream_record(connection *c, esd_proto_t request, const void *data, size_t length); +static int esd_proto_get_latency(connection *c, esd_proto_t request, const void *data, size_t length); +static int esd_proto_server_info(connection *c, esd_proto_t request, const void *data, size_t length); +static int esd_proto_all_info(connection *c, esd_proto_t request, const void *data, size_t length); +static int esd_proto_stream_pan(connection *c, esd_proto_t request, const void *data, size_t length); +static int esd_proto_sample_cache(connection *c, esd_proto_t request, const void *data, size_t length); +static int esd_proto_sample_free_or_play(connection *c, esd_proto_t request, const void *data, size_t length); +static int esd_proto_sample_get_id(connection *c, esd_proto_t request, const void *data, size_t length); +static int esd_proto_standby_or_resume(connection *c, esd_proto_t request, const void *data, size_t length); /* the big map of protocol handler info */ static struct proto_handler proto_map[ESD_PROTO_MAX] = { @@ -185,25 +204,56 @@ static struct proto_handler proto_map[ESD_PROTO_MAX] = { { 0, esd_proto_get_latency, "get latency" } }; -static void connection_free(struct connection *c) { - assert(c); - pa_idxset_remove_by_data(c->protocol->connections, c, NULL); - - if (c->state == ESD_STREAMING_DATA) - c->protocol->n_player--; +static void connection_unlink(connection *c) { + pa_assert(c); - pa_client_free(c->client); + if (!c->protocol) + return; if (c->sink_input) { pa_sink_input_disconnect(c->sink_input); pa_sink_input_unref(c->sink_input); + c->sink_input = NULL; } if (c->source_output) { pa_source_output_disconnect(c->source_output); pa_source_output_unref(c->source_output); + c->source_output = NULL; } + if (c->client) { + pa_client_free(c->client); + c->client = NULL; + } + + if (c->state == ESD_STREAMING_DATA) + c->protocol->n_player--; + + if (c->io) { + pa_iochannel_free(c->io); + c->io = NULL; + } + + if (c->defer_event) { + c->protocol->core->mainloop->defer_free(c->defer_event); + c->defer_event = NULL; + } + + if (c->auth_timeout_event) { + c->protocol->core->mainloop->time_free(c->auth_timeout_event); + c->auth_timeout_event = NULL; + } + + pa_assert_se(pa_idxset_remove_by_data(c->protocol->connections, c, NULL) == c); + c->protocol = NULL; + connection_unref(c); +} + +static void connection_free(pa_object *obj) { + connection *c = CONNECTION(obj); + pa_assert(c); + if (c->input_memblockq) pa_memblockq_free(c->input_memblockq); if (c->output_memblockq) @@ -215,54 +265,44 @@ static void connection_free(struct connection *c) { pa_xfree(c->read_data); pa_xfree(c->write_data); - if (c->io) - pa_iochannel_free(c->io); - - if (c->defer_event) - c->protocol->core->mainloop->defer_free(c->defer_event); - if (c->scache.memchunk.memblock) pa_memblock_unref(c->scache.memchunk.memblock); pa_xfree(c->scache.name); - if (c->auth_timeout_event) - c->protocol->core->mainloop->time_free(c->auth_timeout_event); - pa_xfree(c->original_name); pa_xfree(c); } -static void connection_write_prepare(struct connection *c, size_t length) { +static void connection_write_prepare(connection *c, size_t length) { size_t t; - assert(c); + pa_assert(c); t = c->write_data_length+length; if (c->write_data_alloc < t) c->write_data = pa_xrealloc(c->write_data, c->write_data_alloc = t); - assert(c->write_data); + pa_assert(c->write_data); } -static void connection_write(struct connection *c, const void *data, size_t length) { +static void connection_write(connection *c, const void *data, size_t length) { size_t i; - assert(c); + pa_assert(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, 1); connection_write_prepare(c, length); - assert(c->write_data); + pa_assert(c->write_data); i = c->write_data_length; c->write_data_length += length; - memcpy((char*)c->write_data + i, data, length); + memcpy((uint8_t*) c->write_data + i, data, length); } static void format_esd2native(int format, int swap_bytes, pa_sample_spec *ss) { - assert(ss); + pa_assert(ss); ss->channels = ((format & ESD_MASK_CHAN) == ESD_STEREO) ? 2 : 1; if ((format & ESD_MASK_BITS) == ESD_BITS16) @@ -289,11 +329,13 @@ static int format_native2esd(pa_sample_spec *ss) { /*** esound commands ***/ -static int esd_proto_connect(struct connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_connect(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { uint32_t ekey; int ok; - assert(length == (ESD_KEY_LEN + sizeof(uint32_t))); + connection_assert_ref(c); + pa_assert(data); + pa_assert(length == (ESD_KEY_LEN + sizeof(uint32_t))); if (!c->authorized) { if (memcmp(data, c->protocol->esd_key, ESD_KEY_LEN) != 0) { @@ -316,7 +358,7 @@ static int esd_proto_connect(struct connection *c, PA_GCC_UNUSED esd_proto_t req else if (ekey == ESD_SWAP_ENDIAN_KEY) c->swap_byte_order = 1; else { - pa_log("client sent invalid endian key"); + pa_log_warn("Client sent invalid endian key"); return -1; } @@ -325,7 +367,7 @@ static int esd_proto_connect(struct connection *c, PA_GCC_UNUSED esd_proto_t req return 0; } -static int esd_proto_stream_play(struct connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_stream_play(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { char name[ESD_NAME_MAX], *utf8_name; int32_t format, rate; pa_sample_spec ss; @@ -333,15 +375,17 @@ static int esd_proto_stream_play(struct connection *c, PA_GCC_UNUSED esd_proto_t pa_sink *sink = NULL; pa_sink_input_new_data sdata; - assert(c && length == (sizeof(int32_t)*2+ESD_NAME_MAX)); + connection_assert_ref(c); + pa_assert(data); + pa_assert(length == (sizeof(int32_t)*2+ESD_NAME_MAX)); memcpy(&format, data, sizeof(int32_t)); format = MAYBE_INT32_SWAP(c->swap_byte_order, format); - data = (const char*)data + sizeof(int32_t); + data = (const char*) data + sizeof(int32_t); memcpy(&rate, data, sizeof(int32_t)); rate = MAYBE_INT32_SWAP(c->swap_byte_order, rate); - data = (const char*)data + sizeof(int32_t); + data = (const char*) data + sizeof(int32_t); ss.rate = rate; format_esd2native(format, c->swap_byte_order, &ss); @@ -362,7 +406,7 @@ static int esd_proto_stream_play(struct connection *c, PA_GCC_UNUSED esd_proto_t c->original_name = pa_xstrdup(name); - assert(!c->sink_input && !c->input_memblockq); + pa_assert(!c->sink_input && !c->input_memblockq); pa_sink_input_new_data_init(&sdata); sdata.sink = sink; @@ -385,22 +429,26 @@ static int esd_proto_stream_play(struct connection *c, PA_GCC_UNUSED esd_proto_t l/PLAYBACK_BUFFER_FRAGMENTS, NULL); pa_iochannel_socket_set_rcvbuf(c->io, l/PLAYBACK_BUFFER_FRAGMENTS*2); - c->playback.fragment_size = l/10; + c->playback.fragment_size = l/PLAYBACK_BUFFER_FRAGMENTS; + c->sink_input->parent.process_msg = sink_input_process_msg; c->sink_input->peek = sink_input_peek_cb; c->sink_input->drop = sink_input_drop_cb; c->sink_input->kill = sink_input_kill_cb; - c->sink_input->get_latency = sink_input_get_latency_cb; c->sink_input->userdata = c; c->state = ESD_STREAMING_DATA; c->protocol->n_player++; + pa_atomic_store(&c->playback.missing, pa_memblockq_missing(c->input_memblockq)); + + pa_sink_input_put(c->sink_input); + return 0; } -static int esd_proto_stream_record(struct connection *c, esd_proto_t request, const void *data, size_t length) { +static int esd_proto_stream_record(connection *c, esd_proto_t request, const void *data, size_t length) { char name[ESD_NAME_MAX], *utf8_name; int32_t format, rate; pa_source *source = NULL; @@ -408,15 +456,17 @@ static int esd_proto_stream_record(struct connection *c, esd_proto_t request, co size_t l; pa_source_output_new_data sdata; - assert(c && length == (sizeof(int32_t)*2+ESD_NAME_MAX)); + connection_assert_ref(c); + pa_assert(data); + pa_assert(length == (sizeof(int32_t)*2+ESD_NAME_MAX)); memcpy(&format, data, sizeof(int32_t)); format = MAYBE_INT32_SWAP(c->swap_byte_order, format); - data = (const char*)data + sizeof(int32_t); + data = (const char*) data + sizeof(int32_t); memcpy(&rate, data, sizeof(int32_t)); rate = MAYBE_INT32_SWAP(c->swap_byte_order, rate); - data = (const char*)data + sizeof(int32_t); + data = (const char*) data + sizeof(int32_t); ss.rate = rate; format_esd2native(format, c->swap_byte_order, &ss); @@ -436,7 +486,7 @@ static int esd_proto_stream_record(struct connection *c, esd_proto_t request, co return -1; } } else { - assert(request == ESD_PROTO_STREAM_REC); + pa_assert(request == ESD_PROTO_STREAM_REC); if (c->protocol->source_name) { if (!(source = pa_namereg_get(c->protocol->core, c->protocol->source_name, PA_NAMEREG_SOURCE, 1))) { @@ -455,7 +505,7 @@ static int esd_proto_stream_record(struct connection *c, esd_proto_t request, co c->original_name = pa_xstrdup(name); - assert(!c->output_memblockq && !c->source_output); + pa_assert(!c->output_memblockq && !c->source_output); pa_source_output_new_data_init(&sdata); sdata.source = source; @@ -488,14 +538,18 @@ static int esd_proto_stream_record(struct connection *c, esd_proto_t request, co c->protocol->n_player++; + pa_source_output_put(c->source_output); + return 0; } -static int esd_proto_get_latency(struct connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_get_latency(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { pa_sink *sink; int32_t latency; - assert(c && !data && length == 0); + connection_ref(c); + pa_assert(!data); + pa_assert(length == 0); if (!(sink = pa_namereg_get(c->protocol->core, c->protocol->sink_name, PA_NAMEREG_SINK, 1))) latency = 0; @@ -509,12 +563,14 @@ static int esd_proto_get_latency(struct connection *c, PA_GCC_UNUSED esd_proto_t return 0; } -static int esd_proto_server_info(struct connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_server_info(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { int32_t rate = 44100, format = ESD_STEREO|ESD_BITS16; int32_t response; pa_sink *sink; - assert(c && data && length == sizeof(int32_t)); + connection_ref(c); + pa_assert(data); + pa_assert(length == sizeof(int32_t)); if ((sink = pa_namereg_get(c->protocol->core, c->protocol->sink_name, PA_NAMEREG_SINK, 1))) { rate = sink->sample_spec.rate; @@ -533,14 +589,16 @@ static int esd_proto_server_info(struct connection *c, PA_GCC_UNUSED esd_proto_t return 0; } -static int esd_proto_all_info(struct connection *c, esd_proto_t request, const void *data, size_t length) { +static int esd_proto_all_info(connection *c, esd_proto_t request, const void *data, size_t length) { size_t t, k, s; - struct connection *conn; + connection *conn; uint32_t idx = PA_IDXSET_INVALID; unsigned nsamples; char terminator[sizeof(int32_t)*6+ESD_NAME_MAX]; - assert(c && data && length == sizeof(int32_t)); + connection_ref(c); + pa_assert(data); + pa_assert(length == sizeof(int32_t)); if (esd_proto_server_info(c, request, data, length) < 0) return -1; @@ -561,7 +619,7 @@ static int esd_proto_all_info(struct connection *c, esd_proto_t request, const v if (conn->state != ESD_STREAMING_DATA) continue; - assert(t >= k*2+s); + pa_assert(t >= k*2+s); if (conn->sink_input) { pa_cvolume volume = *pa_sink_input_get_volume(conn->sink_input); @@ -602,7 +660,7 @@ static int esd_proto_all_info(struct connection *c, esd_proto_t request, const v t -= k; } - assert(t == s*(nsamples+1)+k); + pa_assert(t == s*(nsamples+1)+k); t -= k; connection_write(c, terminator, k); @@ -615,7 +673,7 @@ static int esd_proto_all_info(struct connection *c, esd_proto_t request, const v int32_t id, rate, lvolume, rvolume, format, len; char name[ESD_NAME_MAX]; - assert(t >= s*2); + pa_assert(t >= s*2); /* id */ id = MAYBE_INT32_SWAP(c->swap_byte_order, (int) (ce->index+1)); @@ -653,19 +711,21 @@ static int esd_proto_all_info(struct connection *c, esd_proto_t request, const v } } - assert(t == s); + pa_assert(t == s); connection_write(c, terminator, s); return 0; } -static int esd_proto_stream_pan(struct connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_stream_pan(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { int32_t ok; uint32_t idx, lvolume, rvolume; - struct connection *conn; + connection *conn; - assert(c && data && length == sizeof(int32_t)*3); + connection_assert_ref(c); + pa_assert(data); + pa_assert(length == sizeof(int32_t)*3); memcpy(&idx, data, sizeof(uint32_t)); idx = MAYBE_UINT32_SWAP(c->swap_byte_order, idx) - 1; @@ -694,13 +754,15 @@ static int esd_proto_stream_pan(struct connection *c, PA_GCC_UNUSED esd_proto_t return 0; } -static int esd_proto_sample_cache(struct connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_sample_cache(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { pa_sample_spec ss; int32_t format, rate, sc_length; uint32_t idx; char name[ESD_NAME_MAX+sizeof(SCACHE_PREFIX)-1]; - assert(c && data && length == (ESD_NAME_MAX+3*sizeof(int32_t))); + connection_assert_ref(c); + pa_assert(data); + pa_assert(length == (ESD_NAME_MAX+3*sizeof(int32_t))); memcpy(&format, data, sizeof(int32_t)); format = MAYBE_INT32_SWAP(c->swap_byte_order, format); @@ -727,12 +789,12 @@ static int esd_proto_sample_cache(struct connection *c, PA_GCC_UNUSED esd_proto_ CHECK_VALIDITY(pa_utf8_valid(name), "Invalid UTF8 in sample name."); - assert(!c->scache.memchunk.memblock); + pa_assert(!c->scache.memchunk.memblock); c->scache.memchunk.memblock = pa_memblock_new(c->protocol->core->mempool, sc_length); c->scache.memchunk.index = 0; c->scache.memchunk.length = sc_length; c->scache.sample_spec = ss; - assert(!c->scache.name); + pa_assert(!c->scache.name); c->scache.name = pa_xstrdup(name); c->state = ESD_CACHING_SAMPLE; @@ -745,12 +807,14 @@ static int esd_proto_sample_cache(struct connection *c, PA_GCC_UNUSED esd_proto_ return 0; } -static int esd_proto_sample_get_id(struct connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { +static int esd_proto_sample_get_id(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { int32_t ok; uint32_t idx; char name[ESD_NAME_MAX+sizeof(SCACHE_PREFIX)-1]; - assert(c && data && length == ESD_NAME_MAX); + connection_assert_ref(c); + pa_assert(data); + pa_assert(length == ESD_NAME_MAX); strcpy(name, SCACHE_PREFIX); strncpy(name+sizeof(SCACHE_PREFIX)-1, data, ESD_NAME_MAX); @@ -767,12 +831,14 @@ static int esd_proto_sample_get_id(struct connection *c, PA_GCC_UNUSED esd_proto return 0; } -static int esd_proto_sample_free_or_play(struct connection *c, esd_proto_t request, const void *data, size_t length) { +static int esd_proto_sample_free_or_play(connection *c, esd_proto_t request, const void *data, size_t length) { int32_t ok; const char *name; uint32_t idx; - assert(c && data && length == sizeof(int32_t)); + connection_assert_ref(c); + pa_assert(data); + pa_assert(length == sizeof(int32_t)); memcpy(&idx, data, sizeof(uint32_t)); idx = MAYBE_UINT32_SWAP(c->swap_byte_order, idx) - 1; @@ -787,7 +853,7 @@ static int esd_proto_sample_free_or_play(struct connection *c, esd_proto_t reque if (pa_scache_play_item(c->protocol->core, name, sink, PA_VOLUME_NORM) >= 0) ok = idx + 1; } else { - assert(request == ESD_PROTO_SAMPLE_FREE); + pa_assert(request == ESD_PROTO_SAMPLE_FREE); if (pa_scache_remove_item(c->protocol->core, name) >= 0) ok = idx + 1; @@ -799,9 +865,11 @@ static int esd_proto_sample_free_or_play(struct connection *c, esd_proto_t reque return 0; } -static int esd_proto_standby_or_resume(struct connection *c, PA_GCC_UNUSED esd_proto_t request, PA_GCC_UNUSED const void *data, PA_GCC_UNUSED size_t length) { +static int esd_proto_standby_or_resume(connection *c, PA_GCC_UNUSED esd_proto_t request, PA_GCC_UNUSED const void *data, PA_GCC_UNUSED size_t length) { int32_t ok; + connection_assert_ref(c); + connection_write_prepare(c, sizeof(int32_t) * 2); ok = 1; @@ -814,20 +882,21 @@ static int esd_proto_standby_or_resume(struct connection *c, PA_GCC_UNUSED esd_p /*** client callbacks ***/ static void client_kill_cb(pa_client *c) { - assert(c && c->userdata); - connection_free(c->userdata); + pa_assert(c); + + connection_unlink(CONNECTION(c->userdata)); } /*** pa_iochannel callbacks ***/ -static int do_read(struct connection *c) { - assert(c && c->io); +static int do_read(connection *c) { + connection_assert_ref(c); /* pa_log("READ"); */ if (c->state == ESD_NEXT_REQUEST) { ssize_t r; - assert(c->read_data_length < sizeof(c->request)); + pa_assert(c->read_data_length < sizeof(c->request)); if ((r = pa_iochannel_read(c->io, ((uint8_t*) &c->request) + c->read_data_length, sizeof(c->request) - c->read_data_length)) <= 0) { pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); @@ -862,7 +931,7 @@ static int do_read(struct connection *c) { } else { if (c->read_data_alloc < handler->data_length) c->read_data = pa_xrealloc(c->read_data, c->read_data_alloc = handler->data_length); - assert(c->read_data); + pa_assert(c->read_data); c->state = ESD_NEEDS_REQDATA; c->read_data_length = 0; @@ -873,18 +942,21 @@ static int do_read(struct connection *c) { ssize_t r; struct proto_handler *handler = proto_map+c->request; - assert(handler->proc); + pa_assert(handler->proc); - assert(c->read_data && c->read_data_length < handler->data_length); + pa_assert(c->read_data && c->read_data_length < handler->data_length); if ((r = pa_iochannel_read(c->io, (uint8_t*) c->read_data + c->read_data_length, handler->data_length - c->read_data_length)) <= 0) { + if (errno == EINTR || errno == EAGAIN) + return 0; + pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); return -1; } if ((c->read_data_length += r) >= handler->data_length) { size_t l = c->read_data_length; - assert(handler->proc); + pa_assert(handler->proc); c->state = ESD_NEXT_REQUEST; c->read_data_length = 0; @@ -896,22 +968,24 @@ static int do_read(struct connection *c) { ssize_t r; void *p; - assert(c->scache.memchunk.memblock); - assert(c->scache.name); - assert(c->scache.memchunk.index < c->scache.memchunk.length); + pa_assert(c->scache.memchunk.memblock); + pa_assert(c->scache.name); + pa_assert(c->scache.memchunk.index < c->scache.memchunk.length); p = pa_memblock_acquire(c->scache.memchunk.memblock); - - if ((r = pa_iochannel_read(c->io, (uint8_t*) p+c->scache.memchunk.index, c->scache.memchunk.length-c->scache.memchunk.index)) <= 0) { - pa_memblock_release(c->scache.memchunk.memblock); + r = pa_iochannel_read(c->io, (uint8_t*) p+c->scache.memchunk.index, c->scache.memchunk.length-c->scache.memchunk.index); + pa_memblock_release(c->scache.memchunk.memblock); + + if (r <= 0) { + if (errno == EINTR || errno == EAGAIN) + return 0; + pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); return -1; } - pa_memblock_release(c->scache.memchunk.memblock); - c->scache.memchunk.index += r; - assert(c->scache.memchunk.index <= c->scache.memchunk.length); + pa_assert(c->scache.memchunk.index <= c->scache.memchunk.length); if (c->scache.memchunk.index == c->scache.memchunk.length) { uint32_t idx; @@ -938,11 +1012,11 @@ static int do_read(struct connection *c) { size_t l; void *p; - assert(c->input_memblockq); + pa_assert(c->input_memblockq); /* pa_log("STREAMING_DATA"); */ - if (!(l = pa_memblockq_missing(c->input_memblockq))) + if (!(l = pa_atomic_load(&c->playback.missing))) return 0; if (l > c->playback.fragment_size) @@ -956,47 +1030,50 @@ static int do_read(struct connection *c) { } if (!c->playback.current_memblock) { - c->playback.current_memblock = pa_memblock_new(c->protocol->core->mempool, c->playback.fragment_size*2); - assert(c->playback.current_memblock); - assert(pa_memblock_get_length(c->playback.current_memblock) >= l); + pa_assert_se(c->playback.current_memblock = pa_memblock_new(c->protocol->core->mempool, c->playback.fragment_size*2)); c->playback.memblock_index = 0; } p = pa_memblock_acquire(c->playback.current_memblock); + r = pa_iochannel_read(c->io, (uint8_t*) p+c->playback.memblock_index, l); + pa_memblock_release(c->playback.current_memblock); + + if (r <= 0) { + + if (errno == EINTR || errno == EAGAIN) + return 0; - if ((r = pa_iochannel_read(c->io, (uint8_t*) p+c->playback.memblock_index, l)) <= 0) { - pa_memblock_release(c->playback.current_memblock); pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); return -1; } - pa_memblock_release(c->playback.current_memblock); chunk.memblock = c->playback.current_memblock; chunk.index = c->playback.memblock_index; chunk.length = r; - assert(chunk.memblock); c->playback.memblock_index += r; - assert(c->input_memblockq); - pa_memblockq_push_align(c->input_memblockq, &chunk); - assert(c->sink_input); - pa_sink_notify(c->sink_input->sink); + pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, 0, &chunk, NULL); + pa_atomic_sub(&c->playback.missing, r); } return 0; } -static int do_write(struct connection *c) { - assert(c && c->io); +static int do_write(connection *c) { + connection_assert_ref(c); /* pa_log("WRITE"); */ if (c->write_data_length) { ssize_t r; - assert(c->write_data_index < c->write_data_length); + pa_assert(c->write_data_index < c->write_data_length); if ((r = pa_iochannel_write(c->io, (uint8_t*) c->write_data+c->write_data_index, c->write_data_length-c->write_data_index)) < 0) { + + if (errno == EINTR || errno == EAGAIN) + return 0; + pa_log("write(): %s", pa_cstrerror(errno)); return -1; } @@ -1009,37 +1086,36 @@ static int do_write(struct connection *c) { ssize_t r; void *p; - assert(c->output_memblockq); if (pa_memblockq_peek(c->output_memblockq, &chunk) < 0) return 0; - assert(chunk.memblock); - assert(chunk.length); + pa_assert(chunk.memblock); + pa_assert(chunk.length); p = pa_memblock_acquire(chunk.memblock); + r = pa_iochannel_write(c->io, (uint8_t*) p+chunk.index, chunk.length); + pa_memblock_release(chunk.memblock); + + pa_memblock_unref(chunk.memblock); + + if (r < 0) { - if ((r = pa_iochannel_write(c->io, (uint8_t*) p+chunk.index, chunk.length)) < 0) { - pa_memblock_release(chunk.memblock); - pa_memblock_unref(chunk.memblock); + if (errno == EINTR || errno == EAGAIN) + return 0; + pa_log("write(): %s", pa_cstrerror(errno)); return -1; } - pa_memblock_release(chunk.memblock); - - pa_memblockq_drop(c->output_memblockq, &chunk, r); - pa_memblock_unref(chunk.memblock); - - pa_source_notify(c->source_output->source); + pa_memblockq_drop(c->output_memblockq, r); } return 0; } -static void do_work(struct connection *c) { - assert(c); +static void do_work(connection *c) { + connection_assert_ref(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); if (c->dead) @@ -1070,117 +1146,188 @@ fail: pa_iochannel_free(c->io); c->io = NULL; - pa_memblockq_prebuf_disable(c->input_memblockq); - pa_sink_notify(c->sink_input->sink); + pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_DISABLE_PREBUF, NULL, 0, NULL, NULL); } else - connection_free(c); + connection_unlink(c); } static void io_callback(pa_iochannel*io, void *userdata) { - struct connection *c = userdata; - assert(io && c && c->io == io); + connection *c = CONNECTION(userdata); + + connection_assert_ref(c); + pa_assert(io); do_work(c); } -/*** defer callback ***/ - static void defer_callback(pa_mainloop_api*a, pa_defer_event *e, void *userdata) { - struct connection *c = userdata; - assert(a && c && c->defer_event == e); + connection *c = CONNECTION(userdata); -/* pa_log("DEFER"); */ + connection_assert_ref(c); + pa_assert(e); do_work(c); } +static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) { + connection *c = CONNECTION(o); + connection_assert_ref(c); + + switch (code) { + case CONNECTION_MESSAGE_REQUEST_DATA: + do_work(c); + break; + + case CONNECTION_MESSAGE_POST_DATA: +/* pa_log("got data %u", chunk->length); */ + pa_memblockq_push_align(c->output_memblockq, chunk); + do_work(c); + break; + + case CONNECTION_MESSAGE_UNLINK_CONNECTION: + connection_unlink(c); + break; + } + + return 0; +} + /*** sink_input callbacks ***/ -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { - struct connection*c; - assert(i && i->userdata && chunk); - c = i->userdata; +static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) { + pa_sink_input *i = PA_SINK_INPUT(o); + connection*c; - if (pa_memblockq_peek(c->input_memblockq, chunk) < 0) { + pa_sink_input_assert_ref(i); + c = CONNECTION(i->userdata); + connection_assert_ref(c); - if (c->dead) - connection_free(c); + switch (code) { - return -1; - } + case SINK_INPUT_MESSAGE_POST_DATA: { + pa_assert(chunk); - return 0; + /* New data from the main loop */ + pa_memblockq_push_align(c->input_memblockq, chunk); + +/* pa_log("got data, %u", pa_memblockq_get_length(c->input_memblockq)); */ + + return 0; + } + + case SINK_INPUT_MESSAGE_DISABLE_PREBUF: { + pa_memblockq_prebuf_disable(c->input_memblockq); + return 0; + } + + case PA_SINK_INPUT_MESSAGE_GET_LATENCY: { + pa_usec_t *r = userdata; + + *r = pa_bytes_to_usec(pa_memblockq_get_length(c->input_memblockq), &c->sink_input->sample_spec); + + /* Fall through, the default handler will add in the extra + * latency added by the resampler */ + } + + default: + return pa_sink_input_process_msg(o, code, userdata, offset, chunk); + } } -static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_t length) { - struct connection*c = i->userdata; - assert(i && c && length); -/* pa_log("DROP"); */ +static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { + connection*c; + int r; + + pa_assert(i); + c = CONNECTION(i->userdata); + connection_assert_ref(c); + pa_assert(chunk); + + if ((r = pa_memblockq_peek(c->input_memblockq, chunk)) < 0 && c->dead) + pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_UNLINK_CONNECTION, NULL, 0, NULL, NULL); + + return r; +} + +static void sink_input_drop_cb(pa_sink_input *i, size_t length) { + connection*c; + size_t old, new; - pa_memblockq_drop(c->input_memblockq, chunk, length); + pa_assert(i); + c = CONNECTION(i->userdata); + connection_assert_ref(c); + pa_assert(length); - /* do something */ - assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable); + /* pa_log("DROP"); */ - if (!c->dead) - c->protocol->core->mainloop->defer_enable(c->defer_event, 1); + old = pa_memblockq_missing(c->input_memblockq); + pa_memblockq_drop(c->input_memblockq, length); + new = pa_memblockq_missing(c->input_memblockq); -/* assert(pa_memblockq_get_length(c->input_memblockq) > 2048); */ + if (new > old) { + if (pa_atomic_add(&c->playback.missing, new - old) <= 0) + pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); + } } static void sink_input_kill_cb(pa_sink_input *i) { - assert(i && i->userdata); - connection_free((struct connection *) i->userdata); -} + pa_sink_input_assert_ref(i); -static pa_usec_t sink_input_get_latency_cb(pa_sink_input *i) { - struct connection*c = i->userdata; - assert(i && c); - return pa_bytes_to_usec(pa_memblockq_get_length(c->input_memblockq), &c->sink_input->sample_spec); + connection_unlink(CONNECTION(i->userdata)); } /*** source_output callbacks ***/ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) { - struct connection *c = o->userdata; - assert(o && c && chunk); - - pa_memblockq_push(c->output_memblockq, chunk); + connection *c; - /* do something */ - assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable); + pa_assert(o); + c = CONNECTION(o->userdata); + pa_assert(c); + pa_assert(chunk); - if (!c->dead) - c->protocol->core->mainloop->defer_enable(c->defer_event, 1); + pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_POST_DATA, NULL, 0, chunk, NULL); } static void source_output_kill_cb(pa_source_output *o) { - assert(o && o->userdata); - connection_free((struct connection *) o->userdata); + pa_source_output_assert_ref(o); + + connection_unlink(CONNECTION(o->userdata)); } static pa_usec_t source_output_get_latency_cb(pa_source_output *o) { - struct connection*c = o->userdata; - assert(o && c); + connection*c; + + pa_assert(o); + c = CONNECTION(o->userdata); + pa_assert(c); + return pa_bytes_to_usec(pa_memblockq_get_length(c->output_memblockq), &c->source_output->sample_spec); } /*** socket server callback ***/ static void auth_timeout(pa_mainloop_api*m, pa_time_event *e, const struct timeval *tv, void *userdata) { - struct connection *c = userdata; - assert(m && tv && c && c->auth_timeout_event == e); + connection *c = CONNECTION(userdata); + + pa_assert(m); + pa_assert(tv); + connection_assert_ref(c); + pa_assert(c->auth_timeout_event == e); if (!c->authorized) - connection_free(c); + connection_unlink(c); } static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) { - struct connection *c; + connection *c; pa_protocol_esound *p = userdata; char cname[256], pname[128]; - assert(s && io && p); + + pa_assert(s); + pa_assert(io); + pa_assert(p); if (pa_idxset_size(p->connections)+1 > MAX_CONNECTIONS) { pa_log("Warning! Too many connections (%u), dropping incoming connection.", MAX_CONNECTIONS); @@ -1188,16 +1335,16 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) return; } - c = pa_xnew(struct connection, 1); + c = pa_msgobject_new(connection); + c->parent.parent.free = connection_free; + c->parent.process_msg = connection_process_msg; c->protocol = p; c->io = io; pa_iochannel_set_callback(c->io, io_callback, c); pa_iochannel_socket_peer_to_string(io, pname, sizeof(pname)); pa_snprintf(cname, sizeof(cname), "EsounD client (%s)", pname); - assert(p->core); c->client = pa_client_new(p->core, __FILE__, cname); - assert(c->client); c->client->owner = p->module; c->client->kill = client_kill_cb; c->client->userdata = c; @@ -1224,6 +1371,7 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) c->playback.current_memblock = NULL; c->playback.memblock_index = 0; c->playback.fragment_size = 0; + pa_atomic_store(&c->playback.missing, 0); c->scache.memchunk.length = c->scache.memchunk.index = 0; c->scache.memchunk.memblock = NULL; @@ -1245,7 +1393,6 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) c->auth_timeout_event = NULL; c->defer_event = p->core->mainloop->defer_new(p->core->mainloop, defer_callback, c); - assert(c->defer_event); p->core->mainloop->defer_enable(c->defer_event, 0); pa_idxset_put(p->connections, c, &c->index); @@ -1254,22 +1401,22 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) /*** entry points ***/ pa_protocol_esound* pa_protocol_esound_new(pa_core*core, pa_socket_server *server, pa_module *m, pa_modargs *ma) { - pa_protocol_esound *p; + pa_protocol_esound *p = NULL; int public = 0; const char *acl; - assert(core); - assert(server); - assert(m); - assert(ma); - - p = pa_xnew(pa_protocol_esound, 1); + pa_assert(core); + pa_assert(server); + pa_assert(m); + pa_assert(ma); if (pa_modargs_get_value_boolean(ma, "auth-anonymous", &public) < 0) { pa_log("auth-anonymous= expects a boolean argument."); goto fail; } + p = pa_xnew(pa_protocol_esound, 1); + if (pa_authkey_load_auto(pa_modargs_get_value(ma, "cookie", DEFAULT_COOKIE_FILE), p->esd_key, sizeof(p->esd_key)) < 0) goto fail; @@ -1282,13 +1429,12 @@ pa_protocol_esound* pa_protocol_esound_new(pa_core*core, pa_socket_server *serve } else p->auth_ip_acl = NULL; + p->core = core; p->module = m; p->public = public; p->server = server; pa_socket_server_set_callback(p->server, on_connection, p); - p->core = core; p->connections = pa_idxset_new(NULL, NULL); - assert(p->connections); p->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL)); p->source_name = pa_xstrdup(pa_modargs_get_value(ma, "source", NULL)); @@ -1302,17 +1448,20 @@ fail: } void pa_protocol_esound_free(pa_protocol_esound *p) { - struct connection *c; - assert(p); + connection *c; + pa_assert(p); while ((c = pa_idxset_first(p->connections, NULL))) - connection_free(c); - + connection_unlink(c); pa_idxset_free(p->connections, NULL, NULL); + pa_socket_server_unref(p->server); if (p->auth_ip_acl) pa_ip_acl_free(p->auth_ip_acl); + pa_xfree(p->sink_name); + pa_xfree(p->source_name); + pa_xfree(p); } -- cgit From 0a6f9afb8b1f51484ad39c81aefd04a904809170 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 7 Aug 2007 10:47:00 +0000 Subject: add global suspend command to cli git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1586 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/cli-command.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c index d7613530..fac8d0e0 100644 --- a/src/pulsecore/cli-command.c +++ b/src/pulsecore/cli-command.c @@ -117,6 +117,7 @@ static int pa_cli_command_move_source_output(pa_core *c, pa_tokenizer *t, pa_str static int pa_cli_command_vacuum(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); static int pa_cli_command_suspend_sink(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); static int pa_cli_command_suspend_source(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); +static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); /* A method table for all available commands */ @@ -165,6 +166,7 @@ static const struct command commands[] = { { "vacuum", pa_cli_command_vacuum, NULL, 1}, { "suspend-sink", pa_cli_command_suspend_sink, "Suspend sink (args: index|name, bool)", 3}, { "suspend-source", pa_cli_command_suspend_source, "Suspend source (args: index|name, bool)", 3}, + { "suspend", pa_cli_command_suspend, "Suspend all sinks and all sources (args: bool)", 2}, { NULL, NULL, NULL, 0 } }; @@ -961,6 +963,32 @@ static int pa_cli_command_suspend_source(pa_core *c, pa_tokenizer *t, pa_strbuf return 0; } +static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { + const char *m; + pa_sink *sink; + pa_source *source; + int suspend; + uint32_t idx; + + if (!(m = pa_tokenizer_get(t, 1))) { + pa_strbuf_puts(buf, "You need to specify a suspend switch setting (0/1).\n"); + return -1; + } + + if (pa_atoi(m, &suspend) < 0) { + pa_strbuf_puts(buf, "Failed to parse suspend switch.\n"); + return -1; + } + + for (sink = pa_idxset_first(c->sinks, &idx); sink; sink = pa_idxset_next(c->sinks, &idx)) + pa_sink_suspend(sink, suspend); + + for (source = pa_idxset_first(c->sources, &idx); source; source = pa_idxset_next(c->sources, &idx)) + pa_source_suspend(source, suspend); + + return 0; +} + static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { pa_module *m; pa_sink *sink; @@ -983,7 +1011,6 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_G pa_strbuf_printf(buf, "### Configuration dump generated at %s\n", ctime(&now)); #endif - for (m = pa_idxset_first(c->modules, &idx); m; m = pa_idxset_next(c->modules, &idx)) { if (m->auto_unload) continue; -- cgit From 366d1d3441136551e32d375831c1edd85fd370f2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 7 Aug 2007 10:48:29 +0000 Subject: reinitialize sw params after resume git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1587 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-source.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 9a5d5acb..2db9f482 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -264,7 +264,7 @@ static int unsuspend(struct userdata *u) { pa_log_warn("Resume failed, couldn't get original access mode."); goto fail; } - + if (!pa_sample_spec_equal(&ss, &u->source->sample_spec)) { pa_log_warn("Resume failed, couldn't restore original sample settings."); goto fail; @@ -275,6 +275,11 @@ static int unsuspend(struct userdata *u) { goto fail; } + if ((err = pa_alsa_set_sw_params(u->pcm_handle)) < 0) { + pa_log("Failed to set software parameters: %s", snd_strerror(err)); + goto fail; + } + snd_pcm_start(u->pcm_handle); /* FIXME: We need to reload the volume somehow */ @@ -565,8 +570,6 @@ static void thread_func(void *userdata) { if (t < 0) { pa_memblock_unref(chunk.memblock); - pa_assert(t != -EPIPE); - if ((t = snd_pcm_recover(u->pcm_handle, t, 1)) == 0) continue; -- cgit From 981d5fac832b8c02358b4787e14d519c26e4d9ca Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 8 Aug 2007 20:50:37 +0000 Subject: don't print error on socket read/write failure git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1588 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/ioline.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/pulsecore/ioline.c b/src/pulsecore/ioline.c index 07b60bee..23a90a78 100644 --- a/src/pulsecore/ioline.c +++ b/src/pulsecore/ioline.c @@ -293,7 +293,7 @@ static int do_read(pa_ioline *l) { /* Read some data */ if ((r = pa_iochannel_read(l->io, l->rbuf+l->rbuf_index+l->rbuf_valid_length, len)) <= 0) { - if (r < 0) { + if (r < 0 && errno != ECONNRESET) { pa_log("read(): %s", pa_cstrerror(errno)); failure(l, 0); } else @@ -318,9 +318,13 @@ static int do_write(pa_ioline *l) { while (!l->dead && pa_iochannel_is_writable(l->io) && l->wbuf_valid_length) { - if ((r = pa_iochannel_write(l->io, l->wbuf+l->wbuf_index, l->wbuf_valid_length)) < 0) { - pa_log("write(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); + if ((r = pa_iochannel_write(l->io, l->wbuf+l->wbuf_index, l->wbuf_valid_length)) <= 0) { + + if (r < 0 && errno != EPIPE) + pa_log("write(): %s", pa_cstrerror(errno)); + failure(l, 0); + return -1; } -- cgit From 54b9f55d2e50c8c867c40ef2a926ecabbc690cec Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 8 Aug 2007 20:52:52 +0000 Subject: properly reinitialize pollfd array after resume git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1589 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/alsa-util.c | 5 ++ src/modules/module-alsa-sink.c | 102 +++++++++++++++++++++++++++-------------- 2 files changed, 73 insertions(+), 34 deletions(-) diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c index dd063f3b..b5dba562 100644 --- a/src/modules/alsa-util.c +++ b/src/modules/alsa-util.c @@ -377,6 +377,11 @@ int pa_alsa_set_sw_params(snd_pcm_t *pcm) { pa_log_warn("Unable to set stop threshold: %s\n", snd_strerror(err)); return err; } + + if ((err = snd_pcm_sw_params_set_start_threshold(pcm, swparams, (snd_pcm_uframes_t) -1)) < 0) { + pa_log_warn("Unable to set start threshold: %s\n", snd_strerror(err)); + return err; + } if ((err = snd_pcm_sw_params(pcm, swparams)) < 0) { pa_log_warn("Unable to set sw params: %s\n", snd_strerror(err)); diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 5765d780..0e73b3cb 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -96,6 +96,14 @@ struct userdata { int use_mmap; int first; + + struct pollfd *pollfd; + int n_alsa_fds; +}; + +enum { + POLLFD_ASYNCQ, + POLLFD_ALSA_BASE }; static const char* const valid_modargs[] = { @@ -232,6 +240,31 @@ static pa_usec_t sink_get_latency(struct userdata *u) { return r; } +static int build_pollfd(struct userdata *u) { + int err; + + pa_assert(u); + pa_assert(u->pcm_handle); + + if ((u->n_alsa_fds = snd_pcm_poll_descriptors_count(u->pcm_handle)) < 0) { + pa_log("snd_pcm_poll_descriptors_count() failed: %s", snd_strerror(u->n_alsa_fds)); + return -1; + } + + pa_xfree(u->pollfd); + u->pollfd = pa_xnew0(struct pollfd, POLLFD_ALSA_BASE + u->n_alsa_fds); + + u->pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq); + u->pollfd[POLLFD_ASYNCQ].events = POLLIN; + + if ((err = snd_pcm_poll_descriptors(u->pcm_handle, u->pollfd+POLLFD_ALSA_BASE, u->n_alsa_fds)) < 0) { + pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err)); + return -1; + } + + return 0; +} + static int suspend(struct userdata *u) { pa_assert(u); pa_assert(u->pcm_handle); @@ -287,6 +320,14 @@ static int unsuspend(struct userdata *u) { goto fail; } + if ((err = pa_alsa_set_sw_params(u->pcm_handle)) < 0) { + pa_log("Failed to set software parameters: %s", snd_strerror(err)); + goto fail; + } + + if (build_pollfd(u) < 0) + goto fail; + /* FIXME: We need to reload the volume somehow */ u->first = 1; @@ -474,36 +515,19 @@ static int sink_set_mute_cb(pa_sink *s) { } static void thread_func(void *userdata) { - enum { - POLLFD_ASYNCQ, - POLLFD_ALSA_BASE - }; struct userdata *u = userdata; - struct pollfd *pollfd = NULL; - int n_alsa_fds, err; unsigned short revents = 0; snd_pcm_status_t *status; - + int err; + pa_assert(u); snd_pcm_status_alloca(&status); pa_log_debug("Thread starting up"); - if ((n_alsa_fds = snd_pcm_poll_descriptors_count(u->pcm_handle)) < 0) { - pa_log("snd_pcm_poll_descriptors_count() failed: %s", snd_strerror(n_alsa_fds)); + if (build_pollfd(u) < 0) goto fail; - } - - pollfd = pa_xnew0(struct pollfd, POLLFD_ALSA_BASE + n_alsa_fds); - - pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq); - pollfd[POLLFD_ASYNCQ].events = POLLIN; - - if ((err = snd_pcm_poll_descriptors(u->pcm_handle, pollfd+POLLFD_ALSA_BASE, n_alsa_fds)) < 0) { - pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err)); - goto fail; - } for (;;) { pa_msgobject *object; @@ -513,13 +537,13 @@ static void thread_func(void *userdata) { int64_t offset; int r; -/* pa_log("loop"); */ +/* pa_log("loop"); */ /* Check whether there is a message for us to process */ if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; -/* pa_log("processing msg"); */ +/* pa_log("processing msg"); */ if (!object && code == PA_MESSAGE_SHUTDOWN) { pa_asyncmsgq_done(u->asyncmsgq, 0); @@ -545,6 +569,7 @@ static void thread_func(void *userdata) { goto fail; } else { + for (;;) { void *p; snd_pcm_sframes_t t; @@ -560,6 +585,8 @@ static void thread_func(void *userdata) { l = snd_pcm_status_get_avail(status) * u->frame_size; +/* pa_log("%u bytes to write", l); */ + if (l <= 0) break; @@ -578,8 +605,6 @@ static void thread_func(void *userdata) { if (t < 0) { - pa_assert(t != -EPIPE); - if ((t = snd_pcm_recover(u->pcm_handle, t, 1)) == 0) continue; @@ -625,16 +650,15 @@ static void thread_func(void *userdata) { if (pa_asyncmsgq_before_poll(u->asyncmsgq) < 0) continue; -/* pa_log("polling for %i", POLLFD_ALSA_BASE + (PA_SINK_OPENED(u->sink->thread_info.state) ? n_alsa_fds : 0)); */ - r = poll(pollfd, POLLFD_ALSA_BASE + (PA_SINK_OPENED(u->sink->thread_info.state) ? n_alsa_fds : 0), -1); - /*pa_log("polling got dsp=%i amq=%i (%i)", r > 0 ? pollfd[POLLFD_DSP].revents : 0, r > 0 ? pollfd[POLLFD_ASYNCQ].revents : 0, r); */ +/* pa_log("polling for %i", POLLFD_ALSA_BASE + (PA_SINK_OPENED(u->sink->thread_info.state) ? u->n_alsa_fds : 0)); */ + r = poll(u->pollfd, POLLFD_ALSA_BASE + (PA_SINK_OPENED(u->sink->thread_info.state) ? u->n_alsa_fds : 0), -1); /* pa_log("poll end"); */ pa_asyncmsgq_after_poll(u->asyncmsgq); if (r < 0) { if (errno == EINTR) { - pollfd[POLLFD_ASYNCQ].revents = 0; + u->pollfd[POLLFD_ASYNCQ].revents = 0; revents = 0; continue; } @@ -646,16 +670,25 @@ static void thread_func(void *userdata) { pa_assert(r > 0); if (PA_SINK_OPENED(u->sink->thread_info.state)) { - if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, pollfd + POLLFD_ALSA_BASE, n_alsa_fds, &revents)) < 0) { + if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, u->pollfd + POLLFD_ALSA_BASE, u->n_alsa_fds, &revents)) < 0) { pa_log("snd_pcm_poll_descriptors_revents() failed: %s", snd_strerror(err)); goto fail; } -/* pa_log("got alsa event"); */ + if (revents & (POLLERR|POLLNVAL|POLLHUP)) { + if (revents & POLLERR) + pa_log_warn("Got POLLERR from ALSA"); + if (revents & POLLNVAL) + pa_log_warn("Got POLLNVAL from ALSA"); + if (revents & POLLHUP) + pa_log_warn("Got POLLHUP from ALSA"); + + goto fail; + } } else revents = 0; - pa_assert((pollfd[POLLFD_ASYNCQ].revents & ~POLLIN) == 0); + pa_assert((u->pollfd[POLLFD_ASYNCQ].revents & ~POLLIN) == 0); } fail: @@ -666,8 +699,6 @@ fail: finish: pa_log_debug("Thread shutting down"); - - pa_xfree(pollfd); } int pa__init(pa_core *c, pa_module*m) { @@ -727,6 +758,8 @@ int pa__init(pa_core *c, pa_module*m) { m->userdata = u; u->use_mmap = use_mmap; u->first = 1; + u->n_alsa_fds = 0; + u->pollfd = NULL; pa_assert_se(u->asyncmsgq = pa_asyncmsgq_new(0)); snd_config_update_free_global(); @@ -922,7 +955,8 @@ void pa__done(pa_core *c, pa_module*m) { snd_pcm_drop(u->pcm_handle); snd_pcm_close(u->pcm_handle); } - + + pa_xfree(u->pollfd); pa_xfree(u->device_name); pa_xfree(u); -- cgit From df9522cb8c853a26f2deb1f0b36945f0419a4265 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 8 Aug 2007 21:20:20 +0000 Subject: properly reinitialize pollfd array after resume git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1590 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 1 + src/modules/module-alsa-source.c | 80 ++++++++++++++++++++++++++-------------- 2 files changed, 54 insertions(+), 27 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 0e73b3cb..708dd1f4 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -685,6 +685,7 @@ static void thread_func(void *userdata) { goto fail; } +/* pa_log("got alsa event"); */ } else revents = 0; diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 2db9f482..61035c76 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -93,6 +93,14 @@ struct userdata { char *device_name; int use_mmap; + + struct pollfd *pollfd; + int n_alsa_fds; +}; + +enum { + POLLFD_ASYNCQ, + POLLFD_ALSA_BASE }; static const char* const valid_modargs[] = { @@ -220,6 +228,31 @@ static pa_usec_t source_get_latency(struct userdata *u) { return r; } +static int build_pollfd(struct userdata *u) { + int err; + + pa_assert(u); + pa_assert(u->pcm_handle); + + if ((u->n_alsa_fds = snd_pcm_poll_descriptors_count(u->pcm_handle)) < 0) { + pa_log("snd_pcm_poll_descriptors_count() failed: %s", snd_strerror(u->n_alsa_fds)); + return -1; + } + + pa_xfree(u->pollfd); + u->pollfd = pa_xnew0(struct pollfd, POLLFD_ALSA_BASE + u->n_alsa_fds); + + u->pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq); + u->pollfd[POLLFD_ASYNCQ].events = POLLIN; + + if ((err = snd_pcm_poll_descriptors(u->pcm_handle, u->pollfd+POLLFD_ALSA_BASE, u->n_alsa_fds)) < 0) { + pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err)); + return -1; + } + + return 0; +} + static int suspend(struct userdata *u) { pa_assert(u); pa_assert(u->pcm_handle); @@ -279,6 +312,9 @@ static int unsuspend(struct userdata *u) { pa_log("Failed to set software parameters: %s", snd_strerror(err)); goto fail; } + + if (build_pollfd(u) < 0) + goto fail; snd_pcm_start(u->pcm_handle); @@ -467,14 +503,9 @@ static int source_set_mute_cb(pa_source *s) { } static void thread_func(void *userdata) { - enum { - POLLFD_ASYNCQ, - POLLFD_ALSA_BASE - }; struct userdata *u = userdata; - struct pollfd *pollfd = NULL; - int n_alsa_fds, err; + int err; unsigned short revents = 0; snd_pcm_status_t *status; @@ -483,20 +514,8 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); - if ((n_alsa_fds = snd_pcm_poll_descriptors_count(u->pcm_handle)) < 0) { - pa_log("snd_pcm_poll_descriptors_count() failed: %s", snd_strerror(n_alsa_fds)); + if (build_pollfd(u) < 0) goto fail; - } - - pollfd = pa_xnew0(struct pollfd, POLLFD_ALSA_BASE + n_alsa_fds); - - pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq); - pollfd[POLLFD_ASYNCQ].events = POLLIN; - - if ((err = snd_pcm_poll_descriptors(u->pcm_handle, pollfd+POLLFD_ALSA_BASE, n_alsa_fds)) < 0) { - pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err)); - goto fail; - } for (;;) { pa_msgobject *object; @@ -607,15 +626,14 @@ static void thread_func(void *userdata) { continue; /* pa_log("polling for %i", POLLFD_ALSA_BASE + (PA_SOURCE_OPENED(u->source->thread_info.state) ? n_alsa_fds : 0)); */ - r = poll(pollfd, POLLFD_ALSA_BASE + (PA_SOURCE_OPENED(u->source->thread_info.state) ? n_alsa_fds : 0), -1); - /*pa_log("polling got dsp=%i amq=%i (%i)", r > 0 ? pollfd[POLLFD_DSP].revents : 0, r > 0 ? pollfd[POLLFD_ASYNCQ].revents : 0, r); */ + r = poll(u->pollfd, POLLFD_ALSA_BASE + (PA_SOURCE_OPENED(u->source->thread_info.state) ? u->n_alsa_fds : 0), -1); /* pa_log("poll end"); */ pa_asyncmsgq_after_poll(u->asyncmsgq); if (r < 0) { if (errno == EINTR) { - pollfd[POLLFD_ASYNCQ].revents = 0; + u->pollfd[POLLFD_ASYNCQ].revents = 0; revents = 0; continue; } @@ -627,16 +645,26 @@ static void thread_func(void *userdata) { pa_assert(r > 0); if (PA_SOURCE_OPENED(u->source->thread_info.state)) { - if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, pollfd + POLLFD_ALSA_BASE, n_alsa_fds, &revents)) < 0) { + if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, u->pollfd + POLLFD_ALSA_BASE, u->n_alsa_fds, &revents)) < 0) { pa_log("snd_pcm_poll_descriptors_revents() failed: %s", snd_strerror(err)); goto fail; } + if (revents & (POLLERR|POLLNVAL|POLLHUP)) { + if (revents & POLLERR) + pa_log_warn("Got POLLERR from ALSA"); + if (revents & POLLNVAL) + pa_log_warn("Got POLLNVAL from ALSA"); + if (revents & POLLHUP) + pa_log_warn("Got POLLHUP from ALSA"); + + goto fail; + } /* pa_log("got alsa event"); */ } else revents = 0; - pa_assert((pollfd[POLLFD_ASYNCQ].revents & ~POLLIN) == 0); + pa_assert((u->pollfd[POLLFD_ASYNCQ].revents & ~POLLIN) == 0); } fail: @@ -647,11 +675,8 @@ fail: finish: pa_log_debug("Thread shutting down"); - - pa_xfree(pollfd); } - int pa__init(pa_core *c, pa_module*m) { pa_modargs *ma = NULL; @@ -898,6 +923,7 @@ void pa__done(pa_core *c, pa_module*m) { snd_pcm_close(u->pcm_handle); } + pa_xfree(u->pollfd); pa_xfree(u->device_name); pa_xfree(u); -- cgit From fedca91468cc75fc4c38d42464d69166d70ddf3a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 8 Aug 2007 21:20:44 +0000 Subject: Remove warning when client is too slow to handle our data git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1591 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-native.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index bd1605b1..893a6c03 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -402,7 +402,7 @@ static int record_stream_process_msg(pa_msgobject *o, int code, void*userdata, i case RECORD_STREAM_MESSAGE_POST_DATA: if (pa_memblockq_push_align(s->memblockq, chunk) < 0) { - pa_log_warn("Failed to push data into output queue."); +/* pa_log_warn("Failed to push data into output queue."); */ return -1; } -- cgit From e4e9a063078ffb6e792848f1f9e441e121ae62b2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 8 Aug 2007 23:48:25 +0000 Subject: be more verbose when device does not support sampling parameters git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1592 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/alsa-util.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c index b5dba562..5d49a3c4 100644 --- a/src/modules/alsa-util.c +++ b/src/modules/alsa-util.c @@ -324,7 +324,7 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *p goto finish; if (ss->rate != r) { - pa_log_warn("device doesn't support %u Hz, changed to %u Hz.", ss->rate, r); + pa_log_warn("Device %s doesn't support %u Hz, changed to %u Hz.", snd_pcm_name(pcm_handle), ss->rate, r); /* If the sample rate deviates too much, we need to resample */ if (r < ss->rate*.95 || r > ss->rate*1.05) @@ -332,12 +332,12 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *p } if (ss->channels != c) { - pa_log_warn("device doesn't support %u channels, changed to %u.", ss->channels, c); + pa_log_warn("Device %s doesn't support %u channels, changed to %u.", snd_pcm_name(pcm_handle), ss->channels, c); ss->channels = c; } if (ss->format != f) { - pa_log_warn("device doesn't support sample format %s, changed to %s.", pa_sample_format_to_string(ss->format), pa_sample_format_to_string(f)); + pa_log_warn("Device %s doesn't support sample format %s, changed to %s.", snd_pcm_name(pcm_handle), pa_sample_format_to_string(ss->format), pa_sample_format_to_string(f)); ss->format = f; } -- cgit From 26a024622c045aba55980e100541cad74ca21892 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 8 Aug 2007 23:48:47 +0000 Subject: modernize dbus-util.c git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1593 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/dbus-util.c | 272 +++++++++++++++++++++--------------------------- 1 file changed, 121 insertions(+), 151 deletions(-) diff --git a/src/modules/dbus-util.c b/src/modules/dbus-util.c index 7cd9c1d6..24936faa 100644 --- a/src/modules/dbus-util.c +++ b/src/modules/dbus-util.c @@ -26,7 +26,6 @@ #include #endif -#include #include #include #include @@ -35,16 +34,17 @@ #include "dbus-util.h" struct pa_dbus_connection { - int refcount; + PA_REFCNT_DECLARE; + pa_core *core; DBusConnection *connection; const char *property_name; pa_defer_event* dispatch_event; }; -static void dispatch_cb(pa_mainloop_api *ea, pa_defer_event *ev, void *userdata) -{ - DBusConnection *conn = (DBusConnection *) userdata; +static void dispatch_cb(pa_mainloop_api *ea, pa_defer_event *ev, void *userdata) { + DBusConnection *conn = userdata; + if (dbus_connection_dispatch(conn) == DBUS_DISPATCH_COMPLETE) { /* no more data to process, disable the deferred */ ea->defer_enable(ev, 0); @@ -52,14 +52,17 @@ static void dispatch_cb(pa_mainloop_api *ea, pa_defer_event *ev, void *userdata) } /* DBusDispatchStatusFunction callback for the pa mainloop */ -static void dispatch_status(DBusConnection *conn, DBusDispatchStatus status, - void *userdata) -{ - pa_dbus_connection *c = (pa_dbus_connection*) userdata; +static void dispatch_status(DBusConnection *conn, DBusDispatchStatus status, void *userdata) { + pa_dbus_connection *c = userdata; + + pa_assert(c); + switch(status) { + case DBUS_DISPATCH_COMPLETE: c->core->mainloop->defer_enable(c->dispatch_event, 0); break; + case DBUS_DISPATCH_DATA_REMAINS: case DBUS_DISPATCH_NEED_MEMORY: default: @@ -68,12 +71,14 @@ static void dispatch_status(DBusConnection *conn, DBusDispatchStatus status, } } -static pa_io_event_flags_t -get_watch_flags(DBusWatch *watch) -{ - unsigned int flags = dbus_watch_get_flags(watch); - pa_io_event_flags_t events = PA_IO_EVENT_HANGUP | PA_IO_EVENT_ERROR; +static pa_io_event_flags_t get_watch_flags(DBusWatch *watch) { + unsigned int flags; + pa_io_event_flags_t events = 0; + pa_assert(watch); + + flags = dbus_watch_get_flags(watch); + /* no watch flags for disabled watches */ if (!dbus_watch_get_enabled(watch)) return PA_IO_EVENT_NULL; @@ -83,21 +88,18 @@ get_watch_flags(DBusWatch *watch) if (flags & DBUS_WATCH_WRITABLE) events |= PA_IO_EVENT_OUTPUT; - return events; + return events | PA_IO_EVENT_HANGUP | PA_IO_EVENT_ERROR; } /* pa_io_event_cb_t IO event handler */ -static void handle_io_event(PA_GCC_UNUSED pa_mainloop_api *ea, pa_io_event *e, - int fd, pa_io_event_flags_t events, void *userdata) -{ +static void handle_io_event(PA_GCC_UNUSED pa_mainloop_api *ea, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) { unsigned int flags = 0; - DBusWatch *watch = (DBusWatch*) userdata; + DBusWatch *watch = userdata; - assert(fd == dbus_watch_get_unix_fd(watch)); + pa_assert(fd == dbus_watch_get_unix_fd(watch)); if (!dbus_watch_get_enabled(watch)) { - pa_log_warn("Asked to handle disabled watch: %p %i", - (void *) watch, fd); + pa_log_warn("Asked to handle disabled watch: %p %i", (void*) watch, fd); return; } @@ -114,10 +116,8 @@ static void handle_io_event(PA_GCC_UNUSED pa_mainloop_api *ea, pa_io_event *e, } /* pa_time_event_cb_t timer event handler */ -static void handle_time_event(pa_mainloop_api *ea, pa_time_event* e, - const struct timeval *tv, void *userdata) -{ - DBusTimeout *timeout = (DBusTimeout*) userdata; +static void handle_time_event(pa_mainloop_api *ea, pa_time_event* e, const struct timeval *tv, void *userdata) { + DBusTimeout *timeout = userdata; if (dbus_timeout_get_enabled(timeout)) { struct timeval next = *tv; @@ -130,218 +130,188 @@ static void handle_time_event(pa_mainloop_api *ea, pa_time_event* e, } /* DBusAddWatchFunction callback for pa mainloop */ -static dbus_bool_t add_watch(DBusWatch *watch, void *data) -{ +static dbus_bool_t add_watch(DBusWatch *watch, void *data) { + pa_core *c = PA_CORE(data); pa_io_event *ev; - pa_core *c = (pa_core*) data; - ev = c->mainloop->io_new(c->mainloop, dbus_watch_get_unix_fd(watch), - get_watch_flags(watch), - handle_io_event, (void*) watch); - if (NULL == ev) - return FALSE; + pa_assert(watch); + pa_assert(c); + + ev = c->mainloop->io_new(c->mainloop, dbus_watch_get_unix_fd(watch), get_watch_flags(watch), handle_io_event, watch); - /* dbus_watch_set_data(watch, (void*) ev, c->mainloop->io_free); */ - dbus_watch_set_data(watch, (void*) ev, NULL); + dbus_watch_set_data(watch, ev, NULL); return TRUE; } /* DBusRemoveWatchFunction callback for pa mainloop */ -static void remove_watch(DBusWatch *watch, void *data) -{ - pa_core *c = (pa_core*) data; - pa_io_event *ev = (pa_io_event*) dbus_watch_get_data(watch); +static void remove_watch(DBusWatch *watch, void *data) { + pa_core *c = PA_CORE(data); + pa_io_event *ev; - /* free the event */ - if (NULL != ev) + pa_assert(watch); + pa_assert(c); + + if ((ev = dbus_watch_get_data(watch))) c->mainloop->io_free(ev); } /* DBusWatchToggledFunction callback for pa mainloop */ -static void toggle_watch(DBusWatch *watch, void *data) -{ - pa_core *c = (pa_core*) data; - pa_io_event *ev = (pa_io_event*) dbus_watch_get_data(watch); +static void toggle_watch(DBusWatch *watch, void *data) { + pa_core *c = PA_CORE(data); + pa_io_event *ev; + + pa_assert(watch); + pa_core_assert_ref(c); + + pa_assert_se(ev = dbus_watch_get_data(watch)); /* get_watch_flags() checks if the watch is enabled */ c->mainloop->io_enable(ev, get_watch_flags(watch)); } /* DBusAddTimeoutFunction callback for pa mainloop */ -static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data) -{ - struct timeval tv; +static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data) { + pa_core *c = PA_CORE(data); pa_time_event *ev; - pa_core *c = (pa_core*) data; + struct timeval tv; + + pa_assert(timeout); + pa_assert(c); if (!dbus_timeout_get_enabled(timeout)) return FALSE; - if (!pa_gettimeofday(&tv)) - return -1; - + pa_gettimeofday(&tv); pa_timeval_add(&tv, dbus_timeout_get_interval(timeout) * 1000); - ev = c->mainloop->time_new(c->mainloop, &tv, handle_time_event, - (void*) timeout); - if (NULL == ev) - return FALSE; + ev = c->mainloop->time_new(c->mainloop, &tv, handle_time_event, timeout); - /* dbus_timeout_set_data(timeout, (void*) ev, c->mainloop->time_free); */ - dbus_timeout_set_data(timeout, (void*) ev, NULL); + dbus_timeout_set_data(timeout, ev, NULL); return TRUE; } /* DBusRemoveTimeoutFunction callback for pa mainloop */ -static void remove_timeout(DBusTimeout *timeout, void *data) -{ - pa_core *c = (pa_core*) data; - pa_time_event *ev = (pa_time_event*) dbus_timeout_get_data(timeout); +static void remove_timeout(DBusTimeout *timeout, void *data) { + pa_core *c = PA_CORE(data); + pa_time_event *ev; - /* free the event */ - if (NULL != ev) + pa_assert(timeout); + pa_assert(c); + + if ((ev = dbus_timeout_get_data(timeout))) c->mainloop->time_free(ev); } /* DBusTimeoutToggledFunction callback for pa mainloop */ -static void toggle_timeout(DBusTimeout *timeout, void *data) -{ - struct timeval tv; - pa_core *c = (pa_core*) data; - pa_time_event *ev = (pa_time_event*) dbus_timeout_get_data(timeout); +static void toggle_timeout(DBusTimeout *timeout, void *data) { + pa_core *c = PA_CORE(data); + pa_time_event *ev; + + pa_assert(timeout); + pa_assert(c); + + pa_assert_se(ev = dbus_timeout_get_data(timeout)); if (dbus_timeout_get_enabled(timeout)) { + struct timeval tv; + pa_gettimeofday(&tv); pa_timeval_add(&tv, dbus_timeout_get_interval(timeout) * 1000); + c->mainloop->time_restart(ev, &tv); - } else { - /* disable the timeout */ + } else c->mainloop->time_restart(ev, NULL); - } } -static void -pa_dbus_connection_free(pa_dbus_connection *c) -{ - assert(c); - assert(!dbus_connection_get_is_connected(c->connection)); - - /* already disconnected, just free */ - pa_property_remove(c->core, c->property_name); - c->core->mainloop->defer_free(c->dispatch_event); - dbus_connection_unref(c->connection); - pa_xfree(c); -} +static void wakeup_main(void *userdata) { + pa_dbus_connection *c = userdata; -static void -wakeup_main(void *userdata) -{ - pa_dbus_connection *c = (pa_dbus_connection*) userdata; + pa_assert(c); + /* this will wakeup the mainloop and dispatch events, although * it may not be the cleanest way of accomplishing it */ c->core->mainloop->defer_enable(c->dispatch_event, 1); } -static pa_dbus_connection* pa_dbus_connection_new(pa_core* c, DBusConnection *conn, const char* name) -{ - pa_dbus_connection *pconn = pa_xnew(pa_dbus_connection, 1); +static pa_dbus_connection* pa_dbus_connection_new(pa_core* c, DBusConnection *conn, const char* name) { + pa_dbus_connection *pconn; - pconn->refcount = 1; + pconn = pa_xnew(pa_dbus_connection, 1); + PA_REFCNT_INIT(pconn); pconn->core = c; pconn->property_name = name; pconn->connection = conn; - pconn->dispatch_event = c->mainloop->defer_new(c->mainloop, dispatch_cb, - (void*) conn); + pconn->dispatch_event = c->mainloop->defer_new(c->mainloop, dispatch_cb, conn); pa_property_set(c, name, pconn); return pconn; } -DBusConnection* pa_dbus_connection_get(pa_dbus_connection *c) -{ - assert(c && c->connection); +DBusConnection* pa_dbus_connection_get(pa_dbus_connection *c){ + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) > 0); + pa_assert(c->connection); + return c->connection; } -void pa_dbus_connection_unref(pa_dbus_connection *c) -{ - assert(c); +void pa_dbus_connection_unref(pa_dbus_connection *c) { + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) > 0); - /* non-zero refcount, still outstanding refs */ - if (--(c->refcount)) + if (PA_REFCNT_DEC(c) > 0) return; - /* refcount is zero */ if (dbus_connection_get_is_connected(c->connection)) { - /* disconnect as we have no more internal references */ dbus_connection_close(c->connection); - /* must process remaining messages, bit of a kludge to - * handle both unload and shutdown */ - while(dbus_connection_read_write_dispatch(c->connection, -1)); + /* must process remaining messages, bit of a kludge to handle + * both unload and shutdown */ + while (dbus_connection_read_write_dispatch(c->connection, -1)); } - pa_dbus_connection_free(c); + + /* already disconnected, just free */ + pa_property_remove(c->core, c->property_name); + c->core->mainloop->defer_free(c->dispatch_event); + dbus_connection_unref(c->connection); + pa_xfree(c); } -pa_dbus_connection* pa_dbus_connection_ref(pa_dbus_connection *c) -{ - assert(c); +pa_dbus_connection* pa_dbus_connection_ref(pa_dbus_connection *c) { + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) > 0); - ++(c->refcount); + PA_REFCNT_INC(c); return c; } -pa_dbus_connection* pa_dbus_bus_get(pa_core *c, DBusBusType type, - DBusError *error) -{ - const char* name; +pa_dbus_connection* pa_dbus_bus_get(pa_core *c, DBusBusType type, DBusError *error) { + + static const char *const prop_name[] = { + [DBUS_BUS_SESSION] = "dbus-connection-session", + [DBUS_BUS_SYSTEM] = "dbus-connection-system", + [DBUS_BUS_STARTER] = "dbus-connection-starter" + }; DBusConnection *conn; pa_dbus_connection *pconn; - switch (type) { - case DBUS_BUS_SYSTEM: - name = "dbus-connection-system"; - break; - case DBUS_BUS_SESSION: - name = "dbus-connection-session"; - break; - case DBUS_BUS_STARTER: - name = "dbus-connection-starter"; - break; - default: - assert(0); /* never reached */ - break; - } + pa_assert(type == DBUS_BUS_SYSTEM || type == DBUS_BUS_SESSION || type == DBUS_BUS_STARTER); - if ((pconn = pa_property_get(c, name))) + if ((pconn = pa_property_get(c, prop_name[type]))) return pa_dbus_connection_ref(pconn); - /* else */ - conn = dbus_bus_get_private(type, error); - if (conn == NULL || dbus_error_is_set(error)) { + if (!(conn = dbus_bus_get_private(type, error))) return NULL; - } - pconn = pa_dbus_connection_new(c, conn, name); + pconn = pa_dbus_connection_new(c, conn, prop_name[type]); - /* don't exit on disconnect */ dbus_connection_set_exit_on_disconnect(conn, FALSE); - /* set up the DBUS call backs */ - dbus_connection_set_dispatch_status_function(conn, dispatch_status, - (void*) pconn, NULL); - dbus_connection_set_watch_functions(conn, - add_watch, - remove_watch, - toggle_watch, - (void*) c, NULL); - dbus_connection_set_timeout_functions(conn, - add_timeout, - remove_timeout, - toggle_timeout, - (void*) c, NULL); + dbus_connection_set_dispatch_status_function(conn, dispatch_status, pconn, NULL); + dbus_connection_set_watch_functions(conn, add_watch, remove_watch, toggle_watch, c, NULL); + dbus_connection_set_timeout_functions(conn, add_timeout, remove_timeout, toggle_timeout, c, NULL); dbus_connection_set_wakeup_main_function(conn, wakeup_main, pconn, NULL); return pconn; -- cgit From a69f4705c5814cbb29e5ab7dab699adf5eb22253 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 8 Aug 2007 23:49:17 +0000 Subject: modernize module-hal-detect.c and check for ALSA pcm_class != modem git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1594 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-hal-detect.c | 566 ++++++++++++++++++++-------------------- 1 file changed, 282 insertions(+), 284 deletions(-) diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index 6ae9cd0c..84ac0ce4 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -1,25 +1,25 @@ /* $Id$ */ /*** - This file is part of PulseAudio. + This file is part of PulseAudio. - Copyright 2006 Lennart Poettering - Copyright 2006 Shams E. King + Copyright 2006 Lennart Poettering + Copyright 2006 Shams E. King - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. - You should have received a copy of the GNU Lesser General Public License - along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. ***/ #ifdef HAVE_CONFIG_H @@ -27,7 +27,6 @@ #endif #include -#include #include #include #include @@ -55,25 +54,6 @@ PA_MODULE_AUTHOR("Shahms King") PA_MODULE_DESCRIPTION("Detect available audio hardware and load matching drivers") PA_MODULE_VERSION(PACKAGE_VERSION) -typedef enum { -#ifdef HAVE_ALSA - CAP_ALSA, -#endif -#ifdef HAVE_OSS - CAP_OSS, -#endif - CAP_MAX -} capability_t; - -static const char* const capabilities[CAP_MAX] = { -#ifdef HAVE_ALSA - [CAP_ALSA] = "alsa", -#endif -#ifdef HAVE_OSS - [CAP_OSS] = "oss", -#endif -}; - struct device { uint32_t index; char *udi; @@ -81,13 +61,10 @@ struct device { struct userdata { pa_core *core; - LibHalContext *ctx; - capability_t capability; - pa_dbus_connection *conn; + LibHalContext *context; + pa_dbus_connection *connection; pa_hashmap *devices; -#if defined(HAVE_ALSA) && defined(HAVE_OSS) - int use_oss; -#endif + const char *capability; }; struct timerdata { @@ -95,23 +72,23 @@ struct timerdata { char *udi; }; -static const char* get_capability_name(capability_t cap) { - if (cap >= CAP_MAX) - return NULL; - return capabilities[cap]; -} +#define CAPABILITY_ALSA "alsa" +#define CAPABILITY_OSS "oss" static void hal_device_free(struct device* d) { + pa_assert(d); + pa_xfree(d->udi); pa_xfree(d); } static void hal_device_free_cb(void *d, PA_GCC_UNUSED void *data) { - hal_device_free((struct device*) d); + hal_device_free(d); } static const char *strip_udi(const char *udi) { const char *slash; + if ((slash = strrchr(udi, '/'))) return slash+1; @@ -119,6 +96,7 @@ static const char *strip_udi(const char *udi) { } #ifdef HAVE_ALSA + typedef enum { ALSA_TYPE_SINK, ALSA_TYPE_SOURCE, @@ -126,59 +104,61 @@ typedef enum { ALSA_TYPE_MAX } alsa_type_t; -static alsa_type_t hal_device_get_alsa_type(LibHalContext *ctx, const char *udi, - DBusError *error) -{ +static alsa_type_t hal_alsa_device_get_type(LibHalContext *context, const char *udi, DBusError *error) { char *type; alsa_type_t t; - type = libhal_device_get_property_string(ctx, udi, "alsa.type", error); - if (!type || dbus_error_is_set(error)) - return FALSE; + if (!(type = libhal_device_get_property_string(context, udi, "alsa.type", error))) + return ALSA_TYPE_OTHER; - if (!strcmp(type, "playback")) { + if (!strcmp(type, "playback")) t = ALSA_TYPE_SINK; - } else if (!strcmp(type, "capture")) { + else if (!strcmp(type, "capture")) t = ALSA_TYPE_SOURCE; - } else { + else t = ALSA_TYPE_OTHER; - } + libhal_free_string(type); return t; } -static int hal_device_get_alsa_card(LibHalContext *ctx, const char *udi, - DBusError *error) -{ - return libhal_device_get_property_int(ctx, udi, "alsa.card", error); -} - -static int hal_device_get_alsa_device(LibHalContext *ctx, const char *udi, - DBusError *error) -{ - return libhal_device_get_property_int(ctx, udi, "alsa.device", error); +static int hal_alsa_device_is_modem(LibHalContext *context, const char *udi, DBusError *error) { + char *class; + int r; + + if (!(class = libhal_device_get_property_string(context, udi, "alsa.pcm_class", error))) + return 0; + + r = strcmp(class, "modem") == 0; + pa_xfree(class); + + return r; } -static pa_module* hal_device_load_alsa(struct userdata *u, const char *udi, - DBusError *error) -{ +static pa_module* hal_device_load_alsa(struct userdata *u, const char *udi) { char args[128]; alsa_type_t type; int device, card; const char *module_name; + DBusError error; + + dbus_error_init(&error); - type = hal_device_get_alsa_type(u->ctx, udi, error); - if (dbus_error_is_set(error) || type == ALSA_TYPE_OTHER) - return NULL; + type = hal_alsa_device_get_type(u->context, udi, &error); + if (dbus_error_is_set(&error) || type == ALSA_TYPE_OTHER) + goto fail; - device = hal_device_get_alsa_device(u->ctx, udi, error); - if (dbus_error_is_set(error) || device != 0) - return NULL; + device = libhal_device_get_property_int(u->context, udi, "alsa.device", &error); + if (dbus_error_is_set(&error) || device != 0) + goto fail; - card = hal_device_get_alsa_card(u->ctx, udi, error); - if (dbus_error_is_set(error)) - return NULL; + card = libhal_device_get_property_int(u->context, udi, "alsa.card", &error); + if (dbus_error_is_set(&error)) + goto fail; + + if (hal_alsa_device_is_modem(u->context, udi, &error)) + goto fail; if (type == ALSA_TYPE_SINK) { module_name = "module-alsa-sink"; @@ -191,58 +171,67 @@ static pa_module* hal_device_load_alsa(struct userdata *u, const char *udi, pa_log_debug("Loading %s with arguments '%s'", module_name, args); return pa_module_load(u->core, module_name, args); + +fail: + if (dbus_error_is_set(&error)) { + pa_log_error("D-Bus error while parsing ALSA data: %s: %s", error.name, error.message); + dbus_error_free(&error); + } + + return NULL; } #endif #ifdef HAVE_OSS -static dbus_bool_t hal_device_is_oss_pcm(LibHalContext *ctx, const char *udi, - DBusError *error) -{ - dbus_bool_t rv = FALSE; - char* type, *device_file = NULL; + +static int hal_oss_device_is_pcm(LibHalContext *context, const char *udi, DBusError *error) { + char *class = NULL, *dev = NULL, *e; int device; + int r = 0; - type = libhal_device_get_property_string(ctx, udi, "oss.type", error); - if (!type || dbus_error_is_set(error)) - return FALSE; + class = libhal_device_get_property_string(context, udi, "oss.type", error); + if (dbus_error_is_set(error) || !class) + goto finish; - if (!strcmp(type, "pcm")) { - char *e; + if (strcmp(class, "pcm")) + goto finish; - device = libhal_device_get_property_int(ctx, udi, "oss.device", error); - if (dbus_error_is_set(error) || device != 0) - goto exit; + dev = libhal_device_get_property_string(context, udi, "oss.device_file", error); + if (dbus_error_is_set(error) || !dev) + goto finish; - device_file = libhal_device_get_property_string(ctx, udi, "oss.device_file", - error); - if (!device_file || dbus_error_is_set(error)) - goto exit; + if ((e = strrchr(dev, '/'))) + if (pa_startswith(e + 1, "audio")) + goto finish; - /* hack to ignore /dev/audio style devices */ - if ((e = strrchr(device_file, '/'))) - rv = !pa_startswith(e + 1, "audio"); - } + device = libhal_device_get_property_int(context, udi, "oss.device", error); + if (dbus_error_is_set(error) || device != 0) + goto finish; -exit: - libhal_free_string(type); - libhal_free_string(device_file); - return rv; + r = 1; + +finish: + + libhal_free_string(class); + libhal_free_string(dev); + + return r; } -static pa_module* hal_device_load_oss(struct userdata *u, const char *udi, - DBusError *error) -{ +static pa_module* hal_device_load_oss(struct userdata *u, const char *udi) { char args[256]; char* device; + DBusError error; + + dbus_error_init(&error); - if (!hal_device_is_oss_pcm(u->ctx, udi, error) || dbus_error_is_set(error)) - return NULL; + if (!hal_oss_device_is_pcm(u->context, udi, &error) || dbus_error_is_set(&error)) + goto fail; - device = libhal_device_get_property_string(u->ctx, udi, "oss.device_file", - error); - if (!device || dbus_error_is_set(error)) - return NULL; + device = libhal_device_get_property_string(u->context, udi, "oss.device_file", &error); + if (!device || dbus_error_is_set(&error)) + goto fail; pa_snprintf(args, sizeof(args), "device=%s sink_name=oss_output.%s source_name=oss_input.%s", device, strip_udi(udi), strip_udi(udi)); libhal_free_string(device); @@ -250,139 +239,167 @@ static pa_module* hal_device_load_oss(struct userdata *u, const char *udi, pa_log_debug("Loading module-oss with arguments '%s'", args); return pa_module_load(u->core, "module-oss", args); + +fail: + if (dbus_error_is_set(&error)) { + pa_log_error("D-Bus error while parsing OSS data: %s: %s", error.name, error.message); + dbus_error_free(&error); + } + + return NULL; } #endif -static dbus_bool_t hal_device_add(struct userdata *u, const char *udi, - DBusError *error) -{ +static int hal_device_add(struct userdata *u, const char *udi) { pa_module* m = NULL; struct device *d; - switch(u->capability) { + pa_assert(u); + pa_assert(u->capability); + #ifdef HAVE_ALSA - case CAP_ALSA: - m = hal_device_load_alsa(u, udi, error); - break; + if (strcmp(u->capability, CAPABILITY_ALSA) == 0) + m = hal_device_load_alsa(u, udi); #endif #ifdef HAVE_OSS - case CAP_OSS: -#ifdef HAVE_ALSA - if (u->use_oss) -#endif - m = hal_device_load_oss(u, udi, error); - break; + if (strcmp(u->capability, CAPABILITY_OSS) == 0) + m = hal_device_load_oss(u, udi); #endif - default: - assert(FALSE); /* never reached */ - break; - } - if (!m || dbus_error_is_set(error)) - return FALSE; + if (!m) + return -1; d = pa_xnew(struct device, 1); d->udi = pa_xstrdup(udi); d->index = m->index; - pa_hashmap_put(u->devices, d->udi, d); - return TRUE; + return 0; } -static int hal_device_add_all(struct userdata *u, capability_t capability) -{ +static int hal_device_add_all(struct userdata *u, const char *capability) { DBusError error; - int i,n,count; - dbus_bool_t r; + int i, n, count = 0; char** udis; - const char* cap = get_capability_name(capability); - assert(capability < CAP_MAX); - - pa_log_info("Trying capability %u (%s)", capability, cap); + pa_assert(u); + pa_assert(!u->capability); + dbus_error_init(&error); - udis = libhal_find_device_by_capability(u->ctx, cap, &n, &error); + + pa_log_info("Trying capability %s", capability); + + udis = libhal_find_device_by_capability(u->context, capability, &n, &error); if (dbus_error_is_set(&error)) { - pa_log_error("Error finding devices: %s: %s", error.name, - error.message); + pa_log_error("Error finding devices: %s: %s", error.name, error.message); dbus_error_free(&error); return -1; } - count = 0; - u->capability = capability; - for (i = 0; i < n; ++i) { - r = hal_device_add(u, udis[i], &error); - if (dbus_error_is_set(&error)) { - pa_log_error("Error adding device: %s: %s", error.name, - error.message); - dbus_error_free(&error); - count = -1; - break; + + if (n > 0) { + u->capability = capability; + + for (i = 0; i < n; i++) { + if (hal_device_add(u, udis[i]) < 0) + pa_log_debug("Not loaded device %s", udis[i]); + else + count++; } - if (r) - ++count; } libhal_free_string_array(udis); return count; } -static dbus_bool_t device_has_capability(LibHalContext *ctx, const char *udi, - const char* cap, DBusError *error) -{ +static dbus_bool_t device_has_capability(LibHalContext *context, const char *udi, const char* cap, DBusError *error){ dbus_bool_t has_prop; - has_prop = libhal_device_property_exists(ctx, udi, "info.capabilities", - error); + + has_prop = libhal_device_property_exists(context, udi, "info.capabilities", error); if (!has_prop || dbus_error_is_set(error)) return FALSE; - return libhal_device_query_capability(ctx, udi, cap, error); + return libhal_device_query_capability(context, udi, cap, error); } -static void device_added_time_cb(pa_mainloop_api *ea, pa_time_event *ev, - const struct timeval *tv, void *userdata) -{ +static void device_added_time_cb(pa_mainloop_api *ea, pa_time_event *ev, const struct timeval *tv, void *userdata) { DBusError error; - struct timerdata *td = (struct timerdata*) userdata; + struct timerdata *td = userdata; + int b; dbus_error_init(&error); - if (libhal_device_exists(td->u->ctx, td->udi, &error)) - hal_device_add(td->u, td->udi, &error); - + + b = libhal_device_exists(td->u->context, td->udi, &error); + if (dbus_error_is_set(&error)) { - pa_log_error("Error adding device: %s: %s", error.name, - error.message); + pa_log_error("Error adding device: %s: %s", error.name, error.message); dbus_error_free(&error); - } + } else if (b) + hal_device_add(td->u, td->udi); pa_xfree(td->udi); pa_xfree(td); ea->time_free(ev); } -static void device_added_cb(LibHalContext *ctx, const char *udi) -{ +static void device_added_cb(LibHalContext *context, const char *udi) { DBusError error; struct timeval tv; - dbus_bool_t has_cap; struct timerdata *t; - struct userdata *u = (struct userdata*) libhal_ctx_get_user_data(ctx); - const char* cap = get_capability_name(u->capability); + struct userdata *u; + int good = 0; + pa_assert_se(u = libhal_ctx_get_user_data(context)); + pa_log_debug("HAL Device added: %s", udi); dbus_error_init(&error); - has_cap = device_has_capability(ctx, udi, cap, &error); - if (dbus_error_is_set(&error)) { - pa_log_error("Error getting capability: %s: %s", error.name, - error.message); - dbus_error_free(&error); - return; - } - /* skip it */ - if (!has_cap) + if (u->capability) { + + good = device_has_capability(context, udi, u->capability, &error); + + if (dbus_error_is_set(&error)) { + pa_log_error("Error getting capability: %s: %s", error.name, error.message); + dbus_error_free(&error); + return; + } + + } else { + +#ifdef HAVE_ALSA + good = device_has_capability(context, udi, CAPABILITY_ALSA, &error); + + if (dbus_error_is_set(&error)) { + pa_log_error("Error getting capability: %s: %s", error.name, error.message); + dbus_error_free(&error); + return; + } + + if (good) + u->capability = CAPABILITY_ALSA; +#endif +#if defined(HAVE_OSS) && defined(HAVE_ALSA) + if (!good) { +#endif +#ifdef HAS_OSS + good = device_has_capability(context, udi, CAPABILITY_OSS, &error); + + if (dbus_error_is_set(&error)) { + pa_log_error("Error getting capability: %s: %s", error.name, error.message); + dbus_error_free(&error); + return; + } + + if (good) + u->capability = CAPABILITY_OSS; + +#endif +#if defined(HAVE_OSS) && defined(HAVE_ALSA) + } +#endif + } + + if (!good) return; /* actually add the device 1/2 second later */ @@ -392,104 +409,81 @@ static void device_added_cb(LibHalContext *ctx, const char *udi) pa_gettimeofday(&tv); pa_timeval_add(&tv, 500000); - u->core->mainloop->time_new(u->core->mainloop, &tv, - device_added_time_cb, t); + u->core->mainloop->time_new(u->core->mainloop, &tv, device_added_time_cb, t); } -static void device_removed_cb(LibHalContext* ctx, const char *udi) -{ +static void device_removed_cb(LibHalContext* context, const char *udi) { struct device *d; - struct userdata *u = (struct userdata*) libhal_ctx_get_user_data(ctx); + struct userdata *u; + + pa_assert_se(u = libhal_ctx_get_user_data(context)); pa_log_debug("Device removed: %s", udi); + if ((d = pa_hashmap_remove(u->devices, udi))) { pa_module_unload_by_index(u->core, d->index); hal_device_free(d); } } -static void new_capability_cb(LibHalContext *ctx, const char *udi, - const char* capability) -{ - struct userdata *u = (struct userdata*) libhal_ctx_get_user_data(ctx); - const char* capname = get_capability_name(u->capability); +static void new_capability_cb(LibHalContext *context, const char *udi, const char* capability) { + struct userdata *u; + + pa_assert_se(u = libhal_ctx_get_user_data(context)); - if (capname && !strcmp(capname, capability)) { + if (!u->capability || strcmp(u->capability, capability) == 0) /* capability we care about, pretend it's a new device */ - device_added_cb(ctx, udi); - } + device_added_cb(context, udi); } -static void lost_capability_cb(LibHalContext *ctx, const char *udi, - const char* capability) -{ - struct userdata *u = (struct userdata*) libhal_ctx_get_user_data(ctx); - const char* capname = get_capability_name(u->capability); +static void lost_capability_cb(LibHalContext *context, const char *udi, const char* capability) { + struct userdata *u; - if (capname && !strcmp(capname, capability)) { - /* capability we care about, pretend it was removed */ - device_removed_cb(ctx, udi); - } -} + pa_assert_se(u = libhal_ctx_get_user_data(context)); -#if 0 -static void property_modified_cb(LibHalContext *ctx, const char *udi, - const char* key, - dbus_bool_t is_removed, - dbus_bool_t is_added) -{ + if (u->capability && strcmp(u->capability, capability) == 0) + /* capability we care about, pretend it was removed */ + device_removed_cb(context, udi); } -#endif -static void pa_hal_context_free(LibHalContext* hal_ctx) -{ +static void hal_context_free(LibHalContext* hal_context) { DBusError error; dbus_error_init(&error); - libhal_ctx_shutdown(hal_ctx, &error); - libhal_ctx_free(hal_ctx); + + libhal_ctx_shutdown(hal_context, &error); + libhal_ctx_free(hal_context); - if (dbus_error_is_set(&error)) { + if (dbus_error_is_set(&error)) dbus_error_free(&error); - } } -static void userdata_free(struct userdata *u) { - pa_hal_context_free(u->ctx); - /* free the devices with the hashmap */ - pa_hashmap_free(u->devices, hal_device_free_cb, NULL); - pa_dbus_connection_unref(u->conn); - pa_xfree(u); -} - -static LibHalContext* pa_hal_context_new(pa_core* c, DBusConnection *conn) -{ +static LibHalContext* hal_context_new(pa_core* c, DBusConnection *conn) { DBusError error; - LibHalContext *hal_ctx = NULL; + LibHalContext *hal_context = NULL; dbus_error_init(&error); - if (!(hal_ctx = libhal_ctx_new())) { + + if (!(hal_context = libhal_ctx_new())) { pa_log_error("libhal_ctx_new() failed"); goto fail; } - if (!libhal_ctx_set_dbus_connection(hal_ctx, conn)) { - pa_log_error("Error establishing DBUS connection: %s: %s", - error.name, error.message); + if (!libhal_ctx_set_dbus_connection(hal_context, conn)) { + pa_log_error("Error establishing DBUS connection: %s: %s", error.name, error.message); goto fail; } - if (!libhal_ctx_init(hal_ctx, &error)) { - pa_log_error("Couldn't connect to hald: %s: %s", - error.name, error.message); + if (!libhal_ctx_init(hal_context, &error)) { + pa_log_error("Couldn't connect to hald: %s: %s", error.name, error.message); goto fail; } - return hal_ctx; + return hal_context; fail: - if (hal_ctx) - pa_hal_context_free(hal_ctx); + if (hal_context) + hal_context_free(hal_context); if (dbus_error_is_set(&error)) dbus_error_free(&error); @@ -501,78 +495,82 @@ int pa__init(pa_core *c, pa_module*m) { DBusError error; pa_dbus_connection *conn; struct userdata *u = NULL; - LibHalContext *hal_ctx = NULL; + LibHalContext *hal_context = NULL; int n = 0; - - assert(c); - assert(m); + + pa_assert(c); + pa_assert(m); dbus_error_init(&error); + if (!(conn = pa_dbus_bus_get(c, DBUS_BUS_SYSTEM, &error))) { - pa_log_error("Unable to contact DBUS system bus: %s: %s", - error.name, error.message); + pa_log_error("Unable to contact DBUS system bus: %s: %s", error.name, error.message); dbus_error_free(&error); return -1; } - if (!(hal_ctx = pa_hal_context_new(c, pa_dbus_connection_get(conn)))) { + if (!(hal_context = hal_context_new(c, pa_dbus_connection_get(conn)))) { /* pa_hal_context_new() logs appropriate errors */ + pa_dbus_connection_unref(conn); return -1; } u = pa_xnew(struct userdata, 1); u->core = c; - u->ctx = hal_ctx; - u->conn = conn; - u->devices = pa_hashmap_new(pa_idxset_string_hash_func, - pa_idxset_string_compare_func); - m->userdata = (void*) u; + u->context = hal_context; + u->connection = conn; + u->devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); + u->capability = NULL; + m->userdata = u; #ifdef HAVE_ALSA - n = hal_device_add_all(u, CAP_ALSA); + n = hal_device_add_all(u, CAPABILITY_ALSA); #endif #if defined(HAVE_ALSA) && defined(HAVE_OSS) - u->use_oss = 0; - - if (n <= 0) { -#endif + if (n <= 0) +#endif #ifdef HAVE_OSS - n += hal_device_add_all(u, CAP_OSS); + n += hal_device_add_all(u, CAPABILITY_OSS); #endif -#if defined(HAVE_ALSA) && defined(HAVE_OSS) - /* We found something with OSS, but didn't find anything with - * ALSA. Then let's use only OSS from now on. */ - if (n > 0) - u->use_oss = 1; - } -#endif - - libhal_ctx_set_user_data(hal_ctx, u); - libhal_ctx_set_device_added(hal_ctx, device_added_cb); - libhal_ctx_set_device_removed(hal_ctx, device_removed_cb); - libhal_ctx_set_device_new_capability(hal_ctx, new_capability_cb); - libhal_ctx_set_device_lost_capability(hal_ctx, lost_capability_cb); - /*libhal_ctx_set_device_property_modified(hal_ctx, property_modified_cb);*/ + libhal_ctx_set_user_data(hal_context, u); + libhal_ctx_set_device_added(hal_context, device_added_cb); + libhal_ctx_set_device_removed(hal_context, device_removed_cb); + libhal_ctx_set_device_new_capability(hal_context, new_capability_cb); + libhal_ctx_set_device_lost_capability(hal_context, lost_capability_cb); dbus_error_init(&error); - if (!libhal_device_property_watch_all(hal_ctx, &error)) { - pa_log_error("error monitoring device list: %s: %s", - error.name, error.message); + + if (!libhal_device_property_watch_all(hal_context, &error)) { + pa_log_error("Error monitoring device list: %s: %s", error.name, error.message); dbus_error_free(&error); - userdata_free(u); + pa__done(c, m); return -1; } - pa_log_info("loaded %i modules.", n); + pa_log_info("Loaded %i modules.", n); return 0; } void pa__done(PA_GCC_UNUSED pa_core *c, pa_module *m) { - assert (c && m); + struct userdata *u; + + pa_assert(c); + pa_assert(m); + + if (!(u = m->userdata)) + return; - /* free the user data */ - userdata_free(m->userdata); + if (u->context) + hal_context_free(u->context); + + if (u->devices) + pa_hashmap_free(u->devices, hal_device_free_cb, NULL); + + if (u->connection) + pa_dbus_connection_unref(u->connection); + + pa_xfree(u); } -- cgit From 23ba12572589f1912c2d2bb6edce4d47cbcb74bb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Aug 2007 13:36:06 +0000 Subject: fix bug in handling of defer events git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1595 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/mainloop.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index 43cbb19f..eaa41d51 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -574,6 +574,7 @@ static void cleanup_defer_events(pa_mainloop *m, int force) { } if (!e->dead && e->enabled) { + e->enabled = 0; assert(m->n_enabled_defer_events > 0); m->n_enabled_defer_events--; } -- cgit From 0c29a2f1db37ea5c07dc90f282a4e78135e05909 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Aug 2007 13:47:25 +0000 Subject: add new function pa_scache_play_item_by_name git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1596 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core-scache.c | 13 +++++++++++++ src/pulsecore/core-scache.h | 1 + 2 files changed, 14 insertions(+) diff --git a/src/pulsecore/core-scache.c b/src/pulsecore/core-scache.c index d5fe6f20..8a7ba13d 100644 --- a/src/pulsecore/core-scache.c +++ b/src/pulsecore/core-scache.c @@ -304,6 +304,19 @@ int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t return 0; } +int pa_scache_play_item_by_name(pa_core *c, const char *name, const char*sink_name, pa_volume_t volume, int autoload) { + pa_sink *sink; + + pa_assert(c); + pa_assert(name); + + if (!(sink = pa_namereg_get(c, sink_name, PA_NAMEREG_SINK, autoload))) + return -1; + + return pa_scache_play_item(c, name, sink, volume); +} + + const char * pa_scache_get_name_by_id(pa_core *c, uint32_t id) { pa_scache_entry *e; assert(c && id != PA_IDXSET_INVALID); diff --git a/src/pulsecore/core-scache.h b/src/pulsecore/core-scache.h index bbf13f15..ab7ec0ef 100644 --- a/src/pulsecore/core-scache.h +++ b/src/pulsecore/core-scache.h @@ -55,6 +55,7 @@ int pa_scache_add_directory_lazy(pa_core *c, const char *pathname); int pa_scache_remove_item(pa_core *c, const char *name); int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t volume); +int pa_scache_play_item_by_name(pa_core *c, const char *name, const char*sink_name, pa_volume_t volume, int autoload); void pa_scache_free(pa_core *c); const char *pa_scache_get_name_by_id(pa_core *c, uint32_t id); -- cgit From 33cd5e26cf8f7d43902b76172d8027f347e682cb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Aug 2007 13:49:27 +0000 Subject: listen for HAL ACL events; play an event sound on hw coldplug, hotplug and ACL access git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1597 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-hal-detect.c | 186 +++++++++++++++++++++++++++++++++------- 1 file changed, 157 insertions(+), 29 deletions(-) diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index 84ac0ce4..ca22d70b 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -44,6 +44,8 @@ #include #include #include +#include +#include #include @@ -57,6 +59,7 @@ PA_MODULE_VERSION(PACKAGE_VERSION) struct device { uint32_t index; char *udi; + char *sink_name, *source_name; }; struct userdata { @@ -79,6 +82,8 @@ static void hal_device_free(struct device* d) { pa_assert(d); pa_xfree(d->udi); + pa_xfree(d->sink_name); + pa_xfree(d->source_name); pa_xfree(d); } @@ -136,15 +141,22 @@ static int hal_alsa_device_is_modem(LibHalContext *context, const char *udi, DBu return r; } -static pa_module* hal_device_load_alsa(struct userdata *u, const char *udi) { +static pa_module* hal_device_load_alsa(struct userdata *u, const char *udi, char **sink_name, char **source_name) { char args[128]; alsa_type_t type; int device, card; const char *module_name; DBusError error; + pa_module *m; dbus_error_init(&error); + pa_assert(u); + pa_assert(sink_name); + pa_assert(source_name); + + *sink_name = *source_name = NULL; + type = hal_alsa_device_get_type(u->context, udi, &error); if (dbus_error_is_set(&error) || type == ALSA_TYPE_OTHER) goto fail; @@ -161,16 +173,28 @@ static pa_module* hal_device_load_alsa(struct userdata *u, const char *udi) { goto fail; if (type == ALSA_TYPE_SINK) { + *sink_name = pa_sprintf_malloc("alsa_output.%s", strip_udi(udi)); + module_name = "module-alsa-sink"; - pa_snprintf(args, sizeof(args), "device=hw:%u sink_name=alsa_output.%s", card, strip_udi(udi)); + pa_snprintf(args, sizeof(args), "device=hw:%u sink_name=%s", card, *sink_name); } else { + *source_name = pa_sprintf_malloc("alsa_output.%s", strip_udi(udi)); + module_name = "module-alsa-source"; - pa_snprintf(args, sizeof(args), "device=hw:%u source_name=alsa_input.%s", card, strip_udi(udi)); + pa_snprintf(args, sizeof(args), "device=hw:%u source_name=%s", card, *source_name); } pa_log_debug("Loading %s with arguments '%s'", module_name, args); - return pa_module_load(u->core, module_name, args); + m = pa_module_load(u->core, module_name, args); + + if (!m) { + pa_xfree(*sink_name); + pa_xfree(*source_name); + *sink_name = *source_name = NULL; + } + + return m; fail: if (dbus_error_is_set(&error)) { @@ -219,13 +243,20 @@ finish: return r; } -static pa_module* hal_device_load_oss(struct userdata *u, const char *udi) { +static pa_module* hal_device_load_oss(struct userdata *u, const char *udi, char **sink_name, char **source_name) { char args[256]; char* device; DBusError error; + pa_module *m; dbus_error_init(&error); + pa_assert(u); + pa_assert(sink_name); + pa_assert(source_name); + + *sink_name = *source_name = NULL; + if (!hal_oss_device_is_pcm(u->context, udi, &error) || dbus_error_is_set(&error)) goto fail; @@ -233,12 +264,23 @@ static pa_module* hal_device_load_oss(struct userdata *u, const char *udi) { if (!device || dbus_error_is_set(&error)) goto fail; - pa_snprintf(args, sizeof(args), "device=%s sink_name=oss_output.%s source_name=oss_input.%s", device, strip_udi(udi), strip_udi(udi)); + *sink_name = pa_sprintf_malloc("alsa_output.%s", strip_udi(udi)); + *source_name = pa_sprintf_malloc("alsa_output.%s", strip_udi(udi)); + + pa_snprintf(args, sizeof(args), "device=%s sink_name=%s source_name=%s", device, sink_name, source_name); libhal_free_string(device); pa_log_debug("Loading module-oss with arguments '%s'", args); - return pa_module_load(u->core, "module-oss", args); + m = pa_module_load(u->core, "module-oss", args); + + if (!m) { + pa_xfree(*sink_name); + pa_xfree(*source_name); + *sink_name = *source_name = NULL; + } + + return m; fail: if (dbus_error_is_set(&error)) { @@ -250,31 +292,34 @@ fail: } #endif -static int hal_device_add(struct userdata *u, const char *udi) { +static struct device* hal_device_add(struct userdata *u, const char *udi) { pa_module* m = NULL; struct device *d; + char *sink_name = NULL, *source_name = NULL; pa_assert(u); pa_assert(u->capability); #ifdef HAVE_ALSA if (strcmp(u->capability, CAPABILITY_ALSA) == 0) - m = hal_device_load_alsa(u, udi); + m = hal_device_load_alsa(u, udi, &sink_name, &source_name); #endif #ifdef HAVE_OSS if (strcmp(u->capability, CAPABILITY_OSS) == 0) - m = hal_device_load_oss(u, udi); + m = hal_device_load_oss(u, udi, &sink_name, &source_name); #endif if (!m) - return -1; + return NULL; d = pa_xnew(struct device, 1); d->udi = pa_xstrdup(udi); d->index = m->index; + d->sink_name = sink_name; + d->source_name = source_name; pa_hashmap_put(u->devices, d->udi, d); - return 0; + return d; } static int hal_device_add_all(struct userdata *u, const char *capability) { @@ -300,10 +345,15 @@ static int hal_device_add_all(struct userdata *u, const char *capability) { u->capability = capability; for (i = 0; i < n; i++) { - if (hal_device_add(u, udis[i]) < 0) + struct device *d; + + if (!(d = hal_device_add(u, udis[i]))) pa_log_debug("Not loaded device %s", udis[i]); - else + else { + if (d->sink_name) + pa_scache_play_item_by_name(u->core, "pulse-coldplug", d->sink_name, PA_VOLUME_NORM, 0); count++; + } } } @@ -325,6 +375,7 @@ static void device_added_time_cb(pa_mainloop_api *ea, pa_time_event *ev, const s DBusError error; struct timerdata *td = userdata; int b; + struct device *d; dbus_error_init(&error); @@ -333,8 +384,14 @@ static void device_added_time_cb(pa_mainloop_api *ea, pa_time_event *ev, const s if (dbus_error_is_set(&error)) { pa_log_error("Error adding device: %s: %s", error.name, error.message); dbus_error_free(&error); - } else if (b) - hal_device_add(td->u, td->udi); + } else if (b) { + if (!(d = hal_device_add(td->u, td->udi))) + pa_log_debug("Not loaded device %s", td->udi); + else { + if (d->sink_name) + pa_scache_play_item_by_name(td->u->core, "pulse-hotplug", d->sink_name, PA_VOLUME_NORM, 0); + } + } pa_xfree(td->udi); pa_xfree(td); @@ -446,6 +503,66 @@ static void lost_capability_cb(LibHalContext *context, const char *udi, const ch device_removed_cb(context, udi); } + +static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, void *userdata) { + struct userdata*u = userdata; + DBusError error; + + pa_assert(bus); + pa_assert(message); + pa_assert(u); + + dbus_error_init(&error); + + pa_log_debug("dbus: interface=%s, path=%s, member=%s\n", + dbus_message_get_interface(message), + dbus_message_get_path(message), + dbus_message_get_member(message)); + + if (dbus_message_is_signal(message, "org.freedesktop.Hal.Device.AccessControl", "ACLAdded") || + dbus_message_is_signal(message, "org.freedesktop.Hal.Device.AccessControl", "ACLRemoved")) { + uint32_t uid; + int suspend = strcmp(dbus_message_get_member(message), "ACLRemoved") == 0; + + if (!dbus_message_get_args(message, &error, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INVALID) || dbus_error_is_set(&error)) { + pa_log_error("Failed to parse ACL message: %s: %s", error.name, error.message); + goto finish; + } + + if (uid == getuid() || uid == geteuid()) { + struct device *d; + const char *udi; + + udi = dbus_message_get_path(message); + + if ((d = pa_hashmap_get(u->devices, udi))) { + + if (d->sink_name) { + pa_sink *sink; + + if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK, 0))) + if (pa_sink_suspend(sink, suspend) >= 0) + pa_scache_play_item_by_name(u->core, "pulse-access", d->sink_name, PA_VOLUME_NORM, 0); + } + + if (d->source_name) { + pa_source *source; + + if ((source = pa_namereg_get(u->core, d->source_name, PA_NAMEREG_SOURCE, 0))) + pa_source_suspend(source, suspend); + } + } + + } + + } + +finish: + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_HANDLED; +} + static void hal_context_free(LibHalContext* hal_context) { DBusError error; @@ -454,8 +571,7 @@ static void hal_context_free(LibHalContext* hal_context) { libhal_ctx_shutdown(hal_context, &error); libhal_ctx_free(hal_context); - if (dbus_error_is_set(&error)) - dbus_error_free(&error); + dbus_error_free(&error); } static LibHalContext* hal_context_new(pa_core* c, DBusConnection *conn) { @@ -485,8 +601,7 @@ fail: if (hal_context) hal_context_free(hal_context); - if (dbus_error_is_set(&error)) - dbus_error_free(&error); + dbus_error_free(&error); return NULL; } @@ -503,16 +618,17 @@ int pa__init(pa_core *c, pa_module*m) { dbus_error_init(&error); - if (!(conn = pa_dbus_bus_get(c, DBUS_BUS_SYSTEM, &error))) { + if (!(conn = pa_dbus_bus_get(c, DBUS_BUS_SYSTEM, &error)) || dbus_error_is_set(&error)) { + if (conn) + pa_dbus_connection_unref(conn); pa_log_error("Unable to contact DBUS system bus: %s: %s", error.name, error.message); - dbus_error_free(&error); - return -1; + goto fail; } if (!(hal_context = hal_context_new(c, pa_dbus_connection_get(conn)))) { /* pa_hal_context_new() logs appropriate errors */ pa_dbus_connection_unref(conn); - return -1; + goto fail; } u = pa_xnew(struct userdata, 1); @@ -539,18 +655,30 @@ int pa__init(pa_core *c, pa_module*m) { libhal_ctx_set_device_new_capability(hal_context, new_capability_cb); libhal_ctx_set_device_lost_capability(hal_context, lost_capability_cb); - dbus_error_init(&error); - if (!libhal_device_property_watch_all(hal_context, &error)) { pa_log_error("Error monitoring device list: %s: %s", error.name, error.message); - dbus_error_free(&error); - pa__done(c, m); - return -1; + goto fail; } + if (!dbus_connection_add_filter(pa_dbus_connection_get(conn), filter_cb, u, NULL)) { + pa_log_error("Failed to add filter function"); + goto fail; + } + + dbus_bus_add_match(pa_dbus_connection_get(conn), "type='signal',sender='org.freedesktop.Hal', interface='org.freedesktop.Hal.Device.AccessControl'", &error); + if (dbus_error_is_set(&error)) { + pa_log_error("Unable to subscribe to HAL ACL signals: %s: %s", error.name, error.message); + goto fail; + } + pa_log_info("Loaded %i modules.", n); return 0; + +fail: + dbus_error_free(&error); + pa__done(c, m); + return -1; } -- cgit From eaddc0195cf12fa76430d843026188dda6d27aaf Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Aug 2007 16:27:24 +0000 Subject: by default, store esd socket in /tmp/.esd-`id -u`/socket, instead of /tmp/.esd/socket, to allow multiple simultaneous esd instances. this is only compatible with a patched esd, which however ubuntu and fedora ship now. other distros need to patch their esd as well, or may pass socket=/tmp/.esd/socket to module-protocol-esound-unix git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1598 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-protocol-stub.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/modules/module-protocol-stub.c b/src/modules/module-protocol-stub.c index 5c8733fb..3edb59e5 100644 --- a/src/modules/module-protocol-stub.c +++ b/src/modules/module-protocol-stub.c @@ -154,7 +154,6 @@ #define protocol_free pa_protocol_esound_free #define TCPWRAP_SERVICE "esound" #define IPV4_PORT ESD_DEFAULT_PORT - #define UNIX_SOCKET ESD_UNIX_SOCKET_NAME #define MODULE_ARGUMENTS_COMMON "sink", "source", "auth-anonymous", "cookie", #ifdef USE_TCP_SOCKETS #include "module-esound-protocol-tcp-symdef.h" @@ -219,6 +218,10 @@ int pa__init(pa_core *c, pa_module*m) { pa_socket_server *s; int r; char tmp[PATH_MAX]; + +#if defined(USE_PROTOCOL_ESOUND) + char tmp2[PATH_MAX]; +#endif #endif assert(c && m); @@ -262,11 +265,12 @@ int pa__init(pa_core *c, pa_module*m) { #else - pa_runtime_path(pa_modargs_get_value(ma, "socket", UNIX_SOCKET), tmp, sizeof(tmp)); - u->socket_path = pa_xstrdup(tmp); - #if defined(USE_PROTOCOL_ESOUND) + snprintf(tmp2, sizeof(tmp2), "/tmp/.esd-%lu/socket", (unsigned long) getuid()); + pa_runtime_path(pa_modargs_get_value(ma, "socket", tmp2), tmp, sizeof(tmp)); + u->socket_path = pa_xstrdup(tmp); + /* This socket doesn't reside in our own runtime dir but in * /tmp/.esd/, hence we have to create the dir first */ @@ -274,6 +278,10 @@ int pa__init(pa_core *c, pa_module*m) { pa_log("Failed to create socket directory '%s': %s\n", u->socket_path, pa_cstrerror(errno)); goto fail; } + +#else + pa_runtime_path(pa_modargs_get_value(ma, "socket", UNIX_SOCKET), tmp, sizeof(tmp)); + u->socket_path = pa_xstrdup(tmp); #endif if ((r = pa_unix_socket_remove_stale(tmp)) < 0) { -- cgit From ed01e1adb52c804bc43a4ba7b5a7060071a60030 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Aug 2007 17:52:13 +0000 Subject: don't hit an assert when we cannot resume a device git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1599 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 6 ++++-- src/modules/module-alsa-source.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 708dd1f4..1a69954c 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -337,8 +337,10 @@ static int unsuspend(struct userdata *u) { return 0; fail: - snd_pcm_close(u->pcm_handle); - u->pcm_handle = NULL; + if (u->pcm_handle) { + snd_pcm_close(u->pcm_handle); + u->pcm_handle = NULL; + } return -1; } diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 61035c76..553d0283 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -325,8 +325,10 @@ static int unsuspend(struct userdata *u) { return 0; fail: - snd_pcm_close(u->pcm_handle); - u->pcm_handle = NULL; + if (u->pcm_handle) { + snd_pcm_close(u->pcm_handle); + u->pcm_handle = NULL; + } return -1; } -- cgit From 30ccf9a5c9b31fcb370d3c724a1a02fdea94ce65 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Aug 2007 21:05:20 +0000 Subject: add a couple of additional hooks for modules to use git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1600 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core.c | 32 ++++++++++++++++++++++++++++---- src/pulsecore/core.h | 16 ++++++++++++++-- src/pulsecore/sink-input.c | 7 ++++++- src/pulsecore/sink.c | 11 +++++++++-- src/pulsecore/source-output.c | 11 +++++++++-- src/pulsecore/source.c | 11 +++++++++-- 6 files changed, 75 insertions(+), 13 deletions(-) diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c index 1a0e50bb..2cdd4a8e 100644 --- a/src/pulsecore/core.c +++ b/src/pulsecore/core.c @@ -164,10 +164,22 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { c->is_system_instance = 0; - pa_hook_init(&c->hook_sink_input_new, c); + pa_hook_init(&c->hook_sink_new, c); + pa_hook_init(&c->hook_sink_new_post, c); pa_hook_init(&c->hook_sink_disconnect, c); - pa_hook_init(&c->hook_source_output_new, c); + pa_hook_init(&c->hook_sink_disconnect_post, c); + pa_hook_init(&c->hook_source_new, c); + pa_hook_init(&c->hook_source_new_post, c); pa_hook_init(&c->hook_source_disconnect, c); + pa_hook_init(&c->hook_source_disconnect_post, c); + pa_hook_init(&c->hook_sink_input_new, c); + pa_hook_init(&c->hook_sink_input_new_post, c); + pa_hook_init(&c->hook_sink_input_disconnect, c); + pa_hook_init(&c->hook_sink_input_disconnect_post, c); + pa_hook_init(&c->hook_source_output_new, c); + pa_hook_init(&c->hook_source_output_new_post, c); + pa_hook_init(&c->hook_source_output_disconnect, c); + pa_hook_init(&c->hook_source_output_disconnect_post, c); pa_property_init(c); @@ -226,10 +238,22 @@ static void core_free(pa_object *o) { c->mainloop->io_free(c->asyncmsgq_event); - pa_hook_free(&c->hook_sink_input_new); + pa_hook_free(&c->hook_sink_new); + pa_hook_free(&c->hook_sink_new_post); pa_hook_free(&c->hook_sink_disconnect); - pa_hook_free(&c->hook_source_output_new); + pa_hook_free(&c->hook_sink_disconnect_post); + pa_hook_free(&c->hook_source_new); + pa_hook_free(&c->hook_source_new_post); pa_hook_free(&c->hook_source_disconnect); + pa_hook_free(&c->hook_source_disconnect_post); + pa_hook_free(&c->hook_sink_input_new); + pa_hook_free(&c->hook_sink_input_new_post); + pa_hook_free(&c->hook_sink_input_disconnect); + pa_hook_free(&c->hook_sink_input_disconnect_post); + pa_hook_free(&c->hook_source_output_new); + pa_hook_free(&c->hook_source_output_new_post); + pa_hook_free(&c->hook_source_output_disconnect); + pa_hook_free(&c->hook_source_output_disconnect_post); pa_xfree(c); } diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index a64f2179..394785f2 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -88,10 +88,22 @@ struct pa_core { /* hooks */ pa_hook - hook_sink_input_new, + hook_sink_new, + hook_sink_new_post, hook_sink_disconnect, + hook_sink_disconnect_post, + hook_source_new, + hook_source_new_post, + hook_source_disconnect, + hook_source_disconnect_post, + hook_sink_input_new, + hook_sink_input_new_post, + hook_sink_input_disconnect, + hook_sink_input_disconnect_post, hook_source_output_new, - hook_source_disconnect; + hook_source_output_new_post, + hook_source_output_disconnect, + hook_source_output_disconnect_post; pa_asyncmsgq *asyncmsgq; pa_io_event *asyncmsgq_event; diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 0a7033d0..d1bf0acc 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -249,6 +249,8 @@ void pa_sink_input_disconnect(pa_sink_input *i) { pa_assert(i); pa_return_if_fail(i->state != PA_SINK_INPUT_DISCONNECTED); + pa_hook_fire(&i->sink->core->hook_sink_input_disconnect, i); + if (i->sync_prev) i->sync_prev->sync_next = i->sync_next; if (i->sync_next) @@ -265,12 +267,14 @@ void pa_sink_input_disconnect(pa_sink_input *i) { sink_input_set_state(i, PA_SINK_INPUT_DISCONNECTED); pa_sink_update_status(i->sink); - i->sink = NULL; i->peek = NULL; i->drop = NULL; i->kill = NULL; i->get_latency = NULL; i->underrun = NULL; + + pa_hook_fire(&i->sink->core->hook_sink_input_disconnect_post, i); + i->sink = NULL; pa_sink_input_unref(i); } @@ -309,6 +313,7 @@ void pa_sink_input_put(pa_sink_input *i) { pa_sink_update_status(i->sink); pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index); + pa_hook_fire(&i->sink->core->hook_sink_input_new_post, i); } void pa_sink_input_kill(pa_sink_input*i) { diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 150e4cb9..905fe3ff 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -80,6 +80,9 @@ pa_sink* pa_sink_new( pa_return_null_if_fail(!driver || pa_utf8_valid(driver)); pa_return_null_if_fail(name && pa_utf8_valid(name) && *name); + if (pa_hook_fire(&core->hook_sink_new, NULL) < 0) /* FIXME */ + return NULL; + s = pa_msgobject_new(pa_sink); if (!(name = pa_namereg_register(core, name, PA_NAMEREG_SINK, s, fail))) { @@ -146,6 +149,8 @@ pa_sink* pa_sink_new( pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index); + pa_hook_fire(&core->hook_sink_new_post, s); + return s; } @@ -174,11 +179,11 @@ void pa_sink_disconnect(pa_sink* s) { pa_assert(s); pa_return_if_fail(s->state != PA_SINK_DISCONNECTED); + pa_hook_fire(&s->core->hook_sink_disconnect, s); + pa_namereg_unregister(s->core, s->name); pa_idxset_remove_by_data(s->core->sinks, s, NULL); - pa_hook_fire(&s->core->hook_sink_disconnect, s); - while ((i = pa_idxset_first(s->inputs, NULL))) { pa_assert(i != j); pa_sink_input_kill(i); @@ -198,6 +203,8 @@ void pa_sink_disconnect(pa_sink* s) { s->set_state = NULL; pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_REMOVE, s->index); + + pa_hook_fire(&s->core->hook_sink_disconnect_post, s); } static void sink_free(pa_object *o) { diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 9b828e1a..95755f3b 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -187,21 +187,26 @@ void pa_source_output_disconnect(pa_source_output*o) { pa_assert(o); pa_return_if_fail(o->state != PA_SOURCE_OUTPUT_DISCONNECTED); + pa_hook_fire(&o->source->core->hook_source_output_disconnect, o); + pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, 0, NULL); pa_idxset_remove_by_data(o->source->core->source_outputs, o, NULL); pa_idxset_remove_by_data(o->source->outputs, o, NULL); - pa_source_output_unref(o); pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_REMOVE, o->index); source_output_set_state(o, PA_SOURCE_OUTPUT_DISCONNECTED); pa_source_update_status(o->source); - o->source = NULL; o->push = NULL; o->kill = NULL; o->get_latency = NULL; + + pa_hook_fire(&o->source->core->hook_source_output_disconnect_post, o); + + o->source = NULL; + pa_source_output_unref(o); } static void source_output_free(pa_object* mo) { @@ -229,6 +234,8 @@ void pa_source_output_put(pa_source_output *o) { pa_source_update_status(o->source); pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW, o->index); + + pa_hook_fire(&o->source->core->hook_source_output_new_post, o); } void pa_source_output_kill(pa_source_output*o) { diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 241e1fb5..f7825931 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -73,6 +73,9 @@ pa_source* pa_source_new( pa_return_null_if_fail(!driver || pa_utf8_valid(driver)); pa_return_null_if_fail(pa_utf8_valid(name) && *name); + if (pa_hook_fire(&core->hook_sink_new, NULL) < 0) /* FIXME */ + return NULL; + s = pa_msgobject_new(pa_source); if (!(name = pa_namereg_register(core, name, PA_NAMEREG_SOURCE, s, fail))) { @@ -125,6 +128,8 @@ pa_source* pa_source_new( pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index); + pa_hook_fire(&core->hook_source_new_post, s); + return s; } @@ -153,11 +158,11 @@ void pa_source_disconnect(pa_source *s) { pa_assert(s); pa_return_if_fail(s->state != PA_SOURCE_DISCONNECTED); + pa_hook_fire(&s->core->hook_source_disconnect, s); + pa_namereg_unregister(s->core, s->name); pa_idxset_remove_by_data(s->core->sources, s, NULL); - pa_hook_fire(&s->core->hook_source_disconnect, s); - while ((o = pa_idxset_first(s->outputs, NULL))) { pa_assert(o != j); pa_source_output_kill(o); @@ -174,6 +179,8 @@ void pa_source_disconnect(pa_source *s) { s->set_state = NULL; pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_REMOVE, s->index); + + pa_hook_fire(&s->core->hook_source_disconnect_post, s); } static void source_free(pa_object *o) { -- cgit From 9c89f37acea964a470c42d25e4f145c2b3c6083f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Aug 2007 21:06:08 +0000 Subject: if we get access to a device we don't know yet, add it to our tree instead of ignoring it git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1601 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-hal-detect.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index ca22d70b..6e1697fa 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -551,7 +551,9 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo if ((source = pa_namereg_get(u->core, d->source_name, PA_NAMEREG_SOURCE, 0))) pa_source_suspend(source, suspend); } - } + + } else if (!suspend) + hal_device_add(u, udi); } @@ -643,7 +645,7 @@ int pa__init(pa_core *c, pa_module*m) { n = hal_device_add_all(u, CAPABILITY_ALSA); #endif #if defined(HAVE_ALSA) && defined(HAVE_OSS) - if (n <= 0) + if (!u->capability) #endif #ifdef HAVE_OSS n += hal_device_add_all(u, CAPABILITY_OSS); -- cgit From bb46da3b4aaccdbffa73a7fde19b0f1f73fa75e3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Aug 2007 21:07:14 +0000 Subject: add new module-suspend-on-idle module which suspends sinks/sources which are idle for more than 5s (or any other configurable time). Power saving, here we come\! git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1602 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Makefile.am b/src/Makefile.am index 0f2cdecc..bea58665 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -877,6 +877,7 @@ modlibexec_LTLIBRARIES += \ module-detect.la \ module-volume-restore.la \ module-rescue-streams.la \ + module-suspend-on-idle.la \ module-http-protocol-tcp.la \ module-sine.la \ module-native-protocol-tcp.la \ @@ -1027,6 +1028,7 @@ SYMDEF_FILES = \ modules/module-jack-source-symdef.h \ modules/module-volume-restore-symdef.h \ modules/module-rescue-streams-symdef.h \ + modules/module-suspend-on-idle-symdef.h \ modules/module-hal-detect-symdef.h \ modules/gconf/module-gconf-symdef.h @@ -1250,6 +1252,12 @@ module_rescue_streams_la_LDFLAGS = -module -avoid-version module_rescue_streams_la_LIBADD = $(AM_LIBADD) libpulsecore.la module_rescue_streams_la_CFLAGS = $(AM_CFLAGS) +# Suspend-on-idle module +module_suspend_on_idle_la_SOURCES = modules/module-suspend-on-idle.c +module_suspend_on_idle_la_LDFLAGS = -module -avoid-version +module_suspend_on_idle_la_LIBADD = $(AM_LIBADD) libpulsecore.la +module_suspend_on_idle_la_CFLAGS = $(AM_CFLAGS) + # RTP modules module_rtp_send_la_SOURCES = modules/rtp/module-rtp-send.c module_rtp_send_la_LDFLAGS = -module -avoid-version -- cgit From e76efa990e4a157ec6c1599b1fac348fd49acaaf Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Aug 2007 21:08:10 +0000 Subject: forgot to actually add the new suspend-on-idle module source code git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1603 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-suspend-on-idle.c | 303 +++++++++++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 src/modules/module-suspend-on-idle.c diff --git a/src/modules/module-suspend-on-idle.c b/src/modules/module-suspend-on-idle.c new file mode 100644 index 00000000..d2c51a10 --- /dev/null +++ b/src/modules/module-suspend-on-idle.c @@ -0,0 +1,303 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "module-suspend-on-idle-symdef.h" + +PA_MODULE_AUTHOR("Lennart Poettering") +PA_MODULE_DESCRIPTION("When a sink/source is idle for too long, suspend it") +PA_MODULE_VERSION(PACKAGE_VERSION) + +static const char* const valid_modargs[] = { + "timeout", + NULL, +}; + +struct userdata { + pa_core *core; + pa_usec_t timeout; + pa_hashmap *device_infos; + pa_hook_slot *sink_new_slot, *source_new_slot, *sink_disconnect_slot, *source_disconnect_slot; + pa_hook_slot *sink_input_new_slot, *source_output_new_slot, *sink_input_disconnect_slot, *source_output_disconnect_slot; +}; + +struct device_info { + struct userdata *userdata; + pa_sink *sink; + pa_source *source; + struct timeval last_use; + pa_time_event *time_event; +}; + +static void timeout_cb(pa_mainloop_api*a, pa_time_event* e, const struct timeval *tv, void *userdata) { + struct device_info *d = userdata; + + pa_assert(d); + + d->userdata->core->mainloop->time_restart(d->time_event, NULL); + + if (d->sink && pa_sink_used_by(d->sink) <= 0) { + pa_log_info("Sink %s idle for too long, suspending ...", d->sink->name); + pa_sink_suspend(d->sink, 1); + pa_source_suspend(d->sink->monitor_source, 1); + } + + if (d->source && pa_source_used_by(d->source) <= 0) { + pa_log_info("Source %s idle for too long, suspending ...", d->source->name); + pa_source_suspend(d->source, 1); + } +} + +static void restart(struct device_info *d) { + struct timeval tv; + pa_assert(d); + + pa_gettimeofday(&tv); + d->last_use = tv; + pa_timeval_add(&tv, d->userdata->timeout*1000000); + d->userdata->core->mainloop->time_restart(d->time_event, &tv); + + if (d->source) + pa_log_debug("Source %s becomes idle.", d->source->name); + if (d->sink) + pa_log_debug("Sink %s becomes idle.", d->sink->name); +} + +static pa_hook_result_t sink_input_new_hook_cb(pa_core *c, pa_sink_input *s, struct userdata *u) { + struct device_info *d; + + pa_assert(c); + pa_sink_input_assert_ref(s); + pa_assert(u); + + pa_assert_se((d = pa_hashmap_get(u->device_infos, s->sink))); + d->userdata->core->mainloop->time_restart(d->time_event, NULL); + + pa_sink_suspend(s->sink, 0); + pa_source_suspend(s->sink->monitor_source, 0); + + pa_log_debug("Sink %s becomes busy.", s->sink->name); + + return PA_HOOK_OK; +} + +static pa_hook_result_t source_output_new_hook_cb(pa_core *c, pa_source_output *s, struct userdata *u) { + struct device_info *d; + + pa_assert(c); + pa_source_output_assert_ref(s); + pa_assert(u); + + pa_assert_se((d = pa_hashmap_get(u->device_infos, s->source))); + d->userdata->core->mainloop->time_restart(d->time_event, NULL); + + pa_source_suspend(s->source, 0); + if (s->source->monitor_of) + pa_sink_suspend(s->source->monitor_of, 0); + + pa_log_debug("Source %s becomes busy.", s->source->name); + + return PA_HOOK_OK; +} + +static pa_hook_result_t sink_input_disconnect_hook_cb(pa_core *c, pa_sink_input *s, struct userdata *u) { + pa_assert(c); + pa_sink_input_assert_ref(s); + pa_assert(u); + + if (pa_sink_used_by(s->sink) <= 0) { + struct device_info *d; + pa_assert_se((d = pa_hashmap_get(u->device_infos, s->sink))); + restart(d); + } + + return PA_HOOK_OK; +} + +static pa_hook_result_t source_output_disconnect_hook_cb(pa_core *c, pa_source_output *s, struct userdata *u) { + pa_assert(c); + pa_source_output_assert_ref(s); + pa_assert(u); + + if (pa_source_used_by(s->source) <= 0) { + struct device_info *d; + pa_assert_se((d = pa_hashmap_get(u->device_infos, s->source))); + restart(d); + } + + return PA_HOOK_OK; +} + +static pa_hook_result_t device_new_hook_cb(pa_core *c, pa_object *o, struct userdata *u) { + struct device_info *d; + + pa_assert(c); + pa_object_assert_ref(o); + pa_assert(u); + + d = pa_xnew(struct device_info, 1); + d->userdata = u; + d->source = pa_source_isinstance(o) ? pa_source_ref(PA_SOURCE(o)) : NULL; + d->sink = pa_sink_isinstance(o) ? pa_sink_ref(PA_SINK(o)) : NULL; + pa_assert(d->source || d->sink); + d->time_event = c->mainloop->time_new(c->mainloop, NULL, timeout_cb, d); + pa_hashmap_put(u->device_infos, o, d); + + if ((d->sink && pa_sink_used_by(d->sink) <= 0) || + (d->source && pa_source_used_by(d->source) <= 0)) + restart(d); + + return PA_HOOK_OK; +} + +static void device_info_free(struct device_info *d) { + pa_assert(d); + + if (d->source) + pa_source_unref(d->source); + if (d->sink) + pa_sink_unref(d->sink); + + d->userdata->core->mainloop->time_free(d->time_event); + + pa_xfree(d); +} + +static pa_hook_result_t device_disconnect_hook_cb(pa_core *c, pa_object *o, struct userdata *u) { + struct device_info *d; + + pa_assert(c); + pa_object_assert_ref(o); + pa_assert(u); + + pa_assert_se((d = pa_hashmap_remove(u->device_infos, o))); + device_info_free(d); + + return PA_HOOK_OK; +} + +int pa__init(pa_core *c, pa_module*m) { + pa_modargs *ma = NULL; + struct userdata *u; + uint32_t timeout = 5; + uint32_t idx; + pa_sink *sink; + pa_source *source; + + assert(c); + assert(m); + + if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { + pa_log("Failed to parse module arguments."); + goto fail; + } + + if (pa_modargs_get_value_u32(ma, "timeout", &timeout) < 0) { + pa_log("Failed to parse timeout value."); + goto fail; + } + + m->userdata = u = pa_xnew(struct userdata, 1); + u->core = c; + u->timeout = timeout; + u->device_infos = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + + for (sink = pa_idxset_first(c->sinks, &idx); sink; sink = pa_idxset_next(c->sinks, &idx)) + device_new_hook_cb(c, PA_OBJECT(sink), u); + + for (source = pa_idxset_first(c->sources, &idx); source; source = pa_idxset_next(c->sources, &idx)) + device_new_hook_cb(c, PA_OBJECT(source), u); + + u->sink_new_slot = pa_hook_connect(&c->hook_sink_new_post, (pa_hook_cb_t) device_new_hook_cb, u); + u->source_new_slot = pa_hook_connect(&c->hook_source_new_post, (pa_hook_cb_t) device_new_hook_cb, u); + u->sink_disconnect_slot = pa_hook_connect(&c->hook_sink_disconnect_post, (pa_hook_cb_t) device_disconnect_hook_cb, u); + u->source_disconnect_slot = pa_hook_connect(&c->hook_source_disconnect_post, (pa_hook_cb_t) device_disconnect_hook_cb, u); + + u->sink_input_new_slot = pa_hook_connect(&c->hook_sink_input_new_post, (pa_hook_cb_t) sink_input_new_hook_cb, u); + u->source_output_new_slot = pa_hook_connect(&c->hook_source_output_new_post, (pa_hook_cb_t) source_output_new_hook_cb, u); + u->sink_input_disconnect_slot = pa_hook_connect(&c->hook_sink_input_disconnect_post, (pa_hook_cb_t) sink_input_disconnect_hook_cb, u); + u->source_output_disconnect_slot = pa_hook_connect(&c->hook_source_output_disconnect_post, (pa_hook_cb_t) source_output_disconnect_hook_cb, u); + + pa_modargs_free(ma); + return 0; + +fail: + + if (ma) + pa_modargs_free(ma); + + return -1; +} + +void pa__done(pa_core *c, pa_module*m) { + struct userdata *u; + struct device_info *d; + + assert(c); + assert(m); + + if (!m->userdata) + return; + + u = m->userdata; + + if (u->sink_new_slot) + pa_hook_slot_free(u->sink_new_slot); + if (u->sink_disconnect_slot) + pa_hook_slot_free(u->sink_disconnect_slot); + + if (u->source_new_slot) + pa_hook_slot_free(u->source_new_slot); + if (u->source_disconnect_slot) + pa_hook_slot_free(u->source_disconnect_slot); + + if (u->sink_input_new_slot) + pa_hook_slot_free(u->sink_input_new_slot); + if (u->sink_input_disconnect_slot) + pa_hook_slot_free(u->sink_input_disconnect_slot); + + if (u->source_output_new_slot) + pa_hook_slot_free(u->source_output_new_slot); + if (u->source_output_disconnect_slot) + pa_hook_slot_free(u->source_output_disconnect_slot); + + while ((d = pa_hashmap_steal_first(u->device_infos))) + device_info_free(d); + + pa_hashmap_free(u->device_infos, NULL, NULL); + + pa_xfree(u); +} -- cgit From 0f155748da35e97ea00bea85b2b0e2defa7bf931 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Aug 2007 21:17:32 +0000 Subject: protect memimpors with a recursive mutex to avoid deadlock when shutting down git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1604 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/memblock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index f3e400ee..f0e2b4c9 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -743,7 +743,7 @@ pa_memimport* pa_memimport_new(pa_mempool *p, pa_memimport_release_cb_t cb, void pa_assert(cb); i = pa_xnew(pa_memimport, 1); - i->mutex = pa_mutex_new(0); + i->mutex = pa_mutex_new(1); i->pool = p; i->segments = pa_hashmap_new(NULL, NULL); i->blocks = pa_hashmap_new(NULL, NULL); -- cgit From 02bf2f2dd2c443f3994ca1d0e6c5774b38f05c3c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Aug 2007 21:31:58 +0000 Subject: update default configuration git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1605 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/default.pa.in | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in index af2a6789..47d3e797 100755 --- a/src/daemon/default.pa.in +++ b/src/daemon/default.pa.in @@ -1,5 +1,4 @@ -#!@PA_BINARY@ -nF - +#!@PA_BINARY@ -nF # # This file is part of PulseAudio. # @@ -17,8 +16,19 @@ # along with PulseAudio; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +.nofail + +### Load something into the sample cache +load-sample-lazy x11-bell /usr/share/sounds/gtk-events/activate.wav +load-sample-lazy pulse-hotplug /usr/share/sounds/email.wav +load-sample-lazy pulse-coldplug /usr/share/sounds/login.wav +load-sample-lazy pulse-access /usr/share/sounds/generic.wav + +.fail -### Load audio drivers statically +### Load audio drivers statically (it's probably better to not load +### these drivers manually, but instead use module-hal-detect -- +### see below -- for doing this automatically) #load-module module-alsa-sink #load-module module-alsa-source device=hw:1,0 #load-module module-oss device="/dev/dsp" sink_name=output source_name=input @@ -30,17 +40,9 @@ @HAVE_HAL_TRUE@load-module module-hal-detect ### Alternatively use the static hardware detection module (for systems that -### lack HAL support +### lack HAL support) @HAVE_HAL_FALSE@load-module module-detect -### Load audio drivers automatically on access -#add-autoload-sink output module-oss device="/dev/dsp" sink_name=output source_name=input -#add-autoload-source input module-oss device="/dev/dsp" sink_name=output source_name=input -#add-autoload-sink output module-oss-mmap device="/dev/dsp" sink_name=output source_name=input -#add-autoload-source input module-oss-mmap device="/dev/dsp" sink_name=output source_name=input -#add-autoload-sink output module-alsa-sink sink_name=output -#add-autoload-source input module-alsa-source source_name=input - ### Load several protocols load-module module-esound-protocol-unix load-module module-native-protocol-unix @@ -65,15 +67,8 @@ load-module module-volume-restore ### connected to dies, similar for sources load-module module-rescue-streams -### Make some devices default -#set-default-sink output -#set-default-source input - -.nofail - -### Load something to the sample cache -load-sample x11-bell /usr/share/sounds/gtk-events/activate.wav -#load-sample-dir-lazy /usr/share/sounds/*.wav +### Automatically suspend sinks/sources that become idle for too long +load-module module-suspend-on-idle ### Load X11 bell module load-module module-x11-bell sample=x11-bell @@ -85,3 +80,7 @@ load-module module-x11-publish ### Please keep in mind that the modules configured by paprefs might conflict with manually ### loaded modules. load-module module-gconf + +### Make some devices default +#set-default-sink output +#set-default-source input -- cgit From b751f3a3c76b1376ea11356063d5a62a5304b426 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Aug 2007 21:37:19 +0000 Subject: s/login.wav/startup3.wav git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1606 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/default.pa.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in index 47d3e797..63ae82c9 100755 --- a/src/daemon/default.pa.in +++ b/src/daemon/default.pa.in @@ -21,7 +21,7 @@ ### Load something into the sample cache load-sample-lazy x11-bell /usr/share/sounds/gtk-events/activate.wav load-sample-lazy pulse-hotplug /usr/share/sounds/email.wav -load-sample-lazy pulse-coldplug /usr/share/sounds/login.wav +load-sample-lazy pulse-coldplug /usr/share/sounds/startup3.wav load-sample-lazy pulse-access /usr/share/sounds/generic.wav .fail -- cgit From 1c7b84204e0322933a17db511560e86febb1fcc6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Aug 2007 21:56:23 +0000 Subject: play ACL event sound only when gained access, not when losing it git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1607 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-hal-detect.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index 6e1697fa..5dffea55 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -542,7 +542,8 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK, 0))) if (pa_sink_suspend(sink, suspend) >= 0) - pa_scache_play_item_by_name(u->core, "pulse-access", d->sink_name, PA_VOLUME_NORM, 0); + if (!suspend) + pa_scache_play_item_by_name(u->core, "pulse-access", d->sink_name, PA_VOLUME_NORM, 0); } if (d->source_name) { -- cgit From 3dfdb217596aec70d04a66ef3698e9674797d878 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Aug 2007 21:57:01 +0000 Subject: don't assume that sink/source is already unregistered from namereg when disconnect hook is called git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1608 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-rescue-streams.c | 48 ++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/src/modules/module-rescue-streams.c b/src/modules/module-rescue-streams.c index 25005f25..034660e4 100644 --- a/src/modules/module-rescue-streams.c +++ b/src/modules/module-rescue-streams.c @@ -52,20 +52,26 @@ static pa_hook_result_t sink_hook_callback(pa_core *c, pa_sink *sink, void* user pa_sink_input *i; pa_sink *target; - assert(c); - assert(sink); + pa_assert(c); + pa_assert(sink); if (!pa_idxset_size(sink->inputs)) { pa_log_debug("No sink inputs to move away."); return PA_HOOK_OK; } - if (!(target = pa_namereg_get(c, NULL, PA_NAMEREG_SINK, 0))) { - pa_log_info("No evacuation sink found."); - return PA_HOOK_OK; - } + if (!(target = pa_namereg_get(c, NULL, PA_NAMEREG_SINK, 0)) || target == sink) { + uint32_t idx; + + for (target = pa_idxset_first(c->sinks, &idx); target; target = pa_idxset_next(c->sinks, &idx)) + if (target != sink) + break; - assert(target != sink); + if (!target) { + pa_log_info("No evacuation sink found."); + return PA_HOOK_OK; + } + } while ((i = pa_idxset_first(sink->inputs, NULL))) { if (pa_sink_input_move_to(i, target, 1) < 0) { @@ -84,20 +90,28 @@ static pa_hook_result_t source_hook_callback(pa_core *c, pa_source *source, void pa_source_output *o; pa_source *target; - assert(c); - assert(source); + pa_assert(c); + pa_assert(source); if (!pa_idxset_size(source->outputs)) { pa_log_debug("No source outputs to move away."); return PA_HOOK_OK; } - if (!(target = pa_namereg_get(c, NULL, PA_NAMEREG_SOURCE, 0))) { - pa_log_info("No evacuation source found."); - return PA_HOOK_OK; + if (!(target = pa_namereg_get(c, NULL, PA_NAMEREG_SOURCE, 0)) || target == source) { + uint32_t idx; + + for (target = pa_idxset_first(c->sources, &idx); target; target = pa_idxset_next(c->sources, &idx)) + if (target != source && !target->monitor_of == !source->monitor_of) + break; + + if (!target) { + pa_log_info("No evacuation source found."); + return PA_HOOK_OK; + } } - assert(target != source); + pa_assert(target != source); while ((o = pa_idxset_first(source->outputs, NULL))) { if (pa_source_output_move_to(o, target) < 0) { @@ -116,8 +130,8 @@ int pa__init(pa_core *c, pa_module*m) { pa_modargs *ma = NULL; struct userdata *u; - assert(c); - assert(m); + pa_assert(c); + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments"); @@ -135,8 +149,8 @@ int pa__init(pa_core *c, pa_module*m) { void pa__done(pa_core *c, pa_module*m) { struct userdata *u; - assert(c); - assert(m); + pa_assert(c); + pa_assert(m); if (!m->userdata) return; -- cgit From 583167722e4e2ed56de682502129d07750d738d9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Aug 2007 23:46:03 +0000 Subject: modernize git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1609 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-x11-bell.c | 48 +++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/modules/module-x11-bell.c b/src/modules/module-x11-bell.c index b9c4ad49..0c3c63f3 100644 --- a/src/modules/module-x11-bell.c +++ b/src/modules/module-x11-bell.c @@ -26,7 +26,6 @@ #endif #include -#include #include #include @@ -67,30 +66,21 @@ static const char* const valid_modargs[] = { NULL }; -static int ring_bell(struct userdata *u, int percent) { - pa_sink *s; - assert(u); - - if (!(s = pa_namereg_get(u->core, u->sink_name, PA_NAMEREG_SINK, 1))) { - pa_log("Invalid sink: %s", u->sink_name); - return -1; - } - - pa_scache_play_item(u->core, u->scache_item, s, (percent*PA_VOLUME_NORM)/100); - return 0; -} - static int x11_event_callback(pa_x11_wrapper *w, XEvent *e, void *userdata) { XkbBellNotifyEvent *bne; struct userdata *u = userdata; - assert(w && e && u && u->x11_wrapper == w); + + pa_assert(w); + pa_assert(e); + pa_assert(u); + pa_assert(u->x11_wrapper == w); if (((XkbEvent*) e)->any.xkb_type != XkbBellNotify) return 0; bne = (XkbBellNotifyEvent*) e; - if (ring_bell(u, bne->percent) < 0) { + if (pa_scache_play_item_by_name(u->core, u->scache_item, u->sink_name, (bne->percent*PA_VOLUME_NORM)/100, 1) < 0) { pa_log_info("Ringing bell failed, reverting to X11 device bell."); XkbForceDeviceBell(pa_x11_wrapper_get_display(w), bne->device, bne->bell_class, bne->bell_id, bne->percent); } @@ -99,18 +89,21 @@ static int x11_event_callback(pa_x11_wrapper *w, XEvent *e, void *userdata) { } int pa__init(pa_core *c, pa_module*m) { + struct userdata *u = NULL; pa_modargs *ma = NULL; int major, minor; unsigned int auto_ctrls, auto_values; - assert(c && m); + + pa_assert(c); + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { - pa_log("failed to parse module arguments"); + pa_log("Failed to parse module arguments"); goto fail; } - m->userdata = u = pa_xmalloc(sizeof(struct userdata)); + m->userdata = u = pa_xnew(struct userdata, 1); u->core = c; u->scache_item = pa_xstrdup(pa_modargs_get_value(ma, "sample", "x11-bell")); u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL)); @@ -130,7 +123,6 @@ int pa__init(pa_core *c, pa_module*m) { major = XkbMajorVersion; minor = XkbMinorVersion; - if (!XkbQueryExtension(pa_x11_wrapper_get_display(u->x11_wrapper), NULL, &u->xkb_event_base, NULL, &major, &minor)) { pa_log("XkbQueryExtension() failed"); goto fail; @@ -150,14 +142,22 @@ int pa__init(pa_core *c, pa_module*m) { fail: if (ma) pa_modargs_free(ma); - if (m->userdata) - pa__done(c, m); + + pa__done(c, m); + return -1; } void pa__done(pa_core *c, pa_module*m) { - struct userdata *u = m->userdata; - assert(c && m && u); + struct userdata *u; + + assert(c); + assert(m); + + if (!m->userdata) + return; + + u = m->userdata; pa_xfree(u->scache_item); pa_xfree(u->sink_name); -- cgit From d9e44c52cb05df1134087865b1e18de8884af75b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Aug 2007 23:47:06 +0000 Subject: Add X11 XSMP module for hooking into the X11 session manager, for being notified about X11 disconnects before they actually happen, so that we are not killed by the bloody xlibs git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1610 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 9 +- src/daemon/default.pa.in | 3 + src/modules/module-x11-xsmp.c | 201 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 src/modules/module-x11-xsmp.c diff --git a/src/Makefile.am b/src/Makefile.am index bea58665..5edd200f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -924,7 +924,8 @@ endif if HAVE_X11 modlibexec_LTLIBRARIES += \ module-x11-bell.la \ - module-x11-publish.la + module-x11-publish.la \ + module-x11-xsmp.la endif if HAVE_OSS @@ -1016,6 +1017,7 @@ SYMDEF_FILES = \ modules/module-http-protocol-unix-symdef.h \ modules/module-x11-bell-symdef.h \ modules/module-x11-publish-symdef.h \ + modules/module-x11-xsmp-symdef.h \ modules/module-oss-symdef.h \ modules/module-alsa-sink-symdef.h \ modules/module-alsa-source-symdef.h \ @@ -1173,6 +1175,11 @@ module_x11_publish_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) module_x11_publish_la_LDFLAGS = -module -avoid-version module_x11_publish_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) libx11wrap.la libauthkey.la libauthkey-prop.la libx11prop.la libstrlist.la libpulsecore.la +module_x11_xsmp_la_SOURCES = modules/module-x11-xsmp.c +module_x11_xsmp_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) +module_x11_xsmp_la_LDFLAGS = -module -avoid-version +module_x11_xsmp_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) libpulsecore.la + # OSS liboss_util_la_SOURCES = modules/oss-util.c modules/oss-util.h diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in index 63ae82c9..583b26cb 100755 --- a/src/daemon/default.pa.in +++ b/src/daemon/default.pa.in @@ -76,6 +76,9 @@ load-module module-x11-bell sample=x11-bell ### Publish connection data in the X11 root window load-module module-x11-publish +### Register ourselves in the X11 session manager +load-module module-x11-xsmp + ### Load additional modules from GConf settings. This can be configured with the paprefs tool. ### Please keep in mind that the modules configured by paprefs might conflict with manually ### loaded modules. diff --git a/src/modules/module-x11-xsmp.c b/src/modules/module-x11-xsmp.c new file mode 100644 index 00000000..dc23ebe3 --- /dev/null +++ b/src/modules/module-x11-xsmp.c @@ -0,0 +1,201 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "module-x11-xsmp-symdef.h" + +PA_MODULE_AUTHOR("Lennart Poettering") +PA_MODULE_DESCRIPTION("X11 session management") +PA_MODULE_VERSION(PACKAGE_VERSION) + +struct userdata { + pa_core *core; + SmcConn sm_conn; +}; + +static const char* const valid_modargs[] = { + NULL +}; + +static void die_cb(SmcConn connection, SmPointer client_data){ + pa_core *c = client_data; + + pa_log_debug("Got die message from XSM. Exiting..."); + + pa_core_assert_ref(c); + c->mainloop->quit(c->mainloop, 0); +} + +static void save_complete_cb(SmcConn connection, SmPointer client_data) { +} + +static void shutdown_cancelled_cb(SmcConn connection, SmPointer client_data) { + SmcSaveYourselfDone(connection, True); +} + +static void save_yourself_cb(SmcConn connection, SmPointer client_data, int save_type, Bool _shutdown, int interact_style, Bool fast) { + SmcSaveYourselfDone(connection, True); +} + +static void ice_io_cb(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_event_flags_t flags, void *userdata) { + IceConn connection = userdata; + + if (IceProcessMessages(connection, NULL, NULL) == IceProcessMessagesIOError) { + IceSetShutdownNegotiation(connection, False); + IceCloseConnection(connection); + } +} + +static void new_ice_connection(IceConn connection, IcePointer client_data, Bool opening, IcePointer *watch_data) { + pa_core *c = client_data; + + pa_assert(c); + + if (opening) + *watch_data = c->mainloop->io_new(c->mainloop, IceConnectionNumber(connection), PA_IO_EVENT_INPUT, ice_io_cb, connection); + else + c->mainloop->io_free(*watch_data); +} + +int pa__init(pa_core *c, pa_module*m) { + struct userdata *u = NULL; + pa_modargs *ma = NULL; + char t[256], *vendor, *client_id; + SmcCallbacks callbacks; + SmProp prop_program, prop_user; + SmProp *prop_list[2]; + SmPropValue val_program, val_user; + + pa_assert(c); + pa_assert(m); + + if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { + pa_log("Failed to parse module arguments"); + goto fail; + } + + if (!getenv("SESSION_MANAGER")) { + pa_log("X11 session manager not running."); + goto fail; + } + + m->userdata = u = pa_xnew(struct userdata, 1); + u->core = c; + u->sm_conn = NULL; + + IceAddConnectionWatch(new_ice_connection, c); + + memset(&callbacks, 0, sizeof(callbacks)); + callbacks.die.callback = die_cb; + callbacks.die.client_data = c; + + callbacks.save_yourself.callback = save_yourself_cb; + callbacks.save_complete.callback = save_complete_cb; + callbacks.shutdown_cancelled.callback = shutdown_cancelled_cb; + + if (!(u->sm_conn = SmcOpenConnection( + NULL, u, + SmProtoMajor, SmProtoMinor, + SmcSaveYourselfProcMask | SmcDieProcMask | SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask, + &callbacks, NULL, &client_id, + sizeof(t), t))) { + + pa_log("Failed to open connection to session manager: %s", t); + goto fail; + } + + prop_program.name = (char*) SmProgram; + prop_program.type = (char*) SmARRAY8; + val_program.value = (char*) PACKAGE_NAME; + val_program.length = strlen(val_program.value); + prop_program.num_vals = 1; + prop_program.vals = &val_program; + prop_list[0] = &prop_program; + + prop_user.name = (char*) SmUserID; + prop_user.type = (char*) SmARRAY8; + pa_get_user_name(t, sizeof(t)); + val_user.value = t; + val_user.length = strlen(val_user.value); + prop_user.num_vals = 1; + prop_user.vals = &val_user; + prop_list[1] = &prop_user; + + SmcSetProperties(u->sm_conn, PA_ELEMENTSOF(prop_list), prop_list); + + pa_log_info("Connected to session manager '%s' as '%s'.", vendor = SmcVendor(u->sm_conn), client_id); + free(vendor); + free(client_id); + + pa_modargs_free(ma); + + return 0; + +fail: + if (ma) + pa_modargs_free(ma); + + pa__done(c, m); + + return -1; +} + +void pa__done(pa_core *c, pa_module*m) { + struct userdata *u; + + assert(c); + assert(m); + + if (!m->userdata) + return; + + u = m->userdata; + + if (u->sm_conn) + SmcCloseConnection(u->sm_conn, 0, NULL); + + IceRemoveConnectionWatch(new_ice_connection, c); + + pa_xfree(u); +} -- cgit From 3b078b20683da8fde7e291373e7cec0c3901cbac Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Aug 2007 00:15:20 +0000 Subject: Avoid a race condition when one PA instance gets HAL's ACLAdded message before the previous owner instance has given up access to the device, and thus the device is blocked git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1611 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-hal-detect.c | 62 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index 5dffea55..39d8a44a 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -540,10 +540,21 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo if (d->sink_name) { pa_sink *sink; - if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK, 0))) - if (pa_sink_suspend(sink, suspend) >= 0) - if (!suspend) + if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK, 0))) { + + int prev_suspended = pa_sink_get_state(sink) == PA_SINK_SUSPENDED; + + if (pa_sink_suspend(sink, suspend) >= 0) { + if (!suspend && prev_suspended) pa_scache_play_item_by_name(u->core, "pulse-access", d->sink_name, PA_VOLUME_NORM, 0); + else if (suspend && !prev_suspended) { + DBusMessage *msg; + msg = dbus_message_new_signal(udi, "org.pulseaudio.Server", "DirtyGiveUpMessage"); + dbus_connection_send(pa_dbus_connection_get(u->connection), msg, NULL); + dbus_message_unref(msg); + } + } + } } if (d->source_name) { @@ -555,9 +566,46 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo } else if (!suspend) hal_device_add(u, udi); - } + } else if (dbus_message_is_signal(message, "org.pulseaudio.Server", "DirtyGiveUpMessage")) { + /* We use this message to avoid a dirty race condition when we + get an ACLAdded message before the previously owning PA + sever has closed the device. We can remove this as + soon as HAL learns frevoke() */ + + const char *udi; + struct device *d; + + pa_log_debug("Got dirty give up message, trying resume ..."); + + udi = dbus_message_get_path(message); + + if ((d = pa_hashmap_get(u->devices, udi))) { + + if (d->sink_name) { + pa_sink *sink; + + if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK, 0))) { + + int prev_suspended = pa_sink_get_state(sink) == PA_SINK_SUSPENDED; + + if (pa_sink_suspend(sink, 0) >= 0) + if (prev_suspended && !prev_suspended) + pa_scache_play_item_by_name(u->core, "pulse-access", d->sink_name, PA_VOLUME_NORM, 0); + } + } + + if (d->source_name) { + pa_source *source; + + if ((source = pa_namereg_get(u->core, d->source_name, PA_NAMEREG_SOURCE, 0))) + pa_source_suspend(source, 0); + } + + } else + /* Yes, we don't check the UDI for validity, but hopefully HAL will */ + hal_device_add(u, udi); } finish: @@ -673,6 +721,12 @@ int pa__init(pa_core *c, pa_module*m) { pa_log_error("Unable to subscribe to HAL ACL signals: %s: %s", error.name, error.message); goto fail; } + + dbus_bus_add_match(pa_dbus_connection_get(conn), "type='signal',interface='org.pulseaudio.Server'", &error); + if (dbus_error_is_set(&error)) { + pa_log_error("Unable to subscribe to PulseAudio signals: %s: %s", error.name, error.message); + goto fail; + } pa_log_info("Loaded %i modules.", n); -- cgit From 1e5ca51016de2b6ea6f9aa8b23e00d62a851b541 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Aug 2007 00:29:28 +0000 Subject: handle ACLAdded messages for previously unknown devices identically to a really new device git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1612 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-hal-detect.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index 39d8a44a..ed21f4de 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -503,7 +503,6 @@ static void lost_capability_cb(LibHalContext *context, const char *udi, const ch device_removed_cb(context, udi); } - static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, void *userdata) { struct userdata*u = userdata; DBusError error; @@ -565,7 +564,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo } } else if (!suspend) - hal_device_add(u, udi); + device_added_cb(u->context, udi); } } else if (dbus_message_is_signal(message, "org.pulseaudio.Server", "DirtyGiveUpMessage")) { @@ -605,7 +604,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo } else /* Yes, we don't check the UDI for validity, but hopefully HAL will */ - hal_device_add(u, udi); + device_added_cb(u->context, udi); } finish: -- cgit From 10b135a4bf767255ba8497ab51bce68688b6a28f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Aug 2007 00:33:47 +0000 Subject: avoid duplicate loading of modules git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1613 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-hal-detect.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index ed21f4de..d73ca0ce 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -299,7 +299,8 @@ static struct device* hal_device_add(struct userdata *u, const char *udi) { pa_assert(u); pa_assert(u->capability); - + pa_assert(!pa_hashmap_get(u->devices, udi)); + #ifdef HAVE_ALSA if (strcmp(u->capability, CAPABILITY_ALSA) == 0) m = hal_device_load_alsa(u, udi, &sink_name, &source_name); @@ -374,22 +375,25 @@ static dbus_bool_t device_has_capability(LibHalContext *context, const char *udi static void device_added_time_cb(pa_mainloop_api *ea, pa_time_event *ev, const struct timeval *tv, void *userdata) { DBusError error; struct timerdata *td = userdata; - int b; - struct device *d; dbus_error_init(&error); - - b = libhal_device_exists(td->u->context, td->udi, &error); - - if (dbus_error_is_set(&error)) { - pa_log_error("Error adding device: %s: %s", error.name, error.message); - dbus_error_free(&error); - } else if (b) { - if (!(d = hal_device_add(td->u, td->udi))) - pa_log_debug("Not loaded device %s", td->udi); - else { - if (d->sink_name) - pa_scache_play_item_by_name(td->u->core, "pulse-hotplug", d->sink_name, PA_VOLUME_NORM, 0); + + if (!pa_hashmap_get(td->u->devices, td->udi)) { + int b; + struct device *d; + + b = libhal_device_exists(td->u->context, td->udi, &error); + + if (dbus_error_is_set(&error)) { + pa_log_error("Error adding device: %s: %s", error.name, error.message); + dbus_error_free(&error); + } else if (b) { + if (!(d = hal_device_add(td->u, td->udi))) + pa_log_debug("Not loaded device %s", td->udi); + else { + if (d->sink_name) + pa_scache_play_item_by_name(td->u->core, "pulse-hotplug", d->sink_name, PA_VOLUME_NORM, 0); + } } } @@ -406,6 +410,9 @@ static void device_added_cb(LibHalContext *context, const char *udi) { int good = 0; pa_assert_se(u = libhal_ctx_get_user_data(context)); + + if (pa_hashmap_get(u->devices, udi)) + return; pa_log_debug("HAL Device added: %s", udi); -- cgit From e621071bf1a4f82ce5eba36917e67048ac0c59ef Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Aug 2007 12:11:40 +0000 Subject: fix minor memory leakage git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1614 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-volume-restore.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/module-volume-restore.c b/src/modules/module-volume-restore.c index 61a17aef..0f0d998b 100644 --- a/src/modules/module-volume-restore.c +++ b/src/modules/module-volume-restore.c @@ -396,6 +396,8 @@ static pa_hook_result_t sink_input_hook_callback(pa_core *c, pa_sink_input_new_d } } + pa_xfree(name); + return PA_HOOK_OK; } -- cgit From ffa170807086e959ce7cd9b21fb0c29b104b222b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Aug 2007 14:28:39 +0000 Subject: * drop redundant pa_core argument from module initialization functions * make pa__done() implementations optional * a couple of modernizations * wrap lt_dlsym() at a single place * allow passing of an "api" argument to the HAL module, to choose whether OSS devices or ALSA devices should be picked up * optimize fd closing a little on linux in the forked gconf helper * save a little memory in the xsmp module git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1615 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 5 +- src/modules/gconf/module-gconf.c | 96 ++++++++++++++-------- src/modules/module-alsa-sink.c | 16 ++-- src/modules/module-alsa-source.c | 16 ++-- src/modules/module-cli.c | 16 ++-- src/modules/module-defs.h.m4 | 4 +- src/modules/module-detect.c | 29 +++---- src/modules/module-esound-compat-spawnfd.c | 15 ++-- src/modules/module-esound-compat-spawnpid.c | 14 +--- src/modules/module-hal-detect.c | 66 ++++++++++++--- src/modules/module-lirc.c | 33 ++++---- src/modules/module-match.c | 25 +++--- src/modules/module-mmkbd-evdev.c | 34 ++++---- src/modules/module-native-protocol-fd.c | 19 ++--- src/modules/module-null-sink.c | 14 ++-- src/modules/module-oss.c | 16 ++-- src/modules/module-pipe-sink.c | 14 ++-- src/modules/module-pipe-source.c | 14 ++-- src/modules/module-protocol-stub.c | 33 ++++---- src/modules/module-rescue-streams.c | 10 +-- src/modules/module-sine.c | 15 ++-- src/modules/module-suspend-on-idle.c | 36 ++++----- src/modules/module-volume-restore.c | 15 ++-- src/modules/module-x11-bell.c | 14 ++-- src/modules/module-x11-publish.c | 24 +++--- src/modules/module-x11-xsmp.c | 66 +++++++-------- src/modules/module-zeroconf-publish.c | 57 ++++++------- src/pulsecore/ltdl-helper.c | 64 +++++++++++++++ src/pulsecore/ltdl-helper.h | 34 ++++++++ src/pulsecore/modinfo.c | 29 +++---- src/pulsecore/modinfo.h | 2 +- src/pulsecore/module.c | 121 ++++++++++------------------ src/pulsecore/module.h | 10 +-- 33 files changed, 532 insertions(+), 444 deletions(-) create mode 100644 src/pulsecore/ltdl-helper.c create mode 100644 src/pulsecore/ltdl-helper.h diff --git a/src/Makefile.am b/src/Makefile.am index 5edd200f..8273d336 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -624,6 +624,7 @@ libpulsecore_la_SOURCES += \ pulsecore/memchunk.c pulsecore/memchunk.h \ pulsecore/modargs.c pulsecore/modargs.h \ pulsecore/modinfo.c pulsecore/modinfo.h \ + pulsecore/ltdl-helper.c pulsecore/ltdl-helper.h \ pulsecore/module.c pulsecore/module.h \ pulsecore/namereg.c pulsecore/namereg.h \ pulsecore/pid.c pulsecore/pid.h \ @@ -1038,9 +1039,7 @@ EXTRA_DIST += $(SYMDEF_FILES) BUILT_SOURCES += $(SYMDEF_FILES) $(SYMDEF_FILES): modules/module-defs.h.m4 - -mkdir modules - -mkdir modules/gconf - -mkdir modules/rtp + $(mkdir_p) modules modules/gconf modules/rtp $(M4) -Dfname="$@" $< > $@ # Simple protocol diff --git a/src/modules/gconf/module-gconf.c b/src/modules/gconf/module-gconf.c index cbe17d20..7e932c11 100644 --- a/src/modules/gconf/module-gconf.c +++ b/src/modules/gconf/module-gconf.c @@ -25,7 +25,6 @@ #include #endif -#include #include #include #include @@ -34,6 +33,7 @@ #include #include #include +#include #ifdef HAVE_SYS_PRCTL_H #include @@ -95,7 +95,7 @@ struct userdata { static int fill_buf(struct userdata *u) { ssize_t r; - assert(u); + pa_assert(u); if (u->buf_fill >= BUF_MAX) { pa_log("read buffer overflow"); @@ -111,21 +111,21 @@ static int fill_buf(struct userdata *u) { static int read_byte(struct userdata *u) { int ret; - assert(u); + pa_assert(u); if (u->buf_fill < 1) if (fill_buf(u) < 0) return -1; ret = u->buf[0]; - assert(u->buf_fill > 0); + pa_assert(u->buf_fill > 0); u->buf_fill--; memmove(u->buf, u->buf+1, u->buf_fill); return ret; } static char *read_string(struct userdata *u) { - assert(u); + pa_assert(u); for (;;) { char *e; @@ -143,9 +143,9 @@ static char *read_string(struct userdata *u) { } static void unload_one_module(struct userdata *u, struct module_info*m, unsigned i) { - assert(u); - assert(m); - assert(i < m->n_items); + pa_assert(u); + pa_assert(m); + pa_assert(i < m->n_items); if (m->items[i].index == PA_INVALID_INDEX) return; @@ -161,8 +161,8 @@ static void unload_one_module(struct userdata *u, struct module_info*m, unsigned static void unload_all_modules(struct userdata *u, struct module_info*m) { unsigned i; - assert(u); - assert(m); + pa_assert(u); + pa_assert(m); for (i = 0; i < m->n_items; i++) unload_one_module(u, m, i); @@ -180,10 +180,10 @@ static void load_module( pa_module *mod; - assert(u); - assert(m); - assert(name); - assert(args); + pa_assert(u); + pa_assert(m); + pa_assert(name); + pa_assert(args); if (!is_new) { if (m->items[i].index != PA_INVALID_INDEX && @@ -212,8 +212,8 @@ static void module_info_free(void *p, void *userdata) { struct module_info *m = p; struct userdata *u = userdata; - assert(m); - assert(u); + pa_assert(m); + pa_assert(u); unload_all_modules(u, m); pa_xfree(m->name); @@ -356,8 +356,10 @@ static int start_client(const char *n, pid_t *pid) { return pipe_fds[0]; } else { +#ifdef __linux__ + DIR* d; +#endif int max_fd, i; - /* child */ close(pipe_fds[0]); @@ -372,19 +374,46 @@ static int start_client(const char *n, pid_t *pid) { close(2); open("/dev/null", O_WRONLY); - max_fd = 1024; +#ifdef __linux__ + + if ((d = opendir("/proc/self/fd/"))) { + + struct dirent *de; + + while ((de = readdir(d))) { + char *e; + int fd; + + errno = 0; + fd = strtol(de->d_name, &e, 10); + pa_assert(errno == 0 && *e == 0); + if (fd >= 3) + close(fd); + } + + closedir(d); + } else { + +#endif + + max_fd = 1024; + #ifdef HAVE_SYS_RESOURCE_H - { - struct rlimit r; - if (getrlimit(RLIMIT_NOFILE, &r) == 0) - max_fd = r.rlim_max; + { + struct rlimit r; + if (getrlimit(RLIMIT_NOFILE, &r) == 0) + max_fd = r.rlim_max; + } +#endif + + for (i = 3; i < max_fd; i++) + close(i); +# +#ifdef __linux__ } #endif - for (i = 3; i < max_fd; i++) - close(i); - #ifdef PR_SET_PDEATHSIG /* On Linux we can use PR_SET_PDEATHSIG to have the helper process killed when the daemon dies abnormally. On non-Linux @@ -413,12 +442,12 @@ fail: return -1; } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { struct userdata *u; int r; u = pa_xnew(struct userdata, 1); - u->core = c; + u->core = m->core; u->module = m; m->userdata = u; u->module_infos = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); @@ -431,8 +460,8 @@ int pa__init(pa_core *c, pa_module*m) { if ((u->fd = start_client(PA_GCONF_HELPER, &u->pid)) < 0) goto fail; - u->io_event = c->mainloop->io_new( - c->mainloop, + u->io_event = m->core->mainloop->io_new( + m->core->mainloop, u->fd, PA_IO_EVENT_INPUT, io_event_cb, @@ -449,21 +478,20 @@ int pa__init(pa_core *c, pa_module*m) { return 0; fail: - pa__done(c, m); + pa__done(m); return -1; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - assert(c); - assert(m); + pa_assert(m); if (!(u = m->userdata)) return; if (u->io_event) - c->mainloop->io_free(u->io_event); + m->core->mainloop->io_free(u->io_event); if (u->fd >= 0) close(u->fd); diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 1a69954c..387e70c4 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -704,7 +704,7 @@ finish: pa_log_debug("Thread shutting down"); } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { pa_modargs *ma = NULL; int ret = -1; @@ -723,7 +723,6 @@ int pa__init(pa_core *c, pa_module*m) { int namereg_fail; int use_mmap = 1, b; - pa_assert(c); pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { @@ -731,7 +730,7 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - ss = c->default_sample_spec; + ss = m->core->default_sample_spec; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_ALSA) < 0) { pa_log("Failed to parse sample specification and channel map"); goto fail; @@ -756,7 +755,7 @@ int pa__init(pa_core *c, pa_module*m) { } u = pa_xnew0(struct userdata, 1); - u->core = c; + u->core = m->core; u->module = m; m->userdata = u; u->use_mmap = use_mmap; @@ -824,7 +823,7 @@ int pa__init(pa_core *c, pa_module*m) { namereg_fail = 0; } - u->sink = pa_sink_new(c, __FILE__, name, namereg_fail, &ss, &map); + u->sink = pa_sink_new(m->core, __FILE__, name, namereg_fail, &ss, &map); pa_xfree(name_buf); if (!u->sink) { @@ -881,7 +880,7 @@ int pa__init(pa_core *c, pa_module*m) { u->mixer_fdl = pa_alsa_fdlist_new(); - if (pa_alsa_fdlist_set_mixer(u->mixer_fdl, u->mixer_handle, c->mainloop) < 0) { + if (pa_alsa_fdlist_set_mixer(u->mixer_fdl, u->mixer_handle, m->core->mainloop) < 0) { pa_log("failed to initialise file descriptor monitoring"); goto fail; } @@ -917,15 +916,14 @@ finish: fail: if (u) - pa__done(c, m); + pa__done(m); goto finish; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - pa_assert(c); pa_assert(m); if (!(u = m->userdata)) diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 553d0283..7ed430e3 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -679,7 +679,7 @@ finish: pa_log_debug("Thread shutting down"); } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { pa_modargs *ma = NULL; int ret = -1; @@ -698,7 +698,6 @@ int pa__init(pa_core *c, pa_module*m) { int namereg_fail; int use_mmap = 1, b; - pa_assert(c); pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { @@ -706,7 +705,7 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - ss = c->default_sample_spec; + ss = m->core->default_sample_spec; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_ALSA) < 0) { pa_log("Failed to parse sample specification"); goto fail; @@ -732,7 +731,7 @@ int pa__init(pa_core *c, pa_module*m) { } u = pa_xnew0(struct userdata, 1); - u->core = c; + u->core = m->core; u->module = m; m->userdata = u; u->use_mmap = use_mmap; @@ -796,7 +795,7 @@ int pa__init(pa_core *c, pa_module*m) { namereg_fail = 0; } - u->source = pa_source_new(c, __FILE__, name, namereg_fail, &ss, &map); + u->source = pa_source_new(m->core, __FILE__, name, namereg_fail, &ss, &map); pa_xfree(name_buf); if (!u->source) { @@ -849,7 +848,7 @@ int pa__init(pa_core *c, pa_module*m) { u->mixer_fdl = pa_alsa_fdlist_new(); - if (pa_alsa_fdlist_set_mixer(u->mixer_fdl, u->mixer_handle, c->mainloop) < 0) { + if (pa_alsa_fdlist_set_mixer(u->mixer_fdl, u->mixer_handle, m->core->mainloop) < 0) { pa_log("failed to initialise file descriptor monitoring"); goto fail; } @@ -886,15 +885,14 @@ finish: fail: if (u) - pa__done(c, m); + pa__done(m); goto finish; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - pa_assert(c); pa_assert(m); if (!(u = m->userdata)) diff --git a/src/modules/module-cli.c b/src/modules/module-cli.c index 19ac0c26..fd180bc7 100644 --- a/src/modules/module-cli.c +++ b/src/modules/module-cli.c @@ -66,15 +66,14 @@ static void eof_and_exit_cb(pa_cli*c, void *userdata) { m->core->mainloop->quit(m->core->mainloop, 0); } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { pa_iochannel *io; pa_modargs *ma; int exit_on_eof = 0; - assert(c); assert(m); - if (c->running_as_daemon) { + if (m->core->running_as_daemon) { pa_log_info("Running as daemon, refusing to load this module."); return 0; } @@ -94,12 +93,10 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - io = pa_iochannel_new(c->mainloop, STDIN_FILENO, STDOUT_FILENO); - assert(io); + io = pa_iochannel_new(m->core->mainloop, STDIN_FILENO, STDOUT_FILENO); pa_iochannel_set_noclose(io, 1); - m->userdata = pa_cli_new(c, io, m); - assert(m->userdata); + m->userdata = pa_cli_new(m->core, io, m); pa_cli_set_eof_callback(m->userdata, exit_on_eof ? eof_and_exit_cb : eof_and_unload_cb, m); @@ -115,11 +112,10 @@ fail: return -1; } -void pa__done(pa_core *c, pa_module*m) { - assert(c); +void pa__done(pa_module*m) { assert(m); - if (c->running_as_daemon == 0) { + if (m->core->running_as_daemon == 0) { pa_cli_free(m->userdata); pa_stdio_release(); } diff --git a/src/modules/module-defs.h.m4 b/src/modules/module-defs.h.m4 index c961412d..5bff748e 100644 --- a/src/modules/module-defs.h.m4 +++ b/src/modules/module-defs.h.m4 @@ -18,8 +18,8 @@ gen_symbol(pa__get_description) gen_symbol(pa__get_usage) gen_symbol(pa__get_version) -int pa__init(struct pa_core *c, struct pa_module*m); -void pa__done(struct pa_core *c, struct pa_module*m); +int pa__init(pa_module*m); +void pa__done(pa_module*m); const char* pa__get_author(void); const char* pa__get_description(void); diff --git a/src/modules/module-detect.c b/src/modules/module-detect.c index 190cda9d..858147e3 100644 --- a/src/modules/module-detect.c +++ b/src/modules/module-detect.c @@ -52,6 +52,11 @@ PA_MODULE_DESCRIPTION("Detect available audio hardware and load matching drivers PA_MODULE_VERSION(PACKAGE_VERSION) PA_MODULE_USAGE("just-one=") +static const char* const valid_modargs[] = { + "just-one", + NULL +}; + #ifdef HAVE_ALSA static int detect_alsa(pa_core *c, int just_one) { @@ -215,17 +220,11 @@ static int detect_waveout(pa_core *c, int just_one) { } #endif -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { int just_one = 0, n = 0; pa_modargs *ma; - static const char* const valid_modargs[] = { - "just-one", - NULL - }; - - assert(c); - assert(m); + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments"); @@ -238,16 +237,16 @@ int pa__init(pa_core *c, pa_module*m) { } #if HAVE_ALSA - if ((n = detect_alsa(c, just_one)) <= 0) + if ((n = detect_alsa(m->core, just_one)) <= 0) #endif #if HAVE_OSS - if ((n = detect_oss(c, just_one)) <= 0) + if ((n = detect_oss(m->core, just_one)) <= 0) #endif #if HAVE_SOLARIS - if ((n = detect_solaris(c, just_one)) <= 0) + if ((n = detect_solaris(m->core, just_one)) <= 0) #endif #if OS_IS_WIN32 - if ((n = detect_waveout(c, just_one)) <= 0) + if ((n = detect_waveout(m->core, just_one)) <= 0) #endif { pa_log_warn("failed to detect any sound hardware."); @@ -269,9 +268,3 @@ fail: return -1; } - - -void pa__done(PA_GCC_UNUSED pa_core *c, PA_GCC_UNUSED pa_module*m) { - /* NOP */ -} - diff --git a/src/modules/module-esound-compat-spawnfd.c b/src/modules/module-esound-compat-spawnfd.c index 1aecade5..890ebb16 100644 --- a/src/modules/module-esound-compat-spawnfd.c +++ b/src/modules/module-esound-compat-spawnfd.c @@ -26,7 +26,6 @@ #endif #include -#include #include #include @@ -48,21 +47,23 @@ static const char* const valid_modargs[] = { NULL, }; -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { pa_modargs *ma = NULL; int ret = -1, fd = -1; char x = 1; - assert(c && m); + + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs)) || pa_modargs_get_value_s32(ma, "fd", &fd) < 0 || fd < 0) { + pa_log("Failed to parse module arguments"); goto finish; } if (pa_loop_write(fd, &x, sizeof(x), NULL) != sizeof(x)) - pa_log("WARNING: write(%u, 1, 1) failed: %s", fd, pa_cstrerror(errno)); + pa_log_warn("WARNING: write(%u, 1, 1) failed: %s", fd, pa_cstrerror(errno)); close(fd); @@ -76,9 +77,3 @@ finish: return ret; } - -void pa__done(pa_core *c, pa_module*m) { - assert(c && m); -} - - diff --git a/src/modules/module-esound-compat-spawnpid.c b/src/modules/module-esound-compat-spawnpid.c index a9fd166d..1cc86d20 100644 --- a/src/modules/module-esound-compat-spawnpid.c +++ b/src/modules/module-esound-compat-spawnpid.c @@ -25,7 +25,6 @@ #endif #include -#include #include #include #include @@ -48,11 +47,12 @@ static const char* const valid_modargs[] = { NULL, }; -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { pa_modargs *ma = NULL; int ret = -1; uint32_t pid = 0; - assert(c && m); + + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs)) || pa_modargs_get_value_u32(ma, "pid", &pid) < 0 || @@ -62,7 +62,7 @@ int pa__init(pa_core *c, pa_module*m) { } if (kill(pid, SIGUSR1) < 0) - pa_log("WARNING: kill(%u) failed: %s", pid, pa_cstrerror(errno)); + pa_log_warn("WARNING: kill(%u) failed: %s", pid, pa_cstrerror(errno)); pa_module_unload_request(m); @@ -74,9 +74,3 @@ finish: return ret; } - -void pa__done(pa_core *c, pa_module*m) { - assert(c && m); -} - - diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index d73ca0ce..672bdc06 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -46,6 +46,7 @@ #include #include #include +#include #include @@ -55,6 +56,13 @@ PA_MODULE_AUTHOR("Shahms King") PA_MODULE_DESCRIPTION("Detect available audio hardware and load matching drivers") PA_MODULE_VERSION(PACKAGE_VERSION) +#if defined(HAVE_ALSA) && defined(HAVE_OSS) +PA_MODULE_USAGE("api=") +#elif defined(HAVE_ALSA) +PA_MODULE_USAGE("api=") +#elif defined(HAVE_OSS) +PA_MODULE_USAGE("api=") +#endif struct device { uint32_t index; @@ -78,6 +86,11 @@ struct timerdata { #define CAPABILITY_ALSA "alsa" #define CAPABILITY_OSS "oss" +static const char* const valid_modargs[] = { + "api", + NULL +}; + static void hal_device_free(struct device* d) { pa_assert(d); @@ -663,37 +676,65 @@ fail: return NULL; } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { DBusError error; pa_dbus_connection *conn; struct userdata *u = NULL; LibHalContext *hal_context = NULL; int n = 0; + pa_modargs *ma; + const char *api; - pa_assert(c); pa_assert(m); dbus_error_init(&error); - - if (!(conn = pa_dbus_bus_get(c, DBUS_BUS_SYSTEM, &error)) || dbus_error_is_set(&error)) { + + if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { + pa_log("Failed to parse module arguments"); + goto fail; + } + + if ((api = pa_modargs_get_value(ma, "api", NULL))) { + int good = 0; + +#ifdef HAVE_ALSA + if (strcmp(api, CAPABILITY_ALSA) == 0) { + good = 1; + api = CAPABILITY_ALSA; + } +#endif +#ifdef HAVE_OSS + if (strcmp(api, CAPABILITY_OSS) == 0) { + good = 1; + api = CAPABILITY_OSS; + } +#endif + + if (!good) { + pa_log_error("Invalid API specification."); + goto fail; + } + } + + if (!(conn = pa_dbus_bus_get(m->core, DBUS_BUS_SYSTEM, &error)) || dbus_error_is_set(&error)) { if (conn) pa_dbus_connection_unref(conn); pa_log_error("Unable to contact DBUS system bus: %s: %s", error.name, error.message); goto fail; } - if (!(hal_context = hal_context_new(c, pa_dbus_connection_get(conn)))) { + if (!(hal_context = hal_context_new(m->core, pa_dbus_connection_get(conn)))) { /* pa_hal_context_new() logs appropriate errors */ pa_dbus_connection_unref(conn); goto fail; } u = pa_xnew(struct userdata, 1); - u->core = c; + u->core = m->core; u->context = hal_context; u->connection = conn; u->devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - u->capability = NULL; + u->capability = api; m->userdata = u; #ifdef HAVE_ALSA @@ -736,19 +777,24 @@ int pa__init(pa_core *c, pa_module*m) { pa_log_info("Loaded %i modules.", n); + pa_modargs_free(ma); + return 0; fail: + if (ma) + pa_modargs_free(ma); + dbus_error_free(&error); - pa__done(c, m); + pa__done(m); + return -1; } -void pa__done(PA_GCC_UNUSED pa_core *c, pa_module *m) { +void pa__done(pa_module *m) { struct userdata *u; - pa_assert(c); pa_assert(m); if (!(u = m->userdata)) diff --git a/src/modules/module-lirc.c b/src/modules/module-lirc.c index 452fa1f3..6f4e98dc 100644 --- a/src/modules/module-lirc.c +++ b/src/modules/module-lirc.c @@ -68,11 +68,12 @@ static int lirc_in_use = 0; static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GCC_UNUSED int fd, pa_io_event_flags_t events, void*userdata) { struct userdata *u = userdata; char *name = NULL, *code = NULL; - assert(io); - assert(u); + + pa_assert(io); + pa_assert(u); if (events & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) { - pa_log("lost connection to LIRC daemon."); + pa_log("Lost connection to LIRC daemon."); goto fail; } @@ -86,7 +87,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC c = pa_xstrdup(code); c[strcspn(c, "\n\r")] = 0; - pa_log_debug("raw IR code '%s'", c); + pa_log_debug("Raw IR code '%s'", c); pa_xfree(c); while (lirc_code2char(u->config, code, &name) == 0 && name) { @@ -99,7 +100,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC MUTE_TOGGLE } volchange = INVALID; - pa_log_info("translated IR code '%s'", name); + pa_log_info("Translated IR code '%s'", name); if (strcasecmp(name, "volume-up") == 0) volchange = UP; @@ -113,12 +114,12 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC volchange = RESET; if (volchange == INVALID) - pa_log_warn("recieved unknown IR code '%s'", name); + pa_log_warn("Recieved unknown IR code '%s'", name); else { pa_sink *s; if (!(s = pa_namereg_get(u->module->core, u->sink_name, PA_NAMEREG_SINK, 1))) - pa_log("failed to get sink '%s'", u->sink_name); + pa_log("Failed to get sink '%s'", u->sink_name); else { int i; pa_cvolume cv = *pa_sink_get_volume(s); @@ -179,13 +180,14 @@ fail: pa_module_unload_request(u->module); - free(code); + pa_xfree(code); } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { pa_modargs *ma = NULL; struct userdata *u; - assert(c && m); + + pa_assert(m); if (lirc_in_use) { pa_log("module-lirc may no be loaded twice."); @@ -197,7 +199,7 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - m->userdata = u = pa_xmalloc(sizeof(struct userdata)); + m->userdata = u = pa_xnew(struct userdata, 1); u->module = m; u->io = NULL; u->config = NULL; @@ -215,7 +217,7 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - u->io = c->mainloop->io_new(c->mainloop, u->lirc_fd, PA_IO_EVENT_INPUT|PA_IO_EVENT_HANGUP, io_callback, u); + u->io = m->core->mainloop->io_new(m->core->mainloop, u->lirc_fd, PA_IO_EVENT_INPUT|PA_IO_EVENT_HANGUP, io_callback, u); lirc_in_use = 1; @@ -228,14 +230,13 @@ fail: if (ma) pa_modargs_free(ma); - pa__done(c, m); + pa__done(m); return -1; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - assert(c); - assert(m); + pa_assert(m); if (!(u = m->userdata)) return; diff --git a/src/modules/module-match.c b/src/modules/module-match.c index 0b051fac..373ed487 100644 --- a/src/modules/module-match.c +++ b/src/modules/module-match.c @@ -26,7 +26,6 @@ #endif #include -#include #include #include #include @@ -80,6 +79,8 @@ static int load_rules(struct userdata *u, const char *filename) { struct rule *end = NULL; char *fn = NULL; + pa_assert(u); + f = filename ? fopen(fn = pa_xstrdup(filename), "r") : pa_open_config_file(DEFAULT_MATCH_TABLE_FILE, DEFAULT_MATCH_TABLE_FILE_USER, NULL, &fn, "r"); @@ -132,7 +133,7 @@ static int load_rules(struct userdata *u, const char *filename) { goto finish; } - rule = pa_xmalloc(sizeof(struct rule)); + rule = pa_xnew(struct rule, 1); rule->regex = regex; rule->volume = volume; rule->next = NULL; @@ -164,7 +165,9 @@ static void callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, v struct userdata *u = userdata; pa_sink_input *si; struct rule *r; - assert(c && u); + + pa_assert(c); + pa_assert(u); if (t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW)) return; @@ -185,17 +188,18 @@ static void callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, v } } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { pa_modargs *ma = NULL; struct userdata *u; - assert(c && m); + + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments"); goto fail; } - u = pa_xmalloc(sizeof(struct userdata)); + u = pa_xnew(struct userdata, 1); u->rules = NULL; u->subscription = NULL; m->userdata = u; @@ -203,23 +207,24 @@ int pa__init(pa_core *c, pa_module*m) { if (load_rules(u, pa_modargs_get_value(ma, "table", NULL)) < 0) goto fail; - u->subscription = pa_subscription_new(c, PA_SUBSCRIPTION_MASK_SINK_INPUT, callback, u); + u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK_INPUT, callback, u); pa_modargs_free(ma); return 0; fail: - pa__done(c, m); + pa__done(m); if (ma) pa_modargs_free(ma); return -1; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata* u; struct rule *r, *n; - assert(c && m); + + pa_assert(m); if (!(u = m->userdata)) return; diff --git a/src/modules/module-mmkbd-evdev.c b/src/modules/module-mmkbd-evdev.c index 919b399d..03394c0a 100644 --- a/src/modules/module-mmkbd-evdev.c +++ b/src/modules/module-mmkbd-evdev.c @@ -26,7 +26,6 @@ #endif #include -#include #include #include #include @@ -80,11 +79,12 @@ struct userdata { static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GCC_UNUSED int fd, pa_io_event_flags_t events, void*userdata) { struct userdata *u = userdata; - assert(io); - assert(u); + + pa_assert(io); + pa_assert(u); if (events & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) { - pa_log("lost connection to evdev device."); + pa_log("Lost connection to evdev device."); goto fail; } @@ -92,14 +92,14 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC struct input_event ev; if (pa_loop_read(u->fd, &ev, sizeof(ev), &u->fd_type) <= 0) { - pa_log("failed to read from event device: %s", pa_cstrerror(errno)); + pa_log("Failed to read from event device: %s", pa_cstrerror(errno)); goto fail; } if (ev.type == EV_KEY && (ev.value == 1 || ev.value == 2)) { enum { INVALID, UP, DOWN, MUTE_TOGGLE } volchange = INVALID; - pa_log_debug("key code=%u, value=%u", ev.code, ev.value); + pa_log_debug("Key code=%u, value=%u", ev.code, ev.value); switch (ev.code) { case KEY_VOLUMEDOWN: volchange = DOWN; break; @@ -111,7 +111,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC pa_sink *s; if (!(s = pa_namereg_get(u->module->core, u->sink_name, PA_NAMEREG_SINK, 1))) - pa_log("failed to get sink '%s'", u->sink_name); + pa_log("Failed to get sink '%s'", u->sink_name); else { int i; pa_cvolume cv = *pa_sink_get_volume(s); @@ -165,21 +165,23 @@ fail: #define test_bit(bit, array) (array[bit/8] & (1<<(bit%8))) -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { + pa_modargs *ma = NULL; struct userdata *u; int version; struct _input_id input_id; char name[256]; uint8_t evtype_bitmask[EV_MAX/8 + 1]; - assert(c && m); + + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments"); goto fail; } - m->userdata = u = pa_xmalloc(sizeof(struct userdata)); + m->userdata = u = pa_xnew(struct userdata,1); u->module = m; u->io = NULL; u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL)); @@ -221,11 +223,11 @@ int pa__init(pa_core *c, pa_module*m) { } if (!test_bit(EV_KEY, evtype_bitmask)) { - pa_log("device has no keys."); + pa_log("Device has no keys."); goto fail; } - u->io = c->mainloop->io_new(c->mainloop, u->fd, PA_IO_EVENT_INPUT|PA_IO_EVENT_HANGUP, io_callback, u); + u->io = m->core->mainloop->io_new(m->core->mainloop, u->fd, PA_IO_EVENT_INPUT|PA_IO_EVENT_HANGUP, io_callback, u); pa_modargs_free(ma); @@ -236,14 +238,14 @@ fail: if (ma) pa_modargs_free(ma); - pa__done(c, m); + pa__done(m); return -1; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - assert(c); - assert(m); + + pa_assert(m); if (!(u = m->userdata)) return; diff --git a/src/modules/module-native-protocol-fd.c b/src/modules/module-native-protocol-fd.c index 3c1c2bca..b0a9ebb0 100644 --- a/src/modules/module-native-protocol-fd.c +++ b/src/modules/module-native-protocol-fd.c @@ -26,10 +26,10 @@ #endif #include -#include #include #include +#include #include #include #include @@ -48,25 +48,26 @@ static const char* const valid_modargs[] = { NULL, }; -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { pa_iochannel *io; pa_modargs *ma; int fd, r = -1; - assert(c && m); + + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { - pa_log("failed to parse module arguments."); + pa_log("Failed to parse module arguments."); goto finish; } if (pa_modargs_get_value_s32(ma, "fd", &fd) < 0) { - pa_log("invalid file descriptor."); + pa_log("Invalid file descriptor."); goto finish; } - io = pa_iochannel_new(c->mainloop, fd, fd); + io = pa_iochannel_new(m->core->mainloop, fd, fd); - if (!(m->userdata = pa_protocol_native_new_iochannel(c, io, m, ma))) { + if (!(m->userdata = pa_protocol_native_new_iochannel(m->core, io, m, ma))) { pa_iochannel_free(io); goto finish; } @@ -80,8 +81,8 @@ finish: return r; } -void pa__done(pa_core *c, pa_module*m) { - assert(c && m); +void pa__done(pa_module*m) { + pa_assert(m); pa_protocol_native_free(m->userdata); } diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index f0e3a061..2ede01a4 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -198,13 +198,12 @@ finish: pa_log_debug("Thread shutting down"); } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { struct userdata *u = NULL; pa_sample_spec ss; pa_channel_map map; pa_modargs *ma = NULL; - pa_assert(c); pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { @@ -212,20 +211,20 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - ss = c->default_sample_spec; + ss = m->core->default_sample_spec; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) { pa_log("Invalid sample format specification or channel map"); goto fail; } u = pa_xnew0(struct userdata, 1); - u->core = c; + u->core = m->core; u->module = m; m->userdata = u; pa_assert_se(u->asyncmsgq = pa_asyncmsgq_new(0)); - if (!(u->sink = pa_sink_new(c, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map))) { + if (!(u->sink = pa_sink_new(m->core, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map))) { pa_log("Failed to create sink."); goto fail; } @@ -254,15 +253,14 @@ fail: if (ma) pa_modargs_free(ma); - pa__done(c, m); + pa__done(m); return -1; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - pa_assert(c); pa_assert(m); if (!(u = m->userdata)) diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index a43bdb3c..d93d8c79 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -1059,7 +1059,7 @@ finish: pa_log_debug("Thread shutting down"); } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { struct audio_buf_info info; struct userdata *u = NULL; @@ -1075,7 +1075,6 @@ int pa__init(pa_core *c, pa_module*m) { const char *name; int namereg_fail; - pa_assert(c); pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { @@ -1095,7 +1094,7 @@ int pa__init(pa_core *c, pa_module*m) { mode = (playback && record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0)); - ss = c->default_sample_spec; + ss = m->core->default_sample_spec; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_OSS) < 0) { pa_log("Failed to parse sample specification or channel map"); goto fail; @@ -1150,7 +1149,7 @@ int pa__init(pa_core *c, pa_module*m) { pa_assert(frag_size > 0); u = pa_xnew0(struct userdata, 1); - u->core = c; + u->core = m->core; u->module = m; m->userdata = u; u->fd = fd; @@ -1206,7 +1205,7 @@ int pa__init(pa_core *c, pa_module*m) { namereg_fail = 0; } - u->source = pa_source_new(c, __FILE__, name, namereg_fail, &ss, &map); + u->source = pa_source_new(m->core, __FILE__, name, namereg_fail, &ss, &map); pa_xfree(name_buf); if (!u->source) { pa_log("Failed to create source object"); @@ -1260,7 +1259,7 @@ try_write: namereg_fail = 0; } - u->sink = pa_sink_new(c, __FILE__, name, namereg_fail, &ss, &map); + u->sink = pa_sink_new(m->core, __FILE__, name, namereg_fail, &ss, &map); pa_xfree(name_buf); if (!u->sink) { pa_log("Failed to create sink object"); @@ -1310,7 +1309,7 @@ go_on: fail: if (u) - pa__done(c, m); + pa__done(m); else if (fd >= 0) close(fd); @@ -1320,10 +1319,9 @@ fail: return -1; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - pa_assert(c); pa_assert(m); if (!(u = m->userdata)) diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index 83ee06b7..1b6d0813 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -232,7 +232,7 @@ finish: pa_log_debug("Thread shutting down"); } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { struct userdata *u; struct stat st; pa_sample_spec ss; @@ -240,7 +240,6 @@ int pa__init(pa_core *c, pa_module*m) { pa_modargs *ma; char *t; - pa_assert(c); pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { @@ -248,14 +247,14 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - ss = c->default_sample_spec; + ss = m->core->default_sample_spec; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) { pa_log("Invalid sample format specification or channel map"); goto fail; } u = pa_xnew0(struct userdata, 1); - u->core = c; + u->core = m->core; u->module = m; m->userdata = u; pa_memchunk_reset(&u->memchunk); @@ -283,7 +282,7 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - if (!(u->sink = pa_sink_new(c, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map))) { + if (!(u->sink = pa_sink_new(m->core, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map))) { pa_log("Failed to create sink."); goto fail; } @@ -309,15 +308,14 @@ fail: if (ma) pa_modargs_free(ma); - pa__done(c, m); + pa__done(m); return -1; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - pa_assert(c); pa_assert(m); if (!(u = m->userdata)) diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index a5f95f9a..a8fbcf3d 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -210,7 +210,7 @@ finish: pa_log_debug("Thread shutting down"); } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { struct userdata *u; struct stat st; pa_sample_spec ss; @@ -218,7 +218,6 @@ int pa__init(pa_core *c, pa_module*m) { pa_modargs *ma; char *t; - pa_assert(c); pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { @@ -226,14 +225,14 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - ss = c->default_sample_spec; + ss = m->core->default_sample_spec; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) { pa_log("invalid sample format specification or channel map"); goto fail; } u = pa_xnew0(struct userdata, 1); - u->core = c; + u->core = m->core; u->module = m; m->userdata = u; pa_memchunk_reset(&u->memchunk); @@ -261,7 +260,7 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - if (!(u->source = pa_source_new(c, __FILE__, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME), 0, &ss, &map))) { + if (!(u->source = pa_source_new(m->core, __FILE__, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME), 0, &ss, &map))) { pa_log("Failed to create source."); goto fail; } @@ -286,15 +285,14 @@ fail: if (ma) pa_modargs_free(ma); - pa__done(c, m); + pa__done(m); return -1; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - pa_assert(c); pa_assert(m); if (!(u = m->userdata)) diff --git a/src/modules/module-protocol-stub.c b/src/modules/module-protocol-stub.c index 3edb59e5..fb7cf22d 100644 --- a/src/modules/module-protocol-stub.c +++ b/src/modules/module-protocol-stub.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -43,10 +42,9 @@ #include #endif -#include "../pulsecore/winsock.h" - #include +#include #include #include #include @@ -204,10 +202,9 @@ struct userdata { #endif }; -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { pa_modargs *ma = NULL; int ret = -1; - struct userdata *u = NULL; #if defined(USE_TCP_SOCKETS) @@ -224,7 +221,7 @@ int pa__init(pa_core *c, pa_module*m) { #endif #endif - assert(c && m); + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments"); @@ -242,22 +239,22 @@ int pa__init(pa_core *c, pa_module*m) { listen_on = pa_modargs_get_value(ma, "listen", NULL); if (listen_on) { - s_ipv6 = pa_socket_server_new_ipv6_string(c->mainloop, listen_on, port, TCPWRAP_SERVICE); - s_ipv4 = pa_socket_server_new_ipv4_string(c->mainloop, listen_on, port, TCPWRAP_SERVICE); + s_ipv6 = pa_socket_server_new_ipv6_string(m->core->mainloop, listen_on, port, TCPWRAP_SERVICE); + s_ipv4 = pa_socket_server_new_ipv4_string(m->core->mainloop, listen_on, port, TCPWRAP_SERVICE); } else { - s_ipv6 = pa_socket_server_new_ipv6_any(c->mainloop, port, TCPWRAP_SERVICE); - s_ipv4 = pa_socket_server_new_ipv4_any(c->mainloop, port, TCPWRAP_SERVICE); + s_ipv6 = pa_socket_server_new_ipv6_any(m->core->mainloop, port, TCPWRAP_SERVICE); + s_ipv4 = pa_socket_server_new_ipv4_any(m->core->mainloop, port, TCPWRAP_SERVICE); } if (!s_ipv4 && !s_ipv6) goto fail; if (s_ipv4) - if (!(u->protocol_ipv4 = protocol_new(c, s_ipv4, m, ma))) + if (!(u->protocol_ipv4 = protocol_new(m->core, s_ipv4, m, ma))) pa_socket_server_unref(s_ipv4); if (s_ipv6) - if (!(u->protocol_ipv6 = protocol_new(c, s_ipv6, m, ma))) + if (!(u->protocol_ipv6 = protocol_new(m->core, s_ipv6, m, ma))) pa_socket_server_unref(s_ipv6); if (!u->protocol_ipv4 && !u->protocol_ipv6) @@ -274,7 +271,7 @@ int pa__init(pa_core *c, pa_module*m) { /* This socket doesn't reside in our own runtime dir but in * /tmp/.esd/, hence we have to create the dir first */ - if (pa_make_secure_parent_dir(u->socket_path, c->is_system_instance ? 0755 : 0700, (uid_t)-1, (gid_t)-1) < 0) { + if (pa_make_secure_parent_dir(u->socket_path, m->core->is_system_instance ? 0755 : 0700, (uid_t)-1, (gid_t)-1) < 0) { pa_log("Failed to create socket directory '%s': %s\n", u->socket_path, pa_cstrerror(errno)); goto fail; } @@ -292,10 +289,10 @@ int pa__init(pa_core *c, pa_module*m) { if (r) pa_log("Removed stale UNIX socket '%s'.", tmp); - if (!(s = pa_socket_server_new_unix(c->mainloop, tmp))) + if (!(s = pa_socket_server_new_unix(m->core->mainloop, tmp))) goto fail; - if (!(u->protocol_unix = protocol_new(c, s, m, ma))) + if (!(u->protocol_unix = protocol_new(m->core, s, m, ma))) goto fail; #endif @@ -341,11 +338,10 @@ fail: goto finish; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - assert(c); - assert(m); + pa_assert(m); u = m->userdata; @@ -366,7 +362,6 @@ void pa__done(pa_core *c, pa_module*m) { } #endif - pa_xfree(u->socket_path); #endif diff --git a/src/modules/module-rescue-streams.c b/src/modules/module-rescue-streams.c index 034660e4..fa22d60a 100644 --- a/src/modules/module-rescue-streams.c +++ b/src/modules/module-rescue-streams.c @@ -126,11 +126,10 @@ static pa_hook_result_t source_hook_callback(pa_core *c, pa_source *source, void return PA_HOOK_OK; } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { pa_modargs *ma = NULL; struct userdata *u; - pa_assert(c); pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { @@ -139,17 +138,16 @@ int pa__init(pa_core *c, pa_module*m) { } m->userdata = u = pa_xnew(struct userdata, 1); - u->sink_slot = pa_hook_connect(&c->hook_sink_disconnect, (pa_hook_cb_t) sink_hook_callback, NULL); - u->source_slot = pa_hook_connect(&c->hook_source_disconnect, (pa_hook_cb_t) source_hook_callback, NULL); + u->sink_slot = pa_hook_connect(&m->core->hook_sink_disconnect, (pa_hook_cb_t) sink_hook_callback, NULL); + u->source_slot = pa_hook_connect(&m->core->hook_source_disconnect, (pa_hook_cb_t) source_hook_callback, NULL); pa_modargs_free(ma); return 0; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - pa_assert(c); pa_assert(m); if (!m->userdata) diff --git a/src/modules/module-sine.c b/src/modules/module-sine.c index 797ba440..f2830ff0 100644 --- a/src/modules/module-sine.c +++ b/src/modules/module-sine.c @@ -114,7 +114,7 @@ static void calc_sine(float *f, size_t l, float freq) { f[i] = (float) sin((double) i/l*M_PI*2*freq)/2; } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { pa_modargs *ma = NULL; struct userdata *u; pa_sink *sink; @@ -130,13 +130,13 @@ int pa__init(pa_core *c, pa_module*m) { } m->userdata = u = pa_xnew0(struct userdata, 1); - u->core = c; + u->core = m->core; u->module = m; u->sink_input = NULL; u->memblock = NULL; u->peek_index = 0; - if (!(sink = pa_namereg_get(c, pa_modargs_get_value(ma, "sink", NULL), PA_NAMEREG_SINK, 1))) { + if (!(sink = pa_namereg_get(m->core, pa_modargs_get_value(ma, "sink", NULL), PA_NAMEREG_SINK, 1))) { pa_log("No such sink."); goto fail; } @@ -151,7 +151,7 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - u->memblock = pa_memblock_new(c->mempool, pa_bytes_per_second(&ss)); + u->memblock = pa_memblock_new(m->core->mempool, pa_bytes_per_second(&ss)); p = pa_memblock_acquire(u->memblock); calc_sine(p, pa_memblock_get_length(u->memblock), frequency); pa_memblock_release(u->memblock); @@ -165,7 +165,7 @@ int pa__init(pa_core *c, pa_module*m) { pa_sink_input_new_data_set_sample_spec(&data, &ss); data.module = m; - if (!(u->sink_input = pa_sink_input_new(c, &data, 0))) + if (!(u->sink_input = pa_sink_input_new(m->core, &data, 0))) goto fail; u->sink_input->peek = sink_input_peek_cb; @@ -182,14 +182,13 @@ fail: if (ma) pa_modargs_free(ma); - pa__done(c, m); + pa__done(m); return -1; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - pa_assert(c); pa_assert(m); if (!(u = m->userdata)) diff --git a/src/modules/module-suspend-on-idle.c b/src/modules/module-suspend-on-idle.c index d2c51a10..ad148644 100644 --- a/src/modules/module-suspend-on-idle.c +++ b/src/modules/module-suspend-on-idle.c @@ -209,7 +209,7 @@ static pa_hook_result_t device_disconnect_hook_cb(pa_core *c, pa_object *o, stru return PA_HOOK_OK; } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { pa_modargs *ma = NULL; struct userdata *u; uint32_t timeout = 5; @@ -217,8 +217,7 @@ int pa__init(pa_core *c, pa_module*m) { pa_sink *sink; pa_source *source; - assert(c); - assert(m); + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments."); @@ -231,25 +230,25 @@ int pa__init(pa_core *c, pa_module*m) { } m->userdata = u = pa_xnew(struct userdata, 1); - u->core = c; + u->core = m->core; u->timeout = timeout; u->device_infos = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - for (sink = pa_idxset_first(c->sinks, &idx); sink; sink = pa_idxset_next(c->sinks, &idx)) - device_new_hook_cb(c, PA_OBJECT(sink), u); + for (sink = pa_idxset_first(m->core->sinks, &idx); sink; sink = pa_idxset_next(m->core->sinks, &idx)) + device_new_hook_cb(m->core, PA_OBJECT(sink), u); - for (source = pa_idxset_first(c->sources, &idx); source; source = pa_idxset_next(c->sources, &idx)) - device_new_hook_cb(c, PA_OBJECT(source), u); + for (source = pa_idxset_first(m->core->sources, &idx); source; source = pa_idxset_next(m->core->sources, &idx)) + device_new_hook_cb(m->core, PA_OBJECT(source), u); - u->sink_new_slot = pa_hook_connect(&c->hook_sink_new_post, (pa_hook_cb_t) device_new_hook_cb, u); - u->source_new_slot = pa_hook_connect(&c->hook_source_new_post, (pa_hook_cb_t) device_new_hook_cb, u); - u->sink_disconnect_slot = pa_hook_connect(&c->hook_sink_disconnect_post, (pa_hook_cb_t) device_disconnect_hook_cb, u); - u->source_disconnect_slot = pa_hook_connect(&c->hook_source_disconnect_post, (pa_hook_cb_t) device_disconnect_hook_cb, u); + u->sink_new_slot = pa_hook_connect(&m->core->hook_sink_new_post, (pa_hook_cb_t) device_new_hook_cb, u); + u->source_new_slot = pa_hook_connect(&m->core->hook_source_new_post, (pa_hook_cb_t) device_new_hook_cb, u); + u->sink_disconnect_slot = pa_hook_connect(&m->core->hook_sink_disconnect_post, (pa_hook_cb_t) device_disconnect_hook_cb, u); + u->source_disconnect_slot = pa_hook_connect(&m->core->hook_source_disconnect_post, (pa_hook_cb_t) device_disconnect_hook_cb, u); - u->sink_input_new_slot = pa_hook_connect(&c->hook_sink_input_new_post, (pa_hook_cb_t) sink_input_new_hook_cb, u); - u->source_output_new_slot = pa_hook_connect(&c->hook_source_output_new_post, (pa_hook_cb_t) source_output_new_hook_cb, u); - u->sink_input_disconnect_slot = pa_hook_connect(&c->hook_sink_input_disconnect_post, (pa_hook_cb_t) sink_input_disconnect_hook_cb, u); - u->source_output_disconnect_slot = pa_hook_connect(&c->hook_source_output_disconnect_post, (pa_hook_cb_t) source_output_disconnect_hook_cb, u); + u->sink_input_new_slot = pa_hook_connect(&m->core->hook_sink_input_new_post, (pa_hook_cb_t) sink_input_new_hook_cb, u); + u->source_output_new_slot = pa_hook_connect(&m->core->hook_source_output_new_post, (pa_hook_cb_t) source_output_new_hook_cb, u); + u->sink_input_disconnect_slot = pa_hook_connect(&m->core->hook_sink_input_disconnect_post, (pa_hook_cb_t) sink_input_disconnect_hook_cb, u); + u->source_output_disconnect_slot = pa_hook_connect(&m->core->hook_source_output_disconnect_post, (pa_hook_cb_t) source_output_disconnect_hook_cb, u); pa_modargs_free(ma); return 0; @@ -262,12 +261,11 @@ fail: return -1; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; struct device_info *d; - assert(c); - assert(m); + pa_assert(m); if (!m->userdata) return; diff --git a/src/modules/module-volume-restore.c b/src/modules/module-volume-restore.c index 0f0d998b..addd937b 100644 --- a/src/modules/module-volume-restore.c +++ b/src/modules/module-volume-restore.c @@ -420,11 +420,10 @@ static pa_hook_result_t source_output_hook_callback(pa_core *c, pa_source_output return PA_HOOK_OK; } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { pa_modargs *ma = NULL; struct userdata *u; - assert(c); assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { @@ -444,16 +443,15 @@ int pa__init(pa_core *c, pa_module*m) { if (load_rules(u) < 0) goto fail; - u->subscription = pa_subscription_new(c, PA_SUBSCRIPTION_MASK_SINK_INPUT|PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT, subscribe_callback, u); - u->sink_input_hook_slot = pa_hook_connect(&c->hook_sink_input_new, (pa_hook_cb_t) sink_input_hook_callback, u); - u->source_output_hook_slot = pa_hook_connect(&c->hook_source_output_new, (pa_hook_cb_t) source_output_hook_callback, u); + u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK_INPUT|PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT, subscribe_callback, u); + u->sink_input_hook_slot = pa_hook_connect(&m->core->hook_sink_input_new, (pa_hook_cb_t) sink_input_hook_callback, u); + u->source_output_hook_slot = pa_hook_connect(&m->core->hook_source_output_new, (pa_hook_cb_t) source_output_hook_callback, u); pa_modargs_free(ma); return 0; fail: - pa__done(c, m); - + pa__done(m); if (ma) pa_modargs_free(ma); @@ -470,10 +468,9 @@ static void free_func(void *p, void *userdata) { pa_xfree(r); } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata* u; - assert(c); assert(m); if (!(u = m->userdata)) diff --git a/src/modules/module-x11-bell.c b/src/modules/module-x11-bell.c index 0c3c63f3..e59db83c 100644 --- a/src/modules/module-x11-bell.c +++ b/src/modules/module-x11-bell.c @@ -88,14 +88,13 @@ static int x11_event_callback(pa_x11_wrapper *w, XEvent *e, void *userdata) { return 1; } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { struct userdata *u = NULL; pa_modargs *ma = NULL; int major, minor; unsigned int auto_ctrls, auto_values; - pa_assert(c); pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { @@ -104,12 +103,12 @@ int pa__init(pa_core *c, pa_module*m) { } m->userdata = u = pa_xnew(struct userdata, 1); - u->core = c; + u->core = m->core; u->scache_item = pa_xstrdup(pa_modargs_get_value(ma, "sample", "x11-bell")); u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL)); u->x11_client = NULL; - if (!(u->x11_wrapper = pa_x11_wrapper_get(c, pa_modargs_get_value(ma, "display", NULL)))) + if (!(u->x11_wrapper = pa_x11_wrapper_get(m->core, pa_modargs_get_value(ma, "display", NULL)))) goto fail; major = XkbMajorVersion; @@ -143,16 +142,15 @@ fail: if (ma) pa_modargs_free(ma); - pa__done(c, m); + pa__done(m); return -1; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - assert(c); - assert(m); + pa_assert(m); if (!m->userdata) return; diff --git a/src/modules/module-x11-publish.c b/src/modules/module-x11-publish.c index fd1d532f..7da9cc2d 100644 --- a/src/modules/module-x11-publish.c +++ b/src/modules/module-x11-publish.c @@ -26,7 +26,6 @@ #endif #include -#include #include #include #include @@ -76,7 +75,7 @@ struct userdata { }; static int load_key(struct userdata *u, const char*fn) { - assert(u); + pa_assert(u); u->auth_cookie_in_property = 0; @@ -93,7 +92,7 @@ static int load_key(struct userdata *u, const char*fn) { if (pa_authkey_load_auto(fn, u->auth_cookie, sizeof(u->auth_cookie)) < 0) return -1; - pa_log_debug("loading cookie from disk."); + pa_log_debug("Loading cookie from disk."); if (pa_authkey_prop_put(u->core, PA_NATIVE_COOKIE_PROPERTY_NAME, u->auth_cookie, sizeof(u->auth_cookie)) >= 0) u->auth_cookie_in_property = 1; @@ -101,7 +100,7 @@ static int load_key(struct userdata *u, const char*fn) { return 0; } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { struct userdata *u; pa_modargs *ma = NULL; char hn[256], un[128]; @@ -110,23 +109,25 @@ int pa__init(pa_core *c, pa_module*m) { char *s; pa_strlist *l; + pa_assert(m); + if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("failed to parse module arguments"); goto fail; } m->userdata = u = pa_xmalloc(sizeof(struct userdata)); - u->core = c; + u->core = m->core; u->id = NULL; u->auth_cookie_in_property = 0; if (load_key(u, pa_modargs_get_value(ma, "cookie", NULL)) < 0) goto fail; - if (!(u->x11_wrapper = pa_x11_wrapper_get(c, pa_modargs_get_value(ma, "display", NULL)))) + if (!(u->x11_wrapper = pa_x11_wrapper_get(m->core, pa_modargs_get_value(ma, "display", NULL)))) goto fail; - if (!(l = pa_property_get(c, PA_NATIVE_SERVER_PROPERTY_NAME))) + if (!(l = pa_property_get(m->core, PA_NATIVE_SERVER_PROPERTY_NAME))) goto fail; s = pa_strlist_tostring(l); @@ -154,13 +155,14 @@ fail: if (ma) pa_modargs_free(ma); - pa__done(c, m); + pa__done(m); return -1; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata*u; - assert(c && m); + + pa_assert(m); if (!(u = m->userdata)) return; @@ -185,7 +187,7 @@ void pa__done(pa_core *c, pa_module*m) { pa_x11_wrapper_unref(u->x11_wrapper); if (u->auth_cookie_in_property) - pa_authkey_prop_unref(c, PA_NATIVE_COOKIE_PROPERTY_NAME); + pa_authkey_prop_unref(m->core, PA_NATIVE_COOKIE_PROPERTY_NAME); pa_xfree(u->id); pa_xfree(u); diff --git a/src/modules/module-x11-xsmp.c b/src/modules/module-x11-xsmp.c index dc23ebe3..4ef437a1 100644 --- a/src/modules/module-x11-xsmp.c +++ b/src/modules/module-x11-xsmp.c @@ -49,17 +49,14 @@ PA_MODULE_AUTHOR("Lennart Poettering") PA_MODULE_DESCRIPTION("X11 session management") PA_MODULE_VERSION(PACKAGE_VERSION) -struct userdata { - pa_core *core; - SmcConn sm_conn; -}; +static int ice_in_use = 0; static const char* const valid_modargs[] = { NULL }; static void die_cb(SmcConn connection, SmPointer client_data){ - pa_core *c = client_data; + pa_core *c = PA_CORE(client_data); pa_log_debug("Got die message from XSM. Exiting..."); @@ -98,18 +95,26 @@ static void new_ice_connection(IceConn connection, IcePointer client_data, Bool c->mainloop->io_free(*watch_data); } -int pa__init(pa_core *c, pa_module*m) { - struct userdata *u = NULL; +int pa__init(pa_module*m) { + pa_modargs *ma = NULL; char t[256], *vendor, *client_id; SmcCallbacks callbacks; SmProp prop_program, prop_user; SmProp *prop_list[2]; SmPropValue val_program, val_user; + SmcConn connection; - pa_assert(c); pa_assert(m); + if (ice_in_use) { + pa_log("module-x11-xsmp may no be loaded twice."); + return -1; + } + + IceAddConnectionWatch(new_ice_connection, m->core); + ice_in_use = 1; + if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments"); goto fail; @@ -119,23 +124,19 @@ int pa__init(pa_core *c, pa_module*m) { pa_log("X11 session manager not running."); goto fail; } - - m->userdata = u = pa_xnew(struct userdata, 1); - u->core = c; - u->sm_conn = NULL; - - IceAddConnectionWatch(new_ice_connection, c); memset(&callbacks, 0, sizeof(callbacks)); callbacks.die.callback = die_cb; - callbacks.die.client_data = c; - + callbacks.die.client_data = m->core; callbacks.save_yourself.callback = save_yourself_cb; + callbacks.save_yourself.client_data = m->core; callbacks.save_complete.callback = save_complete_cb; + callbacks.save_complete.client_data = m->core; callbacks.shutdown_cancelled.callback = shutdown_cancelled_cb; + callbacks.shutdown_cancelled.client_data = m->core; - if (!(u->sm_conn = SmcOpenConnection( - NULL, u, + if (!(m->userdata = connection = SmcOpenConnection( + NULL, m->core, SmProtoMajor, SmProtoMinor, SmcSaveYourselfProcMask | SmcDieProcMask | SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask, &callbacks, NULL, &client_id, @@ -162,9 +163,9 @@ int pa__init(pa_core *c, pa_module*m) { prop_user.vals = &val_user; prop_list[1] = &prop_user; - SmcSetProperties(u->sm_conn, PA_ELEMENTSOF(prop_list), prop_list); + SmcSetProperties(connection, PA_ELEMENTSOF(prop_list), prop_list); - pa_log_info("Connected to session manager '%s' as '%s'.", vendor = SmcVendor(u->sm_conn), client_id); + pa_log_info("Connected to session manager '%s' as '%s'.", vendor = SmcVendor(connection), client_id); free(vendor); free(client_id); @@ -176,26 +177,19 @@ fail: if (ma) pa_modargs_free(ma); - pa__done(c, m); + pa__done(m); return -1; } -void pa__done(pa_core *c, pa_module*m) { - struct userdata *u; - - assert(c); - assert(m); - - if (!m->userdata) - return; - - u = m->userdata; +void pa__done(pa_module*m) { + pa_assert(m); - if (u->sm_conn) - SmcCloseConnection(u->sm_conn, 0, NULL); + if (m->userdata) + SmcCloseConnection(m->userdata, 0, NULL); - IceRemoveConnectionWatch(new_ice_connection, c); - - pa_xfree(u); + if (ice_in_use) { + IceRemoveConnectionWatch(new_ice_connection, m->core); + ice_in_use = 0; + } } diff --git a/src/modules/module-zeroconf-publish.c b/src/modules/module-zeroconf-publish.c index 69508ad0..34565395 100644 --- a/src/modules/module-zeroconf-publish.c +++ b/src/modules/module-zeroconf-publish.c @@ -102,25 +102,25 @@ struct userdata { }; static void get_service_data(struct userdata *u, struct service *s, pa_sample_spec *ret_ss, char **ret_description) { - assert(u && s && s->loaded.valid && ret_ss && ret_description); + pa_assert(u && s && s->loaded.valid && ret_ss && ret_description); if (s->loaded.type == PA_NAMEREG_SINK) { pa_sink *sink = pa_idxset_get_by_index(u->core->sinks, s->loaded.index); - assert(sink); + pa_assert(sink); *ret_ss = sink->sample_spec; *ret_description = sink->description; } else if (s->loaded.type == PA_NAMEREG_SOURCE) { pa_source *source = pa_idxset_get_by_index(u->core->sources, s->loaded.index); - assert(source); + pa_assert(source); *ret_ss = source->sample_spec; *ret_description = source->description; } else - assert(0); + pa_assert(0); } static AvahiStringList* txt_record_server_data(pa_core *c, AvahiStringList *l) { char s[128]; - assert(c); + pa_assert(c); l = avahi_string_list_add_pair(l, "server-version", PACKAGE_NAME" "PACKAGE_VERSION); l = avahi_string_list_add_pair(l, "user-name", pa_get_user_name(s, sizeof(s))); @@ -150,8 +150,8 @@ static int publish_service(struct userdata *u, struct service *s) { int r = -1; AvahiStringList *txt = NULL; - assert(u); - assert(s); + pa_assert(u); + pa_assert(s); if (!u->client || avahi_client_get_state(u->client) != AVAHI_CLIENT_S_RUNNING) return 0; @@ -265,7 +265,7 @@ static struct service *get_service(struct userdata *u, const char *name, const c static int publish_sink(struct userdata *u, pa_sink *s) { struct service *svc; int ret; - assert(u && s); + pa_assert(u && s); svc = get_service(u, s->name, s->description); if (svc->loaded.valid) @@ -286,7 +286,7 @@ static int publish_source(struct userdata *u, pa_source *s) { struct service *svc; int ret; - assert(u && s); + pa_assert(u && s); svc = get_service(u, s->name, s->description); if (svc->loaded.valid) @@ -309,7 +309,7 @@ static int publish_autoload(struct userdata *u, pa_autoload_entry *s) { struct service *svc; int ret; - assert(u && s); + pa_assert(u && s); svc = get_service(u, s->name, NULL); if (svc->autoload.valid) @@ -328,7 +328,7 @@ static int publish_autoload(struct userdata *u, pa_autoload_entry *s) { static int remove_sink(struct userdata *u, uint32_t idx) { struct service *svc; - assert(u && idx != PA_INVALID_INDEX); + pa_assert(u && idx != PA_INVALID_INDEX); if (!(svc = pa_dynarray_get(u->sink_dynarray, idx))) return 0; @@ -344,7 +344,7 @@ static int remove_sink(struct userdata *u, uint32_t idx) { static int remove_source(struct userdata *u, uint32_t idx) { struct service *svc; - assert(u && idx != PA_INVALID_INDEX); + pa_assert(u && idx != PA_INVALID_INDEX); if (!(svc = pa_dynarray_get(u->source_dynarray, idx))) return 0; @@ -360,7 +360,7 @@ static int remove_source(struct userdata *u, uint32_t idx) { static int remove_autoload(struct userdata *u, uint32_t idx) { struct service *svc; - assert(u && idx != PA_INVALID_INDEX); + pa_assert(u && idx != PA_INVALID_INDEX); if (!(svc = pa_dynarray_get(u->autoload_dynarray, idx))) return 0; @@ -376,7 +376,7 @@ static int remove_autoload(struct userdata *u, uint32_t idx) { static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { struct userdata *u = userdata; - assert(u && c); + pa_assert(u && c); switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) case PA_SUBSCRIPTION_EVENT_SINK: { @@ -439,7 +439,7 @@ static int publish_main_service(struct userdata *u); static void main_entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) { struct userdata *u = userdata; - assert(u); + pa_assert(u); if (state == AVAHI_ENTRY_GROUP_COLLISION) { char *t; @@ -501,7 +501,7 @@ static int publish_all_services(struct userdata *u) { int r = -1; uint32_t idx; - assert(u); + pa_assert(u); pa_log_debug("Publishing services in Zeroconf"); @@ -531,7 +531,7 @@ static void unpublish_all_services(struct userdata *u, int rem) { void *state = NULL; struct service *s; - assert(u); + pa_assert(u); pa_log_debug("Unpublishing services in Zeroconf"); @@ -558,7 +558,7 @@ static void unpublish_all_services(struct userdata *u, int rem) { static void client_callback(AvahiClient *c, AvahiClientState state, void *userdata) { struct userdata *u = userdata; - assert(c); + pa_assert(c); u->client = c; @@ -587,7 +587,8 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void *userda } } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { + struct userdata *u; uint32_t port = PA_NATIVE_DEFAULT_PORT; pa_modargs *ma = NULL; @@ -599,23 +600,23 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - if (pa_modargs_get_value_u32(ma, "port", &port) < 0 || port == 0 || port >= 0xFFFF) { + if (pa_modargs_get_value_u32(ma, "port", &port) < 0 || port <= 0 || port > 0xFFFF) { pa_log("invalid port specified."); goto fail; } m->userdata = u = pa_xnew(struct userdata, 1); - u->core = c; + u->core = m->core; u->port = (uint16_t) port; - u->avahi_poll = pa_avahi_poll_new(c->mainloop); + u->avahi_poll = pa_avahi_poll_new(m->core->mainloop); u->services = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); u->sink_dynarray = pa_dynarray_new(); u->source_dynarray = pa_dynarray_new(); u->autoload_dynarray = pa_dynarray_new(); - u->subscription = pa_subscription_new(c, + u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK| PA_SUBSCRIPTION_MASK_SOURCE| PA_SUBSCRIPTION_MASK_AUTOLOAD, subscribe_callback, u); @@ -634,7 +635,7 @@ int pa__init(pa_core *c, pa_module*m) { return 0; fail: - pa__done(c, m); + pa__done(m); if (ma) pa_modargs_free(ma); @@ -646,8 +647,8 @@ static void service_free(void *p, void *userdata) { struct service *s = p; struct userdata *u = userdata; - assert(s); - assert(u); + pa_assert(s); + pa_assert(u); if (s->entry_group) avahi_entry_group_free(s->entry_group); @@ -657,9 +658,9 @@ static void service_free(void *p, void *userdata) { pa_xfree(s); } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata*u; - assert(c && m); + pa_assert(m); if (!(u = m->userdata)) return; diff --git a/src/pulsecore/ltdl-helper.c b/src/pulsecore/ltdl-helper.c new file mode 100644 index 00000000..bdce18ef --- /dev/null +++ b/src/pulsecore/ltdl-helper.c @@ -0,0 +1,64 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include + +#include +#include + +#include "ltdl-helper.h" + +pa_void_func_t pa_load_sym(lt_dlhandle handle, const char *module, const char *symbol) { + char *sn, *c; + pa_void_func_t f; + + pa_assert(handle); + pa_assert(module); + pa_assert(symbol); + + if ((f = ((pa_void_func_t) (long) lt_dlsym(handle, symbol)))) + return f; + + /* As the .la files might have been cleansed from the system, we should + * try with the ltdl prefix as well. */ + + sn = pa_sprintf_malloc("%s_LTX_%s", module, symbol); + + for (c = sn; *c; c++) + if (!isalnum(*c)) + *c = '_'; + + f = (pa_void_func_t) (long) lt_dlsym(handle, sn); + pa_xfree(sn); + + return f; +} diff --git a/src/pulsecore/ltdl-helper.h b/src/pulsecore/ltdl-helper.h new file mode 100644 index 00000000..5c7388a1 --- /dev/null +++ b/src/pulsecore/ltdl-helper.h @@ -0,0 +1,34 @@ +#ifndef foopulsecoreltdlhelperhfoo +#define foopulsecoreltdlhelperhfoo + +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include + +typedef void (*pa_void_func_t)(void); + +pa_void_func_t pa_load_sym(lt_dlhandle handle, const char*module, const char *symbol); + +#endif + diff --git a/src/pulsecore/modinfo.c b/src/pulsecore/modinfo.c index 58394e59..79baef84 100644 --- a/src/pulsecore/modinfo.c +++ b/src/pulsecore/modinfo.c @@ -26,12 +26,13 @@ #endif #include -#include #include #include #include +#include +#include #include "modinfo.h" @@ -40,30 +41,24 @@ #define PA_SYMBOL_USAGE "pa__get_usage" #define PA_SYMBOL_VERSION "pa__get_version" -/* lt_dlsym() violates ISO C, so confide the breakage into this function to - * avoid warnings. */ -typedef void (*fnptr)(void); -static inline fnptr lt_dlsym_fn(lt_dlhandle handle, const char *symbol) { - return (fnptr) (long) lt_dlsym(handle, symbol); -} - -pa_modinfo *pa_modinfo_get_by_handle(lt_dlhandle dl) { +pa_modinfo *pa_modinfo_get_by_handle(lt_dlhandle dl, const char *module_name) { pa_modinfo *i; const char* (*func)(void); - assert(dl); + + pa_assert(dl); i = pa_xnew0(pa_modinfo, 1); - if ((func = (const char* (*)(void)) lt_dlsym_fn(dl, PA_SYMBOL_AUTHOR))) + if ((func = (const char* (*)(void)) pa_load_sym(dl, module_name, PA_SYMBOL_AUTHOR))) i->author = pa_xstrdup(func()); - if ((func = (const char* (*)(void)) lt_dlsym_fn(dl, PA_SYMBOL_DESCRIPTION))) + if ((func = (const char* (*)(void)) pa_load_sym(dl, module_name, PA_SYMBOL_DESCRIPTION))) i->description = pa_xstrdup(func()); - if ((func = (const char* (*)(void)) lt_dlsym_fn(dl, PA_SYMBOL_USAGE))) + if ((func = (const char* (*)(void)) pa_load_sym(dl, module_name, PA_SYMBOL_USAGE))) i->usage = pa_xstrdup(func()); - if ((func = (const char* (*)(void)) lt_dlsym_fn(dl, PA_SYMBOL_VERSION))) + if ((func = (const char* (*)(void)) pa_load_sym(dl, module_name, PA_SYMBOL_VERSION))) i->version = pa_xstrdup(func()); return i; @@ -72,14 +67,15 @@ pa_modinfo *pa_modinfo_get_by_handle(lt_dlhandle dl) { pa_modinfo *pa_modinfo_get_by_name(const char *name) { lt_dlhandle dl; pa_modinfo *i; - assert(name); + + pa_assert(name); if (!(dl = lt_dlopenext(name))) { pa_log("Failed to open module \"%s\": %s", name, lt_dlerror()); return NULL; } - i = pa_modinfo_get_by_handle(dl); + i = pa_modinfo_get_by_handle(dl, name); lt_dlclose(dl); return i; @@ -87,6 +83,7 @@ pa_modinfo *pa_modinfo_get_by_name(const char *name) { void pa_modinfo_free(pa_modinfo *i) { assert(i); + pa_xfree(i->author); pa_xfree(i->description); pa_xfree(i->usage); diff --git a/src/pulsecore/modinfo.h b/src/pulsecore/modinfo.h index 3ee33ede..02e536c6 100644 --- a/src/pulsecore/modinfo.h +++ b/src/pulsecore/modinfo.h @@ -34,7 +34,7 @@ typedef struct pa_modinfo { } pa_modinfo; /* Read meta data from an libtool handle */ -pa_modinfo *pa_modinfo_get_by_handle(lt_dlhandle dl); +pa_modinfo *pa_modinfo_get_by_handle(lt_dlhandle dl, const char *module_name); /* Read meta data from a module file */ pa_modinfo *pa_modinfo_get_by_name(const char *name); diff --git a/src/pulsecore/module.c b/src/pulsecore/module.c index 09b15b8b..bd565546 100644 --- a/src/pulsecore/module.c +++ b/src/pulsecore/module.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -40,6 +39,8 @@ #include #include #include +#include +#include #include "module.h" @@ -48,69 +49,31 @@ #define UNLOAD_POLL_TIME 2 -/* lt_dlsym() violates ISO C, so confide the breakage into this function to - * avoid warnings. */ -typedef void (*fnptr)(void); -static inline fnptr lt_dlsym_fn(lt_dlhandle handle, const char *symbol) { - return (fnptr) (long) lt_dlsym(handle, symbol); -} - static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { - pa_core *c = userdata; + pa_core *c = PA_CORE(userdata); struct timeval ntv; - assert(c && c->mainloop == m && c->module_auto_unload_event == e); + + pa_core_assert_ref(c); + pa_assert(c->mainloop == m); + pa_assert(c->module_auto_unload_event == e); pa_module_unload_unused(c); pa_gettimeofday(&ntv); - ntv.tv_sec += UNLOAD_POLL_TIME; + pa_timeval_add(&ntv, UNLOAD_POLL_TIME*1000000); m->time_restart(e, &ntv); } -static inline fnptr load_sym(lt_dlhandle handle, const char *module, const char *symbol) { - char *buffer, *ch; - size_t buflen; - fnptr res; - - res = lt_dlsym_fn(handle, symbol); - if (res) - return res; - - /* As the .la files might have been cleansed from the system, we should - * try with the ltdl prefix as well. */ - - buflen = strlen(symbol) + strlen(module) + strlen("_LTX_") + 1; - buffer = pa_xmalloc(buflen); - assert(buffer); - - strcpy(buffer, module); - - for (ch = buffer;*ch != '\0';ch++) { - if (!isalnum(*ch)) - *ch = '_'; - } - - strcat(buffer, "_LTX_"); - strcat(buffer, symbol); - - res = lt_dlsym_fn(handle, buffer); - - pa_xfree(buffer); - - return res; -} - pa_module* pa_module_load(pa_core *c, const char *name, const char *argument) { pa_module *m = NULL; - int r; - assert(c && name); + pa_assert(c); + pa_assert(name); if (c->disallow_module_loading) goto fail; - m = pa_xmalloc(sizeof(pa_module)); - + m = pa_xnew(pa_module, 1); m->name = pa_xstrdup(name); m->argument = pa_xstrdup(argument); @@ -119,24 +82,19 @@ pa_module* pa_module_load(pa_core *c, const char *name, const char *argument) { goto fail; } - if (!(m->init = (int (*)(pa_core *_c, pa_module*_m)) load_sym(m->dl, name, PA_SYMBOL_INIT))) { + if (!(m->init = (int (*)(pa_module*_m)) pa_load_sym(m->dl, name, PA_SYMBOL_INIT))) { pa_log("Failed to load module \"%s\": symbol \""PA_SYMBOL_INIT"\" not found.", name); goto fail; } - if (!(m->done = (void (*)(pa_core *_c, pa_module*_m)) load_sym(m->dl, name, PA_SYMBOL_DONE))) { - pa_log("Failed to load module \"%s\": symbol \""PA_SYMBOL_DONE"\" not found.", name); - goto fail; - } - + m->done = (void (*)(pa_module*_m)) pa_load_sym(m->dl, name, PA_SYMBOL_DONE); m->userdata = NULL; m->core = c; m->n_used = -1; m->auto_unload = 0; m->unload_requested = 0; - assert(m->init); - if (m->init(c, m) < 0) { + if (m->init(m) < 0) { pa_log_error("Failed to load module \"%s\" (argument: \"%s\"): initialization failed.", name, argument ? argument : ""); goto fail; } @@ -147,14 +105,12 @@ pa_module* pa_module_load(pa_core *c, const char *name, const char *argument) { if (!c->module_auto_unload_event) { struct timeval ntv; pa_gettimeofday(&ntv); - ntv.tv_sec += UNLOAD_POLL_TIME; + pa_timeval_add(&ntv, UNLOAD_POLL_TIME*1000000); c->module_auto_unload_event = c->mainloop->time_new(c->mainloop, &ntv, timeout_callback, c); } - assert(c->module_auto_unload_event); - assert(c->modules); - r = pa_idxset_put(c->modules, m, &m->index); - assert(r >= 0 && m->index != PA_IDXSET_INVALID); + pa_assert_se(pa_idxset_put(c->modules, m, &m->index) >= 0); + pa_assert(m->index != PA_IDXSET_INVALID); pa_log_info("Loaded \"%s\" (index: #%u; argument: \"%s\").", m->name, m->index, m->argument ? m->argument : ""); @@ -178,14 +134,16 @@ fail: } static void pa_module_free(pa_module *m) { - assert(m && m->done && m->core); + pa_assert(m); + pa_assert(m->core); if (m->core->disallow_module_loading) return; pa_log_info("Unloading \"%s\" (index: #%u).", m->name, m->index); - m->done(m->core, m); + if (m->done) + m->done(m); lt_dlclose(m->dl); @@ -199,9 +157,9 @@ static void pa_module_free(pa_module *m) { } void pa_module_unload(pa_core *c, pa_module *m) { - assert(c && m); + pa_assert(c && m); - assert(c->modules); + pa_assert(c->modules); if (!(m = pa_idxset_remove_by_data(c->modules, m, NULL))) return; @@ -210,9 +168,9 @@ void pa_module_unload(pa_core *c, pa_module *m) { void pa_module_unload_by_index(pa_core *c, uint32_t idx) { pa_module *m; - assert(c && idx != PA_IDXSET_INVALID); + pa_assert(c); + pa_assert(idx != PA_IDXSET_INVALID); - assert(c->modules); if (!(m = pa_idxset_remove_by_index(c->modules, idx))) return; @@ -221,13 +179,14 @@ void pa_module_unload_by_index(pa_core *c, uint32_t idx) { static void free_callback(void *p, PA_GCC_UNUSED void *userdata) { pa_module *m = p; - assert(m); + pa_assert(m); pa_module_free(m); } void pa_module_unload_all(pa_core *c) { pa_module *m; - assert(c); + + pa_assert(c); if (!c->modules) return; @@ -252,7 +211,10 @@ void pa_module_unload_all(pa_core *c) { static int unused_callback(void *p, PA_GCC_UNUSED uint32_t idx, int *del, void *userdata) { pa_module *m = p; time_t *now = userdata; - assert(p && del && now); + + pa_assert(m); + pa_assert(del); + pa_assert(now); if (m->n_used == 0 && m->auto_unload && m->last_used_time+m->core->module_idle_time <= *now) { pa_module_free(m); @@ -264,7 +226,7 @@ static int unused_callback(void *p, PA_GCC_UNUSED uint32_t idx, int *del, void * void pa_module_unload_unused(pa_core *c) { time_t now; - assert(c); + pa_assert(c); if (!c->modules) return; @@ -275,7 +237,7 @@ void pa_module_unload_unused(pa_core *c) { static int unload_callback(void *p, PA_GCC_UNUSED uint32_t idx, int *del, PA_GCC_UNUSED void *userdata) { pa_module *m = p; - assert(m); + pa_assert(m); if (m->unload_requested) { pa_module_free(m); @@ -286,18 +248,19 @@ static int unload_callback(void *p, PA_GCC_UNUSED uint32_t idx, int *del, PA_GCC } static void defer_cb(pa_mainloop_api*api, pa_defer_event *e, void *userdata) { - pa_core *core = userdata; + pa_core *core = PA_CORE(userdata); + + pa_core_assert_ref(core); api->defer_enable(e, 0); if (!core->modules) return; pa_idxset_foreach(core->modules, unload_callback, NULL); - } void pa_module_unload_request(pa_module *m) { - assert(m); + pa_assert(m); m->unload_requested = 1; @@ -308,19 +271,19 @@ void pa_module_unload_request(pa_module *m) { } void pa_module_set_used(pa_module*m, int used) { - assert(m); + pa_assert(m); if (m->n_used != used) pa_subscription_post(m->core, PA_SUBSCRIPTION_EVENT_MODULE|PA_SUBSCRIPTION_EVENT_CHANGE, m->index); - if (m->n_used != used && used == 0) + if (used == 0 && m->n_used > 0) time(&m->last_used_time); m->n_used = used; } pa_modinfo *pa_module_get_info(pa_module *m) { - assert(m); + pa_assert(m); - return pa_modinfo_get_by_handle(m->dl); + return pa_modinfo_get_by_handle(m->dl, m->name); } diff --git a/src/pulsecore/module.h b/src/pulsecore/module.h index 750dfaa8..7a93a071 100644 --- a/src/pulsecore/module.h +++ b/src/pulsecore/module.h @@ -39,8 +39,8 @@ struct pa_module { lt_dlhandle dl; - int (*init)(pa_core *c, pa_module*m); - void (*done)(pa_core *c, pa_module*m); + int (*init)(pa_module*m); + void (*done)(pa_module*m); void *userdata; @@ -62,9 +62,9 @@ void pa_module_unload_request(pa_module *m); void pa_module_set_used(pa_module*m, int used); -#define PA_MODULE_AUTHOR(s) const char * pa__get_author(void) { return s; } -#define PA_MODULE_DESCRIPTION(s) const char * pa__get_description(void) { return s; } -#define PA_MODULE_USAGE(s) const char * pa__get_usage(void) { return s; } +#define PA_MODULE_AUTHOR(s) const char *pa__get_author(void) { return s; } +#define PA_MODULE_DESCRIPTION(s) const char *pa__get_description(void) { return s; } +#define PA_MODULE_USAGE(s) const char *pa__get_usage(void) { return s; } #define PA_MODULE_VERSION(s) const char * pa__get_version(void) { return s; } pa_modinfo *pa_module_get_info(pa_module *m); -- cgit From 357c0e415f027aaa306d9918bee8d7410ef91054 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Aug 2007 14:49:26 +0000 Subject: fix closing of fds in gconf module git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1616 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/gconf/module-gconf.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/modules/gconf/module-gconf.c b/src/modules/gconf/module-gconf.c index 7e932c11..24f60b1e 100644 --- a/src/modules/gconf/module-gconf.c +++ b/src/modules/gconf/module-gconf.c @@ -381,14 +381,17 @@ static int start_client(const char *n, pid_t *pid) { struct dirent *de; while ((de = readdir(d))) { - char *e; + char *e = NULL; int fd; + + if (de->d_name[0] == '.') + continue; errno = 0; fd = strtol(de->d_name, &e, 10); - pa_assert(errno == 0 && *e == 0); + pa_assert(errno == 0 && e && *e == 0); - if (fd >= 3) + if (fd >= 3 && dirfd(d) != fd) close(fd); } -- cgit From 72840abe8afca442645b00a54fbf7b31928024c0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Aug 2007 15:09:28 +0000 Subject: minor cleanliness fixes git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1617 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/mainloop.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index eaa41d51..0563507d 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -305,6 +305,7 @@ static void mainloop_defer_free(pa_defer_event *e) { if (e->enabled) { assert(e->mainloop->n_enabled_defer_events > 0); e->mainloop->n_enabled_defer_events--; + e->enabled = 0; } } @@ -395,6 +396,7 @@ static void mainloop_time_free(pa_time_event *e) { if (e->enabled) { assert(e->mainloop->n_enabled_time_events > 0); e->mainloop->n_enabled_time_events--; + e->enabled = 0; } if (e->mainloop->cached_next_time_event == e) @@ -541,6 +543,7 @@ static void cleanup_time_events(pa_mainloop *m, int force) { if (!e->dead && e->enabled) { assert(m->n_enabled_time_events > 0); m->n_enabled_time_events--; + e->enabled = 0; } if (e->destroy_callback) @@ -574,9 +577,9 @@ static void cleanup_defer_events(pa_mainloop *m, int force) { } if (!e->dead && e->enabled) { - e->enabled = 0; assert(m->n_enabled_defer_events > 0); m->n_enabled_defer_events--; + e->enabled = 0; } if (e->destroy_callback) -- cgit From ac49cc2029a40c6017b0c9533c4a27b0a1d7e3dd Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Aug 2007 15:51:55 +0000 Subject: do not acces playback pa_messagq from main thread git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1618 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-native.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 893a6c03..0816ea68 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -104,6 +104,10 @@ typedef struct playback_stream { pa_atomic_t missing; size_t last_missing; + + /* Only updated after SINK_INPUT_MESSAGE_UPDATE_LATENCY */ + int64_t read_index, write_index; + size_t resampled_chunk_length; } playback_stream; typedef struct upload_stream { @@ -175,7 +179,8 @@ enum { SINK_INPUT_MESSAGE_FLUSH, SINK_INPUT_MESSAGE_TRIGGER, SINK_INPUT_MESSAGE_SEEK, - SINK_INPUT_MESSAGE_PREBUF_FORCE + SINK_INPUT_MESSAGE_PREBUF_FORCE, + SINK_INPUT_MESSAGE_UPDATE_LATENCY }; enum { @@ -726,10 +731,10 @@ static void connection_free(pa_object *o) { pa_xfree(c); } +/* Called from thread context */ static void request_bytes(playback_stream *s) { size_t new_missing, delta, previous_missing; - /* pa_log("request_bytes()"); */ playback_stream_assert_ref(s); @@ -804,8 +809,9 @@ static void send_record_stream_killed(record_stream *r) { pa_pstream_send_tagstruct(r->connection->pstream, t); } -/*** sinkinput callbacks ***/ +/*** sink input callbacks ***/ +/* Called from thread context */ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) { pa_sink_input *i = PA_SINK_INPUT(o); playback_stream *s; @@ -897,6 +903,13 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int return 0; } + + case SINK_INPUT_MESSAGE_UPDATE_LATENCY: + + s->read_index = pa_memblockq_get_read_index(s->memblockq); + s->write_index = pa_memblockq_get_write_index(s->memblockq); + s->resampled_chunk_length = s->sink_input->thread_info.resampled_chunk.memblock ? s->sink_input->thread_info.resampled_chunk.length : 0; + return 0; case PA_SINK_INPUT_MESSAGE_SET_STATE: @@ -918,6 +931,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int return pa_sink_input_process_msg(o, code, userdata, offset, chunk); } +/* Called from thread context */ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { playback_stream *s; @@ -943,6 +957,7 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { return 0; } +/* Called from thread context */ static void sink_input_drop_cb(pa_sink_input *i, size_t length) { playback_stream *s; @@ -976,6 +991,7 @@ static void sink_input_kill_cb(pa_sink_input *i) { /*** source_output callbacks ***/ +/* Called from thread context */ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) { record_stream *s; @@ -1472,20 +1488,21 @@ static void command_get_playback_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ s = pa_idxset_get_by_index(c->output_streams, idx); CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); CHECK_VALIDITY(c->pstream, playback_stream_isinstance(s), tag, PA_ERR_NOENTITY); - + CHECK_VALIDITY(c->pstream, pa_asyncmsgq_send(s->sink_input->sink->asyncmsgq, PA_MSGOBJECT(s->sink_input), SINK_INPUT_MESSAGE_UPDATE_LATENCY, s, 0, NULL) == 0, tag, PA_ERR_NOENTITY) + reply = reply_new(tag); - + latency = pa_sink_get_latency(s->sink_input->sink); -/* if (s->sink_input->resampled_chunk.memblock) */ /* FIXME*/ -/* latency += pa_bytes_to_usec(s->sink_input->resampled_chunk.length, &s->sink_input->sample_spec); */ + latency += pa_bytes_to_usec(s->resampled_chunk_length, &s->sink_input->sample_spec); + pa_tagstruct_put_usec(reply, latency); pa_tagstruct_put_usec(reply, 0); pa_tagstruct_put_boolean(reply, pa_sink_input_get_state(s->sink_input) == PA_SINK_INPUT_RUNNING); pa_tagstruct_put_timeval(reply, &tv); pa_tagstruct_put_timeval(reply, pa_gettimeofday(&now)); - pa_tagstruct_puts64(reply, pa_memblockq_get_write_index(s->memblockq)); - pa_tagstruct_puts64(reply, pa_memblockq_get_read_index(s->memblockq)); + pa_tagstruct_puts64(reply, s->write_index); + pa_tagstruct_puts64(reply, s->read_index); pa_pstream_send_tagstruct(c->pstream, reply); } -- cgit From d4cb042a563f51d47b7b724d7fa1936896d3be24 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Aug 2007 16:47:39 +0000 Subject: move pa_queue to an implementation based on pa_flist git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1619 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 8 +++++- src/pulsecore/queue.c | 51 ++++++++++++++++++++++--------------- src/tests/queue-test.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 21 deletions(-) create mode 100644 src/tests/queue-test.c diff --git a/src/Makefile.am b/src/Makefile.am index 8273d336..6cb3f288 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -223,7 +223,8 @@ noinst_PROGRAMS = \ thread-test \ flist-test \ asyncq-test \ - asyncmsgq-test + asyncmsgq-test \ + queue-test if HAVE_SIGXCPU noinst_PROGRAMS += \ @@ -293,6 +294,11 @@ asyncmsgq_test_CFLAGS = $(AM_CFLAGS) asyncmsgq_test_LDADD = $(AM_LDADD) libpulsecore.la asyncmsgq_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) +queue_test_SOURCES = tests/queue-test.c +queue_test_CFLAGS = $(AM_CFLAGS) +queue_test_LDADD = $(AM_LDADD) libpulsecore.la +queue_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + mcalign_test_SOURCES = tests/mcalign-test.c mcalign_test_CFLAGS = $(AM_CFLAGS) mcalign_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecore.la diff --git a/src/pulsecore/queue.c b/src/pulsecore/queue.c index 1dd0f606..b095481a 100644 --- a/src/pulsecore/queue.c +++ b/src/pulsecore/queue.c @@ -25,13 +25,16 @@ #include #endif -#include #include #include +#include +#include #include "queue.h" +PA_STATIC_FLIST_DECLARE(entries, 0, pa_xfree); + struct queue_entry { struct queue_entry *next; void *data; @@ -44,40 +47,42 @@ struct pa_queue { pa_queue* pa_queue_new(void) { pa_queue *q = pa_xnew(pa_queue, 1); + q->front = q->back = NULL; q->length = 0; + return q; } void pa_queue_free(pa_queue* q, void (*destroy)(void *p, void *userdata), void *userdata) { - struct queue_entry *e; - assert(q); - - e = q->front; - while (e) { - struct queue_entry *n = e->next; + void *data; + pa_assert(q); + while ((data = pa_queue_pop(q))) if (destroy) - destroy(e->data, userdata); - - pa_xfree(e); - e = n; - } + destroy(data, userdata); + pa_assert(!q->front); + pa_assert(!q->back); + pa_assert(q->length == 0); + pa_xfree(q); } void pa_queue_push(pa_queue *q, void *p) { struct queue_entry *e; - e = pa_xnew(struct queue_entry, 1); + if (!(e = pa_flist_pop(PA_STATIC_FLIST_GET(entries)))) + e = pa_xnew(struct queue_entry, 1); + e->data = p; e->next = NULL; - if (q->back) + if (q->back) { + pa_assert(q->front); q->back->next = e; - else { - assert(!q->front); + } else { + pa_assert(!q->front); q->front = e; } @@ -88,24 +93,30 @@ void pa_queue_push(pa_queue *q, void *p) { void* pa_queue_pop(pa_queue *q) { void *p; struct queue_entry *e; - assert(q); + pa_assert(q); if (!(e = q->front)) return NULL; q->front = e->next; - if (q->back == e) + + if (q->back == e) { + pa_assert(!e->next); q->back = NULL; + } p = e->data; - pa_xfree(e); + if (pa_flist_push(PA_STATIC_FLIST_GET(entries), e) < 0) + pa_xfree(e); + q->length--; return p; } int pa_queue_is_empty(pa_queue *q) { - assert(q); + pa_assert(q); + return q->length == 0; } diff --git a/src/tests/queue-test.c b/src/tests/queue-test.c new file mode 100644 index 00000000..088b0741 --- /dev/null +++ b/src/tests/queue-test.c @@ -0,0 +1,69 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + pa_queue *q; + + pa_assert_se(q = pa_queue_new()); + + pa_assert(pa_queue_is_empty(q)); + + pa_queue_push(q, (void*) "eins"); + pa_log("%s\n", (char*) pa_queue_pop(q)); + + pa_assert(pa_queue_is_empty(q)); + + pa_queue_push(q, (void*) "zwei"); + pa_queue_push(q, (void*) "drei"); + pa_queue_push(q, (void*) "vier"); + + pa_log("%s\n", (char*) pa_queue_pop(q)); + pa_log("%s\n", (char*) pa_queue_pop(q)); + + pa_queue_push(q, (void*) "fuenf"); + + pa_log("%s\n", (char*) pa_queue_pop(q)); + pa_log("%s\n", (char*) pa_queue_pop(q)); + + pa_assert(pa_queue_is_empty(q)); + + pa_queue_push(q, (void*) "sechs"); + pa_queue_push(q, (void*) "sieben"); + + pa_queue_free(q, NULL, NULL); + + return 0; +} -- cgit From 27f75a5a1e5243aeb23664f0b1fc5bea18fcc906 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Aug 2007 21:59:51 +0000 Subject: Rename pa_once_t to pa_once git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1620 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/flist.h | 4 ++-- src/pulsecore/once-posix.c | 2 +- src/pulsecore/once.h | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pulsecore/flist.h b/src/pulsecore/flist.h index 177edd6a..69b9c741 100644 --- a/src/pulsecore/flist.h +++ b/src/pulsecore/flist.h @@ -47,13 +47,13 @@ void* pa_flist_pop(pa_flist*l); #define PA_STATIC_FLIST_DECLARE(name, size, destroy_cb) \ static struct { \ pa_flist *flist; \ - pa_once_t once; \ + pa_once once; \ } name##_static_flist = { NULL, PA_ONCE_INIT }; \ static void name##_init(void) { \ name##_static_flist.flist = pa_flist_new(size); \ } \ static inline pa_flist* name##_get(void) { \ - pa_once(&name##_static_flist.once, name##_init); \ + pa_run_once(&name##_static_flist.once, name##_init); \ return name##_static_flist.flist; \ } \ static void name##_destructor(void) PA_GCC_DESTRUCTOR; \ diff --git a/src/pulsecore/once-posix.c b/src/pulsecore/once-posix.c index 25ccb035..fd6288fe 100644 --- a/src/pulsecore/once-posix.c +++ b/src/pulsecore/once-posix.c @@ -33,7 +33,7 @@ #include "once.h" /* Not reentrant -- how could it be? */ -void pa_once(pa_once_t *control, pa_once_func_t func) { +void pa_run_once(pa_once *control, pa_once_func_t func) { pa_mutex *m; pa_assert(control); diff --git a/src/pulsecore/once.h b/src/pulsecore/once.h index b2602121..d9372d86 100644 --- a/src/pulsecore/once.h +++ b/src/pulsecore/once.h @@ -30,17 +30,17 @@ typedef struct pa_once { pa_atomic_ptr_t mutex; pa_atomic_t ref, done; -} pa_once_t; +} pa_once; #define PA_ONCE_INIT \ { \ .mutex = PA_ATOMIC_PTR_INIT(NULL), \ - .ref = PA_ATOMIC_INIT(0), \ - .done = PA_ATOMIC_INIT(0) \ + .ref = PA_ATOMIC_INIT(0), \ + .done = PA_ATOMIC_INIT(0) \ } typedef void (*pa_once_func_t) (void); -void pa_once(pa_once_t *o, pa_once_func_t f); +void pa_run_once(pa_once *o, pa_once_func_t f); #endif -- cgit From aff77c162bad2c9375a908a871f01a6fddd02278 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Aug 2007 22:00:22 +0000 Subject: update thread test to use pa_once instead of pa_once_t git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1621 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/tests/thread-test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/thread-test.c b/src/tests/thread-test.c index 2153c985..0077cde5 100644 --- a/src/tests/thread-test.c +++ b/src/tests/thread-test.c @@ -42,7 +42,7 @@ static void once_func(void) { pa_log("once!"); } -static pa_once_t once = PA_ONCE_INIT; +static pa_once once = PA_ONCE_INIT; static void thread_func(void *data) { pa_tls_set(tls, data); @@ -72,7 +72,7 @@ static void thread_func(void *data) { pa_mutex_unlock(mutex); - pa_once(&once, once_func); + pa_run_once(&once, once_func); pa_cond_signal(cond2, 0); -- cgit From f7171e86caef4f71f58d4f65d9cada4e53a19396 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Aug 2007 22:01:17 +0000 Subject: Wrap two pa_asyncmsq in a new pa_thread_mq object for bidirectional, lock-free communication between a main loop and a thread git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1622 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 1 + src/pulsecore/thread-mq.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++ src/pulsecore/thread-mq.h | 49 +++++++++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 src/pulsecore/thread-mq.c create mode 100644 src/pulsecore/thread-mq.h diff --git a/src/Makefile.am b/src/Makefile.am index 6cb3f288..2d3af078 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -662,6 +662,7 @@ libpulsecore_la_SOURCES += \ pulsecore/flist.c pulsecore/flist.h \ pulsecore/asyncmsgq.c pulsecore/asyncmsgqq.h \ pulsecore/asyncq.c pulsecore/asyncq.h \ + pulsecore/thread-mq.c pulsecore/thread-mq.h \ pulsecore/fdsem.c pulsecore/fdsem.h \ pulsecore/object.c pulsecore/object.h \ pulsecore/msgobject.c pulsecore/msgobject.h \ diff --git a/src/pulsecore/thread-mq.c b/src/pulsecore/thread-mq.c new file mode 100644 index 00000000..224a14cb --- /dev/null +++ b/src/pulsecore/thread-mq.c @@ -0,0 +1,119 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "thread-mq.h" + +static pa_once once = PA_ONCE_INIT; +static pa_tls *tls; + +static void asyncmsgq_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) { + pa_thread_mq *q = userdata; + + pa_assert(pa_asyncmsgq_get_fd(q->outq) == fd); + pa_assert(events == PA_IO_EVENT_INPUT); + + pa_asyncmsgq_after_poll(q->outq); + + for (;;) { + pa_msgobject *object; + int code; + void *data; + int64_t offset; + pa_memchunk chunk; + + /* Check whether there is a message for us to process */ + while (pa_asyncmsgq_get(q->outq, &object, &code, &data, &offset, &chunk, 0) == 0) { + int ret; + + ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); + pa_asyncmsgq_done(q->outq, ret); + } + + if (pa_asyncmsgq_before_poll(q->outq) == 0) + break; + } +} + +void pa_thread_mq_init(pa_thread_mq *q, pa_mainloop_api *mainloop) { + pa_assert(q); + pa_assert(mainloop); + + q->mainloop = mainloop; + pa_assert_se(q->inq = pa_asyncmsgq_new(0)); + pa_assert_se(q->outq = pa_asyncmsgq_new(0)); + + pa_assert_se(pa_asyncmsgq_before_poll(q->outq) == 0); + pa_assert_se(q->io_event = mainloop->io_new(mainloop, pa_asyncmsgq_get_fd(q->outq), PA_IO_EVENT_INPUT, asyncmsgq_cb, q)); +} + +void pa_thread_mq_done(pa_thread_mq *q) { + pa_assert(q); + + q->mainloop->io_free(q->io_event); + q->io_event = NULL; + + pa_asyncmsgq_after_poll(q->outq); + pa_asyncmsgq_free(q->inq); + pa_asyncmsgq_free(q->outq); + q->inq = q->outq = NULL; + + q->mainloop = NULL; +} + +static void init_tls(void) { + tls = pa_tls_new(NULL); +} + +void pa_thread_mq_install(pa_thread_mq *q) { + pa_assert(q); + + pa_run_once(&once, init_tls); + pa_tls_set(tls, q); +} + +pa_thread_mq *pa_thread_mq_get(void) { + pa_thread_mq *q; + + pa_run_once(&once, init_tls); + pa_assert_se(q = pa_tls_get(tls)); + return q; +} + diff --git a/src/pulsecore/thread-mq.h b/src/pulsecore/thread-mq.h new file mode 100644 index 00000000..13b6e01f --- /dev/null +++ b/src/pulsecore/thread-mq.h @@ -0,0 +1,49 @@ +#ifndef foopulsethreadmqhfoo +#define foopulsethreadmqhfoo + +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include +#include + +/* Two way communication between a thread and a mainloop. Before the + * thread is started a pa_pthread_mq should be initialized and than + * attached to the thread using pa_thread_mq_install(). */ + +typedef struct pa_thread_mq { + pa_mainloop_api *mainloop; + pa_asyncmsgq *inq, *outq; + pa_io_event *io_event; +} pa_thread_mq; + +void pa_thread_mq_init(pa_thread_mq *q, pa_mainloop_api *mainloop); +void pa_thread_mq_done(pa_thread_mq *q); + +/* Install the specified pa_thread_mq object for the current thread */ +void pa_thread_mq_install(pa_thread_mq *q); + +/* Return the pa_thread_mq object that is set for the current thread */ +pa_thread_mq *pa_thread_mq_get(void); + +#endif -- cgit From b3f1a133f1600adc112044aafd799e35462fdf7d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Aug 2007 22:01:54 +0000 Subject: minor update git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1623 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/pstream.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c index ea238805..ed552705 100644 --- a/src/pulsecore/pstream.c +++ b/src/pulsecore/pstream.c @@ -238,7 +238,6 @@ pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_mempool *poo m->defer_enable(p->defer_event, 0); p->send_queue = pa_queue_new(); - pa_assert(p->send_queue); p->write.current = NULL; p->write.index = 0; @@ -377,6 +376,7 @@ void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa p->mainloop->defer_enable(p->defer_event, 1); } +/* might be called from thread context */ static void memimport_release_cb(pa_memimport *i, uint32_t block_id, void *userdata) { struct item_info *item; pa_pstream *p = userdata; @@ -400,6 +400,7 @@ static void memimport_release_cb(pa_memimport *i, uint32_t block_id, void *userd p->mainloop->defer_enable(p->defer_event, 1); } +/* might be called from thread context */ static void memexport_revoke_cb(pa_memexport *e, uint32_t block_id, void *userdata) { struct item_info *item; pa_pstream *p = userdata; -- cgit From 3eae9038ebf428c40aae51354b32beb4909c1cbb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Aug 2007 22:02:39 +0000 Subject: make use of pa_thread_mq everywhere git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1624 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 32 ++++++++++++++++-------------- src/modules/module-alsa-source.c | 32 +++++++++++++++++------------- src/modules/module-null-sink.c | 30 +++++++++++++++------------- src/modules/module-oss.c | 36 ++++++++++++++++++---------------- src/modules/module-pipe-sink.c | 31 +++++++++++++++-------------- src/modules/module-pipe-source.c | 31 +++++++++++++++-------------- src/pulsecore/core.c | 41 ++------------------------------------- src/pulsecore/core.h | 3 --- src/pulsecore/play-memchunk.c | 3 ++- src/pulsecore/protocol-esound.c | 12 ++++++++---- src/pulsecore/protocol-native.c | 13 +++++++------ src/pulsecore/protocol-simple.c | 7 ++++--- src/pulsecore/sound-file-stream.c | 3 ++- 13 files changed, 127 insertions(+), 147 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 387e70c4..d3fe885d 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -50,6 +50,7 @@ #include #include #include +#include #include "alsa-util.h" #include "module-alsa-sink-symdef.h" @@ -78,7 +79,7 @@ struct userdata { pa_module *module; pa_sink *sink; pa_thread *thread; - pa_asyncmsgq *asyncmsgq; + pa_thread_mq thread_mq; snd_pcm_t *pcm_handle; @@ -254,7 +255,7 @@ static int build_pollfd(struct userdata *u) { pa_xfree(u->pollfd); u->pollfd = pa_xnew0(struct pollfd, POLLFD_ALSA_BASE + u->n_alsa_fds); - u->pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq); + u->pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->thread_mq.inq); u->pollfd[POLLFD_ASYNCQ].events = POLLIN; if ((err = snd_pcm_poll_descriptors(u->pcm_handle, u->pollfd+POLLFD_ALSA_BASE, u->n_alsa_fds)) < 0) { @@ -528,6 +529,8 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); + pa_thread_mq_install(&u->thread_mq); + if (build_pollfd(u) < 0) goto fail; @@ -542,18 +545,18 @@ static void thread_func(void *userdata) { /* pa_log("loop"); */ /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &offset, &chunk, 0) == 0) { + if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; /* pa_log("processing msg"); */ if (!object && code == PA_MESSAGE_SHUTDOWN) { - pa_asyncmsgq_done(u->asyncmsgq, 0); + pa_asyncmsgq_done(u->thread_mq.inq, 0); goto finish; } ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); - pa_asyncmsgq_done(u->asyncmsgq, ret); + pa_asyncmsgq_done(u->thread_mq.inq, ret); continue; } @@ -649,14 +652,14 @@ static void thread_func(void *userdata) { } /* Hmm, nothing to do. Let's sleep */ - if (pa_asyncmsgq_before_poll(u->asyncmsgq) < 0) + if (pa_asyncmsgq_before_poll(u->thread_mq.inq) < 0) continue; /* pa_log("polling for %i", POLLFD_ALSA_BASE + (PA_SINK_OPENED(u->sink->thread_info.state) ? u->n_alsa_fds : 0)); */ r = poll(u->pollfd, POLLFD_ALSA_BASE + (PA_SINK_OPENED(u->sink->thread_info.state) ? u->n_alsa_fds : 0), -1); /* pa_log("poll end"); */ - pa_asyncmsgq_after_poll(u->asyncmsgq); + pa_asyncmsgq_after_poll(u->thread_mq.inq); if (r < 0) { if (errno == EINTR) { @@ -697,8 +700,8 @@ static void thread_func(void *userdata) { fail: /* We have to continue processing messages until we receive the * SHUTDOWN message */ - pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); - pa_asyncmsgq_wait_for(u->asyncmsgq, PA_MESSAGE_SHUTDOWN); + pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); + pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); finish: pa_log_debug("Thread shutting down"); @@ -762,7 +765,7 @@ int pa__init(pa_module*m) { u->first = 1; u->n_alsa_fds = 0; u->pollfd = NULL; - pa_assert_se(u->asyncmsgq = pa_asyncmsgq_new(0)); + pa_thread_mq_init(&u->thread_mq, m->core->mainloop); snd_config_update_free_global(); if ((err = snd_pcm_open(&u->pcm_handle, dev = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { @@ -835,7 +838,7 @@ int pa__init(pa_module*m) { u->sink->userdata = u; pa_sink_set_module(u->sink, m); - pa_sink_set_asyncmsgq(u->sink, u->asyncmsgq); + pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); pa_sink_set_description(u->sink, t = pa_sprintf_malloc( "ALSA PCM on %s (%s)", dev, @@ -933,13 +936,12 @@ void pa__done(pa_module*m) { pa_sink_disconnect(u->sink); if (u->thread) { - pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); + pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); pa_thread_free(u->thread); } - if (u->asyncmsgq) - pa_asyncmsgq_free(u->asyncmsgq); - + pa_thread_mq_done(&u->thread_mq); + if (u->sink) pa_sink_unref(u->sink); diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 7ed430e3..55af4735 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -51,6 +51,7 @@ #include #include #include +#include #include "alsa-util.h" #include "module-alsa-source-symdef.h" @@ -78,7 +79,7 @@ struct userdata { pa_module *module; pa_source *source; pa_thread *thread; - pa_asyncmsgq *asyncmsgq; + pa_thread_mq thread_mq; snd_pcm_t *pcm_handle; @@ -242,7 +243,7 @@ static int build_pollfd(struct userdata *u) { pa_xfree(u->pollfd); u->pollfd = pa_xnew0(struct pollfd, POLLFD_ALSA_BASE + u->n_alsa_fds); - u->pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq); + u->pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->thread_mq.inq); u->pollfd[POLLFD_ASYNCQ].events = POLLIN; if ((err = snd_pcm_poll_descriptors(u->pcm_handle, u->pollfd+POLLFD_ALSA_BASE, u->n_alsa_fds)) < 0) { @@ -516,6 +517,8 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); + pa_thread_mq_install(&u->thread_mq); + if (build_pollfd(u) < 0) goto fail; @@ -530,18 +533,18 @@ static void thread_func(void *userdata) { /* pa_log("loop"); */ /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &offset, &chunk, 0) == 0) { + if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; /* pa_log("processing msg"); */ if (!object && code == PA_MESSAGE_SHUTDOWN) { - pa_asyncmsgq_done(u->asyncmsgq, 0); + pa_asyncmsgq_done(u->thread_mq.inq, 0); goto finish; } ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); - pa_asyncmsgq_done(u->asyncmsgq, ret); + pa_asyncmsgq_done(u->thread_mq.inq, ret); continue; } @@ -624,14 +627,14 @@ static void thread_func(void *userdata) { } /* Hmm, nothing to do. Let's sleep */ - if (pa_asyncmsgq_before_poll(u->asyncmsgq) < 0) + if (pa_asyncmsgq_before_poll(u->thread_mq.inq) < 0) continue; /* pa_log("polling for %i", POLLFD_ALSA_BASE + (PA_SOURCE_OPENED(u->source->thread_info.state) ? n_alsa_fds : 0)); */ r = poll(u->pollfd, POLLFD_ALSA_BASE + (PA_SOURCE_OPENED(u->source->thread_info.state) ? u->n_alsa_fds : 0), -1); /* pa_log("poll end"); */ - pa_asyncmsgq_after_poll(u->asyncmsgq); + pa_asyncmsgq_after_poll(u->thread_mq.inq); if (r < 0) { if (errno == EINTR) { @@ -672,8 +675,8 @@ static void thread_func(void *userdata) { fail: /* We have to continue processing messages until we receive the * SHUTDOWN message */ - pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); - pa_asyncmsgq_wait_for(u->asyncmsgq, PA_MESSAGE_SHUTDOWN); + pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); + pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); finish: pa_log_debug("Thread shutting down"); @@ -735,7 +738,9 @@ int pa__init(pa_module*m) { u->module = m; m->userdata = u; u->use_mmap = use_mmap; - pa_assert_se(u->asyncmsgq = pa_asyncmsgq_new(0)); + u->n_alsa_fds = 0; + u->pollfd = NULL; + pa_thread_mq_init(&u->thread_mq, m->core->mainloop); snd_config_update_free_global(); if ((err = snd_pcm_open(&u->pcm_handle, dev = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) { @@ -807,7 +812,7 @@ int pa__init(pa_module*m) { u->source->userdata = u; pa_source_set_module(u->source, m); - pa_source_set_asyncmsgq(u->source, u->asyncmsgq); + pa_source_set_asyncmsgq(u->source, u->thread_mq.inq); pa_source_set_description(u->source, t = pa_sprintf_malloc( "ALSA PCM on %s (%s)", dev, @@ -902,12 +907,11 @@ void pa__done(pa_module*m) { pa_source_disconnect(u->source); if (u->thread) { - pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); + pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); pa_thread_free(u->thread); } - if (u->asyncmsgq) - pa_asyncmsgq_free(u->asyncmsgq); + pa_thread_mq_done(&u->thread_mq); if (u->source) pa_source_unref(u->source); diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index 2ede01a4..8b17b59e 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -46,6 +46,7 @@ #include #include #include +#include #include "module-null-sink-symdef.h" @@ -67,7 +68,7 @@ struct userdata { pa_module *module; pa_sink *sink; pa_thread *thread; - pa_asyncmsgq *asyncmsgq; + pa_thread_mq thread_mq; size_t block_size; struct timeval timestamp; @@ -118,10 +119,12 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); + pa_thread_mq_install(&u->thread_mq); + pa_gettimeofday(&u->timestamp); memset(&pollfd, 0, sizeof(pollfd)); - pollfd.fd = pa_asyncmsgq_get_fd(u->asyncmsgq); + pollfd.fd = pa_asyncmsgq_get_fd(u->thread_mq.inq); pollfd.events = POLLIN; for (;;) { @@ -134,16 +137,16 @@ static void thread_func(void *userdata) { int64_t offset; /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &offset, &chunk, 0) == 0) { + if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; if (!object && code == PA_MESSAGE_SHUTDOWN) { - pa_asyncmsgq_done(u->asyncmsgq, 0); + pa_asyncmsgq_done(u->thread_mq.inq, 0); goto finish; } ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); - pa_asyncmsgq_done(u->asyncmsgq, ret); + pa_asyncmsgq_done(u->thread_mq.inq, ret); continue; } @@ -169,11 +172,11 @@ static void thread_func(void *userdata) { /* Hmm, nothing to do. Let's sleep */ - if (pa_asyncmsgq_before_poll(u->asyncmsgq) < 0) + if (pa_asyncmsgq_before_poll(u->thread_mq.inq) < 0) continue; r = poll(&pollfd, 1, timeout); - pa_asyncmsgq_after_poll(u->asyncmsgq); + pa_asyncmsgq_after_poll(u->thread_mq.inq); if (r < 0) { if (errno == EINTR) { @@ -191,8 +194,8 @@ static void thread_func(void *userdata) { fail: /* We have to continue processing messages until we receive the * SHUTDOWN message */ - pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); - pa_asyncmsgq_wait_for(u->asyncmsgq, PA_MESSAGE_SHUTDOWN); + pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); + pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); finish: pa_log_debug("Thread shutting down"); @@ -222,7 +225,7 @@ int pa__init(pa_module*m) { u->module = m; m->userdata = u; - pa_assert_se(u->asyncmsgq = pa_asyncmsgq_new(0)); + pa_thread_mq_init(&u->thread_mq, m->core->mainloop); if (!(u->sink = pa_sink_new(m->core, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map))) { pa_log("Failed to create sink."); @@ -233,7 +236,7 @@ int pa__init(pa_module*m) { u->sink->userdata = u; pa_sink_set_module(u->sink, m); - pa_sink_set_asyncmsgq(u->sink, u->asyncmsgq); + pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); pa_sink_set_description(u->sink, pa_modargs_get_value(ma, "description", "NULL sink")); u->block_size = pa_bytes_per_second(&ss) / 20; /* 50 ms */ @@ -270,12 +273,11 @@ void pa__done(pa_module*m) { pa_sink_disconnect(u->sink); if (u->thread) { - pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); + pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); pa_thread_free(u->thread); } - if (u->asyncmsgq) - pa_asyncmsgq_free(u->asyncmsgq); + pa_thread_mq_done(&u->thread_mq); if (u->sink) pa_sink_unref(u->sink); diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index d93d8c79..d71de99a 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -79,6 +79,7 @@ #include #include #include +#include #include "oss-util.h" #include "module-oss-symdef.h" @@ -111,7 +112,7 @@ struct userdata { pa_sink *sink; pa_source *source; pa_thread *thread; - pa_asyncmsgq *asyncmsgq; + pa_thread_mq thread_mq; char *device_name; @@ -793,11 +794,13 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); + pa_thread_mq_install(&u->thread_mq); + trigger(u, 0); memset(&pollfd, 0, sizeof(pollfd)); - pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq); + pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->thread_mq.inq); pollfd[POLLFD_ASYNCQ].events = POLLIN; pollfd[POLLFD_DSP].fd = u->fd; @@ -812,18 +815,18 @@ static void thread_func(void *userdata) { /* pa_log("loop"); */ /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &offset, &chunk, 0) == 0) { + if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; /* pa_log("processing msg"); */ if (!object && code == PA_MESSAGE_SHUTDOWN) { - pa_asyncmsgq_done(u->asyncmsgq, 0); + pa_asyncmsgq_done(u->thread_mq.inq, 0); goto finish; } ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); - pa_asyncmsgq_done(u->asyncmsgq, ret); + pa_asyncmsgq_done(u->thread_mq.inq, ret); continue; } @@ -1016,14 +1019,14 @@ static void thread_func(void *userdata) { /* Hmm, nothing to do. Let's sleep */ - if (pa_asyncmsgq_before_poll(u->asyncmsgq) < 0) + if (pa_asyncmsgq_before_poll(u->thread_mq.inq) < 0) continue; /* pa_log("polling for %i (legend: %i=POLLIN, %i=POLLOUT)", u->fd >= 0 ? pollfd[POLLFD_DSP].events : -1, POLLIN, POLLOUT); */ r = poll(pollfd, u->fd >= 0 ? POLLFD_MAX : POLLFD_DSP, -1); /* pa_log("polling got dsp=%i amq=%i (%i)", r > 0 ? pollfd[POLLFD_DSP].revents : 0, r > 0 ? pollfd[POLLFD_ASYNCQ].revents : 0, r); */ - pa_asyncmsgq_after_poll(u->asyncmsgq); + pa_asyncmsgq_after_poll(u->thread_mq.inq); if (u->fd < 0) pollfd[POLLFD_DSP].revents = 0; @@ -1052,8 +1055,8 @@ static void thread_func(void *userdata) { fail: /* We have to continue processing messages until we receive the * SHUTDOWN message */ - pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); - pa_asyncmsgq_wait_for(u->asyncmsgq, PA_MESSAGE_SHUTDOWN); + pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); + pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); finish: pa_log_debug("Thread shutting down"); @@ -1161,7 +1164,7 @@ int pa__init(pa_module*m) { u->in_nfrags = u->out_nfrags = u->nfrags = nfrags; u->out_fragment_size = u->in_fragment_size = u->frag_size = frag_size; u->use_mmap = use_mmap; - pa_assert_se(u->asyncmsgq = pa_asyncmsgq_new(0)); + pa_thread_mq_init(&u->thread_mq, m->core->mainloop); if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) >= 0) { pa_log_info("Input -- %u fragments of size %u.", info.fragstotal, info.fragsize); @@ -1216,7 +1219,7 @@ int pa__init(pa_module*m) { u->source->userdata = u; pa_source_set_module(u->source, m); - pa_source_set_asyncmsgq(u->source, u->asyncmsgq); + pa_source_set_asyncmsgq(u->source, u->thread_mq.inq); pa_source_set_description(u->source, t = pa_sprintf_malloc( "OSS PCM on %s%s%s%s", dev, @@ -1270,7 +1273,7 @@ try_write: u->sink->userdata = u; pa_sink_set_module(u->sink, m); - pa_sink_set_asyncmsgq(u->sink, u->asyncmsgq); + pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); pa_sink_set_description(u->sink, t = pa_sprintf_malloc( "OSS PCM on %s%s%s%s", dev, @@ -1300,9 +1303,9 @@ go_on: /* Read mixer settings */ if (u->source) - pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->source), PA_SOURCE_MESSAGE_GET_VOLUME, &u->source->volume, 0, NULL, NULL); + pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->source), PA_SOURCE_MESSAGE_GET_VOLUME, &u->source->volume, 0, NULL, NULL); if (u->sink) - pa_asyncmsgq_post(u->asyncmsgq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_GET_VOLUME, &u->sink->volume, 0, NULL, NULL); + pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_GET_VOLUME, &u->sink->volume, 0, NULL, NULL); return 0; @@ -1334,12 +1337,11 @@ void pa__done(pa_module*m) { pa_source_disconnect(u->source); if (u->thread) { - pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); + pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); pa_thread_free(u->thread); } - if (u->asyncmsgq) - pa_asyncmsgq_free(u->asyncmsgq); + pa_thread_mq_done(&u->thread_mq); if (u->sink) pa_sink_unref(u->sink); diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index 1b6d0813..2f82cae8 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -45,6 +45,7 @@ #include #include #include +#include #include "module-pipe-sink-symdef.h" @@ -67,7 +68,7 @@ struct userdata { pa_module *module; pa_sink *sink; pa_thread *thread; - pa_asyncmsgq *asyncmsgq; + pa_thread_mq thread_mq; char *filename; int fd; @@ -121,9 +122,11 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); + pa_thread_mq_install(&u->thread_mq); + memset(&pollfd, 0, sizeof(pollfd)); - pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq); + pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->thread_mq.inq); pollfd[POLLFD_ASYNCQ].events = POLLIN; pollfd[POLLFD_FIFO].fd = u->fd; @@ -136,16 +139,16 @@ static void thread_func(void *userdata) { int64_t offset; /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &offset, &chunk, 0) == 0) { + if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; if (!object && code == PA_MESSAGE_SHUTDOWN) { - pa_asyncmsgq_done(u->asyncmsgq, 0); + pa_asyncmsgq_done(u->thread_mq.inq, 0); goto finish; } ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); - pa_asyncmsgq_done(u->asyncmsgq, ret); + pa_asyncmsgq_done(u->thread_mq.inq, ret); continue; } @@ -194,14 +197,14 @@ static void thread_func(void *userdata) { /* Hmm, nothing to do. Let's sleep */ - if (pa_asyncmsgq_before_poll(u->asyncmsgq) < 0) + if (pa_asyncmsgq_before_poll(u->thread_mq.inq) < 0) continue; /* pa_log("polling for %u", pollfd[POLLFD_FIFO].events); */ r = poll(pollfd, POLLFD_MAX, -1); /* pa_log("polling got %u", r > 0 ? pollfd[POLLFD_FIFO].revents : 0); */ - pa_asyncmsgq_after_poll(u->asyncmsgq); + pa_asyncmsgq_after_poll(u->thread_mq.inq); if (r < 0) { if (errno == EINTR) { @@ -225,8 +228,8 @@ static void thread_func(void *userdata) { fail: /* We have to continue processing messages until we receive the * SHUTDOWN message */ - pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); - pa_asyncmsgq_wait_for(u->asyncmsgq, PA_MESSAGE_SHUTDOWN); + pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); + pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); finish: pa_log_debug("Thread shutting down"); @@ -258,8 +261,7 @@ int pa__init(pa_module*m) { u->module = m; m->userdata = u; pa_memchunk_reset(&u->memchunk); - - pa_assert_se(u->asyncmsgq = pa_asyncmsgq_new(0)); + pa_thread_mq_init(&u->thread_mq, m->core->mainloop); u->filename = pa_xstrdup(pa_modargs_get_value(ma, "file", DEFAULT_FILE_NAME)); @@ -291,7 +293,7 @@ int pa__init(pa_module*m) { u->sink->userdata = u; pa_sink_set_module(u->sink, m); - pa_sink_set_asyncmsgq(u->sink, u->asyncmsgq); + pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Unix FIFO sink '%s'", u->filename)); pa_xfree(t); @@ -325,12 +327,11 @@ void pa__done(pa_module*m) { pa_sink_disconnect(u->sink); if (u->thread) { - pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); + pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); pa_thread_free(u->thread); } - if (u->asyncmsgq) - pa_asyncmsgq_free(u->asyncmsgq); + pa_thread_mq_done(&u->thread_mq); if (u->sink) pa_sink_unref(u->sink); diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index a8fbcf3d..2209d1ee 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "module-pipe-source-symdef.h" @@ -66,7 +67,7 @@ struct userdata { pa_module *module; pa_source *source; pa_thread *thread; - pa_asyncmsgq *asyncmsgq; + pa_thread_mq thread_mq; char *filename; int fd; @@ -99,9 +100,11 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); + pa_thread_mq_install(&u->thread_mq); + memset(&pollfd, 0, sizeof(pollfd)); - pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq); + pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->thread_mq.inq); pollfd[POLLFD_ASYNCQ].events = POLLIN; pollfd[POLLFD_FIFO].fd = u->fd; @@ -114,16 +117,16 @@ static void thread_func(void *userdata) { int64_t offset; /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->asyncmsgq, &object, &code, &data, &offset, &chunk, 0) == 0) { + if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; if (!object && code == PA_MESSAGE_SHUTDOWN) { - pa_asyncmsgq_done(u->asyncmsgq, 0); + pa_asyncmsgq_done(u->thread_mq.inq, 0); goto finish; } ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); - pa_asyncmsgq_done(u->asyncmsgq, ret); + pa_asyncmsgq_done(u->thread_mq.inq, ret); continue; } @@ -175,14 +178,14 @@ static void thread_func(void *userdata) { /* Hmm, nothing to do. Let's sleep */ - if (pa_asyncmsgq_before_poll(u->asyncmsgq) < 0) + if (pa_asyncmsgq_before_poll(u->thread_mq.inq) < 0) continue; /* pa_log("polling for %i", pollfd[POLLFD_FIFO].events); */ r = poll(pollfd, POLLFD_MAX, -1); /* pa_log("polling got %i (r=%i) %i", r > 0 ? pollfd[POLLFD_FIFO].revents : 0, r, r > 0 ? pollfd[POLLFD_ASYNCQ].revents: 0); */ - pa_asyncmsgq_after_poll(u->asyncmsgq); + pa_asyncmsgq_after_poll(u->thread_mq.inq); if (r < 0) { if (errno == EINTR) @@ -203,8 +206,8 @@ static void thread_func(void *userdata) { fail: /* We have to continue processing messages until we receive the * SHUTDOWN message */ - pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); - pa_asyncmsgq_wait_for(u->asyncmsgq, PA_MESSAGE_SHUTDOWN); + pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); + pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); finish: pa_log_debug("Thread shutting down"); @@ -236,8 +239,7 @@ int pa__init(pa_module*m) { u->module = m; m->userdata = u; pa_memchunk_reset(&u->memchunk); - - pa_assert_se(u->asyncmsgq = pa_asyncmsgq_new(0)); + pa_thread_mq_init(&u->thread_mq, m->core->mainloop); u->filename = pa_xstrdup(pa_modargs_get_value(ma, "file", DEFAULT_FILE_NAME)); @@ -268,7 +270,7 @@ int pa__init(pa_module*m) { u->source->userdata = u; pa_source_set_module(u->source, m); - pa_source_set_asyncmsgq(u->source, u->asyncmsgq); + pa_source_set_asyncmsgq(u->source, u->thread_mq.inq); pa_source_set_description(u->source, t = pa_sprintf_malloc("Unix FIFO source '%s'", u->filename)); pa_xfree(t); @@ -302,12 +304,11 @@ void pa__done(pa_module*m) { pa_source_disconnect(u->source); if (u->thread) { - pa_asyncmsgq_send(u->asyncmsgq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); + pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); pa_thread_free(u->thread); } - if (u->asyncmsgq) - pa_asyncmsgq_free(u->asyncmsgq); + pa_thread_mq_done(&u->thread_mq); if (u->source) pa_source_unref(u->source); diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c index 2cdd4a8e..a56dd4ef 100644 --- a/src/pulsecore/core.c +++ b/src/pulsecore/core.c @@ -67,34 +67,6 @@ static int core_process_msg(pa_msgobject *o, int code, void *userdata, int64_t o } } -static void asyncmsgq_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) { - pa_core *c = userdata; - - pa_assert(pa_asyncmsgq_get_fd(c->asyncmsgq) == fd); - pa_assert(events == PA_IO_EVENT_INPUT); - - pa_asyncmsgq_after_poll(c->asyncmsgq); - - for (;;) { - pa_msgobject *object; - int code; - void *data; - int64_t offset; - pa_memchunk chunk; - - /* Check whether there is a message for us to process */ - while (pa_asyncmsgq_get(c->asyncmsgq, &object, &code, &data, &offset, &chunk, 0) == 0) { - int ret; - - ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); - pa_asyncmsgq_done(c->asyncmsgq, ret); - } - - if (pa_asyncmsgq_before_poll(c->asyncmsgq) == 0) - break; - } -} - static void core_free(pa_object *o); pa_core* pa_core_new(pa_mainloop_api *m, int shared) { @@ -189,10 +161,6 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { pa_check_signal_is_blocked(SIGPIPE); #endif - pa_assert_se(c->asyncmsgq = pa_asyncmsgq_new(0)); - pa_assert_se(pa_asyncmsgq_before_poll(c->asyncmsgq) == 0); - pa_assert_se(c->asyncmsgq_event = c->mainloop->io_new(c->mainloop, pa_asyncmsgq_get_fd(c->asyncmsgq), PA_IO_EVENT_INPUT, asyncmsgq_cb, c)); - return c; } @@ -229,15 +197,10 @@ static void core_free(pa_object *o) { pa_xfree(c->default_source_name); pa_xfree(c->default_sink_name); - pa_asyncmsgq_after_poll(c->asyncmsgq); - pa_asyncmsgq_free(c->asyncmsgq); - pa_mempool_free(c->mempool); pa_property_cleanup(c); - c->mainloop->io_free(c->asyncmsgq_event); - pa_hook_free(&c->hook_sink_new); pa_hook_free(&c->hook_sink_new_post); pa_hook_free(&c->hook_sink_disconnect); @@ -260,13 +223,13 @@ static void core_free(pa_object *o) { static void quit_callback(pa_mainloop_api*m, pa_time_event *e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { pa_core *c = userdata; - assert(c->quit_event = e); + pa_assert(c->quit_event = e); m->quit(m, 0); } void pa_core_check_quit(pa_core *c) { - assert(c); + pa_assert(c); if (!c->quit_event && c->exit_idle_time >= 0 && pa_idxset_size(c->clients) == 0) { struct timeval tv; diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index 394785f2..d86d5514 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -104,9 +104,6 @@ struct pa_core { hook_source_output_new_post, hook_source_output_disconnect, hook_source_output_disconnect_post; - - pa_asyncmsgq *asyncmsgq; - pa_io_event *asyncmsgq_event; }; PA_DECLARE_CLASS(pa_core); diff --git a/src/pulsecore/play-memchunk.c b/src/pulsecore/play-memchunk.c index 419d523f..d2d71804 100644 --- a/src/pulsecore/play-memchunk.c +++ b/src/pulsecore/play-memchunk.c @@ -33,6 +33,7 @@ #include #include +#include #include "play-memchunk.h" @@ -111,7 +112,7 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { if (u->memchunk.length <= 0) { pa_memblock_unref(u->memchunk.memblock); u->memchunk.memblock = NULL; - pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u), MEMCHUNK_STREAM_MESSAGE_UNLINK, NULL, 0, NULL, NULL); + pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(u), MEMCHUNK_STREAM_MESSAGE_UNLINK, NULL, 0, NULL, NULL); return -1; } diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c index 74607146..c5505e57 100644 --- a/src/pulsecore/protocol-esound.c +++ b/src/pulsecore/protocol-esound.c @@ -53,6 +53,7 @@ #include #include #include +#include #include "endianmacros.h" @@ -1194,6 +1195,7 @@ static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int6 /*** sink_input callbacks ***/ +/* Called from thread context */ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) { pa_sink_input *i = PA_SINK_INPUT(o); connection*c; @@ -1234,7 +1236,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int } } - +/* Called from thread context */ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { connection*c; int r; @@ -1245,11 +1247,12 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { pa_assert(chunk); if ((r = pa_memblockq_peek(c->input_memblockq, chunk)) < 0 && c->dead) - pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_UNLINK_CONNECTION, NULL, 0, NULL, NULL); + pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_UNLINK_CONNECTION, NULL, 0, NULL, NULL); return r; } +/* Called from thread context */ static void sink_input_drop_cb(pa_sink_input *i, size_t length) { connection*c; size_t old, new; @@ -1267,7 +1270,7 @@ static void sink_input_drop_cb(pa_sink_input *i, size_t length) { if (new > old) { if (pa_atomic_add(&c->playback.missing, new - old) <= 0) - pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); + pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); } } @@ -1279,6 +1282,7 @@ static void sink_input_kill_cb(pa_sink_input *i) { /*** source_output callbacks ***/ +/* Called from thread context */ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) { connection *c; @@ -1287,7 +1291,7 @@ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) pa_assert(c); pa_assert(chunk); - pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_POST_DATA, NULL, 0, chunk, NULL); + pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_POST_DATA, NULL, 0, chunk, NULL); } static void source_output_kill_cb(pa_source_output *o) { diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 0816ea68..00b4d13e 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -60,6 +60,7 @@ #include #include #include +#include #include "protocol-native.h" @@ -752,7 +753,7 @@ static void request_bytes(playback_stream *s) { previous_missing = pa_atomic_add(&s->missing, delta); if (previous_missing < pa_memblockq_get_minreq(s->memblockq) && previous_missing+delta >= pa_memblockq_get_minreq(s->memblockq)) - pa_asyncmsgq_post(s->connection->protocol->core->asyncmsgq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); + pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); } static void send_memblock(connection *c) { @@ -833,7 +834,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int if (pa_memblockq_push_align(s->memblockq, chunk) < 0) { pa_log_warn("Failed to push data into queue"); - pa_asyncmsgq_post(s->connection->protocol->core->asyncmsgq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_OVERFLOW, NULL, 0, NULL, NULL); + pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_OVERFLOW, NULL, 0, NULL, NULL); pa_memblockq_seek(s->memblockq, chunk->length, PA_SEEK_RELATIVE); } @@ -848,7 +849,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int pa_memblockq_prebuf_disable(s->memblockq); if (!pa_memblockq_is_readable(s->memblockq)) - pa_asyncmsgq_post(s->connection->protocol->core->asyncmsgq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_DRAIN_ACK, userdata, 0, NULL, NULL); + pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_DRAIN_ACK, userdata, 0, NULL, NULL); else { s->drain_tag = PA_PTR_TO_UINT(userdata); s->drain_request = 1; @@ -941,7 +942,7 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { pa_assert(chunk); if (pa_memblockq_get_length(s->memblockq) <= 0 && !s->underrun) { - pa_asyncmsgq_post(s->connection->protocol->core->asyncmsgq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_UNDERFLOW, NULL, 0, NULL, NULL); + pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_UNDERFLOW, NULL, 0, NULL, NULL); s->underrun = 1; } @@ -970,7 +971,7 @@ static void sink_input_drop_cb(pa_sink_input *i, size_t length) { if (s->drain_request && !pa_memblockq_is_readable(s->memblockq)) { s->drain_request = 0; - pa_asyncmsgq_post(s->connection->protocol->core->asyncmsgq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_DRAIN_ACK, PA_UINT_TO_PTR(s->drain_tag), 0, NULL, NULL); + pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_DRAIN_ACK, PA_UINT_TO_PTR(s->drain_tag), 0, NULL, NULL); } request_bytes(s); @@ -1000,7 +1001,7 @@ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) record_stream_assert_ref(s); pa_assert(chunk); - pa_asyncmsgq_post(s->connection->protocol->core->asyncmsgq, PA_MSGOBJECT(s), RECORD_STREAM_MESSAGE_POST_DATA, NULL, 0, chunk, NULL); + pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), RECORD_STREAM_MESSAGE_POST_DATA, NULL, 0, chunk, NULL); } static void source_output_kill_cb(pa_source_output *o) { diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index dd61c7ee..bc48ac37 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "protocol-simple.h" @@ -356,7 +357,7 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { /* pa_log("peeked %u %i", r >= 0 ? chunk->length: 0, r); */ if (c->dead && r < 0) - pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_UNLINK_CONNECTION, NULL, 0, NULL, NULL); + pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_UNLINK_CONNECTION, NULL, 0, NULL, NULL); return r; } @@ -377,7 +378,7 @@ static void sink_input_drop_cb(pa_sink_input *i, size_t length) { if (new > old) { if (pa_atomic_add(&c->playback.missing, new - old) <= 0) - pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); + pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); } } @@ -399,7 +400,7 @@ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) pa_assert(c); pa_assert(chunk); - pa_asyncmsgq_post(c->protocol->core->asyncmsgq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_POST_DATA, NULL, 0, chunk, NULL); + pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_POST_DATA, NULL, 0, chunk, NULL); } /* Called from main context */ diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index 4e0e91e0..e0d51a7d 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "sound-file-stream.h" @@ -161,7 +162,7 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { pa_memblock_unref(u->memchunk.memblock); pa_memchunk_reset(&u->memchunk); - pa_asyncmsgq_post(u->core->asyncmsgq, PA_MSGOBJECT(u), FILE_STREAM_MESSAGE_UNLINK, NULL, 0, NULL, NULL); + pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(u), FILE_STREAM_MESSAGE_UNLINK, NULL, 0, NULL, NULL); sf_close(u->sndfile); u->sndfile = NULL; -- cgit From 4e145b676ab76235468953634ba6d17717a3d933 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Aug 2007 23:40:05 +0000 Subject: if no thread-mq is attached to the current thread, return an error, don't hit an assert git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1625 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread-mq.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/pulsecore/thread-mq.c b/src/pulsecore/thread-mq.c index 224a14cb..89b65e5c 100644 --- a/src/pulsecore/thread-mq.c +++ b/src/pulsecore/thread-mq.c @@ -110,10 +110,7 @@ void pa_thread_mq_install(pa_thread_mq *q) { } pa_thread_mq *pa_thread_mq_get(void) { - pa_thread_mq *q; - pa_run_once(&once, init_tls); - pa_assert_se(q = pa_tls_get(tls)); - return q; + return pa_tls_get(tls); } -- cgit From ff4814cac79bc947d6430d79c1ae09d21247305c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Aug 2007 23:41:50 +0000 Subject: add callbacks for the revoke/release stuff, so that we can make this thing thread-safe git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1626 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/pstream.c | 63 +++++++++++++++++++++++++++++++++++++++++++------ src/pulsecore/pstream.h | 6 ++++- 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c index ed552705..b91813e4 100644 --- a/src/pulsecore/pstream.c +++ b/src/pulsecore/pstream.c @@ -155,6 +155,12 @@ struct pa_pstream { pa_pstream_notify_cb_t die_callback; void *die_callback_userdata; + pa_pstream_block_id_cb_t revoke_callback; + void *revoke_callback_userdata; + + pa_pstream_block_id_cb_t release_callback; + void *release_callback_userdata; + pa_mempool *mempool; #ifdef HAVE_CREDS @@ -254,7 +260,11 @@ pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_mempool *poo p->drain_callback_userdata = NULL; p->die_callback = NULL; p->die_callback_userdata = NULL; - + p->revoke_callback = NULL; + p->revoke_callback_userdata = NULL; + p->release_callback = NULL; + p->release_callback_userdata = NULL; + p->mempool = pool; p->use_shm = 0; @@ -376,11 +386,8 @@ void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa p->mainloop->defer_enable(p->defer_event, 1); } -/* might be called from thread context */ -static void memimport_release_cb(pa_memimport *i, uint32_t block_id, void *userdata) { +void pa_pstream_send_release(pa_pstream *p, uint32_t block_id) { struct item_info *item; - pa_pstream *p = userdata; - pa_assert(p); pa_assert(PA_REFCNT_VALUE(p) > 0); @@ -401,13 +408,26 @@ static void memimport_release_cb(pa_memimport *i, uint32_t block_id, void *userd } /* might be called from thread context */ -static void memexport_revoke_cb(pa_memexport *e, uint32_t block_id, void *userdata) { - struct item_info *item; +static void memimport_release_cb(pa_memimport *i, uint32_t block_id, void *userdata) { pa_pstream *p = userdata; pa_assert(p); pa_assert(PA_REFCNT_VALUE(p) > 0); + if (p->dead) + return; + + if (p->release_callback) + p->release_callback(p, block_id, p->release_callback_userdata); + else + pa_pstream_send_release(p, block_id); +} + +void pa_pstream_send_revoke(pa_pstream *p, uint32_t block_id) { + struct item_info *item; + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); + if (p->dead) return; /* pa_log("Revoking block %u", block_id); */ @@ -423,6 +443,19 @@ static void memexport_revoke_cb(pa_memexport *e, uint32_t block_id, void *userda p->mainloop->defer_enable(p->defer_event, 1); } +/* might be called from thread context */ +static void memexport_revoke_cb(pa_memexport *e, uint32_t block_id, void *userdata) { + pa_pstream *p = userdata; + + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); + + if (p->revoke_callback) + p->revoke_callback(p, block_id, p->revoke_callback_userdata); + else + pa_pstream_send_revoke(p, block_id); +} + static void prepare_next_write_item(pa_pstream *p) { pa_assert(p); pa_assert(PA_REFCNT_VALUE(p) > 0); @@ -875,6 +908,22 @@ void pa_pstream_set_recieve_memblock_callback(pa_pstream *p, pa_pstream_memblock p->recieve_memblock_callback_userdata = userdata; } +void pa_pstream_set_release_callback(pa_pstream *p, pa_pstream_block_id_cb_t cb, void *userdata) { + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); + + p->release_callback = cb; + p->release_callback_userdata = userdata; +} + +void pa_pstream_set_revoke_callback(pa_pstream *p, pa_pstream_block_id_cb_t cb, void *userdata) { + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) > 0); + + p->release_callback = cb; + p->release_callback_userdata = userdata; +} + int pa_pstream_is_pending(pa_pstream *p) { int b; diff --git a/src/pulsecore/pstream.h b/src/pulsecore/pstream.h index 544cba4d..72babea9 100644 --- a/src/pulsecore/pstream.h +++ b/src/pulsecore/pstream.h @@ -41,6 +41,7 @@ typedef struct pa_pstream pa_pstream; typedef void (*pa_pstream_packet_cb_t)(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata); typedef void (*pa_pstream_memblock_cb_t)(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata); typedef void (*pa_pstream_notify_cb_t)(pa_pstream *p, void *userdata); +typedef void (*pa_pstream_block_id_cb_t)(pa_pstream *p, uint32_t block_id, void *userdata); pa_pstream* pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_mempool *p); void pa_pstream_unref(pa_pstream*p); @@ -48,12 +49,15 @@ pa_pstream* pa_pstream_ref(pa_pstream*p); void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const pa_creds *creds); void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk); +void pa_pstream_send_release(pa_pstream *p, uint32_t block_id); +void pa_pstream_send_revoke(pa_pstream *p, uint32_t block_id); void pa_pstream_set_recieve_packet_callback(pa_pstream *p, pa_pstream_packet_cb_t cb, void *userdata); void pa_pstream_set_recieve_memblock_callback(pa_pstream *p, pa_pstream_memblock_cb_t cb, void *userdata); void pa_pstream_set_drain_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata); - void pa_pstream_set_die_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata); +void pa_pstream_set_release_callback(pa_pstream *p, pa_pstream_block_id_cb_t cb, void *userdata); +void pa_pstream_set_revoke_callback(pa_pstream *p, pa_pstream_block_id_cb_t cb, void *userdata); int pa_pstream_is_pending(pa_pstream *p); -- cgit From d2fed9d419be4cc3aa7417471166e16f1de3f7dd Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 10 Aug 2007 23:42:17 +0000 Subject: make revoke/release thread safe in the native protocol git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1627 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-native.c | 45 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 00b4d13e..a67f9b02 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -139,7 +139,6 @@ struct connection { pa_time_event *auth_timeout_event; }; - PA_DECLARE_CLASS(record_stream); #define RECORD_STREAM(o) (record_stream_cast(o)) static PA_DEFINE_CHECK_TYPE(record_stream, pa_msgobject); @@ -195,6 +194,11 @@ enum { RECORD_STREAM_MESSAGE_POST_DATA /* data from source output to main loop */ }; +enum { + CONNECTION_MESSAGE_RELEASE, + CONNECTION_MESSAGE_REVOKE +}; + static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk); static void sink_input_drop_cb(pa_sink_input *i, size_t length); static void sink_input_kill_cb(pa_sink_input *i); @@ -681,6 +685,24 @@ static playback_stream* playback_stream_new( return s; } +static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) { + connection *c = CONNECTION(o); + connection_assert_ref(c); + + switch (code) { + + case CONNECTION_MESSAGE_REVOKE: + pa_pstream_send_revoke(c->pstream, PA_PTR_TO_UINT(userdata)); + break; + + case CONNECTION_MESSAGE_RELEASE: + pa_pstream_send_release(c->pstream, PA_PTR_TO_UINT(userdata)); + break; + } + + return 0; +} + static void connection_unlink(connection *c) { record_stream *r; output_stream *o; @@ -2702,6 +2724,24 @@ static void pstream_drain_callback(pa_pstream *p, void *userdata) { send_memblock(c); } +static void pstream_revoke_callback(pa_pstream *p, uint32_t block_id, void *userdata) { + pa_thread_mq *q; + + if (!(q = pa_thread_mq_get())) + pa_pstream_send_revoke(p, block_id); + else + pa_asyncmsgq_post(q->outq, PA_MSGOBJECT(userdata), CONNECTION_MESSAGE_REVOKE, PA_UINT_TO_PTR(block_id), 0, NULL, NULL); +} + +static void pstream_release_callback(pa_pstream *p, uint32_t block_id, void *userdata) { + pa_thread_mq *q; + + if (!(q = pa_thread_mq_get())) + pa_pstream_send_release(p, block_id); + else + pa_asyncmsgq_post(q->outq, PA_MSGOBJECT(userdata), CONNECTION_MESSAGE_RELEASE, PA_UINT_TO_PTR(block_id), 0, NULL, NULL); +} + /*** client callbacks ***/ static void client_kill_cb(pa_client *c) { @@ -2741,6 +2781,7 @@ static void on_connection(PA_GCC_UNUSED pa_socket_server*s, pa_iochannel *io, vo c = pa_msgobject_new(connection); c->parent.parent.free = connection_free; + c->parent.process_msg = connection_process_msg; c->authorized = !!p->public; @@ -2772,6 +2813,8 @@ static void on_connection(PA_GCC_UNUSED pa_socket_server*s, pa_iochannel *io, vo pa_pstream_set_recieve_memblock_callback(c->pstream, pstream_memblock_callback, c); pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c); pa_pstream_set_drain_callback(c->pstream, pstream_drain_callback, c); + pa_pstream_set_revoke_callback(c->pstream, pstream_revoke_callback, c); + pa_pstream_set_release_callback(c->pstream, pstream_release_callback, c); c->pdispatch = pa_pdispatch_new(p->core->mainloop, command_table, PA_COMMAND_MAX); -- cgit From 59c9ed5473a04e51eed51112612a9065f4f41093 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 00:10:29 +0000 Subject: move pstream item allocation to pa_flist git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1628 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/pstream.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c index b91813e4..33bc520c 100644 --- a/src/pulsecore/pstream.c +++ b/src/pulsecore/pstream.c @@ -49,6 +49,7 @@ #include #include #include +#include #include "pstream.h" @@ -84,6 +85,8 @@ typedef uint32_t pa_pstream_descriptor[PA_PSTREAM_DESCRIPTOR_MAX]; #define FRAME_SIZE_MAX_ALLOW PA_SCACHE_ENTRY_SIZE_MAX /* allow uploading a single sample in one frame at max */ #define FRAME_SIZE_MAX_USE (1024*64) +PA_STATIC_FLIST_DECLARE(items, 0, pa_xfree); + struct item_info { enum { PA_PSTREAM_ITEM_PACKET, @@ -92,7 +95,6 @@ struct item_info { PA_PSTREAM_ITEM_SHMREVOKE } type; - /* packet info */ pa_packet *packet; #ifdef HAVE_CREDS @@ -295,7 +297,8 @@ static void item_free(void *item, PA_GCC_UNUSED void *q) { pa_packet_unref(i->packet); } - pa_xfree(i); + if (pa_flist_push(PA_STATIC_FLIST_GET(items), i) < 0) + pa_xfree(i); } static void pstream_free(pa_pstream *p) { @@ -330,7 +333,9 @@ void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const pa_creds *cre if (p->dead) return; - i = pa_xnew(struct item_info, 1); + if (!(i = pa_flist_pop(PA_STATIC_FLIST_GET(items)))) + i = pa_xnew(struct item_info, 1); + i->type = PA_PSTREAM_ITEM_PACKET; i->packet = pa_packet_ref(packet); @@ -362,7 +367,8 @@ void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa struct item_info *i; size_t n; - i = pa_xnew(struct item_info, 1); + if (!(i = pa_flist_pop(PA_STATIC_FLIST_GET(items)))) + i = pa_xnew(struct item_info, 1); i->type = PA_PSTREAM_ITEM_MEMBLOCK; n = length < FRAME_SIZE_MAX_USE ? length : FRAME_SIZE_MAX_USE; @@ -396,7 +402,8 @@ void pa_pstream_send_release(pa_pstream *p, uint32_t block_id) { /* pa_log("Releasing block %u", block_id); */ - item = pa_xnew(struct item_info, 1); + if (!(item = pa_flist_pop(PA_STATIC_FLIST_GET(items)))) + item = pa_xnew(struct item_info, 1); item->type = PA_PSTREAM_ITEM_SHMRELEASE; item->block_id = block_id; #ifdef HAVE_CREDS @@ -432,7 +439,8 @@ void pa_pstream_send_revoke(pa_pstream *p, uint32_t block_id) { return; /* pa_log("Revoking block %u", block_id); */ - item = pa_xnew(struct item_info, 1); + if (!(item = pa_flist_pop(PA_STATIC_FLIST_GET(items)))) + item = pa_xnew(struct item_info, 1); item->type = PA_PSTREAM_ITEM_SHMREVOKE; item->block_id = block_id; #ifdef HAVE_CREDS -- cgit From b44ce9e4e04ac41436fec9f57b509c49a78b617b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 15:56:06 +0000 Subject: add default fragment settings variables to pa_core git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1629 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core.c | 2 ++ src/pulsecore/core.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c index a56dd4ef..8b10d398 100644 --- a/src/pulsecore/core.c +++ b/src/pulsecore/core.c @@ -112,6 +112,8 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { c->default_sample_spec.format = PA_SAMPLE_S16NE; c->default_sample_spec.rate = 44100; c->default_sample_spec.channels = 2; + c->default_n_fragments = 4; + c->default_fragment_size_msec = 25; c->module_auto_unload_event = NULL; c->module_defer_unload_event = NULL; diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index d86d5514..003b24b1 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -65,6 +65,8 @@ struct pa_core { char *default_source_name, *default_sink_name; pa_sample_spec default_sample_spec; + unsigned default_n_fragments, default_fragment_size_msec; + pa_time_event *module_auto_unload_event; pa_defer_event *module_defer_unload_event; -- cgit From e2a10de756136110d7fdeac0d8543e452dd610ad Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 15:56:57 +0000 Subject: allow setting the default sample and fragment settings from the config file git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1630 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/daemon-conf.c | 235 +++++++++++++++++++++++++++++++++++----------- src/daemon/daemon-conf.h | 3 + src/daemon/daemon.conf.in | 9 ++ src/daemon/main.c | 3 + 4 files changed, 196 insertions(+), 54 deletions(-) diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c index 8cab327f..b6e8d540 100644 --- a/src/daemon/daemon-conf.c +++ b/src/daemon/daemon-conf.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -39,6 +38,7 @@ #include #include #include +#include #include "daemon-conf.h" @@ -77,7 +77,10 @@ static const pa_daemon_conf default_conf = { .use_pid_file = 1, .system_instance = 0, .no_cpu_limit = 0, - .disable_shm = 0 + .disable_shm = 0, + .default_n_fragments = 4, + .default_fragment_size_msec = 25, + .default_sample_spec = { .format = PA_SAMPLE_S16NE, .rate = 44100, .channels = 2 } #ifdef HAVE_SYS_RESOURCE_H , .rlimit_as = { .value = 0, .is_set = 0 }, .rlimit_core = { .value = 0, .is_set = 0 }, @@ -96,7 +99,7 @@ static const pa_daemon_conf default_conf = { pa_daemon_conf* pa_daemon_conf_new(void) { FILE *f; - pa_daemon_conf *c = pa_xmemdup(&default_conf, sizeof(default_conf)); + pa_daemon_conf *c = pa_xnewdup(pa_daemon_conf, &default_conf, 1); if ((f = pa_open_config_file(DEFAULT_SCRIPT_FILE, DEFAULT_SCRIPT_FILE_USER, ENV_SCRIPT_FILE, &c->default_script_file, "r"))) fclose(f); @@ -106,7 +109,7 @@ pa_daemon_conf* pa_daemon_conf_new(void) { } void pa_daemon_conf_free(pa_daemon_conf *c) { - assert(c); + pa_assert(c); pa_xfree(c->script_commands); pa_xfree(c->dl_search_path); pa_xfree(c->default_script_file); @@ -115,7 +118,8 @@ void pa_daemon_conf_free(pa_daemon_conf *c) { } int pa_daemon_conf_set_log_target(pa_daemon_conf *c, const char *string) { - assert(c && string); + pa_assert(c); + pa_assert(string); if (!strcmp(string, "auto")) c->auto_log_target = 1; @@ -133,7 +137,8 @@ int pa_daemon_conf_set_log_target(pa_daemon_conf *c, const char *string) { int pa_daemon_conf_set_log_level(pa_daemon_conf *c, const char *string) { uint32_t u; - assert(c && string); + pa_assert(c); + pa_assert(string); if (pa_atou(string, &u) >= 0) { if (u >= PA_LOG_LEVEL_MAX) @@ -158,7 +163,8 @@ int pa_daemon_conf_set_log_level(pa_daemon_conf *c, const char *string) { int pa_daemon_conf_set_resample_method(pa_daemon_conf *c, const char *string) { int m; - assert(c && string); + pa_assert(c); + pa_assert(string); if ((m = pa_parse_resample_method(string)) < 0) return -1; @@ -169,7 +175,11 @@ int pa_daemon_conf_set_resample_method(pa_daemon_conf *c, const char *string) { static int parse_log_target(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { pa_daemon_conf *c = data; - assert(filename && lvalue && rvalue && data); + + pa_assert(filename); + pa_assert(lvalue); + pa_assert(rvalue); + pa_assert(data); if (pa_daemon_conf_set_log_target(c, rvalue) < 0) { pa_log("[%s:%u] Invalid log target '%s'.", filename, line, rvalue); @@ -181,7 +191,11 @@ static int parse_log_target(const char *filename, unsigned line, const char *lva static int parse_log_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { pa_daemon_conf *c = data; - assert(filename && lvalue && rvalue && data); + + pa_assert(filename); + pa_assert(lvalue); + pa_assert(rvalue); + pa_assert(data); if (pa_daemon_conf_set_log_level(c, rvalue) < 0) { pa_log("[%s:%u] Invalid log level '%s'.", filename, line, rvalue); @@ -193,10 +207,14 @@ static int parse_log_level(const char *filename, unsigned line, const char *lval static int parse_resample_method(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { pa_daemon_conf *c = data; - assert(filename && lvalue && rvalue && data); + + pa_assert(filename); + pa_assert(lvalue); + pa_assert(rvalue); + pa_assert(data); if (pa_daemon_conf_set_resample_method(c, rvalue) < 0) { - pa_log("[%s:%u] Inavalid resample method '%s'.", filename, line, rvalue); + pa_log("[%s:%u] Invalid resample method '%s'.", filename, line, rvalue); return -1; } @@ -206,10 +224,11 @@ static int parse_resample_method(const char *filename, unsigned line, const char static int parse_rlimit(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { #ifdef HAVE_SYS_RESOURCE_H struct pa_rlimit *r = data; - assert(filename); - assert(lvalue); - assert(rvalue); - assert(r); + + pa_assert(filename); + pa_assert(lvalue); + pa_assert(rvalue); + pa_assert(r); if (rvalue[strspn(rvalue, "\t ")] == 0) { /* Empty string */ @@ -218,7 +237,7 @@ static int parse_rlimit(const char *filename, unsigned line, const char *lvalue, } else { int32_t k; if (pa_atoi(rvalue, &k) < 0) { - pa_log("[%s:%u] Inavalid rlimit '%s'.", filename, line, rvalue); + pa_log("[%s:%u] Invalid rlimit '%s'.", filename, line, rvalue); return -1; } r->is_set = k >= 0; @@ -231,43 +250,138 @@ static int parse_rlimit(const char *filename, unsigned line, const char *lvalue, return 0; } +static int parse_sample_format(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { + pa_daemon_conf *c = data; + pa_sample_format_t f; + + pa_assert(filename); + pa_assert(lvalue); + pa_assert(rvalue); + pa_assert(data); + + if ((f = pa_parse_sample_format(rvalue)) < 0) { + pa_log("[%s:%u] Invalid sample format '%s'.", filename, line, rvalue); + return -1; + } + + c->default_sample_spec.format = f; + return 0; +} + +static int parse_sample_rate(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { + pa_daemon_conf *c = data; + int32_t r; + + pa_assert(filename); + pa_assert(lvalue); + pa_assert(rvalue); + pa_assert(data); + + if (pa_atoi(rvalue, &r) < 0 || r > PA_RATE_MAX || r <= 0) { + pa_log("[%s:%u] Invalid sample rate '%s'.", filename, line, rvalue); + return -1; + } + + c->default_sample_spec.rate = r; + return 0; +} + +static int parse_sample_channels(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { + pa_daemon_conf *c = data; + int32_t n; + + pa_assert(filename); + pa_assert(lvalue); + pa_assert(rvalue); + pa_assert(data); + + if (pa_atoi(rvalue, &n) < 0 || n > PA_CHANNELS_MAX || n <= 0) { + pa_log("[%s:%u] Invalid sample channels '%s'.", filename, line, rvalue); + return -1; + } + + c->default_sample_spec.channels = (uint8_t) n; + return 0; +} + +static int parse_fragments(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { + pa_daemon_conf *c = data; + int32_t n; + + pa_assert(filename); + pa_assert(lvalue); + pa_assert(rvalue); + pa_assert(data); + + if (pa_atoi(rvalue, &n) < 0 || n < 2) { + pa_log("[%s:%u] Invalid number of fragments '%s'.", filename, line, rvalue); + return -1; + } + + c->default_n_fragments = (unsigned) n; + return 0; +} + +static int parse_fragment_size_msec(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { + pa_daemon_conf *c = data; + int32_t n; + + pa_assert(filename); + pa_assert(lvalue); + pa_assert(rvalue); + pa_assert(data); + + if (pa_atoi(rvalue, &n) < 0 || n < 1) { + pa_log("[%s:%u] Invalid fragment size '%s'.", filename, line, rvalue); + return -1; + } + + c->default_fragment_size_msec = (unsigned) n; + return 0; +} + int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) { int r = -1; FILE *f = NULL; pa_config_item table[] = { - { "daemonize", pa_config_parse_bool, NULL }, - { "fail", pa_config_parse_bool, NULL }, - { "high-priority", pa_config_parse_bool, NULL }, - { "disallow-module-loading", pa_config_parse_bool, NULL }, - { "exit-idle-time", pa_config_parse_int, NULL }, - { "module-idle-time", pa_config_parse_int, NULL }, - { "scache-idle-time", pa_config_parse_int, NULL }, - { "dl-search-path", pa_config_parse_string, NULL }, - { "default-script-file", pa_config_parse_string, NULL }, - { "log-target", parse_log_target, NULL }, - { "log-level", parse_log_level, NULL }, - { "verbose", parse_log_level, NULL }, - { "resample-method", parse_resample_method, NULL }, - { "use-pid-file", pa_config_parse_bool, NULL }, - { "system-instance", pa_config_parse_bool, NULL }, - { "no-cpu-limit", pa_config_parse_bool, NULL }, - { "disable-shm", pa_config_parse_bool, NULL }, + { "daemonize", pa_config_parse_bool, NULL }, + { "fail", pa_config_parse_bool, NULL }, + { "high-priority", pa_config_parse_bool, NULL }, + { "disallow-module-loading", pa_config_parse_bool, NULL }, + { "exit-idle-time", pa_config_parse_int, NULL }, + { "module-idle-time", pa_config_parse_int, NULL }, + { "scache-idle-time", pa_config_parse_int, NULL }, + { "dl-search-path", pa_config_parse_string, NULL }, + { "default-script-file", pa_config_parse_string, NULL }, + { "log-target", parse_log_target, NULL }, + { "log-level", parse_log_level, NULL }, + { "verbose", parse_log_level, NULL }, + { "resample-method", parse_resample_method, NULL }, + { "use-pid-file", pa_config_parse_bool, NULL }, + { "system-instance", pa_config_parse_bool, NULL }, + { "no-cpu-limit", pa_config_parse_bool, NULL }, + { "disable-shm", pa_config_parse_bool, NULL }, + { "default-sample-format", parse_sample_format, NULL }, + { "default-sample-rate", parse_sample_rate, NULL }, + { "default-sample-channels", parse_sample_channels, NULL }, + { "default-fragments", parse_fragments, NULL }, + { "default-fragment-size-msec", parse_fragment_size_msec, NULL }, #ifdef HAVE_SYS_RESOURCE_H - { "rlimit-as", parse_rlimit, NULL }, - { "rlimit-core", parse_rlimit, NULL }, - { "rlimit-data", parse_rlimit, NULL }, - { "rlimit-fsize", parse_rlimit, NULL }, - { "rlimit-nofile", parse_rlimit, NULL }, - { "rlimit-stack", parse_rlimit, NULL }, + { "rlimit-as", parse_rlimit, NULL }, + { "rlimit-core", parse_rlimit, NULL }, + { "rlimit-data", parse_rlimit, NULL }, + { "rlimit-fsize", parse_rlimit, NULL }, + { "rlimit-nofile", parse_rlimit, NULL }, + { "rlimit-stack", parse_rlimit, NULL }, #ifdef RLIMIT_NPROC - { "rlimit-nproc", parse_rlimit, NULL }, + { "rlimit-nproc", parse_rlimit, NULL }, #endif #ifdef RLIMIT_MEMLOCK - { "rlimit-memlock", parse_rlimit, NULL }, + { "rlimit-memlock", parse_rlimit, NULL }, #endif #endif - { NULL, NULL, NULL }, + { NULL, NULL, NULL }, }; table[0].data = &c->daemonize; @@ -287,25 +401,29 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) { table[14].data = &c->system_instance; table[15].data = &c->no_cpu_limit; table[16].data = &c->disable_shm; + table[17].data = c; + table[18].data = c; + table[19].data = c; + table[20].data = c; + table[21].data = c; #ifdef HAVE_SYS_RESOURCE_H - table[17].data = &c->rlimit_as; - table[18].data = &c->rlimit_core; - table[19].data = &c->rlimit_data; - table[20].data = &c->rlimit_fsize; - table[21].data = &c->rlimit_nofile; - table[22].data = &c->rlimit_stack; + table[22].data = &c->rlimit_as; + table[23].data = &c->rlimit_core; + table[24].data = &c->rlimit_data; + table[25].data = &c->rlimit_fsize; + table[26].data = &c->rlimit_nofile; + table[27].data = &c->rlimit_stack; #ifdef RLIMIT_NPROC - table[23].data = &c->rlimit_nproc; + table[28].data = &c->rlimit_nproc; #endif #ifdef RLIMIT_MEMLOCK #ifndef RLIMIT_NPROC #error "Houston, we have a numbering problem!" #endif - table[24].data = &c->rlimit_memlock; + table[29].data = &c->rlimit_memlock; #endif #endif - pa_xfree(c->config_file); c->config_file = NULL; @@ -351,12 +469,16 @@ static const char* const log_level_to_string[] = { }; char *pa_daemon_conf_dump(pa_daemon_conf *c) { - pa_strbuf *s = pa_strbuf_new(); + pa_strbuf *s; + + pa_assert(c); + + s = pa_strbuf_new(); if (c->config_file) pa_strbuf_printf(s, "### Read from configuration file: %s ###\n", c->config_file); - assert(c->log_level <= PA_LOG_LEVEL_MAX); + pa_assert(c->log_level <= PA_LOG_LEVEL_MAX); pa_strbuf_printf(s, "daemonize = %i\n", !!c->daemonize); pa_strbuf_printf(s, "fail = %i\n", !!c->fail); @@ -373,7 +495,12 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) { pa_strbuf_printf(s, "use-pid-file = %i\n", c->use_pid_file); pa_strbuf_printf(s, "system-instance = %i\n", !!c->system_instance); pa_strbuf_printf(s, "no-cpu-limit = %i\n", !!c->no_cpu_limit); - pa_strbuf_printf(s, "disable_shm = %i\n", !!c->disable_shm); + pa_strbuf_printf(s, "disable-shm = %i\n", !!c->disable_shm); + pa_strbuf_printf(s, "default-sample-format = %s\n", pa_sample_format_to_string(c->default_sample_spec.format)); + pa_strbuf_printf(s, "default-sample-rate = %u\n", c->default_sample_spec.rate); + pa_strbuf_printf(s, "default-sample-channels = %u\n", c->default_sample_spec.channels); + pa_strbuf_printf(s, "default-fragments = %u\n", c->default_n_fragments); + pa_strbuf_printf(s, "default-fragment-size-msec = %u\n", c->default_fragment_size_msec); #ifdef HAVE_SYS_RESOURCE_H pa_strbuf_printf(s, "rlimit-as = %li\n", c->rlimit_as.is_set ? (long int) c->rlimit_as.value : -1); pa_strbuf_printf(s, "rlimit-core = %li\n", c->rlimit_core.is_set ? (long int) c->rlimit_core.value : -1); diff --git a/src/daemon/daemon-conf.h b/src/daemon/daemon-conf.h index 4843a610..cb717ece 100644 --- a/src/daemon/daemon-conf.h +++ b/src/daemon/daemon-conf.h @@ -26,6 +26,7 @@ ***/ #include +#include #ifdef HAVE_SYS_RESOURCE_H #include @@ -80,6 +81,8 @@ typedef struct pa_daemon_conf { #endif #endif + unsigned default_n_fragments, default_fragment_size_msec; + pa_sample_spec default_sample_spec; } pa_daemon_conf; /* Allocate a new structure and fill it with sane defaults */ diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in index 29b22a42..9bd5cba6 100644 --- a/src/daemon/daemon.conf.in +++ b/src/daemon/daemon.conf.in @@ -99,3 +99,12 @@ ## Disable shared memory data transfer ; disable-shm = 0 + +## Default sample format +; default-sample-format = s16le +; default-sample-rate = 44100 +; default-sample-channels = 2 + +## Default fragment settings, for device drivers that need this +; default-fragments = 4 +; default-fragment-size-msec = 25 diff --git a/src/daemon/main.c b/src/daemon/main.c index a1926fe5..eac470bf 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -573,6 +573,9 @@ int main(int argc, char *argv[]) { } c->is_system_instance = !!conf->system_instance; + c->default_sample_spec = conf->default_sample_spec; + c->default_n_fragments = conf->default_n_fragments; + c->default_fragment_size_msec = conf->default_fragment_size_msec; r = pa_signal_init(pa_mainloop_get_api(mainloop)); assert(r == 0); -- cgit From a7a5f43f6770facb030481afde00a9363fa8fe1c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 15:57:21 +0000 Subject: modernization git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1631 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/conf-parser.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/pulsecore/conf-parser.c b/src/pulsecore/conf-parser.c index 12efbd2c..47ec72c2 100644 --- a/src/pulsecore/conf-parser.c +++ b/src/pulsecore/conf-parser.c @@ -25,7 +25,6 @@ #include #endif -#include #include #include #include @@ -35,6 +34,7 @@ #include #include #include +#include #include "conf-parser.h" @@ -43,7 +43,10 @@ /* Run the user supplied parser for an assignment */ static int next_assignment(const char *filename, unsigned line, const pa_config_item *t, const char *lvalue, const char *rvalue, void *userdata) { - assert(filename && t && lvalue && rvalue); + pa_assert(filename); + pa_assert(t); + pa_assert(lvalue); + pa_assert(rvalue); for (; t->parse; t++) if (!strcmp(lvalue, t->lvalue)) @@ -56,7 +59,7 @@ static int next_assignment(const char *filename, unsigned line, const pa_config_ /* Returns non-zero when c is contained in s */ static int in_string(char c, const char *s) { - assert(s); + pa_assert(s); for (; *s; s++) if (*s == c) @@ -107,7 +110,9 @@ int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void int r = -1; unsigned line = 0; int do_close = !f; - assert(filename && t); + + pa_assert(filename); + pa_assert(t); if (!f && !(f = fopen(filename, "r"))) { if (errno == ENOENT) { @@ -148,7 +153,11 @@ finish: int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { int *i = data; int32_t k; - assert(filename && lvalue && rvalue && data); + + pa_assert(filename); + pa_assert(lvalue); + pa_assert(rvalue); + pa_assert(data); if (pa_atoi(rvalue, &k) < 0) { pa_log("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue); @@ -161,7 +170,11 @@ int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { int *b = data, k; - assert(filename && lvalue && rvalue && data); + + pa_assert(filename); + pa_assert(lvalue); + pa_assert(rvalue); + pa_assert(data); if ((k = pa_parse_boolean(rvalue)) < 0) { pa_log("[%s:%u] Failed to parse boolean value: %s", filename, line, rvalue); @@ -175,7 +188,11 @@ int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue int pa_config_parse_string(const char *filename, PA_GCC_UNUSED unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { char **s = data; - assert(filename && lvalue && rvalue && data); + + pa_assert(filename); + pa_assert(lvalue); + pa_assert(rvalue); + pa_assert(data); pa_xfree(*s); *s = *rvalue ? pa_xstrdup(rvalue) : NULL; -- cgit From 793f750429a32379fd034d06ee24a3ed768df4a4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 15:58:15 +0000 Subject: fix default device naming and fix api selection code git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1632 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-hal-detect.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index 672bdc06..e95e97fd 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -155,7 +155,7 @@ static int hal_alsa_device_is_modem(LibHalContext *context, const char *udi, DBu } static pa_module* hal_device_load_alsa(struct userdata *u, const char *udi, char **sink_name, char **source_name) { - char args[128]; + char *args; alsa_type_t type; int device, card; const char *module_name; @@ -189,18 +189,20 @@ static pa_module* hal_device_load_alsa(struct userdata *u, const char *udi, char *sink_name = pa_sprintf_malloc("alsa_output.%s", strip_udi(udi)); module_name = "module-alsa-sink"; - pa_snprintf(args, sizeof(args), "device=hw:%u sink_name=%s", card, *sink_name); + args = pa_sprintf_malloc("device=hw:%u sink_name=%s", card, *sink_name); } else { - *source_name = pa_sprintf_malloc("alsa_output.%s", strip_udi(udi)); + *source_name = pa_sprintf_malloc("alsa_input.%s", strip_udi(udi)); module_name = "module-alsa-source"; - pa_snprintf(args, sizeof(args), "device=hw:%u source_name=%s", card, *source_name); + args = pa_sprintf_malloc("device=hw:%u source_name=%s", card, *source_name); } pa_log_debug("Loading %s with arguments '%s'", module_name, args); m = pa_module_load(u->core, module_name, args); + pa_xfree(args); + if (!m) { pa_xfree(*sink_name); pa_xfree(*source_name); @@ -257,7 +259,7 @@ finish: } static pa_module* hal_device_load_oss(struct userdata *u, const char *udi, char **sink_name, char **source_name) { - char args[256]; + char* args; char* device; DBusError error; pa_module *m; @@ -277,15 +279,15 @@ static pa_module* hal_device_load_oss(struct userdata *u, const char *udi, char if (!device || dbus_error_is_set(&error)) goto fail; - *sink_name = pa_sprintf_malloc("alsa_output.%s", strip_udi(udi)); - *source_name = pa_sprintf_malloc("alsa_output.%s", strip_udi(udi)); + *sink_name = pa_sprintf_malloc("oss_output.%s", strip_udi(udi)); + *source_name = pa_sprintf_malloc("oss_input.%s", strip_udi(udi)); - pa_snprintf(args, sizeof(args), "device=%s sink_name=%s source_name=%s", device, sink_name, source_name); + args = pa_sprintf_malloc("device=%s sink_name=%s source_name=%s", device, *sink_name, *source_name); libhal_free_string(device); pa_log_debug("Loading module-oss with arguments '%s'", args); - m = pa_module_load(u->core, "module-oss", args); + pa_xfree(args); if (!m) { pa_xfree(*sink_name); @@ -342,10 +344,12 @@ static int hal_device_add_all(struct userdata *u, const char *capability) { char** udis; pa_assert(u); - pa_assert(!u->capability); dbus_error_init(&error); + if (u->capability && strcmp(u->capability, capability) != 0) + return 0; + pa_log_info("Trying capability %s", capability); udis = libhal_find_device_by_capability(u->context, capability, &n, &error); @@ -356,7 +360,6 @@ static int hal_device_add_all(struct userdata *u, const char *capability) { } if (n > 0) { - u->capability = capability; for (i = 0; i < n; i++) { struct device *d; @@ -741,7 +744,7 @@ int pa__init(pa_module*m) { n = hal_device_add_all(u, CAPABILITY_ALSA); #endif #if defined(HAVE_ALSA) && defined(HAVE_OSS) - if (!u->capability) + if (n <= 0) #endif #ifdef HAVE_OSS n += hal_device_add_all(u, CAPABILITY_OSS); -- cgit From e1100b5b20a39813a86559a91afa5da3afb51752 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 15:59:02 +0000 Subject: modify alsa drivers to make use of new global fragment setting variables git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1633 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 7 ++----- src/modules/module-alsa-source.c | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index d3fe885d..af03a958 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -71,9 +71,6 @@ PA_MODULE_USAGE( #define DEFAULT_DEVICE "default" -#define DEFAULT_NFRAGS 4 -#define DEFAULT_FRAGSIZE_MSEC 25 - struct userdata { pa_core *core; pa_module *module; @@ -741,8 +738,8 @@ int pa__init(pa_module*m) { frame_size = pa_frame_size(&ss); - nfrags = DEFAULT_NFRAGS; - frag_size = pa_usec_to_bytes(DEFAULT_FRAGSIZE_MSEC*1000, &ss); + nfrags = m->core->default_n_fragments; + frag_size = pa_usec_to_bytes(m->core->default_fragment_size_msec*1000, &ss); if (frag_size <= 0) frag_size = frame_size; diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 55af4735..5de24069 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -71,8 +71,6 @@ PA_MODULE_USAGE( "mmap=") #define DEFAULT_DEVICE "default" -#define DEFAULT_NFRAGS 4 -#define DEFAULT_FRAGSIZE_MSEC 25 struct userdata { pa_core *core; @@ -716,9 +714,8 @@ int pa__init(pa_module*m) { frame_size = pa_frame_size(&ss); - /* Fix latency to 100ms */ - nfrags = DEFAULT_NFRAGS; - frag_size = pa_usec_to_bytes(DEFAULT_FRAGSIZE_MSEC*1000, &ss); + nfrags = m->core->default_n_fragments; + frag_size = pa_usec_to_bytes(m->core->default_fragment_size_msec*1000, &ss); if (frag_size <= 0) frag_size = frame_size; -- cgit From f7b707b9541fa2e5e7a709ccb3f26c0be11bc6a9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 16:00:02 +0000 Subject: allow destruction of pa_fdsem object that are still in 'poll' state git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1634 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/fdsem.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/pulsecore/fdsem.c b/src/pulsecore/fdsem.c index 4de531ae..c51ebba6 100644 --- a/src/pulsecore/fdsem.c +++ b/src/pulsecore/fdsem.c @@ -64,8 +64,6 @@ pa_fdsem *pa_fdsem_new(void) { void pa_fdsem_free(pa_fdsem *f) { pa_assert(f); - pa_assert(pa_atomic_load(&f->waiting) == 0); - close(f->fds[0]); close(f->fds[1]); @@ -168,17 +166,16 @@ int pa_fdsem_before_poll(pa_fdsem *f) { pa_atomic_inc(&f->waiting); if (pa_atomic_cmpxchg(&f->signalled, 1, 0)) { - pa_atomic_dec(&f->waiting); + pa_assert_se(pa_atomic_dec(&f->waiting) >= 1); return -1; - } - + } return 0; } int pa_fdsem_after_poll(pa_fdsem *f) { pa_assert(f); - pa_atomic_dec(&f->waiting); + pa_assert_se(pa_atomic_dec(&f->waiting) >= 1); flush(f); -- cgit From c1c59b4675d1c6912badc3f93fbc5d9ccecb7610 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 16:01:25 +0000 Subject: add proper refcounting to pa_asyncmsgq objects, to allow destruction from the dispatched callbacks git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1635 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/asyncmsgq.c | 39 ++++++++++++++++++++++++++++++--------- src/pulsecore/asyncmsgq.h | 5 +++-- src/pulsecore/thread-mq.c | 17 ++++++++++------- src/tests/asyncmsgq-test.c | 2 +- 4 files changed, 44 insertions(+), 19 deletions(-) diff --git a/src/pulsecore/asyncmsgq.c b/src/pulsecore/asyncmsgq.c index ed71d374..1bef8bda 100644 --- a/src/pulsecore/asyncmsgq.c +++ b/src/pulsecore/asyncmsgq.c @@ -53,6 +53,7 @@ struct asyncmsgq_item { }; struct pa_asyncmsgq { + PA_REFCNT_DECLARE; pa_asyncq *asyncq; pa_mutex *mutex; /* only for the writer side */ @@ -64,6 +65,7 @@ pa_asyncmsgq *pa_asyncmsgq_new(unsigned size) { a = pa_xnew(pa_asyncmsgq, 1); + PA_REFCNT_INIT(a); pa_assert_se(a->asyncq = pa_asyncq_new(size)); pa_assert_se(a->mutex = pa_mutex_new(0)); a->current = NULL; @@ -71,7 +73,7 @@ pa_asyncmsgq *pa_asyncmsgq_new(unsigned size) { return a; } -void pa_asyncmsgq_free(pa_asyncmsgq *a) { +static void asyncmsgq_free(pa_asyncmsgq *a) { struct asyncmsgq_item *i; pa_assert(a); @@ -97,9 +99,23 @@ void pa_asyncmsgq_free(pa_asyncmsgq *a) { pa_xfree(a); } +pa_asyncmsgq* pa_asyncmsgq_ref(pa_asyncmsgq *q) { + pa_assert(PA_REFCNT_VALUE(q) > 0); + + PA_REFCNT_INC(q); + return q; +} + +void pa_asyncmsgq_unref(pa_asyncmsgq* q) { + pa_assert(PA_REFCNT_VALUE(q) > 0); + + if (PA_REFCNT_DEC(q) <= 0) + asyncmsgq_free(q); +} + void pa_asyncmsgq_post(pa_asyncmsgq *a, pa_msgobject *object, int code, const void *userdata, int64_t offset, const pa_memchunk *chunk, pa_free_cb_t free_cb) { struct asyncmsgq_item *i; - pa_assert(a); + pa_assert(PA_REFCNT_VALUE(a) > 0); if (!(i = pa_flist_pop(PA_STATIC_FLIST_GET(asyncmsgq)))) i = pa_xnew(struct asyncmsgq_item, 1); @@ -125,7 +141,7 @@ void pa_asyncmsgq_post(pa_asyncmsgq *a, pa_msgobject *object, int code, const vo int pa_asyncmsgq_send(pa_asyncmsgq *a, pa_msgobject *object, int code, const void *userdata, int64_t offset, const pa_memchunk *chunk) { struct asyncmsgq_item i; - pa_assert(a); + pa_assert(PA_REFCNT_VALUE(a) > 0); i.code = code; i.object = object; @@ -152,7 +168,7 @@ int pa_asyncmsgq_send(pa_asyncmsgq *a, pa_msgobject *object, int code, const voi } int pa_asyncmsgq_get(pa_asyncmsgq *a, pa_msgobject **object, int *code, void **userdata, int64_t *offset, pa_memchunk *chunk, int wait) { - pa_assert(a); + pa_assert(PA_REFCNT_VALUE(a) > 0); pa_assert(code); pa_assert(!a->current); @@ -181,6 +197,7 @@ int pa_asyncmsgq_get(pa_asyncmsgq *a, pa_msgobject **object, int *code, void **u } void pa_asyncmsgq_done(pa_asyncmsgq *a, int ret) { + pa_assert(PA_REFCNT_VALUE(a) > 0); pa_assert(a); pa_assert(a->current); @@ -207,12 +224,14 @@ void pa_asyncmsgq_done(pa_asyncmsgq *a, int ret) { int pa_asyncmsgq_wait_for(pa_asyncmsgq *a, int code) { int c; - pa_assert(a); + pa_assert(PA_REFCNT_VALUE(a) > 0); + + pa_asyncmsgq_ref(a); do { pa_msgobject *o; void *data; - int64_t offset; + int64_t offset; pa_memchunk chunk; int ret; @@ -224,23 +243,25 @@ int pa_asyncmsgq_wait_for(pa_asyncmsgq *a, int code) { } while (c != code); + pa_asyncmsgq_unref(a); + return 0; } int pa_asyncmsgq_get_fd(pa_asyncmsgq *a) { - pa_assert(a); + pa_assert(PA_REFCNT_VALUE(a) > 0); return pa_asyncq_get_fd(a->asyncq); } int pa_asyncmsgq_before_poll(pa_asyncmsgq *a) { - pa_assert(a); + pa_assert(PA_REFCNT_VALUE(a) > 0); return pa_asyncq_before_poll(a->asyncq); } void pa_asyncmsgq_after_poll(pa_asyncmsgq *a) { - pa_assert(a); + pa_assert(PA_REFCNT_VALUE(a) > 0); pa_asyncq_after_poll(a->asyncq); } diff --git a/src/pulsecore/asyncmsgq.h b/src/pulsecore/asyncmsgq.h index b0f1a6e4..2f188376 100644 --- a/src/pulsecore/asyncmsgq.h +++ b/src/pulsecore/asyncmsgq.h @@ -49,13 +49,14 @@ * latter waits for completion, synchronously. */ enum { - PA_MESSAGE_SHUTDOWN /* A generic message to inform the handler of this queue to quit */ + PA_MESSAGE_SHUTDOWN = -1/* A generic message to inform the handler of this queue to quit */ }; typedef struct pa_asyncmsgq pa_asyncmsgq; pa_asyncmsgq* pa_asyncmsgq_new(size_t size); -void pa_asyncmsgq_free(pa_asyncmsgq* q); +pa_asyncmsgq* pa_asyncmsgq_ref(pa_asyncmsgq *q); +void pa_asyncmsgq_unref(pa_asyncmsgq* q); void pa_asyncmsgq_post(pa_asyncmsgq *q, pa_msgobject *object, int code, const void *userdata, int64_t offset, const pa_memchunk *memchunk, pa_free_cb_t userdata_free_cb); int pa_asyncmsgq_send(pa_asyncmsgq *q, pa_msgobject *object, int code, const void *userdata, int64_t offset, const pa_memchunk *memchunk); diff --git a/src/pulsecore/thread-mq.c b/src/pulsecore/thread-mq.c index 89b65e5c..513409d4 100644 --- a/src/pulsecore/thread-mq.c +++ b/src/pulsecore/thread-mq.c @@ -46,11 +46,13 @@ static pa_tls *tls; static void asyncmsgq_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) { pa_thread_mq *q = userdata; + pa_asyncmsgq *aq; pa_assert(pa_asyncmsgq_get_fd(q->outq) == fd); pa_assert(events == PA_IO_EVENT_INPUT); - pa_asyncmsgq_after_poll(q->outq); + pa_asyncmsgq_ref(aq = q->outq); + pa_asyncmsgq_after_poll(aq); for (;;) { pa_msgobject *object; @@ -60,16 +62,18 @@ static void asyncmsgq_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_even pa_memchunk chunk; /* Check whether there is a message for us to process */ - while (pa_asyncmsgq_get(q->outq, &object, &code, &data, &offset, &chunk, 0) == 0) { + while (pa_asyncmsgq_get(aq, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); - pa_asyncmsgq_done(q->outq, ret); + pa_asyncmsgq_done(aq, ret); } - if (pa_asyncmsgq_before_poll(q->outq) == 0) + if (pa_asyncmsgq_before_poll(aq) == 0) break; } + + pa_asyncmsgq_unref(aq); } void pa_thread_mq_init(pa_thread_mq *q, pa_mainloop_api *mainloop) { @@ -90,9 +94,8 @@ void pa_thread_mq_done(pa_thread_mq *q) { q->mainloop->io_free(q->io_event); q->io_event = NULL; - pa_asyncmsgq_after_poll(q->outq); - pa_asyncmsgq_free(q->inq); - pa_asyncmsgq_free(q->outq); + pa_asyncmsgq_unref(q->inq); + pa_asyncmsgq_unref(q->outq); q->inq = q->outq = NULL; q->mainloop = NULL; diff --git a/src/tests/asyncmsgq-test.c b/src/tests/asyncmsgq-test.c index baf93a0c..e7d662e1 100644 --- a/src/tests/asyncmsgq-test.c +++ b/src/tests/asyncmsgq-test.c @@ -104,7 +104,7 @@ int main(int argc, char *argv[]) { pa_thread_free(t); - pa_asyncmsgq_free(q); + pa_asyncmsgq_unref(q); return 0; } -- cgit From 107b23d202ca62eb5d510438799702bdfe1ef54e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 16:07:38 +0000 Subject: fix module-hal when no api= argument is specified git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1636 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-hal-detect.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index e95e97fd..f00a60db 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -360,6 +360,7 @@ static int hal_device_add_all(struct userdata *u, const char *capability) { } if (n > 0) { + u->capability = capability; for (i = 0; i < n; i++) { struct device *d; -- cgit From 447c4a53276516f1ac71a4684ca5a6277a442c79 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 16:08:20 +0000 Subject: deal with messages properly which are recieved after destruction of a stream git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1637 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-native.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index a67f9b02..1a112a8d 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -407,6 +407,9 @@ static int record_stream_process_msg(pa_msgobject *o, int code, void*userdata, i record_stream *s = RECORD_STREAM(o); record_stream_assert_ref(s); + if (!s->connection) + return -1; + switch (code) { case RECORD_STREAM_MESSAGE_POST_DATA: @@ -524,6 +527,9 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata, playback_stream *s = PLAYBACK_STREAM(o); playback_stream_assert_ref(s); + if (!s->connection) + return -1; + switch (code) { case PLAYBACK_STREAM_MESSAGE_REQUEST_DATA: { pa_tagstruct *t; @@ -689,6 +695,9 @@ static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int6 connection *c = CONNECTION(o); connection_assert_ref(c); + if (!c->protocol) + return -1; + switch (code) { case CONNECTION_MESSAGE_REVOKE: -- cgit From b71dde0e358cd53505a7ec85f942d7724acef5c1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 16:51:21 +0000 Subject: make sure that the device access event sound is only generated once git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1638 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-hal-detect.c | 75 +++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 21 deletions(-) diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index f00a60db..441ebfed 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -68,6 +68,7 @@ struct device { uint32_t index; char *udi; char *sink_name, *source_name; + int acl_race_fix; }; struct userdata { @@ -329,6 +330,7 @@ static struct device* hal_device_add(struct userdata *u, const char *udi) { return NULL; d = pa_xnew(struct device, 1); + d->acl_race_fix = 0; d->udi = pa_xstrdup(udi); d->index = m->index; d->sink_name = sink_name; @@ -559,23 +561,27 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo udi = dbus_message_get_path(message); if ((d = pa_hashmap_get(u->devices, udi))) { - + int send_acl_race_fix_message = 0; + + d->acl_race_fix = 0; + if (d->sink_name) { pa_sink *sink; if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK, 0))) { - int prev_suspended = pa_sink_get_state(sink) == PA_SINK_SUSPENDED; - if (pa_sink_suspend(sink, suspend) >= 0) { - if (!suspend && prev_suspended) + if (prev_suspended && !suspend) { + /* resume */ + if (pa_sink_suspend(sink, 0) >= 0) pa_scache_play_item_by_name(u->core, "pulse-access", d->sink_name, PA_VOLUME_NORM, 0); - else if (suspend && !prev_suspended) { - DBusMessage *msg; - msg = dbus_message_new_signal(udi, "org.pulseaudio.Server", "DirtyGiveUpMessage"); - dbus_connection_send(pa_dbus_connection_get(u->connection), msg, NULL); - dbus_message_unref(msg); - } + else + d->acl_race_fix = 1; + + } else if (!prev_suspended && suspend) { + /* suspend */ + if (pa_sink_suspend(sink, 1) >= 0) + send_acl_race_fix_message = 1; } } } @@ -583,10 +589,29 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo if (d->source_name) { pa_source *source; - if ((source = pa_namereg_get(u->core, d->source_name, PA_NAMEREG_SOURCE, 0))) - pa_source_suspend(source, suspend); + if ((source = pa_namereg_get(u->core, d->source_name, PA_NAMEREG_SOURCE, 0))) { + int prev_suspended = pa_source_get_state(source) == PA_SOURCE_SUSPENDED; + + if (prev_suspended && !suspend) { + /* resume */ + if (pa_source_suspend(source, 0) < 0) + d->acl_race_fix = 1; + + } else if (!prev_suspended && suspend) { + /* suspend */ + if (pa_source_suspend(source, 0) >= 0) + send_acl_race_fix_message = 1; + } + } } - + + if (send_acl_race_fix_message) { + DBusMessage *msg; + msg = dbus_message_new_signal(udi, "org.pulseaudio.Server", "DirtyGiveUpMessage"); + dbus_connection_send(pa_dbus_connection_get(u->connection), msg, NULL); + dbus_message_unref(msg); + } + } else if (!suspend) device_added_cb(u->context, udi); } @@ -600,30 +625,38 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *message, vo const char *udi; struct device *d; - pa_log_debug("Got dirty give up message, trying resume ..."); - udi = dbus_message_get_path(message); - if ((d = pa_hashmap_get(u->devices, udi))) { + if ((d = pa_hashmap_get(u->devices, udi)) && d->acl_race_fix) { + pa_log_debug("Got dirty give up message for '%s', trying resume ...", udi); + d->acl_race_fix = 0; + if (d->sink_name) { pa_sink *sink; if ((sink = pa_namereg_get(u->core, d->sink_name, PA_NAMEREG_SINK, 0))) { int prev_suspended = pa_sink_get_state(sink) == PA_SINK_SUSPENDED; - - if (pa_sink_suspend(sink, 0) >= 0) - if (prev_suspended && !prev_suspended) + + if (prev_suspended) { + /* resume */ + if (pa_sink_suspend(sink, 0) >= 0) pa_scache_play_item_by_name(u->core, "pulse-access", d->sink_name, PA_VOLUME_NORM, 0); + } } } if (d->source_name) { pa_source *source; - if ((source = pa_namereg_get(u->core, d->source_name, PA_NAMEREG_SOURCE, 0))) - pa_source_suspend(source, 0); + if ((source = pa_namereg_get(u->core, d->source_name, PA_NAMEREG_SOURCE, 0))) { + + int prev_suspended = pa_source_get_state(source) == PA_SOURCE_SUSPENDED; + + if (prev_suspended) + pa_source_suspend(source, 0); + } } } else -- cgit From a3cd8002b524ab323b964847fc0daa08e85f1bc8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 17:09:07 +0000 Subject: port oss driver to make use of the default fragment sizes as defined in pa_core: store in the sink/source description whether mmap is used; if mmap() fails, fall back to UNIX read/write mode instead of bailing out immediately git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1639 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-oss.c | 48 ++++++++++++++++++++---------------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index d71de99a..1a366633 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -103,9 +103,6 @@ PA_MODULE_USAGE( #define DEFAULT_DEVICE "/dev/dsp" -#define DEFAULT_NFRAGS 4 -#define DEFAULT_FRAGSIZE_MSEC 25 - struct userdata { pa_core *core; pa_module *module; @@ -1103,8 +1100,8 @@ int pa__init(pa_module*m) { goto fail; } - nfrags = DEFAULT_NFRAGS; - frag_size = pa_usec_to_bytes(DEFAULT_FRAGSIZE_MSEC*1000, &ss); + nfrags = m->core->default_n_fragments; + frag_size = pa_usec_to_bytes(m->core->default_fragment_size_msec*1000, &ss); if (frag_size <= 0) frag_size = pa_frame_size(&ss); @@ -1127,7 +1124,7 @@ int pa__init(pa_module*m) { } if (use_mmap && mode == O_WRONLY) { - pa_log_info("Device opened for write only, cannot do memory mapping, falling back to UNIX read/write mode."); + pa_log_info("Device opened for playback only, cannot do memory mapping, falling back to UNIX write() mode."); use_mmap = 0; } @@ -1188,17 +1185,11 @@ int pa__init(pa_module*m) { if (use_mmap) { if ((u->in_mmap = mmap(NULL, u->in_hwbuf_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { - if (mode == O_RDWR) { - pa_log_debug("mmap() failed for input. Changing to O_WRONLY mode."); - mode = O_WRONLY; - goto try_write; - } else { - pa_log("mmap(): %s", pa_cstrerror(errno)); - goto fail; - } - } - - pa_log_debug("Successfully mmap()ed input buffer."); + pa_log_warn("mmap(PROT_READ) failed, reverting to non-mmap mode: %s", pa_cstrerror(errno)); + use_mmap = u->use_mmap = 0; + u->in_mmap = NULL; + } else + pa_log_debug("Successfully mmap()ed input buffer."); } if ((name = pa_modargs_get_value(ma, "source_name", NULL))) @@ -1221,11 +1212,12 @@ int pa__init(pa_module*m) { pa_source_set_module(u->source, m); pa_source_set_asyncmsgq(u->source, u->thread_mq.inq); pa_source_set_description(u->source, t = pa_sprintf_malloc( - "OSS PCM on %s%s%s%s", + "OSS PCM on %s%s%s%s%s", dev, hwdesc[0] ? " (" : "", hwdesc[0] ? hwdesc : "", - hwdesc[0] ? ")" : "")); + hwdesc[0] ? ")" : "", + use_mmap ? " via DMA" : "")); pa_xfree(t); u->source->is_hardware = 1; u->source->refresh_volume = 1; @@ -1234,8 +1226,6 @@ int pa__init(pa_module*m) { u->in_mmap_memblocks = pa_xnew0(pa_memblock*, u->in_nfrags); } -try_write: - if (mode != O_RDONLY) { char *name_buf = NULL; @@ -1246,13 +1236,14 @@ try_write: mode = O_WRONLY; goto go_on; } else { - pa_log("mmap(): %s", pa_cstrerror(errno)); - goto fail; + pa_log_warn("mmap(PROT_WRITE) failed, reverting to non-mmap mode: %s", pa_cstrerror(errno)); + u->use_mmap = use_mmap = 0; + u->out_mmap = NULL; } + } else { + pa_log_debug("Successfully mmap()ed output buffer."); + pa_silence_memory(u->out_mmap, u->out_hwbuf_size, &ss); } - - pa_log_debug("Successfully mmap()ed output buffer."); - pa_silence_memory(u->out_mmap, u->out_hwbuf_size, &ss); } if ((name = pa_modargs_get_value(ma, "sink_name", NULL))) @@ -1275,11 +1266,12 @@ try_write: pa_sink_set_module(u->sink, m); pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); pa_sink_set_description(u->sink, t = pa_sprintf_malloc( - "OSS PCM on %s%s%s%s", + "OSS PCM on %s%s%s%s%s", dev, hwdesc[0] ? " (" : "", hwdesc[0] ? hwdesc : "", - hwdesc[0] ? ")" : "")); + hwdesc[0] ? ")" : "", + use_mmap ? " via DMA" : "")); pa_xfree(t); u->sink->is_hardware = 1; u->sink->refresh_volume = 1; -- cgit From 50e014e7a9bc1742d5a9f37f7fa057a6a23a1d6c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 19:08:06 +0000 Subject: use single array for storing pa_core hook lists, add sink state changed hook, drop NO_HOOKS flags for sink inputs/source outputs, listen for resume events in module-suspend-on-idle.c git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1640 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-rescue-streams.c | 4 +-- src/modules/module-suspend-on-idle.c | 64 +++++++++++++++++++++++++++++------- src/modules/module-volume-restore.c | 4 +-- src/pulsecore/core.c | 40 ++++------------------ src/pulsecore/core.h | 38 +++++++++++---------- src/pulsecore/sink-input.c | 11 +++---- src/pulsecore/sink-input.h | 1 - src/pulsecore/sink.c | 11 +++---- src/pulsecore/source-output.c | 11 +++---- src/pulsecore/source-output.h | 3 +- src/pulsecore/source.c | 10 +++--- 11 files changed, 104 insertions(+), 93 deletions(-) diff --git a/src/modules/module-rescue-streams.c b/src/modules/module-rescue-streams.c index fa22d60a..e0eed036 100644 --- a/src/modules/module-rescue-streams.c +++ b/src/modules/module-rescue-streams.c @@ -138,8 +138,8 @@ int pa__init(pa_module*m) { } m->userdata = u = pa_xnew(struct userdata, 1); - u->sink_slot = pa_hook_connect(&m->core->hook_sink_disconnect, (pa_hook_cb_t) sink_hook_callback, NULL); - u->source_slot = pa_hook_connect(&m->core->hook_source_disconnect, (pa_hook_cb_t) source_hook_callback, NULL); + u->sink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_DISCONNECT], (pa_hook_cb_t) sink_hook_callback, NULL); + u->source_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_DISCONNECT], (pa_hook_cb_t) source_hook_callback, NULL); pa_modargs_free(ma); return 0; diff --git a/src/modules/module-suspend-on-idle.c b/src/modules/module-suspend-on-idle.c index ad148644..0d21cfbe 100644 --- a/src/modules/module-suspend-on-idle.c +++ b/src/modules/module-suspend-on-idle.c @@ -50,7 +50,7 @@ struct userdata { pa_core *core; pa_usec_t timeout; pa_hashmap *device_infos; - pa_hook_slot *sink_new_slot, *source_new_slot, *sink_disconnect_slot, *source_disconnect_slot; + pa_hook_slot *sink_new_slot, *source_new_slot, *sink_disconnect_slot, *source_disconnect_slot, *sink_state_changed_slot, *source_state_changed_slot; pa_hook_slot *sink_input_new_slot, *source_output_new_slot, *sink_input_disconnect_slot, *source_output_disconnect_slot; }; @@ -69,13 +69,13 @@ static void timeout_cb(pa_mainloop_api*a, pa_time_event* e, const struct timeval d->userdata->core->mainloop->time_restart(d->time_event, NULL); - if (d->sink && pa_sink_used_by(d->sink) <= 0) { + if (d->sink && pa_sink_used_by(d->sink) <= 0 && pa_sink_get_state(d->sink) != PA_SINK_SUSPENDED) { pa_log_info("Sink %s idle for too long, suspending ...", d->sink->name); pa_sink_suspend(d->sink, 1); pa_source_suspend(d->sink->monitor_source, 1); } - if (d->source && pa_source_used_by(d->source) <= 0) { + if (d->source && pa_source_used_by(d->source) <= 0 && pa_source_get_state(d->source) != PA_SOURCE_SUSPENDED) { pa_log_info("Source %s idle for too long, suspending ...", d->source->name); pa_source_suspend(d->source, 1); } @@ -209,6 +209,40 @@ static pa_hook_result_t device_disconnect_hook_cb(pa_core *c, pa_object *o, stru return PA_HOOK_OK; } +static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *o, struct userdata *u) { + struct device_info *d; + + pa_assert(c); + pa_object_assert_ref(o); + pa_assert(u); + + if (!(d = pa_hashmap_get(u->device_infos, o))) + return PA_HOOK_OK; + + if (pa_sink_isinstance(o)) { + pa_sink *s = PA_SINK(o); + + if (pa_sink_used_by(s) <= 0) { + pa_sink_state_t state = pa_sink_get_state(s); + + if (state == PA_SINK_RUNNING || state == PA_SINK_IDLE) + restart(d); + } + + } else if (pa_source_isinstance(o)) { + pa_source *s = PA_SOURCE(o); + + if (pa_source_used_by(s) <= 0) { + pa_sink_state_t state = pa_source_get_state(s); + + if (state == PA_SINK_RUNNING || state == PA_SINK_IDLE) + restart(d); + } + } + + return PA_HOOK_OK; +} + int pa__init(pa_module*m) { pa_modargs *ma = NULL; struct userdata *u; @@ -240,15 +274,17 @@ int pa__init(pa_module*m) { for (source = pa_idxset_first(m->core->sources, &idx); source; source = pa_idxset_next(m->core->sources, &idx)) device_new_hook_cb(m->core, PA_OBJECT(source), u); - u->sink_new_slot = pa_hook_connect(&m->core->hook_sink_new_post, (pa_hook_cb_t) device_new_hook_cb, u); - u->source_new_slot = pa_hook_connect(&m->core->hook_source_new_post, (pa_hook_cb_t) device_new_hook_cb, u); - u->sink_disconnect_slot = pa_hook_connect(&m->core->hook_sink_disconnect_post, (pa_hook_cb_t) device_disconnect_hook_cb, u); - u->source_disconnect_slot = pa_hook_connect(&m->core->hook_source_disconnect_post, (pa_hook_cb_t) device_disconnect_hook_cb, u); - - u->sink_input_new_slot = pa_hook_connect(&m->core->hook_sink_input_new_post, (pa_hook_cb_t) sink_input_new_hook_cb, u); - u->source_output_new_slot = pa_hook_connect(&m->core->hook_source_output_new_post, (pa_hook_cb_t) source_output_new_hook_cb, u); - u->sink_input_disconnect_slot = pa_hook_connect(&m->core->hook_sink_input_disconnect_post, (pa_hook_cb_t) sink_input_disconnect_hook_cb, u); - u->source_output_disconnect_slot = pa_hook_connect(&m->core->hook_source_output_disconnect_post, (pa_hook_cb_t) source_output_disconnect_hook_cb, u); + u->sink_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_NEW_POST], (pa_hook_cb_t) device_new_hook_cb, u); + u->source_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_NEW_POST], (pa_hook_cb_t) device_new_hook_cb, u); + u->sink_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_DISCONNECT], (pa_hook_cb_t) device_disconnect_hook_cb, u); + u->source_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_DISCONNECT], (pa_hook_cb_t) device_disconnect_hook_cb, u); + u->sink_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], (pa_hook_cb_t) device_state_changed_hook_cb, u); + u->source_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], (pa_hook_cb_t) device_state_changed_hook_cb, u); + + u->sink_input_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], (pa_hook_cb_t) sink_input_new_hook_cb, u); + u->source_output_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PUT], (pa_hook_cb_t) source_output_new_hook_cb, u); + u->sink_input_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_DISCONNECT_POST], (pa_hook_cb_t) sink_input_disconnect_hook_cb, u); + u->source_output_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_DISCONNECT_POST], (pa_hook_cb_t) source_output_disconnect_hook_cb, u); pa_modargs_free(ma); return 0; @@ -276,11 +312,15 @@ void pa__done(pa_module*m) { pa_hook_slot_free(u->sink_new_slot); if (u->sink_disconnect_slot) pa_hook_slot_free(u->sink_disconnect_slot); + if (u->sink_state_changed_slot) + pa_hook_slot_free(u->sink_state_changed_slot); if (u->source_new_slot) pa_hook_slot_free(u->source_new_slot); if (u->source_disconnect_slot) pa_hook_slot_free(u->source_disconnect_slot); + if (u->source_state_changed_slot) + pa_hook_slot_free(u->source_state_changed_slot); if (u->sink_input_new_slot) pa_hook_slot_free(u->sink_input_new_slot); diff --git a/src/modules/module-volume-restore.c b/src/modules/module-volume-restore.c index addd937b..0041760b 100644 --- a/src/modules/module-volume-restore.c +++ b/src/modules/module-volume-restore.c @@ -444,8 +444,8 @@ int pa__init(pa_module*m) { goto fail; u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK_INPUT|PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT, subscribe_callback, u); - u->sink_input_hook_slot = pa_hook_connect(&m->core->hook_sink_input_new, (pa_hook_cb_t) sink_input_hook_callback, u); - u->source_output_hook_slot = pa_hook_connect(&m->core->hook_source_output_new, (pa_hook_cb_t) source_output_hook_callback, u); + u->sink_input_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], (pa_hook_cb_t) sink_input_hook_callback, u); + u->source_output_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_NEW], (pa_hook_cb_t) source_output_hook_callback, u); pa_modargs_free(ma); return 0; diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c index 8b10d398..2e9d96b1 100644 --- a/src/pulsecore/core.c +++ b/src/pulsecore/core.c @@ -72,7 +72,8 @@ static void core_free(pa_object *o); pa_core* pa_core_new(pa_mainloop_api *m, int shared) { pa_core* c; pa_mempool *pool; - + int j; + pa_assert(m); if (shared) { @@ -138,22 +139,8 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { c->is_system_instance = 0; - pa_hook_init(&c->hook_sink_new, c); - pa_hook_init(&c->hook_sink_new_post, c); - pa_hook_init(&c->hook_sink_disconnect, c); - pa_hook_init(&c->hook_sink_disconnect_post, c); - pa_hook_init(&c->hook_source_new, c); - pa_hook_init(&c->hook_source_new_post, c); - pa_hook_init(&c->hook_source_disconnect, c); - pa_hook_init(&c->hook_source_disconnect_post, c); - pa_hook_init(&c->hook_sink_input_new, c); - pa_hook_init(&c->hook_sink_input_new_post, c); - pa_hook_init(&c->hook_sink_input_disconnect, c); - pa_hook_init(&c->hook_sink_input_disconnect_post, c); - pa_hook_init(&c->hook_source_output_new, c); - pa_hook_init(&c->hook_source_output_new_post, c); - pa_hook_init(&c->hook_source_output_disconnect, c); - pa_hook_init(&c->hook_source_output_disconnect_post, c); + for (j = 0; j < PA_CORE_HOOK_MAX; j++) + pa_hook_init(&c->hooks[j], c); pa_property_init(c); @@ -168,6 +155,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { static void core_free(pa_object *o) { pa_core *c = PA_CORE(o); + int j; pa_assert(c); pa_module_unload_all(c); @@ -203,22 +191,8 @@ static void core_free(pa_object *o) { pa_property_cleanup(c); - pa_hook_free(&c->hook_sink_new); - pa_hook_free(&c->hook_sink_new_post); - pa_hook_free(&c->hook_sink_disconnect); - pa_hook_free(&c->hook_sink_disconnect_post); - pa_hook_free(&c->hook_source_new); - pa_hook_free(&c->hook_source_new_post); - pa_hook_free(&c->hook_source_disconnect); - pa_hook_free(&c->hook_source_disconnect_post); - pa_hook_free(&c->hook_sink_input_new); - pa_hook_free(&c->hook_sink_input_new_post); - pa_hook_free(&c->hook_sink_input_disconnect); - pa_hook_free(&c->hook_sink_input_disconnect_post); - pa_hook_free(&c->hook_source_output_new); - pa_hook_free(&c->hook_source_output_new_post); - pa_hook_free(&c->hook_source_output_disconnect); - pa_hook_free(&c->hook_source_output_disconnect_post); + for (j = 0; j < PA_CORE_HOOK_MAX; j++) + pa_hook_free(&c->hooks[j]); pa_xfree(c); } diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index 003b24b1..c49a77d5 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -42,6 +42,26 @@ typedef struct pa_core pa_core; #include #include +typedef enum pa_core_hook { + PA_CORE_HOOK_SINK_NEW_POST, + PA_CORE_HOOK_SINK_DISCONNECT, + PA_CORE_HOOK_SINK_DISCONNECT_POST, + PA_CORE_HOOK_SINK_STATE_CHANGED, + PA_CORE_HOOK_SOURCE_NEW_POST, + PA_CORE_HOOK_SOURCE_DISCONNECT, + PA_CORE_HOOK_SOURCE_DISCONNECT_POST, + PA_CORE_HOOK_SOURCE_STATE_CHANGED, + PA_CORE_HOOK_SINK_INPUT_NEW, + PA_CORE_HOOK_SINK_INPUT_PUT, + PA_CORE_HOOK_SINK_INPUT_DISCONNECT, + PA_CORE_HOOK_SINK_INPUT_DISCONNECT_POST, + PA_CORE_HOOK_SOURCE_OUTPUT_NEW, + PA_CORE_HOOK_SOURCE_OUTPUT_PUT, + PA_CORE_HOOK_SOURCE_OUTPUT_DISCONNECT, + PA_CORE_HOOK_SOURCE_OUTPUT_DISCONNECT_POST, + PA_CORE_HOOK_MAX +} pa_core_hook_t; + /* The core structure of PulseAudio. Every PulseAudio daemon contains * exactly one of these. It is used for storing kind of global * variables for the daemon. */ @@ -89,23 +109,7 @@ struct pa_core { int is_system_instance; /* hooks */ - pa_hook - hook_sink_new, - hook_sink_new_post, - hook_sink_disconnect, - hook_sink_disconnect_post, - hook_source_new, - hook_source_new_post, - hook_source_disconnect, - hook_source_disconnect_post, - hook_sink_input_new, - hook_sink_input_new_post, - hook_sink_input_disconnect, - hook_sink_input_disconnect_post, - hook_source_output_new, - hook_source_output_new_post, - hook_source_output_disconnect, - hook_source_output_disconnect_post; + pa_hook hooks[PA_CORE_HOOK_MAX]; }; PA_DECLARE_CLASS(pa_core); diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index d1bf0acc..77b95feb 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -98,9 +98,8 @@ pa_sink_input* pa_sink_input_new( pa_assert(core); pa_assert(data); - if (!(flags & PA_SINK_INPUT_NO_HOOKS)) - if (pa_hook_fire(&core->hook_sink_input_new, data) < 0) - return NULL; + if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], data) < 0) + return NULL; pa_return_null_if_fail(!data->driver || pa_utf8_valid(data->driver)); pa_return_null_if_fail(!data->name || pa_utf8_valid(data->name)); @@ -249,7 +248,7 @@ void pa_sink_input_disconnect(pa_sink_input *i) { pa_assert(i); pa_return_if_fail(i->state != PA_SINK_INPUT_DISCONNECTED); - pa_hook_fire(&i->sink->core->hook_sink_input_disconnect, i); + pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_DISCONNECT], i); if (i->sync_prev) i->sync_prev->sync_next = i->sync_next; @@ -273,7 +272,7 @@ void pa_sink_input_disconnect(pa_sink_input *i) { i->get_latency = NULL; i->underrun = NULL; - pa_hook_fire(&i->sink->core->hook_sink_input_disconnect_post, i); + pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_DISCONNECT_POST], i); i->sink = NULL; pa_sink_input_unref(i); } @@ -313,7 +312,7 @@ void pa_sink_input_put(pa_sink_input *i) { pa_sink_update_status(i->sink); pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index); - pa_hook_fire(&i->sink->core->hook_sink_input_new_post, i); + pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], i); } void pa_sink_input_kill(pa_sink_input*i) { diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index 0168805a..5a48418c 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -47,7 +47,6 @@ typedef enum pa_sink_input_state { typedef enum pa_sink_input_flags { PA_SINK_INPUT_VARIABLE_RATE = 1, - PA_SINK_INPUT_NO_HOOKS = 2 } pa_sink_input_flags_t; struct pa_sink_input { diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 905fe3ff..929542cc 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -80,9 +80,6 @@ pa_sink* pa_sink_new( pa_return_null_if_fail(!driver || pa_utf8_valid(driver)); pa_return_null_if_fail(name && pa_utf8_valid(name) && *name); - if (pa_hook_fire(&core->hook_sink_new, NULL) < 0) /* FIXME */ - return NULL; - s = pa_msgobject_new(pa_sink); if (!(name = pa_namereg_register(core, name, PA_NAMEREG_SINK, s, fail))) { @@ -149,7 +146,7 @@ pa_sink* pa_sink_new( pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index); - pa_hook_fire(&core->hook_sink_new_post, s); + pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_NEW_POST], s); return s; } @@ -170,6 +167,8 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state) { return -1; s->state = state; + + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], s); return 0; } @@ -179,7 +178,7 @@ void pa_sink_disconnect(pa_sink* s) { pa_assert(s); pa_return_if_fail(s->state != PA_SINK_DISCONNECTED); - pa_hook_fire(&s->core->hook_sink_disconnect, s); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_DISCONNECT], s); pa_namereg_unregister(s->core, s->name); pa_idxset_remove_by_data(s->core->sinks, s, NULL); @@ -204,7 +203,7 @@ void pa_sink_disconnect(pa_sink* s) { pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_REMOVE, s->index); - pa_hook_fire(&s->core->hook_sink_disconnect_post, s); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_DISCONNECT_POST], s); } static void sink_free(pa_object *o) { diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 95755f3b..2dc66bfa 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -76,9 +76,8 @@ pa_source_output* pa_source_output_new( pa_assert(core); pa_assert(data); - if (!(flags & PA_SOURCE_OUTPUT_NO_HOOKS)) - if (pa_hook_fire(&core->hook_source_output_new, data) < 0) - return NULL; + if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_NEW], data) < 0) + return NULL; pa_return_null_if_fail(!data->driver || pa_utf8_valid(data->driver)); pa_return_null_if_fail(!data->name || pa_utf8_valid(data->name)); @@ -187,7 +186,7 @@ void pa_source_output_disconnect(pa_source_output*o) { pa_assert(o); pa_return_if_fail(o->state != PA_SOURCE_OUTPUT_DISCONNECTED); - pa_hook_fire(&o->source->core->hook_source_output_disconnect, o); + pa_hook_fire(&o->source->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_DISCONNECT], o); pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, 0, NULL); @@ -203,7 +202,7 @@ void pa_source_output_disconnect(pa_source_output*o) { o->kill = NULL; o->get_latency = NULL; - pa_hook_fire(&o->source->core->hook_source_output_disconnect_post, o); + pa_hook_fire(&o->source->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_DISCONNECT_POST], o); o->source = NULL; pa_source_output_unref(o); @@ -235,7 +234,7 @@ void pa_source_output_put(pa_source_output *o) { pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW, o->index); - pa_hook_fire(&o->source->core->hook_source_output_new_post, o); + pa_hook_fire(&o->source->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PUT], o); } void pa_source_output_kill(pa_source_output*o) { diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h index 47cc8c40..b17adcb5 100644 --- a/src/pulsecore/source-output.h +++ b/src/pulsecore/source-output.h @@ -42,8 +42,7 @@ typedef enum pa_source_output_state { } pa_source_output_state_t; typedef enum pa_source_output_flags { - PA_SOURCE_OUTPUT_NO_HOOKS = 1, - PA_SOURCE_OUTPUT_VARIABLE_RATE = 2 + PA_SOURCE_OUTPUT_VARIABLE_RATE = 1 } pa_source_output_flags_t; struct pa_source_output { diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index f7825931..0e448f60 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -73,9 +73,6 @@ pa_source* pa_source_new( pa_return_null_if_fail(!driver || pa_utf8_valid(driver)); pa_return_null_if_fail(pa_utf8_valid(name) && *name); - if (pa_hook_fire(&core->hook_sink_new, NULL) < 0) /* FIXME */ - return NULL; - s = pa_msgobject_new(pa_source); if (!(name = pa_namereg_register(core, name, PA_NAMEREG_SOURCE, s, fail))) { @@ -128,7 +125,7 @@ pa_source* pa_source_new( pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index); - pa_hook_fire(&core->hook_source_new_post, s); + pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_NEW_POST], s); return s; } @@ -149,6 +146,7 @@ static int source_set_state(pa_source *s, pa_source_state_t state) { return -1; s->state = state; + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], s); return 0; } @@ -158,7 +156,7 @@ void pa_source_disconnect(pa_source *s) { pa_assert(s); pa_return_if_fail(s->state != PA_SOURCE_DISCONNECTED); - pa_hook_fire(&s->core->hook_source_disconnect, s); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_DISCONNECT], s); pa_namereg_unregister(s->core, s->name); pa_idxset_remove_by_data(s->core->sources, s, NULL); @@ -180,7 +178,7 @@ void pa_source_disconnect(pa_source *s) { pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_REMOVE, s->index); - pa_hook_fire(&s->core->hook_source_disconnect_post, s); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_DISCONNECT_POST], s); } static void source_free(pa_object *o) { -- cgit From e71a34762ec607f6c28130987a622bed3ae5fbb5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 20:29:42 +0000 Subject: restore the ability move record streams between sources git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1641 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core.h | 4 ++ src/pulsecore/source-output.c | 94 ++++++++++++++++++++++++------------------- 2 files changed, 56 insertions(+), 42 deletions(-) diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index c49a77d5..4d92960d 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -55,10 +55,14 @@ typedef enum pa_core_hook { PA_CORE_HOOK_SINK_INPUT_PUT, PA_CORE_HOOK_SINK_INPUT_DISCONNECT, PA_CORE_HOOK_SINK_INPUT_DISCONNECT_POST, + PA_CORE_HOOK_SINK_INPUT_MOVE, + PA_CORE_HOOK_SINK_INPUT_MOVE_POST, PA_CORE_HOOK_SOURCE_OUTPUT_NEW, PA_CORE_HOOK_SOURCE_OUTPUT_PUT, PA_CORE_HOOK_SOURCE_OUTPUT_DISCONNECT, PA_CORE_HOOK_SOURCE_OUTPUT_DISCONNECT_POST, + PA_CORE_HOOK_SOURCE_OUTPUT_MOVE, + PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_POST, PA_CORE_HOOK_MAX } pa_core_hook_t; diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 2dc66bfa..34bb9de5 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -229,7 +229,7 @@ static void source_output_free(pa_object* mo) { void pa_source_output_put(pa_source_output *o) { pa_source_output_assert_ref(o); - pa_asyncmsgq_post(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_ADD_OUTPUT, pa_source_output_ref(o), 0, NULL, (pa_free_cb_t) pa_source_output_unref); + pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_ADD_OUTPUT, o, 0, NULL); pa_source_update_status(o->source); pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW, o->index); @@ -327,63 +327,73 @@ pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o) { } int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { -/* pa_source *origin; */ -/* pa_resampler *new_resampler = NULL; */ + pa_source *origin; + pa_resampler *new_resampler = NULL; pa_source_output_assert_ref(o); pa_source_assert_ref(dest); + + origin = o->source; - return -1; + if (dest == origin) + return 0; -/* origin = o->source; */ + if (pa_idxset_size(dest->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) { + pa_log_warn("Failed to move source output: too many outputs per source."); + return -1; + } -/* if (dest == origin) */ -/* return 0; */ + if (o->thread_info.resampler && + pa_sample_spec_equal(&origin->sample_spec, &dest->sample_spec) && + pa_channel_map_equal(&origin->channel_map, &dest->channel_map)) -/* if (pa_idxset_size(dest->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) { */ -/* pa_log_warn("Failed to move source output: too many outputs per source."); */ -/* return -1; */ -/* } */ + /* Try to reuse the old resampler if possible */ + new_resampler = o->thread_info.resampler; -/* if (o->resampler && */ -/* pa_sample_spec_equal(&origin->sample_spec, &dest->sample_spec) && */ -/* pa_channel_map_equal(&origin->channel_map, &dest->channel_map)) */ + else if (!pa_sample_spec_equal(&o->sample_spec, &dest->sample_spec) || + !pa_channel_map_equal(&o->channel_map, &dest->channel_map)) { -/* /\* Try to reuse the old resampler if possible *\/ */ -/* new_resampler = o->resampler; */ + /* Okey, we need a new resampler for the new source */ -/* else if (!pa_sample_spec_equal(&o->sample_spec, &dest->sample_spec) || */ -/* !pa_channel_map_equal(&o->channel_map, &dest->channel_map)) { */ + if (!(new_resampler = pa_resampler_new( + dest->core->mempool, + &dest->sample_spec, &dest->channel_map, + &o->sample_spec, &o->channel_map, + o->resample_method))) { + pa_log_warn("Unsupported resampling operation."); + return -1; + } + } -/* /\* Okey, we need a new resampler for the new source *\/ */ + pa_hook_fire(&o->source->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE], o); -/* if (!(new_resampler = pa_resampler_new( */ -/* dest->core->mempool, */ -/* &dest->sample_spec, &dest->channel_map, */ -/* &o->sample_spec, &o->channel_map, */ -/* o->resample_method))) { */ -/* pa_log_warn("Unsupported resampling operation."); */ -/* return -1; */ -/* } */ -/* } */ + /* Okey, let's move it */ + pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, 0, NULL); + + pa_idxset_remove_by_data(origin->outputs, o, NULL); + pa_idxset_put(dest->outputs, o, NULL); + o->source = dest; + + /* Replace resampler */ + if (new_resampler != o->thread_info.resampler) { + if (o->thread_info.resampler) + pa_resampler_free(o->thread_info.resampler); + o->thread_info.resampler = new_resampler; + } + + pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_ADD_OUTPUT, o, 0, NULL); -/* /\* Okey, let's move it *\/ */ -/* pa_idxset_remove_by_data(origin->outputs, o, NULL); */ -/* pa_idxset_put(dest->outputs, o, NULL); */ -/* o->source = dest; */ + pa_source_update_status(origin); + pa_source_update_status(dest); -/* /\* Replace resampler *\/ */ -/* if (new_resampler != o->resampler) { */ -/* if (o->resampler) */ -/* pa_resampler_free(o->resampler); */ -/* o->resampler = new_resampler; */ -/* } */ + pa_hook_fire(&o->source->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_POST], o); -/* /\* Notify everyone *\/ */ -/* pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); */ -/* pa_source_notify(o->source); */ + pa_log_debug("Successfully moved source output %i from %s to %s.", o->index, origin->name, dest->name); -/* return 0; */ + /* Notify everyone */ + pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); + + return 0; } int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, int64_t offset, pa_memchunk* chunk) { -- cgit From 44b82a1925dd5a229999828191c4e14c65086160 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 20:30:21 +0000 Subject: Add 'via DMA' to sink/source description if device is accessed with mmap() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1642 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 5 +++-- src/modules/module-alsa-source.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index af03a958..5491aac5 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -837,9 +837,10 @@ int pa__init(pa_module*m) { pa_sink_set_module(u->sink, m); pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); pa_sink_set_description(u->sink, t = pa_sprintf_malloc( - "ALSA PCM on %s (%s)", + "ALSA PCM on %s (%s)%s", dev, - snd_pcm_info_get_name(pcm_info))); + snd_pcm_info_get_name(pcm_info), + use_mmap ? " via DMA" : "")); pa_xfree(t); u->sink->is_hardware = 1; diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 5de24069..b6471850 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -811,9 +811,10 @@ int pa__init(pa_module*m) { pa_source_set_module(u->source, m); pa_source_set_asyncmsgq(u->source, u->thread_mq.inq); pa_source_set_description(u->source, t = pa_sprintf_malloc( - "ALSA PCM on %s (%s)", + "ALSA PCM on %s (%s)%s", dev, - snd_pcm_info_get_name(pcm_info))); + snd_pcm_info_get_name(pcm_info), + use_mmap ? " via DMA" : "")); pa_xfree(t); u->source->is_hardware = 1; -- cgit From 57734ec414c7411a9a8724a2f9ee0cb77c6a37f9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 20:31:08 +0000 Subject: hook into move operations for resuming/suspending devices appropriately git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1643 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-suspend-on-idle.c | 128 +++++++++++++++++++++++++++++------ 1 file changed, 109 insertions(+), 19 deletions(-) diff --git a/src/modules/module-suspend-on-idle.c b/src/modules/module-suspend-on-idle.c index 0d21cfbe..d2f9b7dd 100644 --- a/src/modules/module-suspend-on-idle.c +++ b/src/modules/module-suspend-on-idle.c @@ -50,8 +50,23 @@ struct userdata { pa_core *core; pa_usec_t timeout; pa_hashmap *device_infos; - pa_hook_slot *sink_new_slot, *source_new_slot, *sink_disconnect_slot, *source_disconnect_slot, *sink_state_changed_slot, *source_state_changed_slot; - pa_hook_slot *sink_input_new_slot, *source_output_new_slot, *sink_input_disconnect_slot, *source_output_disconnect_slot; + pa_hook_slot + *sink_new_slot, + *source_new_slot, + *sink_disconnect_slot, + *source_disconnect_slot, + *sink_state_changed_slot, + *source_state_changed_slot; + + pa_hook_slot + *sink_input_new_slot, + *source_output_new_slot, + *sink_input_disconnect_slot, + *source_output_disconnect_slot, + *sink_input_move_slot, + *source_output_move_slot, + *sink_input_move_post_slot, + *source_output_move_post_slot; }; struct device_info { @@ -90,10 +105,31 @@ static void restart(struct device_info *d) { pa_timeval_add(&tv, d->userdata->timeout*1000000); d->userdata->core->mainloop->time_restart(d->time_event, &tv); - if (d->source) - pa_log_debug("Source %s becomes idle.", d->source->name); if (d->sink) pa_log_debug("Sink %s becomes idle.", d->sink->name); + if (d->source) + pa_log_debug("Source %s becomes idle.", d->source->name); +} + +static void resume(struct device_info *d) { + pa_assert(d); + + d->userdata->core->mainloop->time_restart(d->time_event, NULL); + + if (d->sink) { + pa_sink_suspend(d->sink, 0); + pa_source_suspend(d->sink->monitor_source, 0); + + pa_log_debug("Sink %s becomes busy.", d->sink->name); + } + + if (d->source) { + pa_source_suspend(d->source, 0); + if (d->source->monitor_of) + pa_sink_suspend(d->source->monitor_of, 0); + + pa_log_debug("Source %s becomes busy.", d->source->name); + } } static pa_hook_result_t sink_input_new_hook_cb(pa_core *c, pa_sink_input *s, struct userdata *u) { @@ -104,12 +140,7 @@ static pa_hook_result_t sink_input_new_hook_cb(pa_core *c, pa_sink_input *s, str pa_assert(u); pa_assert_se((d = pa_hashmap_get(u->device_infos, s->sink))); - d->userdata->core->mainloop->time_restart(d->time_event, NULL); - - pa_sink_suspend(s->sink, 0); - pa_source_suspend(s->sink->monitor_source, 0); - - pa_log_debug("Sink %s becomes busy.", s->sink->name); + resume(d); return PA_HOOK_OK; } @@ -122,13 +153,7 @@ static pa_hook_result_t source_output_new_hook_cb(pa_core *c, pa_source_output * pa_assert(u); pa_assert_se((d = pa_hashmap_get(u->device_infos, s->source))); - d->userdata->core->mainloop->time_restart(d->time_event, NULL); - - pa_source_suspend(s->source, 0); - if (s->source->monitor_of) - pa_sink_suspend(s->source->monitor_of, 0); - - pa_log_debug("Source %s becomes busy.", s->source->name); + resume(d); return PA_HOOK_OK; } @@ -161,6 +186,58 @@ static pa_hook_result_t source_output_disconnect_hook_cb(pa_core *c, pa_source_o return PA_HOOK_OK; } +static pa_hook_result_t sink_input_move_hook_cb(pa_core *c, pa_sink_input *s, struct userdata *u) { + pa_assert(c); + pa_sink_input_assert_ref(s); + pa_assert(u); + + if (pa_sink_used_by(s->sink) <= 1) { + struct device_info *d; + pa_assert_se((d = pa_hashmap_get(u->device_infos, s->sink))); + restart(d); + } + + return PA_HOOK_OK; +} + +static pa_hook_result_t sink_input_move_post_hook_cb(pa_core *c, pa_sink_input *s, struct userdata *u) { + struct device_info *d; + pa_assert(c); + pa_sink_input_assert_ref(s); + pa_assert(u); + + pa_assert_se((d = pa_hashmap_get(u->device_infos, s->sink))); + resume(d); + + return PA_HOOK_OK; +} + +static pa_hook_result_t source_output_move_hook_cb(pa_core *c, pa_source_output *s, struct userdata *u) { + pa_assert(c); + pa_source_output_assert_ref(s); + pa_assert(u); + + if (pa_source_used_by(s->source) <= 1) { + struct device_info *d; + pa_assert_se((d = pa_hashmap_get(u->device_infos, s->source))); + restart(d); + } + + return PA_HOOK_OK; +} + +static pa_hook_result_t source_output_move_post_hook_cb(pa_core *c, pa_source_output *s, struct userdata *u) { + struct device_info *d; + pa_assert(c); + pa_source_output_assert_ref(s); + pa_assert(u); + + pa_assert_se((d = pa_hashmap_get(u->device_infos, s->source))); + resume(d); + + return PA_HOOK_OK; +} + static pa_hook_result_t device_new_hook_cb(pa_core *c, pa_object *o, struct userdata *u) { struct device_info *d; @@ -276,8 +353,8 @@ int pa__init(pa_module*m) { u->sink_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_NEW_POST], (pa_hook_cb_t) device_new_hook_cb, u); u->source_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_NEW_POST], (pa_hook_cb_t) device_new_hook_cb, u); - u->sink_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_DISCONNECT], (pa_hook_cb_t) device_disconnect_hook_cb, u); - u->source_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_DISCONNECT], (pa_hook_cb_t) device_disconnect_hook_cb, u); + u->sink_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_DISCONNECT_POST], (pa_hook_cb_t) device_disconnect_hook_cb, u); + u->source_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_DISCONNECT_POST], (pa_hook_cb_t) device_disconnect_hook_cb, u); u->sink_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], (pa_hook_cb_t) device_state_changed_hook_cb, u); u->source_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], (pa_hook_cb_t) device_state_changed_hook_cb, u); @@ -285,6 +362,11 @@ int pa__init(pa_module*m) { u->source_output_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PUT], (pa_hook_cb_t) source_output_new_hook_cb, u); u->sink_input_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_DISCONNECT_POST], (pa_hook_cb_t) sink_input_disconnect_hook_cb, u); u->source_output_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_DISCONNECT_POST], (pa_hook_cb_t) source_output_disconnect_hook_cb, u); + u->sink_input_move_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE], (pa_hook_cb_t) sink_input_move_hook_cb, u); + u->source_output_move_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE], (pa_hook_cb_t) source_output_move_hook_cb, u); + u->sink_input_move_post_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_POST], (pa_hook_cb_t) sink_input_move_post_hook_cb, u); + u->source_output_move_post_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_POST], (pa_hook_cb_t) source_output_move_post_hook_cb, u); + pa_modargs_free(ma); return 0; @@ -326,11 +408,19 @@ void pa__done(pa_module*m) { pa_hook_slot_free(u->sink_input_new_slot); if (u->sink_input_disconnect_slot) pa_hook_slot_free(u->sink_input_disconnect_slot); + if (u->sink_input_move_slot) + pa_hook_slot_free(u->sink_input_move_slot); + if (u->sink_input_move_post_slot) + pa_hook_slot_free(u->sink_input_move_post_slot); if (u->source_output_new_slot) pa_hook_slot_free(u->source_output_new_slot); if (u->source_output_disconnect_slot) pa_hook_slot_free(u->source_output_disconnect_slot); + if (u->source_output_move_slot) + pa_hook_slot_free(u->source_output_move_slot); + if (u->source_output_move_post_slot) + pa_hook_slot_free(u->source_output_move_post_slot); while ((d = pa_hashmap_steal_first(u->device_infos))) device_info_free(d); -- cgit From 06f2799d8f695fc4545a5027980518be72c18788 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 20:31:34 +0000 Subject: minor modernizations git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1644 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-volume-restore.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/modules/module-volume-restore.c b/src/modules/module-volume-restore.c index 0041760b..8c916c39 100644 --- a/src/modules/module-volume-restore.c +++ b/src/modules/module-volume-restore.c @@ -26,7 +26,6 @@ #endif #include -#include #include #include #include @@ -85,8 +84,8 @@ static pa_cvolume* parse_volume(const char *s, pa_cvolume *v) { long k; unsigned i; - assert(s); - assert(v); + pa_assert(s); + pa_assert(v); if (!isdigit(*s)) return NULL; @@ -170,7 +169,7 @@ static int load_rules(struct userdata *u) { continue; } - assert(ln == buf_source); + pa_assert(ln == buf_source); if (buf_volume[0]) { if (!parse_volume(buf_volume, &v)) { @@ -297,8 +296,8 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 struct rule *r; char *name; - assert(c); - assert(u); + pa_assert(c); + pa_assert(u); if (t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW) && t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE) && @@ -313,7 +312,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 if (!si->client || !(name = client_name(si->client))) return; } else { - assert((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT); + pa_assert((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT); if (!(so = pa_idxset_get_by_index(c->source_outputs, idx))) return; @@ -341,7 +340,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 u->modified = 1; } } else { - assert(so); + pa_assert(so); if (!r->source || strcmp(so->source->name, r->source) != 0) { pa_log_info("Saving source for <%s>", r->name); @@ -363,7 +362,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 r->sink = pa_xstrdup(si->sink->name); r->source = NULL; } else { - assert(so); + pa_assert(so); r->volume_is_set = 0; r->sink = NULL; r->source = pa_xstrdup(so->source->name); @@ -378,7 +377,7 @@ static pa_hook_result_t sink_input_hook_callback(pa_core *c, pa_sink_input_new_d struct rule *r; char *name; - assert(data); + pa_assert(data); if (!data->client || !(name = client_name(data->client))) return PA_HOOK_OK; @@ -405,7 +404,7 @@ static pa_hook_result_t source_output_hook_callback(pa_core *c, pa_source_output struct rule *r; char *name; - assert(data); + pa_assert(data); if (!data->client || !(name = client_name(data->client))) return PA_HOOK_OK; @@ -424,7 +423,7 @@ int pa__init(pa_module*m) { pa_modargs *ma = NULL; struct userdata *u; - assert(m); + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments"); @@ -460,7 +459,7 @@ fail: static void free_func(void *p, void *userdata) { struct rule *r = p; - assert(r); + pa_assert(r); pa_xfree(r->name); pa_xfree(r->sink); @@ -471,7 +470,7 @@ static void free_func(void *p, void *userdata) { void pa__done(pa_module*m) { struct userdata* u; - assert(m); + pa_assert(m); if (!(u = m->userdata)) return; -- cgit From 45e495499e5dede1d7c0e8b18b4b2ef3df215d3e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 23:43:39 +0000 Subject: fix latency reporting for oss and alsa modules git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1645 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 13 +++++++------ src/modules/module-alsa-source.c | 13 +++++++------ src/modules/module-oss.c | 2 +- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 5491aac5..cf999a92 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -217,17 +217,18 @@ static int mmap_write(struct userdata *u) { static pa_usec_t sink_get_latency(struct userdata *u) { pa_usec_t r = 0; + snd_pcm_status_t *status; snd_pcm_sframes_t frames = 0; int err; + + snd_pcm_status_alloca(&status); pa_assert(u); - snd_pcm_avail_update(u->pcm_handle); - - if ((err = snd_pcm_delay(u->pcm_handle, &frames)) < 0) { + if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) pa_log("Failed to get delay: %s", snd_strerror(err)); - return 0; - } + else + frames = snd_pcm_status_get_delay(status); if (frames > 0) r = pa_bytes_to_usec(frames * u->frame_size, &u->sink->sample_spec); @@ -356,7 +357,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse *((pa_usec_t*) data) = r; - break; + return 0; } case PA_SINK_MESSAGE_SET_STATE: diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index b6471850..8ff074d6 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -209,17 +209,18 @@ static int mmap_read(struct userdata *u) { static pa_usec_t source_get_latency(struct userdata *u) { pa_usec_t r = 0; + snd_pcm_status_t *status; snd_pcm_sframes_t frames = 0; int err; + + snd_pcm_status_alloca(&status); pa_assert(u); - snd_pcm_avail_update(u->pcm_handle); - - if ((err = snd_pcm_delay(u->pcm_handle, &frames)) < 0) { + if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) pa_log("Failed to get delay: %s", snd_strerror(err)); - return 0; - } + else + frames = snd_pcm_status_get_delay(status); if (frames > 0) r = pa_bytes_to_usec(frames * u->frame_size, &u->source->sample_spec); @@ -345,7 +346,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off *((pa_usec_t*) data) = r; - break; + return 0; } case PA_SOURCE_MESSAGE_SET_STATE: diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 1a366633..d9b5b963 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -597,7 +597,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse *((pa_usec_t*) data) = r; - break; + return 0; } case PA_SINK_MESSAGE_SET_STATE: -- cgit From 14d93fce4467b6fe4cfab8424e29a97521590c72 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 23:44:00 +0000 Subject: minor cleanup git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1646 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/play-memchunk.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pulsecore/play-memchunk.c b/src/pulsecore/play-memchunk.c index d2d71804..f2925d1b 100644 --- a/src/pulsecore/play-memchunk.c +++ b/src/pulsecore/play-memchunk.c @@ -63,7 +63,6 @@ static void memchunk_stream_unlink(memchunk_stream *u) { pa_sink_input_unref(u->sink_input); u->sink_input = NULL; - /* Make sure we don't decrease the ref count twice. */ memchunk_stream_unref(u); } @@ -160,7 +159,6 @@ int pa_play_memchunk( u->parent.parent.free = memchunk_stream_free; u->parent.process_msg = memchunk_stream_process_msg; u->core = sink->core; - u->sink_input = NULL; u->memchunk = *chunk; pa_memblock_ref(u->memchunk.memblock); -- cgit From 3d81dde3355db7f5f61a06670dfd6610b723adad Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 23:45:13 +0000 Subject: modernize pa_play_memblockq() and add a new function pa_memblockq_sink_input_new() which allows creation of memblockq streams without activating them immediately git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1647 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/play-memblockq.c | 196 ++++++++++++++++++++++++++++++++--------- src/pulsecore/play-memblockq.h | 10 +++ 2 files changed, 163 insertions(+), 43 deletions(-) diff --git a/src/pulsecore/play-memblockq.c b/src/pulsecore/play-memblockq.c index 51ea22e8..0d7efc5c 100644 --- a/src/pulsecore/play-memblockq.c +++ b/src/pulsecore/play-memblockq.c @@ -26,7 +26,6 @@ #endif #include -#include #include #include @@ -34,53 +33,106 @@ #include #include +#include #include "play-memblockq.h" -static void sink_input_kill_cb(pa_sink_input *i) { - pa_memblockq *q; - assert(i); - assert(i->userdata); +typedef struct memblockq_stream { + pa_msgobject parent; + pa_core *core; + pa_sink_input *sink_input; + pa_memblockq *memblockq; +} memblockq_stream; + +enum { + MEMBLOCKQ_STREAM_MESSAGE_UNLINK, +}; + +PA_DECLARE_CLASS(memblockq_stream); +#define MEMBLOCKQ_STREAM(o) (memblockq_stream_cast(o)) +static PA_DEFINE_CHECK_TYPE(memblockq_stream, pa_msgobject); + +static void memblockq_stream_unlink(memblockq_stream *u) { + pa_assert(u); + + if (!u->sink_input) + return; + + pa_sink_input_disconnect(u->sink_input); + + pa_sink_input_unref(u->sink_input); + u->sink_input = NULL; + + memblockq_stream_unref(u); +} - q = i->userdata; +static void memblockq_stream_free(pa_object *o) { + memblockq_stream *u = MEMBLOCKQ_STREAM(o); + pa_assert(u); - pa_sink_input_disconnect(i); - pa_sink_input_unref(i); + memblockq_stream_unlink(u); + + if (u->memblockq) + pa_memblockq_free(u->memblockq); - pa_memblockq_free(q); + pa_xfree(u); } -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { - pa_memblockq *q; - assert(i); - assert(chunk); - assert(i->userdata); - - q = i->userdata; +static int memblockq_stream_process_msg(pa_msgobject *o, int code, void*userdata, int64_t offset, pa_memchunk *chunk) { + memblockq_stream *u = MEMBLOCKQ_STREAM(o); + memblockq_stream_assert_ref(u); + + switch (code) { + case MEMBLOCKQ_STREAM_MESSAGE_UNLINK: + memblockq_stream_unlink(u); + break; + } - return pa_memblockq_peek(q, chunk); + return 0; } -static void si_kill_cb(PA_GCC_UNUSED pa_mainloop_api *m, void *i) { - sink_input_kill_cb(i); +static void sink_input_kill_cb(pa_sink_input *i) { + pa_sink_input_assert_ref(i); + + memblockq_stream_unlink(MEMBLOCKQ_STREAM(i->userdata)); } -static void sink_input_drop_cb(pa_sink_input *i, size_t length) { - pa_memblockq *q; +static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { + memblockq_stream *u; - assert(i); - assert(length > 0); - assert( i->userdata); + pa_assert(i); + pa_assert(chunk); + u = MEMBLOCKQ_STREAM(i->userdata); + memblockq_stream_assert_ref(u); - q = i->userdata; + if (!u->memblockq) + return -1; - pa_memblockq_drop(q, length); + if (pa_memblockq_peek(u->memblockq, chunk) < 0) { + pa_memblockq_free(u->memblockq); + u->memblockq = NULL; + pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(u), MEMBLOCKQ_STREAM_MESSAGE_UNLINK, NULL, 0, NULL, NULL); + return -1; + } - if (pa_memblockq_get_length(q) <= 0) - pa_mainloop_api_once(i->sink->core->mainloop, si_kill_cb, i); + return 0; } -int pa_play_memblockq( +static void sink_input_drop_cb(pa_sink_input *i, size_t length) { + memblockq_stream *u; + + pa_assert(i); + pa_assert(length > 0); + u = MEMBLOCKQ_STREAM(i->userdata); + memblockq_stream_assert_ref(u); + + if (!u->memblockq) + return; + + pa_memblockq_drop(u->memblockq, length); +} + +pa_sink_input* pa_memblockq_sink_input_new( pa_sink *sink, const char *name, const pa_sample_spec *ss, @@ -88,39 +140,97 @@ int pa_play_memblockq( pa_memblockq *q, pa_cvolume *volume) { - pa_sink_input *si; + memblockq_stream *u = NULL; pa_sink_input_new_data data; - assert(sink); - assert(ss); - assert(q); + pa_assert(sink); + pa_assert(ss); - if (pa_memblockq_get_length(q) <= 0) { + /* We allow creating this stream with no q set, so that it can be + * filled in later */ + + if (q && pa_memblockq_get_length(q) <= 0) { pa_memblockq_free(q); - return 0; + return NULL; } if (volume && pa_cvolume_is_muted(volume)) { pa_memblockq_free(q); - return 0; + return NULL; } + u = pa_msgobject_new(memblockq_stream); + u->parent.parent.free = memblockq_stream_free; + u->parent.process_msg = memblockq_stream_process_msg; + u->core = sink->core; + u->sink_input = NULL; + u->memblockq = q; + pa_sink_input_new_data_init(&data); data.sink = sink; data.name = name; data.driver = __FILE__; - pa_sink_input_new_data_set_channel_map(&data, map); pa_sink_input_new_data_set_sample_spec(&data, ss); + pa_sink_input_new_data_set_channel_map(&data, map); pa_sink_input_new_data_set_volume(&data, volume); - if (!(si = pa_sink_input_new(sink->core, &data, 0))) - return -1; + if (!(u->sink_input = pa_sink_input_new(sink->core, &data, 0))) + goto fail; + + u->sink_input->peek = sink_input_peek_cb; + u->sink_input->drop = sink_input_drop_cb; + u->sink_input->kill = sink_input_kill_cb; + u->sink_input->userdata = u; + + if (q) + pa_memblockq_prebuf_disable(q); + + /* The reference to u is dangling here, because we want + * to keep this stream around until it is fully played. */ + + /* This sink input is not "put" yet, i.e. pa_sink_input_put() has + * not been called! */ + + return pa_sink_input_ref(u->sink_input); + +fail: + if (u) + memblockq_stream_unref(u); + + return NULL; +} - si->peek = sink_input_peek_cb; - si->drop = sink_input_drop_cb; - si->kill = sink_input_kill_cb; +int pa_play_memblockq( + pa_sink *sink, + const char *name, + const pa_sample_spec *ss, + const pa_channel_map *map, + pa_memblockq *q, + pa_cvolume *volume) { + + pa_sink_input *i; + + pa_assert(sink); + pa_assert(ss); + pa_assert(q); + + if (!(i = pa_memblockq_sink_input_new(sink, name, ss, map, q, volume))) + return -1; - si->userdata = q; + pa_sink_input_put(i); + pa_sink_input_unref(i); return 0; } + +void pa_memblockq_sink_input_set_queue(pa_sink_input *i, pa_memblockq *q) { + memblockq_stream *u; + + pa_sink_input_assert_ref(i); + u = MEMBLOCKQ_STREAM(i->userdata); + memblockq_stream_assert_ref(u); + + if (u->memblockq) + pa_memblockq_free(u->memblockq); + u->memblockq = q; +} diff --git a/src/pulsecore/play-memblockq.h b/src/pulsecore/play-memblockq.h index 8248e859..d8790316 100644 --- a/src/pulsecore/play-memblockq.h +++ b/src/pulsecore/play-memblockq.h @@ -27,6 +27,16 @@ #include #include +pa_sink_input* pa_memblockq_sink_input_new( + pa_sink *sink, + const char *name, + const pa_sample_spec *ss, + const pa_channel_map *map, + pa_memblockq *q, + pa_cvolume *volume); + +void pa_memblockq_sink_input_set_queue(pa_sink_input *i, pa_memblockq *q); + int pa_play_memblockq( pa_sink *sink, const char *name, -- cgit From 79a586db1775bdadc5f1716f3e398c6c45237af1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 23:45:50 +0000 Subject: add comments describing the context these functions are called from git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1648 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/source-output.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 34bb9de5..ce81fccb 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -258,6 +258,7 @@ pa_usec_t pa_source_output_get_latency(pa_source_output *o) { return r; } +/* Called from thread context */ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) { pa_memchunk rchunk; @@ -396,6 +397,7 @@ int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { return 0; } +/* Called from thread context */ int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, int64_t offset, pa_memchunk* chunk) { pa_source_output *o = PA_SOURCE_OUTPUT(mo); -- cgit From 1cecd46d9573d7bbe1a4e53b469b232a86e47b2a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 11 Aug 2007 23:46:51 +0000 Subject: Resurrect ability to move streams between sinks git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1649 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink-input.c | 334 ++++++++++++++++++++++----------------------- src/pulsecore/sink-input.h | 9 +- src/pulsecore/sink.c | 67 +++++++++ src/pulsecore/sink.h | 1 + 4 files changed, 239 insertions(+), 172 deletions(-) diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 77b95feb..5fd1da47 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -202,7 +202,7 @@ pa_sink_input* pa_sink_input_new( pa_atomic_store(&i->thread_info.drained, 1); i->thread_info.sample_spec = i->sample_spec; i->thread_info.silence_memblock = NULL; -/* i->thread_info.move_silence = 0; */ + i->thread_info.move_silence = 0; pa_memchunk_reset(&i->thread_info.resampled_chunk); i->thread_info.resampler = resampler; i->thread_info.volume = i->volume; @@ -336,6 +336,7 @@ pa_usec_t pa_sink_input_get_latency(pa_sink_input *i) { return r; } +/* Called from thread context */ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) { int ret = -1; int do_volume_adj_here; @@ -350,24 +351,24 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) pa_assert(i->thread_info.state == PA_SINK_INPUT_RUNNING || i->thread_info.state == PA_SINK_INPUT_DRAINED); -/* if (i->thread_info.move_silence > 0) { */ -/* size_t l; */ + if (i->thread_info.move_silence > 0) { + size_t l; -/* /\* We have just been moved and shall play some silence for a */ -/* * while until the old sink has drained its playback buffer *\/ */ + /* We have just been moved and shall play some silence for a + * while until the old sink has drained its playback buffer */ -/* if (!i->thread_info.silence_memblock) */ -/* i->thread_info.silence_memblock = pa_silence_memblock_new(i->sink->core->mempool, &i->sink->sample_spec, SILENCE_BUFFER_LENGTH); */ + if (!i->thread_info.silence_memblock) + i->thread_info.silence_memblock = pa_silence_memblock_new(i->sink->core->mempool, &i->sink->sample_spec, SILENCE_BUFFER_LENGTH); -/* chunk->memblock = pa_memblock_ref(i->thread_info.silence_memblock); */ -/* chunk->index = 0; */ -/* l = pa_memblock_get_length(chunk->memblock); */ -/* chunk->length = i->move_silence < l ? i->move_silence : l; */ + chunk->memblock = pa_memblock_ref(i->thread_info.silence_memblock); + chunk->index = 0; + l = pa_memblock_get_length(chunk->memblock); + chunk->length = i->thread_info.move_silence < l ? i->thread_info.move_silence : l; -/* ret = 0; */ -/* do_volume_adj_here = 1; */ -/* goto finish; */ -/* } */ + ret = 0; + do_volume_adj_here = 1; + goto finish; + } if (!i->thread_info.resampler) { do_volume_adj_here = 0; /* FIXME??? */ @@ -437,36 +438,25 @@ finish: return ret; } +/* Called from thread context */ void pa_sink_input_drop(pa_sink_input *i, size_t length) { pa_sink_input_assert_ref(i); pa_assert(length > 0); -/* if (i->move_silence > 0) { */ - -/* if (chunk) { */ -/* size_t l; */ - -/* l = pa_memblock_get_length(i->silence_memblock); */ - -/* if (chunk->memblock != i->silence_memblock || */ -/* chunk->index != 0 || */ -/* (chunk->memblock && (chunk->length != (l < i->move_silence ? l : i->move_silence)))) */ -/* return; */ + if (i->thread_info.move_silence > 0) { -/* } */ + pa_assert(i->thread_info.move_silence >= length); -/* pa_assert(i->move_silence >= length); */ + i->thread_info.move_silence -= length; -/* i->move_silence -= length; */ - -/* if (i->move_silence <= 0) { */ -/* pa_assert(i->silence_memblock); */ -/* pa_memblock_unref(i->silence_memblock); */ -/* i->silence_memblock = NULL; */ -/* } */ + if (i->thread_info.move_silence <= 0) { + pa_assert(i->thread_info.silence_memblock); + pa_memblock_unref(i->thread_info.silence_memblock); + i->thread_info.silence_memblock = NULL; + } -/* return; */ -/* } */ + return; + } if (i->thread_info.resampled_chunk.memblock) { size_t l = length; @@ -509,11 +499,14 @@ void pa_sink_input_drop(pa_sink_input *i, size_t length) { length -= l; } else { + size_t l; + /* Hmmm, peeking failed, so let's at least drop * the right amount of data */ - - if (i->drop) - i->drop(i, pa_resampler_request(i->thread_info.resampler, length)); + + if ((l = pa_resampler_request(i->thread_info.resampler, length)) > 0) + if (i->drop) + i->drop(i, l); break; } @@ -609,166 +602,166 @@ pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i) { } int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { -/* pa_resampler *new_resampler = NULL; */ -/* pa_memblockq *buffer = NULL; */ -/* pa_sink *origin; */ + pa_resampler *new_resampler = NULL; + pa_sink *origin; + pa_usec_t silence_usec = 0; + pa_sink_input_move_info info; pa_sink_input_assert_ref(i); pa_sink_assert_ref(dest); - return -1; + origin = i->sink; -/* origin = i->sink; */ + if (dest == origin) + return 0; -/* if (dest == origin) */ -/* return 0; */ + if (i->sync_next || i->sync_prev) { + pa_log_warn("Moving synchronised streams not supported."); + return -1; + } -/* if (pa_idxset_size(dest->inputs) >= PA_MAX_INPUTS_PER_SINK) { */ -/* pa_log_warn("Failed to move sink input: too many inputs per sink."); */ -/* return -1; */ -/* } */ + if (pa_idxset_size(dest->inputs) >= PA_MAX_INPUTS_PER_SINK) { + pa_log_warn("Failed to move sink input: too many inputs per sink."); + return -1; + } -/* if (i->resampler && */ -/* pa_sample_spec_equal(&origin->sample_spec, &dest->sample_spec) && */ -/* pa_channel_map_equal(&origin->channel_map, &dest->channel_map)) */ + if (i->thread_info.resampler && + pa_sample_spec_equal(&origin->sample_spec, &dest->sample_spec) && + pa_channel_map_equal(&origin->channel_map, &dest->channel_map)) -/* /\* Try to reuse the old resampler if possible *\/ */ -/* new_resampler = i->resampler; */ + /* Try to reuse the old resampler if possible */ + new_resampler = i->thread_info.resampler; -/* else if ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) || */ -/* !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec) || */ -/* !pa_channel_map_equal(&i->channel_map, &dest->channel_map)) { */ + else if ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) || + !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec) || + !pa_channel_map_equal(&i->channel_map, &dest->channel_map)) { -/* /\* Okey, we need a new resampler for the new sink *\/ */ + /* Okey, we need a new resampler for the new sink */ -/* if (!(new_resampler = pa_resampler_new( */ -/* dest->core->mempool, */ -/* &i->sample_spec, &i->channel_map, */ -/* &dest->sample_spec, &dest->channel_map, */ -/* i->resample_method))) { */ -/* pa_log_warn("Unsupported resampling operation."); */ -/* return -1; */ -/* } */ -/* } */ + if (!(new_resampler = pa_resampler_new( + dest->core->mempool, + &i->sample_spec, &i->channel_map, + &dest->sample_spec, &dest->channel_map, + i->resample_method))) { + pa_log_warn("Unsupported resampling operation."); + return -1; + } + } -/* if (!immediately) { */ -/* pa_usec_t old_latency, new_latency; */ -/* pa_usec_t silence_usec = 0; */ + pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE], i); -/* buffer = pa_memblockq_new(0, MOVE_BUFFER_LENGTH, 0, pa_frame_size(&origin->sample_spec), 0, 0, NULL); */ - -/* /\* Let's do a little bit of Voodoo for compensating latency */ -/* * differences *\/ */ + memset(&info, 0, sizeof(info)); + info.sink_input = i; + + if (!immediately) { + pa_usec_t old_latency, new_latency; -/* old_latency = pa_sink_get_latency(origin); */ -/* new_latency = pa_sink_get_latency(dest); */ + /* Let's do a little bit of Voodoo for compensating latency + * differences. We assume that the accuracy for our + * estimations is still good enough, even though we do these + * operations non-atomic. */ -/* /\* The already resampled data should go to the old sink *\/ */ - -/* if (old_latency >= new_latency) { */ + old_latency = pa_sink_get_latency(origin); + new_latency = pa_sink_get_latency(dest); -/* /\* The latency of the old sink is larger than the latency */ -/* * of the new sink. Therefore to compensate for the */ -/* * difference we to play silence on the new one for a */ -/* * while *\/ */ + /* The already resampled data should go to the old sink */ -/* silence_usec = old_latency - new_latency; */ + if (old_latency >= new_latency) { -/* } else { */ -/* size_t l; */ -/* int volume_is_norm; */ + /* The latency of the old sink is larger than the latency + * of the new sink. Therefore to compensate for the + * difference we to play silence on the new one for a + * while */ -/* /\* The latency of new sink is larger than the latency of */ -/* * the old sink. Therefore we have to precompute a little */ -/* * and make sure that this is still played on the old */ -/* * sink, until we can play the first sample on the new */ -/* * sink.*\/ */ + silence_usec = old_latency - new_latency; -/* l = pa_usec_to_bytes(new_latency - old_latency, &origin->sample_spec); */ + } else { -/* volume_is_norm = pa_cvolume_is_norm(&i->volume); */ + /* The latency of new sink is larger than the latency of + * the old sink. Therefore we have to precompute a little + * and make sure that this is still played on the old + * sink, until we can play the first sample on the new + * sink.*/ -/* while (l > 0) { */ -/* pa_memchunk chunk; */ -/* pa_cvolume volume; */ -/* size_t n; */ + info.buffer_bytes = pa_usec_to_bytes(new_latency - old_latency, &origin->sample_spec); + } -/* if (pa_sink_input_peek(i, &chunk, &volume) < 0) */ -/* break; */ + /* Okey, let's move it */ + + if (info.buffer_bytes > 0) { + + info.ghost_sink_input = pa_memblockq_sink_input_new( + origin, + "Ghost Stream", + &origin->sample_spec, + &origin->channel_map, + NULL, + NULL); + + info.buffer = pa_memblockq_new(0, MOVE_BUFFER_LENGTH, 0, pa_frame_size(&origin->sample_spec), 0, 0, NULL); + } + } -/* n = chunk.length > l ? l : chunk.length; */ -/* pa_sink_input_drop(i, &chunk, n); */ -/* chunk.length = n; */ + pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT_AND_BUFFER, &info, 0, NULL); -/* if (!volume_is_norm) { */ -/* pa_memchunk_make_writable(&chunk, 0); */ -/* pa_volume_memchunk(&chunk, &origin->sample_spec, &volume); */ -/* } */ + if (info.ghost_sink_input) { + /* Basically, do what pa_sink_input_put() does ...*/ + pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, info.ghost_sink_input->index); + pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], info.ghost_sink_input); + pa_sink_input_unref(info.ghost_sink_input); + } + + pa_idxset_remove_by_data(origin->inputs, i, NULL); + pa_idxset_put(dest->inputs, i, NULL); + i->sink = dest; + + /* Replace resampler */ + if (new_resampler != i->thread_info.resampler) { + if (i->thread_info.resampler) + pa_resampler_free(i->thread_info.resampler); + i->thread_info.resampler = new_resampler; + + /* if the resampler changed, the silence memblock is + * probably invalid now, too */ + if (i->thread_info.silence_memblock) { + pa_memblock_unref(i->thread_info.silence_memblock); + i->thread_info.silence_memblock = NULL; + } + } -/* if (pa_memblockq_push(buffer, &chunk) < 0) { */ -/* pa_memblock_unref(chunk.memblock); */ -/* break; */ -/* } */ + /* Dump already resampled data */ + if (i->thread_info.resampled_chunk.memblock) { + /* Hmm, this data has already been added to the ghost queue, presumably, hence let's sleep a little bit longer */ + silence_usec += pa_bytes_to_usec(i->thread_info.resampled_chunk.length, &origin->sample_spec); + pa_memblock_unref(i->thread_info.resampled_chunk.memblock); + pa_memchunk_reset(&i->thread_info.resampled_chunk); + } -/* pa_memblock_unref(chunk.memblock); */ -/* l -= n; */ -/* } */ -/* } */ + /* Calculate the new sleeping time */ + if (immediately) + i->thread_info.move_silence = 0; + else + i->thread_info.move_silence = pa_usec_to_bytes( + pa_bytes_to_usec(i->thread_info.move_silence, &i->sample_spec) + + silence_usec, + &i->sample_spec); -/* if (i->resampled_chunk.memblock) { */ + pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, i, 0, NULL); + + pa_sink_update_status(origin); + pa_sink_update_status(dest); -/* /\* There is still some data left in the already resampled */ -/* * memory block. Hence, let's output it on the old sink */ -/* * and sleep so long on the new sink *\/ */ - -/* pa_memblockq_push(buffer, &i->resampled_chunk); */ -/* silence_usec += pa_bytes_to_usec(i->resampled_chunk.length, &origin->sample_spec); */ -/* } */ - -/* /\* Calculate the new sleeping time *\/ */ -/* i->move_silence = pa_usec_to_bytes( */ -/* pa_bytes_to_usec(i->move_silence, &i->sample_spec) + */ -/* silence_usec, */ -/* &i->sample_spec); */ -/* } */ - -/* /\* Okey, let's move it *\/ */ -/* pa_idxset_remove_by_data(origin->inputs, i, NULL); */ -/* pa_idxset_put(dest->inputs, i, NULL); */ -/* i->sink = dest; */ - -/* /\* Replace resampler *\/ */ -/* if (new_resampler != i->resampler) { */ -/* if (i->resampler) */ -/* pa_resampler_free(i->resampler); */ -/* i->resampler = new_resampler; */ - -/* /\* if the resampler changed, the silence memblock is */ -/* * probably invalid now, too *\/ */ -/* if (i->silence_memblock) { */ -/* pa_memblock_unref(i->silence_memblock); */ -/* i->silence_memblock = NULL; */ -/* } */ -/* } */ + pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_POST], i); + + pa_log_debug("Successfully moved sink input %i from %s to %s.", i->index, origin->name, dest->name); + + /* Notify everyone */ + pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); -/* /\* Dump already resampled data *\/ */ -/* if (i->resampled_chunk.memblock) { */ -/* pa_memblock_unref(i->resampled_chunk.memblock); */ -/* i->resampled_chunk.memblock = NULL; */ -/* i->resampled_chunk.index = i->resampled_chunk.length = 0; */ -/* } */ - -/* /\* Notify everyone *\/ */ -/* pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); */ -/* pa_sink_notify(i->sink); */ - -/* /\* Ok, now let's feed the precomputed buffer to the old sink *\/ */ -/* if (buffer) */ -/* pa_play_memblockq(origin, "Ghost Stream", &origin->sample_spec, &origin->channel_map, buffer, NULL); */ - -/* return 0; */ + return 0; } +/* Called from thread context */ int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) { pa_sink_input *i = PA_SINK_INPUT(o); @@ -789,19 +782,18 @@ int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t if (i->thread_info.resampled_chunk.memblock) *r += pa_bytes_to_usec(i->thread_info.resampled_chunk.length, &i->sink->sample_spec); -/* if (i->move_silence) */ -/* r += pa_bytes_to_usec(i->move_silence, &i->sink->sample_spec); */ + if (i->thread_info.move_silence) + *r += pa_bytes_to_usec(i->thread_info.move_silence, &i->sink->sample_spec); return 0; } - case PA_SINK_INPUT_MESSAGE_SET_RATE: { + case PA_SINK_INPUT_MESSAGE_SET_RATE: i->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata); pa_resampler_set_input_rate(i->thread_info.resampler, PA_PTR_TO_UINT(userdata)); return 0; - } case PA_SINK_INPUT_MESSAGE_SET_STATE: { pa_sink_input *ssync; diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index 5a48418c..d728d462 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -95,7 +95,7 @@ struct pa_sink_input { /* Some silence to play before the actual data. This is used to * compensate for latency differences when moving a sink input * "hot" between sinks. */ - /* size_t move_silence; */ + size_t move_silence; pa_memblock *silence_memblock; /* may be NULL */ pa_sink_input *sync_prev, *sync_next; @@ -188,4 +188,11 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) void pa_sink_input_drop(pa_sink_input *i, size_t length); int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk); +typedef struct pa_sink_input_move_info { + pa_sink_input *sink_input; + pa_sink_input *ghost_sink_input; + pa_memblockq *buffer; + size_t buffer_bytes; +} pa_sink_input_move_info; + #endif diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 929542cc..df08ff6e 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "sink.h" @@ -721,6 +722,72 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse return 0; } + case PA_SINK_MESSAGE_REMOVE_INPUT_AND_BUFFER: { + pa_sink_input_move_info *info = userdata; + int volume_is_norm; + + /* We don't support moving synchronized streams. */ + pa_assert(!info->sink_input->sync_prev); + pa_assert(!info->sink_input->sync_next); + pa_assert(!info->sink_input->thread_info.sync_next); + pa_assert(!info->sink_input->thread_info.sync_prev); + + if (info->ghost_sink_input) { + pa_assert(info->buffer_bytes > 0); + pa_assert(info->buffer); + + volume_is_norm = pa_cvolume_is_norm(&info->sink_input->thread_info.volume); + + pa_log_debug("Buffering %u bytes ...", info->buffer_bytes); + + while (info->buffer_bytes > 0) { + pa_memchunk memchunk; + pa_cvolume volume; + size_t n; + + if (pa_sink_input_peek(info->sink_input, &memchunk, &volume) < 0) + break; + + n = memchunk.length > info->buffer_bytes ? info->buffer_bytes : memchunk.length; + pa_sink_input_drop(info->sink_input, n); + memchunk.length = n; + + if (!volume_is_norm) { + pa_memchunk_make_writable(&memchunk, 0); + pa_volume_memchunk(&memchunk, &s->sample_spec, &volume); + } + + if (pa_memblockq_push(info->buffer, &memchunk) < 0) { + pa_memblock_unref(memchunk.memblock); + break; + } + + pa_memblock_unref(memchunk.memblock); + info->buffer_bytes -= n; + } + + /* Add the remaining already resampled chunk to the buffer */ + if (info->sink_input->thread_info.resampled_chunk.memblock) + pa_memblockq_push(info->buffer, &info->sink_input->thread_info.resampled_chunk); + + pa_memblockq_sink_input_set_queue(info->ghost_sink_input, info->buffer); + + pa_log_debug("Buffered %u bytes ...", pa_memblockq_get_length(info->buffer)); + } + + /* Let's remove the sink input ...*/ + if (pa_hashmap_remove(s->thread_info.inputs, PA_UINT32_TO_PTR(info->sink_input->index))) + pa_sink_input_unref(info->sink_input); + + /* .. and add the ghost sink input instead */ + if (info->ghost_sink_input) { + pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(info->ghost_sink_input->index), pa_sink_input_ref(info->ghost_sink_input)); + info->ghost_sink_input->thread_info.sync_prev = info->ghost_sink_input->thread_info.sync_next = NULL; + } + + return 0; + } + case PA_SINK_MESSAGE_SET_VOLUME: s->thread_info.soft_volume = *((pa_cvolume*) userdata); return 0; diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index 494bb6a9..8a6fa236 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -110,6 +110,7 @@ typedef enum pa_sink_message { PA_SINK_MESSAGE_GET_LATENCY, PA_SINK_MESSAGE_SET_STATE, PA_SINK_MESSAGE_PING, + PA_SINK_MESSAGE_REMOVE_INPUT_AND_BUFFER, PA_SINK_MESSAGE_MAX } pa_sink_message_t; -- cgit From b16d8e2df4ad18074195da590831cb0ca3d48dee Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 12 Aug 2007 18:40:50 +0000 Subject: bump soname and stuff for fedora pre-release git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1650 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 89fcb062..ba93bcb6 100644 --- a/configure.ac +++ b/configure.ac @@ -26,7 +26,7 @@ AC_PREREQ(2.57) m4_define(PA_MAJOR, [0]) m4_define(PA_MINOR, [9]) -m4_define(PA_MICRO, [6]) +m4_define(PA_MICRO, [7]) AC_INIT([pulseaudio], PA_MAJOR.PA_MINOR.PA_MICRO,[mzcbylcnhqvb (at) 0pointer (dot) de]) AC_CONFIG_SRCDIR([src/daemon/main.c]) @@ -39,8 +39,8 @@ AC_SUBST(PACKAGE_URL, [http://0pointer.de/lennart/projects/pulseaudio/]) AC_SUBST(PA_API_VERSION, 10) AC_SUBST(PA_PROTOCOL_VERSION, 10) -AC_SUBST(LIBPULSE_VERSION_INFO, [2:0:2]) -AC_SUBST(LIBPULSECORE_VERSION_INFO, [3:0:0]) +AC_SUBST(LIBPULSE_VERSION_INFO, [2:1:2]) +AC_SUBST(LIBPULSECORE_VERSION_INFO, [4:0:0]) AC_SUBST(LIBPULSE_SIMPLE_VERSION_INFO, [0:0:0]) AC_SUBST(LIBPULSE_BROWSE_VERSION_INFO, [1:0:1]) AC_SUBST(LIBPULSE_MAINLOOP_GLIB_VERSION_INFO, [0:2:0]) -- cgit From 55f3d34923caf6421b40ac2e901441ac8b165f5b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 12 Aug 2007 20:24:03 +0000 Subject: ship full libltdl tree in SVN to make sure we can build this crack on fedora git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1651 fefdeb5f-60dc-0310-8127-8f9354f1896f --- bootstrap.sh | 6 +- configure.ac | 7 +- libltdl/COPYING.LIB | 515 ++ libltdl/Makefile | 656 ++ libltdl/Makefile.am | 32 + libltdl/Makefile.in | 656 ++ libltdl/README | 10 + libltdl/acinclude.m4 | 7012 ++++++++++++++ libltdl/aclocal.m4 | 875 ++ libltdl/config-h.in | 195 + libltdl/config.guess | 1516 +++ libltdl/config.h | 196 + libltdl/config.log | 1609 ++++ libltdl/config.status | 1118 +++ libltdl/config.sub | 1626 ++++ libltdl/configure | 23808 ++++++++++++++++++++++++++++++++++++++++++++++++ libltdl/configure.ac | 79 + libltdl/install-sh | 519 ++ libltdl/libtool | 7895 ++++++++++++++++ libltdl/ltdl.c | 4543 +++++++++ libltdl/ltdl.h | 367 + libltdl/ltmain.sh | 6930 ++++++++++++++ libltdl/missing | 360 + libltdl/mkinstalldirs | 161 + libltdl/stamp-h1 | 1 + 25 files changed, 60686 insertions(+), 6 deletions(-) create mode 100644 libltdl/COPYING.LIB create mode 100644 libltdl/Makefile create mode 100644 libltdl/Makefile.am create mode 100644 libltdl/Makefile.in create mode 100644 libltdl/README create mode 100644 libltdl/acinclude.m4 create mode 100644 libltdl/aclocal.m4 create mode 100644 libltdl/config-h.in create mode 100755 libltdl/config.guess create mode 100644 libltdl/config.h create mode 100644 libltdl/config.log create mode 100755 libltdl/config.status create mode 100755 libltdl/config.sub create mode 100755 libltdl/configure create mode 100644 libltdl/configure.ac create mode 100755 libltdl/install-sh create mode 100755 libltdl/libtool create mode 100644 libltdl/ltdl.c create mode 100644 libltdl/ltdl.h create mode 100644 libltdl/ltmain.sh create mode 100755 libltdl/missing create mode 100755 libltdl/mkinstalldirs create mode 100644 libltdl/stamp-h1 diff --git a/bootstrap.sh b/bootstrap.sh index b85f025e..b8db16fa 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -25,10 +25,10 @@ run_versioned() { V=$(echo "$2" | sed -e 's,\.,,g') - if [ -e "`which $1$V`" ] ; then + if [ -e "`which $1$V 2> /dev/null`" ] ; then P="$1$V" else - if [ -e "`which $1-$2`" ] ; then + if [ -e "`which $1-$2 2> /dev/null`" ] ; then P="$1-$2" else P="$1" @@ -54,7 +54,7 @@ else run_versioned aclocal "$VERSION" run_versioned autoconf 2.59 -Wall run_versioned autoheader 2.59 - run_versioned automake "$VERSION" -a -c --foreign + run_versioned automake "$VERSION" --copy --foreign --add-missing if test "x$NOCONFIGURE" = "x"; then CFLAGS="-g -O0" ./configure --sysconfdir=/etc --localstatedir=/var --enable-force-preopen "$@" diff --git a/configure.ac b/configure.ac index ba93bcb6..6d7f0bec 100644 --- a/configure.ac +++ b/configure.ac @@ -110,12 +110,11 @@ fi AC_LTDL_ENABLE_INSTALL AC_LIBLTDL_INSTALLABLE -AC_SUBST(LTDLINCL) -AC_SUBST(LIBLTDL) AC_LIBTOOL_DLOPEN AC_LIBTOOL_WIN32_DLL AC_PROG_LIBTOOL -AC_CONFIG_SUBDIRS(libltdl) +AC_SUBST(LTDLINCL) +AC_SUBST(LIBLTDL) if test "x$enable_ltdl_install" = "xno" && test "x$ac_cv_lib_ltdl_lt_dlinit" = "xno" ; then AC_MSG_ERROR([[ @@ -783,6 +782,8 @@ src/pulse/version.h ]) AC_OUTPUT +AC_CONFIG_SUBDIRS(libltdl) + # ========================================================================== ENABLE_X11=no if test "x$HAVE_X11" = "x1" ; then diff --git a/libltdl/COPYING.LIB b/libltdl/COPYING.LIB new file mode 100644 index 00000000..ba2be481 --- /dev/null +++ b/libltdl/COPYING.LIB @@ -0,0 +1,515 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +^L + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +^L + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +^L + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +^L + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +^L + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +^L + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +^L + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +^L + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper +mail. + +You should also get your employer (if you work as a programmer) or +your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James +Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/libltdl/Makefile b/libltdl/Makefile new file mode 100644 index 00000000..90fddd7b --- /dev/null +++ b/libltdl/Makefile @@ -0,0 +1,656 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + + + +pkgdatadir = $(datadir)/libltdl +pkglibdir = $(libdir)/libltdl +pkgincludedir = $(includedir)/libltdl +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = i686-pc-linux-gnu +host_triplet = i686-pc-linux-gnu +subdir = . +DIST_COMMON = README $(am__configure_deps) $(am__include_HEADERS_DIST) \ + $(am__noinst_HEADERS_DIST) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config-h.in \ + $(top_srcdir)/configure COPYING.LIB config.guess config.sub \ + install-sh ltmain.sh missing mkinstalldirs +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" +libLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) +am__DEPENDENCIES_1 = +libltdl_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libltdl_la_OBJECTS = ltdl.lo +libltdl_la_OBJECTS = $(am_libltdl_la_OBJECTS) +libltdl_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libltdl_la_LDFLAGS) $(LDFLAGS) -o $@ +am_libltdl_la_rpath = -rpath $(libdir) +libltdlc_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libltdlc_la_OBJECTS = ltdl.lo +libltdlc_la_OBJECTS = $(am_libltdlc_la_OBJECTS) +#am_libltdlc_la_rpath = +DEFAULT_INCLUDES = -I. +depcomp = +am__depfiles_maybe = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libltdl_la_SOURCES) $(libltdlc_la_SOURCES) +DIST_SOURCES = $(libltdl_la_SOURCES) $(libltdlc_la_SOURCES) +am__include_HEADERS_DIST = ltdl.h +includeHEADERS_INSTALL = $(INSTALL_HEADER) +am__noinst_HEADERS_DIST = ltdl.h +HEADERS = $(include_HEADERS) $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = ${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run aclocal-1.10 +AMTAR = ${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run tar +AR = ar +AS = as +AUTOCONF = ${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run autoconf +AUTOHEADER = ${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run autoheader +AUTOMAKE = ${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run automake-1.10 +AWK = gawk +CC = gcc +CCDEPMODE = depmode=none +CFLAGS = -g -O2 +CPP = gcc -E +CPPFLAGS = +CXX = g++ +CXXCPP = g++ -E +CXXDEPMODE = depmode=none +CXXFLAGS = -g -O2 +CYGPATH_W = echo +DEFS = -DHAVE_CONFIG_H +DEPDIR = .deps +DLLTOOL = dlltool +ECHO = echo +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = /bin/grep -E +EXEEXT = +F77 = gfortran +FFLAGS = -g -O2 +GREP = /bin/grep +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = $(install_sh) -c -s +LDFLAGS = +LIBADD_DL = -ldl +LIBOBJS = +LIBS = +LIBTOOL = $(SHELL) $(top_builddir)/libtool +LIBTOOL_DEPS = ./ltmain.sh +LN_S = ln -s +LTLIBOBJS = +MAKEINFO = ${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run makeinfo +MKDIR_P = /bin/mkdir -p +OBJDUMP = objdump +OBJEXT = o +PACKAGE = libltdl +PACKAGE_BUGREPORT = bug-libtool@gnu.org +PACKAGE_NAME = libltdl +PACKAGE_STRING = libltdl 1.2 +PACKAGE_TARNAME = libltdl +PACKAGE_VERSION = 1.2 +PATH_SEPARATOR = : +RANLIB = ranlib +SED = /bin/sed +SET_MAKE = +SHELL = /bin/sh +STRIP = strip +VERSION = 1.2 +abs_builddir = /home/lennart/projects/pulseaudio/libltdl +abs_srcdir = /home/lennart/projects/pulseaudio/libltdl +abs_top_builddir = /home/lennart/projects/pulseaudio/libltdl +abs_top_srcdir = /home/lennart/projects/pulseaudio/libltdl +ac_ct_CC = gcc +ac_ct_CXX = g++ +ac_ct_F77 = gfortran +am__include = include +am__leading_dot = . +am__quote = +am__tar = ${AMTAR} chof - "$$tardir" +am__untar = ${AMTAR} xf - +bindir = ${exec_prefix}/bin +build = i686-pc-linux-gnu +build_alias = +build_cpu = i686 +build_os = linux-gnu +build_vendor = pc +builddir = . +datadir = ${datarootdir} +datarootdir = ${prefix}/share +docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} +dvidir = ${docdir} +exec_prefix = ${prefix} +host = i686-pc-linux-gnu +host_alias = +host_cpu = i686 +host_os = linux-gnu +host_vendor = pc +htmldir = ${docdir} +includedir = ${prefix}/include +infodir = ${datarootdir}/info +install_sh = $(SHELL) /home/lennart/projects/pulseaudio/libltdl/install-sh +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +mandir = ${datarootdir}/man +mkdir_p = /bin/mkdir -p +oldincludedir = /usr/include +pdfdir = ${docdir} +prefix = /usr/local +program_transform_name = s,x,x, +psdir = ${docdir} +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +srcdir = . +sysconfdir = ${prefix}/etc +target_alias = +top_builddir = . +top_srcdir = . +AUTOMAKE_OPTIONS = no-dependencies foreign +include_HEADERS = ltdl.h +lib_LTLIBRARIES = libltdl.la +#noinst_HEADERS = ltdl.h +#noinst_LTLIBRARIES = libltdlc.la +CLEANFILES = libltdl.la libltdlc.la +libltdl_la_SOURCES = ltdl.c +libltdl_la_LDFLAGS = -no-undefined -version-info 4:5:1 +libltdl_la_LIBADD = $(LIBADD_DL) +libltdlc_la_SOURCES = ltdl.c +libltdlc_la_LIBADD = $(LIBADD_DL) +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +am--refresh: + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \ + cd $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/config-h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config-h.in: $(am__configure_deps) + cd $(top_srcdir) && $(AUTOHEADER) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ + $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libltdl.la: $(libltdl_la_OBJECTS) $(libltdl_la_DEPENDENCIES) + $(libltdl_la_LINK) $(am_libltdl_la_rpath) $(libltdl_la_OBJECTS) $(libltdl_la_LIBADD) $(LIBS) +libltdlc.la: $(libltdlc_la_OBJECTS) $(libltdlc_la_DEPENDENCIES) + $(LINK) $(am_libltdlc_la_rpath) $(libltdlc_la_OBJECTS) $(libltdlc_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +.c.o: + $(COMPILE) -c $< + +.c.obj: + $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: + $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ + $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ + rm -f "$(DESTDIR)$(includedir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) config-h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) config-h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) config-h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) config-h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d $(distdir) || mkdir $(distdir) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r $(distdir) +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && cd $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) config.h +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + clean-noinstLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-includeHEADERS + +install-dvi: install-dvi-am + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \ + clean-generic clean-libLTLIBRARIES clean-libtool \ + clean-noinstLTLIBRARIES ctags dist dist-all dist-bzip2 \ + dist-gzip dist-shar dist-tarZ dist-zip distcheck distclean \ + distclean-compile distclean-generic distclean-hdr \ + distclean-libtool distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-includeHEADERS install-info \ + install-info-am install-libLTLIBRARIES install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-includeHEADERS \ + uninstall-libLTLIBRARIES + + +ltdl.lo: ltdl.h config.h + +$(libltdl_la_OBJECTS) $(libltdlc_la_OBJECTS): libtool +libtool: $(LIBTOOL_DEPS) + $(SHELL) ./config.status --recheck +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libltdl/Makefile.am b/libltdl/Makefile.am new file mode 100644 index 00000000..2a1e7019 --- /dev/null +++ b/libltdl/Makefile.am @@ -0,0 +1,32 @@ +## Process this file with automake to produce Makefile.in + +AUTOMAKE_OPTIONS = no-dependencies foreign + +if INSTALL_LTDL +include_HEADERS = ltdl.h +lib_LTLIBRARIES = libltdl.la +else +noinst_HEADERS = ltdl.h +endif + +if CONVENIENCE_LTDL +noinst_LTLIBRARIES = libltdlc.la +endif + +## Make sure these will be cleaned even when they're not built by +## default. +CLEANFILES = libltdl.la libltdlc.la + +libltdl_la_SOURCES = ltdl.c +libltdl_la_LDFLAGS = -no-undefined -version-info 4:5:1 +libltdl_la_LIBADD = $(LIBADD_DL) + +libltdlc_la_SOURCES = ltdl.c +libltdlc_la_LIBADD = $(LIBADD_DL) + +## Because we do not have automatic dependency tracking: +ltdl.lo: ltdl.h config.h + +$(libltdl_la_OBJECTS) $(libltdlc_la_OBJECTS): libtool +libtool: $(LIBTOOL_DEPS) + $(SHELL) ./config.status --recheck diff --git a/libltdl/Makefile.in b/libltdl/Makefile.in new file mode 100644 index 00000000..4319156e --- /dev/null +++ b/libltdl/Makefile.in @@ -0,0 +1,656 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +DIST_COMMON = README $(am__configure_deps) $(am__include_HEADERS_DIST) \ + $(am__noinst_HEADERS_DIST) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config-h.in \ + $(top_srcdir)/configure COPYING.LIB config.guess config.sub \ + install-sh ltmain.sh missing mkinstalldirs +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" +libLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) +am__DEPENDENCIES_1 = +libltdl_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libltdl_la_OBJECTS = ltdl.lo +libltdl_la_OBJECTS = $(am_libltdl_la_OBJECTS) +libltdl_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libltdl_la_LDFLAGS) $(LDFLAGS) -o $@ +@INSTALL_LTDL_TRUE@am_libltdl_la_rpath = -rpath $(libdir) +libltdlc_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libltdlc_la_OBJECTS = ltdl.lo +libltdlc_la_OBJECTS = $(am_libltdlc_la_OBJECTS) +@CONVENIENCE_LTDL_TRUE@am_libltdlc_la_rpath = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = +am__depfiles_maybe = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libltdl_la_SOURCES) $(libltdlc_la_SOURCES) +DIST_SOURCES = $(libltdl_la_SOURCES) $(libltdlc_la_SOURCES) +am__include_HEADERS_DIST = ltdl.h +includeHEADERS_INSTALL = $(INSTALL_HEADER) +am__noinst_HEADERS_DIST = ltdl.h +HEADERS = $(include_HEADERS) $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBADD_DL = @LIBADD_DL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = no-dependencies foreign +@INSTALL_LTDL_TRUE@include_HEADERS = ltdl.h +@INSTALL_LTDL_TRUE@lib_LTLIBRARIES = libltdl.la +@INSTALL_LTDL_FALSE@noinst_HEADERS = ltdl.h +@CONVENIENCE_LTDL_TRUE@noinst_LTLIBRARIES = libltdlc.la +CLEANFILES = libltdl.la libltdlc.la +libltdl_la_SOURCES = ltdl.c +libltdl_la_LDFLAGS = -no-undefined -version-info 4:5:1 +libltdl_la_LIBADD = $(LIBADD_DL) +libltdlc_la_SOURCES = ltdl.c +libltdlc_la_LIBADD = $(LIBADD_DL) +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +am--refresh: + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \ + cd $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/config-h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config-h.in: $(am__configure_deps) + cd $(top_srcdir) && $(AUTOHEADER) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ + $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libltdl.la: $(libltdl_la_OBJECTS) $(libltdl_la_DEPENDENCIES) + $(libltdl_la_LINK) $(am_libltdl_la_rpath) $(libltdl_la_OBJECTS) $(libltdl_la_LIBADD) $(LIBS) +libltdlc.la: $(libltdlc_la_OBJECTS) $(libltdlc_la_DEPENDENCIES) + $(LINK) $(am_libltdlc_la_rpath) $(libltdlc_la_OBJECTS) $(libltdlc_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +.c.o: + $(COMPILE) -c $< + +.c.obj: + $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: + $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ + $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ + rm -f "$(DESTDIR)$(includedir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) config-h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) config-h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) config-h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) config-h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d $(distdir) || mkdir $(distdir) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r $(distdir) +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && cd $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) config.h +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + clean-noinstLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-includeHEADERS + +install-dvi: install-dvi-am + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \ + clean-generic clean-libLTLIBRARIES clean-libtool \ + clean-noinstLTLIBRARIES ctags dist dist-all dist-bzip2 \ + dist-gzip dist-shar dist-tarZ dist-zip distcheck distclean \ + distclean-compile distclean-generic distclean-hdr \ + distclean-libtool distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-includeHEADERS install-info \ + install-info-am install-libLTLIBRARIES install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-includeHEADERS \ + uninstall-libLTLIBRARIES + + +ltdl.lo: ltdl.h config.h + +$(libltdl_la_OBJECTS) $(libltdlc_la_OBJECTS): libtool +libtool: $(LIBTOOL_DEPS) + $(SHELL) ./config.status --recheck +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libltdl/README b/libltdl/README new file mode 100644 index 00000000..da0a449c --- /dev/null +++ b/libltdl/README @@ -0,0 +1,10 @@ +This is GNU libltdl, a system independent dlopen wrapper for GNU libtool. + +It supports the following dlopen interfaces: +* dlopen (Solaris, Linux and various BSD flavors) +* shl_load (HP-UX) +* LoadLibrary (Win16 and Win32) +* load_add_on (BeOS) +* GNU DLD (emulates dynamic linking for static libraries) +* dyld (darwin/Mac OS X) +* libtool's dlpreopen diff --git a/libltdl/acinclude.m4 b/libltdl/acinclude.m4 new file mode 100644 index 00000000..3f1dd408 --- /dev/null +++ b/libltdl/acinclude.m4 @@ -0,0 +1,7012 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +## Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 +## Free Software Foundation, Inc. +## Originally by Gordon Matzigkeit , 1996 +## +## This file is free software; the Free Software Foundation gives +## unlimited permission to copy and/or distribute it, with or without +## modifications, as long as this notice is preserved. + +# serial 51 AC_PROG_LIBTOOL + + +# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) +# ----------------------------------------------------------- +# If this macro is not defined by Autoconf, define it here. +m4_ifdef([AC_PROVIDE_IFELSE], + [], + [m4_define([AC_PROVIDE_IFELSE], + [m4_ifdef([AC_PROVIDE_$1], + [$2], [$3])])]) + + +# AC_PROG_LIBTOOL +# --------------- +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl +dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX +dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. + AC_PROVIDE_IFELSE([AC_PROG_CXX], + [AC_LIBTOOL_CXX], + [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX + ])]) +dnl And a similar setup for Fortran 77 support + AC_PROVIDE_IFELSE([AC_PROG_F77], + [AC_LIBTOOL_F77], + [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 +])]) + +dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. +dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run +dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. + AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [ifdef([AC_PROG_GCJ], + [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([A][M_PROG_GCJ], + [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([LT_AC_PROG_GCJ], + [define([LT_AC_PROG_GCJ], + defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) +])])# AC_PROG_LIBTOOL + + +# _AC_PROG_LIBTOOL +# ---------------- +AC_DEFUN([_AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl +AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl +AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl +AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Prevent multiple expansion +define([AC_PROG_LIBTOOL], []) +])# _AC_PROG_LIBTOOL + + +# AC_LIBTOOL_SETUP +# ---------------- +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.50)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl + +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +AC_LIBTOOL_SYS_MAX_CMD_LEN +AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +AC_LIBTOOL_OBJDIR + +AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +_LT_AC_PROG_ECHO_BACKSLASH + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] + +# Same as above, but do not quote variable references. +[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'] + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" + +AC_CHECK_TOOL(AR, ar, false) +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$SED" && SED=sed +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +AC_ARG_WITH([pic], + [AC_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) +test -z "$pic_mode" && pic_mode=default + +# Use C for the default configuration in the libtool script +tagname= +AC_LIBTOOL_LANG_C_CONFIG +_LT_AC_TAGCONFIG +])# AC_LIBTOOL_SETUP + + +# _LT_AC_SYS_COMPILER +# ------------------- +AC_DEFUN([_LT_AC_SYS_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_AC_SYS_COMPILER + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +AC_DEFUN([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` +]) + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +AC_DEFUN([_LT_COMPILER_BOILERPLATE], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +AC_DEFUN([_LT_LINKER_BOILERPLATE], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* +])# _LT_LINKER_BOILERPLATE + + +# _LT_AC_SYS_LIBPATH_AIX +# ---------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_LINK_IFELSE(AC_LANG_PROGRAM,[ +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi],[]) +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +])# _LT_AC_SYS_LIBPATH_AIX + + +# _LT_AC_SHELL_INIT(ARG) +# ---------------------- +AC_DEFUN([_LT_AC_SHELL_INIT], +[ifdef([AC_DIVERSION_NOTICE], + [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +$1 +AC_DIVERT_POP +])# _LT_AC_SHELL_INIT + + +# _LT_AC_PROG_ECHO_BACKSLASH +# -------------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], +[_LT_AC_SHELL_INIT([ +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1 && unset CDPATH + +if test -z "$ECHO"; then +if test "X${echo_test_string+set}" != Xset; then +# find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string=`eval $cmd`) 2>/dev/null && + echo_test_string=`eval $cmd` && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +])])# _LT_AC_PROG_ECHO_BACKSLASH + + +# _LT_AC_LOCK +# ----------- +AC_DEFUN([_LT_AC_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + libsuff=64 + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) LD="${LD-ld} -64" ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; + ]) +esac + +need_locks="$enable_libtool_lock" + +])# _LT_AC_LOCK + + +# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], +[AC_REQUIRE([LT_AC_PROG_SED]) +AC_CACHE_CHECK([$1], [$2], + [$2=no + ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $rm conftest* +]) + +if test x"[$]$2" = xyes; then + ifelse([$5], , :, [$5]) +else + ifelse([$6], , :, [$6]) +fi +])# AC_LIBTOOL_COMPILER_OPTION + + +# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ------------------------------------------------------------ +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + ifelse([$4], , :, [$4]) +else + ifelse([$5], , :, [$5]) +fi +])# AC_LIBTOOL_LINKER_OPTION + + +# AC_LIBTOOL_SYS_MAX_CMD_LEN +# -------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], +[# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ + = "XX$teststring") >/dev/null 2>&1 && + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +])# AC_LIBTOOL_SYS_MAX_CMD_LEN + + +# _LT_AC_CHECK_DLFCN +# ------------------ +AC_DEFUN([_LT_AC_CHECK_DLFCN], +[AC_CHECK_HEADERS(dlfcn.h)dnl +])# _LT_AC_CHECK_DLFCN + + +# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# --------------------------------------------------------------------- +AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_AC_TRY_DLOPEN_SELF + + +# AC_LIBTOOL_DLOPEN_SELF +# ---------------------- +AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +])# AC_LIBTOOL_DLOPEN_SELF + + +# AC_LIBTOOL_PROG_CC_C_O([TAGNAME]) +# --------------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler +AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* +]) +])# AC_LIBTOOL_PROG_CC_C_O + + +# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME]) +# ----------------------------------------- +# Check to see if we can do hard links to lock some files if needed +AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], +[AC_REQUIRE([_LT_AC_LOCK])dnl + +hard_links="nottested" +if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS + + +# AC_LIBTOOL_OBJDIR +# ----------------- +AC_DEFUN([AC_LIBTOOL_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +])# AC_LIBTOOL_OBJDIR + + +# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME]) +# ---------------------------------------------- +# Check hardcoding attributes. +AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_AC_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ + test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \ + test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_AC_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_AC_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_AC_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH + + +# AC_LIBTOOL_SYS_LIB_STRIP +# ------------------------ +AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], +[striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) +fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +])# AC_LIBTOOL_SYS_LIB_STRIP + + +# AC_LIBTOOL_SYS_DYNAMIC_LINKER +# ----------------------------- +# PORTME Fill in your ld.so characteristics +AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +m4_if($1,[],[ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$lt_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e 's/;/ /g'` + else + lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`echo $lt_tmp_lt_search_path_spec | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + sys_lib_search_path_spec=`echo $lt_search_path_spec` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[123]]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[[3-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi +])# AC_LIBTOOL_SYS_DYNAMIC_LINKER + + +# _LT_AC_TAGCONFIG +# ---------------- +AC_DEFUN([_LT_AC_TAGCONFIG], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_ARG_WITH([tags], + [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], + [include additional configurations @<:@automatic@:>@])], + [tagnames="$withval"]) + +if test -f "$ltmain" && test -n "$tagnames"; then + if test ! -f "${ofile}"; then + AC_MSG_WARN([output file `$ofile' does not exist]) + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) + else + AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) + fi + fi + if test -z "$LTCFLAGS"; then + eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" + fi + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for tagname in $tagnames; do + IFS="$lt_save_ifs" + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in + "") ;; + *) AC_MSG_ERROR([invalid tag name: $tagname]) + ;; + esac + + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null + then + AC_MSG_ERROR([tag name \"$tagname\" already exists]) + fi + + # Update the list of available tags. + if test -n "$tagname"; then + echo appending configuration tag \"$tagname\" to $ofile + + case $tagname in + CXX) + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_LIBTOOL_LANG_CXX_CONFIG + else + tagname="" + fi + ;; + + F77) + if test -n "$F77" && test "X$F77" != "Xno"; then + AC_LIBTOOL_LANG_F77_CONFIG + else + tagname="" + fi + ;; + + GCJ) + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + AC_LIBTOOL_LANG_GCJ_CONFIG + else + tagname="" + fi + ;; + + RC) + AC_LIBTOOL_LANG_RC_CONFIG + ;; + + *) + AC_MSG_ERROR([Unsupported tag name: $tagname]) + ;; + esac + + # Append the new tag name to the list of available tags. + if test -n "$tagname" ; then + available_tags="$available_tags $tagname" + fi + fi + done + IFS="$lt_save_ifs" + + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + else + rm -f "${ofile}T" + AC_MSG_ERROR([unable to update list of available tagged configurations.]) + fi +fi +])# _LT_AC_TAGCONFIG + + +# AC_LIBTOOL_DLOPEN +# ----------------- +# enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], + [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_DLOPEN + + +# AC_LIBTOOL_WIN32_DLL +# -------------------- +# declare package support for building win32 DLLs +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_WIN32_DLL + + +# AC_ENABLE_SHARED([DEFAULT]) +# --------------------------- +# implement the --enable-shared flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([shared], + [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]AC_ENABLE_SHARED_DEFAULT) +])# AC_ENABLE_SHARED + + +# AC_DISABLE_SHARED +# ----------------- +# set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no) +])# AC_DISABLE_SHARED + + +# AC_ENABLE_STATIC([DEFAULT]) +# --------------------------- +# implement the --enable-static flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([static], + [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]AC_ENABLE_STATIC_DEFAULT) +])# AC_ENABLE_STATIC + + +# AC_DISABLE_STATIC +# ----------------- +# set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no) +])# AC_DISABLE_STATIC + + +# AC_ENABLE_FAST_INSTALL([DEFAULT]) +# --------------------------------- +# implement the --enable-fast-install flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([fast-install], + [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) +])# AC_ENABLE_FAST_INSTALL + + +# AC_DISABLE_FAST_INSTALL +# ----------------------- +# set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no) +])# AC_DISABLE_FAST_INSTALL + + +# AC_LIBTOOL_PICMODE([MODE]) +# -------------------------- +# implement the --with-pic flag +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default) +])# AC_LIBTOOL_PICMODE + + +# AC_PROG_EGREP +# ------------- +# This is predefined starting with Autoconf 2.54, so this conditional +# definition can be removed once we require Autoconf 2.54 or later. +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], +[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], + [if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi]) + EGREP=$ac_cv_prog_egrep + AC_SUBST([EGREP]) +])]) + + +# AC_PATH_TOOL_PREFIX +# ------------------- +# find a file program which can recognize shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +])# AC_PATH_TOOL_PREFIX + + +# AC_PATH_MAGIC +# ------------- +# find a file program which can recognize a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# AC_PATH_MAGIC + + +# AC_PROG_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH([gnu-ld], + [AC_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no]) +AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +nto-qnx*) + lt_cv_deplibs_check_method=unknown + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown +])# AC_DEPLIBS_CHECK_METHOD + + +# AC_PROG_NM +# ---------- +# find the pathname to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +])# AC_PROG_NM + + +# AC_CHECK_LIBM +# ------------- +# check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +])# AC_CHECK_LIBM + + +# AC_LIBLTDL_CONVENIENCE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl convenience library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-convenience to the configure arguments. Note that +# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, +# it is assumed to be `libltdl'. LIBLTDL will be prefixed with +# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/' +# (note the single quotes!). If your package is not flat and you're not +# using automake, define top_builddir and top_srcdir appropriately in +# the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_CONVENIENCE + + +# AC_LIBLTDL_INSTALLABLE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl installable library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-install to the configure arguments. Note that +# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, +# and an installed libltdl is not found, it is assumed to be `libltdl'. +# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and top_srcdir +# appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, lt_dlinit, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + LTDLINCL= + fi + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_INSTALLABLE + + +# AC_LIBTOOL_CXX +# -------------- +# enable support for C++ libraries +AC_DEFUN([AC_LIBTOOL_CXX], +[AC_REQUIRE([_LT_AC_LANG_CXX]) +])# AC_LIBTOOL_CXX + + +# _LT_AC_LANG_CXX +# --------------- +AC_DEFUN([_LT_AC_LANG_CXX], +[AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) +])# _LT_AC_LANG_CXX + +# _LT_AC_PROG_CXXCPP +# ------------------ +AC_DEFUN([_LT_AC_PROG_CXXCPP], +[ +AC_REQUIRE([AC_PROG_CXX]) +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +fi +])# _LT_AC_PROG_CXXCPP + +# AC_LIBTOOL_F77 +# -------------- +# enable support for Fortran 77 libraries +AC_DEFUN([AC_LIBTOOL_F77], +[AC_REQUIRE([_LT_AC_LANG_F77]) +])# AC_LIBTOOL_F77 + + +# _LT_AC_LANG_F77 +# --------------- +AC_DEFUN([_LT_AC_LANG_F77], +[AC_REQUIRE([AC_PROG_F77]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) +])# _LT_AC_LANG_F77 + + +# AC_LIBTOOL_GCJ +# -------------- +# enable support for GCJ libraries +AC_DEFUN([AC_LIBTOOL_GCJ], +[AC_REQUIRE([_LT_AC_LANG_GCJ]) +])# AC_LIBTOOL_GCJ + + +# _LT_AC_LANG_GCJ +# --------------- +AC_DEFUN([_LT_AC_LANG_GCJ], +[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], + [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], + [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], + [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) +])# _LT_AC_LANG_GCJ + + +# AC_LIBTOOL_RC +# ------------- +# enable support for Windows resource files +AC_DEFUN([AC_LIBTOOL_RC], +[AC_REQUIRE([LT_AC_PROG_RC]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC]) +])# AC_LIBTOOL_RC + + +# AC_LIBTOOL_LANG_C_CONFIG +# ------------------------ +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) +AC_DEFUN([_LT_AC_LANG_C_CONFIG], +[lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) +AC_LIBTOOL_SYS_LIB_STRIP +AC_LIBTOOL_DLOPEN_SELF + +# Report which library types will actually be built +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_C_CONFIG + + +# AC_LIBTOOL_LANG_CXX_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) +AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], +[AC_LANG_PUSH(C++) +AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) + +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_AC_TAGVAR(allow_undefined_flag, $1)= +_LT_AC_TAGVAR(always_export_symbols, $1)=no +_LT_AC_TAGVAR(archive_expsym_cmds, $1)= +_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_direct, $1)=no +_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= +_LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_AC_TAGVAR(hardcode_automatic, $1)=no +_LT_AC_TAGVAR(module_cmds, $1)= +_LT_AC_TAGVAR(module_expsym_cmds, $1)= +_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_AC_TAGVAR(no_undefined_flag, $1)= +_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= +_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Dependencies to place before and after the object being linked: +_LT_AC_TAGVAR(predep_objects, $1)= +_LT_AC_TAGVAR(postdep_objects, $1)= +_LT_AC_TAGVAR(predeps, $1)= +_LT_AC_TAGVAR(postdeps, $1)= +_LT_AC_TAGVAR(compiler_lib_search_path, $1)= + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_LD=$LD +lt_save_GCC=$GCC +GCC=$GXX +lt_save_with_gnu_ld=$with_gnu_ld +lt_save_path_LD=$lt_cv_path_LD +if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx +else + $as_unset lt_cv_prog_gnu_ld +fi +if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX +else + $as_unset lt_cv_path_LD +fi +test -z "${LDCXX+set}" || LD=$LDCXX +CC=${CXX-"c++"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) + +# We don't want -fno-exception wen compiling C++ code, so set the +# no_builtin_flag separately +if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' +else + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= +fi + +if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + AC_PROG_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + +else + GXX=no + with_gnu_ld=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +_LT_AC_TAGVAR(ld_shlibs, $1)=yes +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes ; then + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + freebsd[[12]]*) + # C++ shared libraries reported to be fairly broken before switch to ELF + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + freebsd-elf*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + ;; + gnu*) + ;; + hpux9*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) ;; + *) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + interix[[3-9]]*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' + fi + fi + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc*) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC*) + # Portland Group C++ compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + m88k*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + openbsd2*) + # C++ shared libraries are fairly broken + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + osf3*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ + $rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | grep -v '^2\.7' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + fi + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + # So that behaviour is only enabled if SCOABSPATH is set to a + # non-empty value in the environment. Most likely only useful for + # creating official distributions of packages. + # This is a hack until libtool officially supports absolute path + # names for shared libraries. + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + vxworks*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; +esac +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_AC_TAGVAR(GCC, $1)="$GXX" +_LT_AC_TAGVAR(LD, $1)="$LD" + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +AC_LIBTOOL_POSTDEP_PREDEP($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC=$lt_save_CC +LDCXX=$LD +LD=$lt_save_LD +GCC=$lt_save_GCC +with_gnu_ldcxx=$with_gnu_ld +with_gnu_ld=$lt_save_with_gnu_ld +lt_cv_path_LDCXX=$lt_cv_path_LD +lt_cv_path_LD=$lt_save_path_LD +lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld +lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +])# AC_LIBTOOL_LANG_CXX_CONFIG + +# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) +# ------------------------------------ +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +ifelse([$1],[],[cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext <&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + # + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + if test "$solaris_use_stlport4" != yes; then + _LT_AC_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_AC_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_AC_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac +])# AC_LIBTOOL_POSTDEP_PREDEP + +# AC_LIBTOOL_LANG_F77_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG], [_LT_AC_LANG_F77_CONFIG(F77)]) +AC_DEFUN([_LT_AC_LANG_F77_CONFIG], +[AC_REQUIRE([AC_PROG_F77]) +AC_LANG_PUSH(Fortran 77) + +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_AC_TAGVAR(allow_undefined_flag, $1)= +_LT_AC_TAGVAR(always_export_symbols, $1)=no +_LT_AC_TAGVAR(archive_expsym_cmds, $1)= +_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_direct, $1)=no +_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= +_LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(hardcode_automatic, $1)=no +_LT_AC_TAGVAR(module_cmds, $1)= +_LT_AC_TAGVAR(module_expsym_cmds, $1)= +_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_AC_TAGVAR(no_undefined_flag, $1)= +_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= +_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="\ + subroutine t + return + end +" + +# Code to be used in simple link tests +lt_simple_link_test_code="\ + program t + end +" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${F77-"f77"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) + +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +_LT_AC_TAGVAR(GCC, $1)="$G77" +_LT_AC_TAGVAR(LD, $1)="$LD" + +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_F77_CONFIG + + +# AC_LIBTOOL_LANG_GCJ_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG], [_LT_AC_LANG_GCJ_CONFIG(GCJ)]) +AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG], +[AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${GCJ-"gcj"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_RESTORE +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_GCJ_CONFIG + + +# AC_LIBTOOL_LANG_RC_CONFIG +# ------------------------- +# Ensure that the configuration vars for the Windows resource compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG], [_LT_AC_LANG_RC_CONFIG(RC)]) +AC_DEFUN([_LT_AC_LANG_RC_CONFIG], +[AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${RC-"windres"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_RESTORE +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_RC_CONFIG + + +# AC_LIBTOOL_CONFIG([TAGNAME]) +# ---------------------------- +# If TAGNAME is not passed, then create an initial libtool script +# with a default configuration from the untagged config vars. Otherwise +# add code to config.status for appending the configuration named by +# TAGNAME from the matching tagged config vars. +AC_DEFUN([AC_LIBTOOL_CONFIG], +[# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + _LT_AC_TAGVAR(compiler, $1) \ + _LT_AC_TAGVAR(CC, $1) \ + _LT_AC_TAGVAR(LD, $1) \ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1) \ + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1) \ + _LT_AC_TAGVAR(lt_prog_compiler_static, $1) \ + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) \ + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1) \ + _LT_AC_TAGVAR(thread_safe_flag_spec, $1) \ + _LT_AC_TAGVAR(whole_archive_flag_spec, $1) \ + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) \ + _LT_AC_TAGVAR(old_archive_cmds, $1) \ + _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) \ + _LT_AC_TAGVAR(predep_objects, $1) \ + _LT_AC_TAGVAR(postdep_objects, $1) \ + _LT_AC_TAGVAR(predeps, $1) \ + _LT_AC_TAGVAR(postdeps, $1) \ + _LT_AC_TAGVAR(compiler_lib_search_path, $1) \ + _LT_AC_TAGVAR(archive_cmds, $1) \ + _LT_AC_TAGVAR(archive_expsym_cmds, $1) \ + _LT_AC_TAGVAR(postinstall_cmds, $1) \ + _LT_AC_TAGVAR(postuninstall_cmds, $1) \ + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) \ + _LT_AC_TAGVAR(allow_undefined_flag, $1) \ + _LT_AC_TAGVAR(no_undefined_flag, $1) \ + _LT_AC_TAGVAR(export_symbols_cmds, $1) \ + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) \ + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) \ + _LT_AC_TAGVAR(hardcode_libdir_separator, $1) \ + _LT_AC_TAGVAR(hardcode_automatic, $1) \ + _LT_AC_TAGVAR(module_cmds, $1) \ + _LT_AC_TAGVAR(module_expsym_cmds, $1) \ + _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) \ + _LT_AC_TAGVAR(fix_srcfile_path, $1) \ + _LT_AC_TAGVAR(exclude_expsyms, $1) \ + _LT_AC_TAGVAR(include_expsyms, $1); do + + case $var in + _LT_AC_TAGVAR(old_archive_cmds, $1) | \ + _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) | \ + _LT_AC_TAGVAR(archive_cmds, $1) | \ + _LT_AC_TAGVAR(archive_expsym_cmds, $1) | \ + _LT_AC_TAGVAR(module_cmds, $1) | \ + _LT_AC_TAGVAR(module_expsym_cmds, $1) | \ + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) | \ + _LT_AC_TAGVAR(export_symbols_cmds, $1) | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\[$]0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\[$]0 --fallback-echo"[$]/[$]0 --fallback-echo"/'` + ;; + esac + +ifelse([$1], [], + [cfgfile="${ofile}T" + trap "$rm \"$cfgfile\"; exit 1" 1 2 15 + $rm -f "$cfgfile" + AC_MSG_NOTICE([creating $ofile])], + [cfgfile="$ofile"]) + + cat <<__EOF__ >> "$cfgfile" +ifelse([$1], [], +[#! $SHELL + +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="$SED -e 1s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# The names of the tagged configurations supported by this script. +available_tags= + +# ### BEGIN LIBTOOL CONFIG], +[# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) + +# Is the compiler the GNU C compiler? +with_gcc=$_LT_AC_TAGVAR(GCC, $1) + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_[]_LT_AC_TAGVAR(LD, $1) + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1) +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) + +# Commands used to build and install a shared archive. +archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) +archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) +module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1) + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1) + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1) + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to yes if exported symbols are required. +always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) + +# The commands to list exported symbols. +export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1) + +# Symbols that must always be exported. +include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) + +ifelse([$1],[], +[# ### END LIBTOOL CONFIG], +[# ### END LIBTOOL TAG CONFIG: $tagname]) + +__EOF__ + +ifelse([$1],[], [ + case $host_os in + aix3*) + cat <<\EOF >> "$cfgfile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || \ + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +]) +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi +])# AC_LIBTOOL_CONFIG + + +# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl + +_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + + AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI + + +# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +# --------------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([LT_AC_PROG_SED]) +AC_REQUIRE([AC_PROG_NM]) +AC_REQUIRE([AC_OBJEXT]) +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) # Its linker distinguishes data from code symbols + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +linux* | k*bsd*-gnu) + if test "$host_cpu" = ia64; then + symcode='[[ABCDGIRSTW]]' + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if grep ' nm_test_var$' "$nlist" >/dev/null; then + if grep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[[]] = +{ +EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE + + +# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME]) +# --------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], +[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_static, $1)= + +AC_MSG_CHECKING([for $compiler option to produce PIC]) + ifelse([$1],[CXX],[ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + icpc* | ecpc*) + # Intel C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC*) + # Portland Group C++ compiler. + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + newsos6) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + icc* | ecc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + esac + ;; + esac + ;; + + osf3* | osf4* | osf5*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then + AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], + _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), + [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\" +AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) +]) + + +# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME]) +# ------------------------------------ +# See if the linker supports building shared libraries. +AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +ifelse([$1],[CXX],[ + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix4* | aix5*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + ;; + *) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +],[ + runpath_var= + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)= + _LT_AC_TAGVAR(archive_expsym_cmds, $1)= + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown + _LT_AC_TAGVAR(hardcode_automatic, $1)=no + _LT_AC_TAGVAR(module_cmds, $1)= + _LT_AC_TAGVAR(module_expsym_cmds, $1)= + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_AC_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + _LT_CC_BASENAME([$compiler]) + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + interix[[3-9]]*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | k*bsd*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + *) + tmp_sharedflag='-shared' ;; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + # see comment about different semantics on the GNU ld section + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + bsdi[[45]]*) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_AC_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_AC_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + $rm conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + else + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) + ;; + esac + fi + ;; +esac +])# AC_LIBTOOL_PROG_LD_SHLIBS + + +# _LT_AC_FILE_LTDLL_C +# ------------------- +# Be careful that the start marker always follows a newline. +AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ +])# _LT_AC_FILE_LTDLL_C + + +# _LT_AC_TAGVAR(VARNAME, [TAGNAME]) +# --------------------------------- +AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) + + +# old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +# This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL]) + +AC_DEFUN([LT_AC_PROG_GCJ], +[AC_CHECK_TOOL(GCJ, gcj, no) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS) +]) + +AC_DEFUN([LT_AC_PROG_RC], +[AC_CHECK_TOOL(RC, windres, no) +]) + + +# Cheap backport of AS_EXECUTABLE_P and required macros +# from Autoconf 2.59; we should not use $as_executable_p directly. + +# _AS_TEST_PREPARE +# ---------------- +m4_ifndef([_AS_TEST_PREPARE], +[m4_defun([_AS_TEST_PREPARE], +[if test -x / >/dev/null 2>&1; then + as_executable_p='test -x' +else + as_executable_p='test -f' +fi +])])# _AS_TEST_PREPARE + +# AS_EXECUTABLE_P +# --------------- +# Check whether a file is executable. +m4_ifndef([AS_EXECUTABLE_P], +[m4_defun([AS_EXECUTABLE_P], +[AS_REQUIRE([_AS_TEST_PREPARE])dnl +$as_executable_p $1[]dnl +])])# AS_EXECUTABLE_P + +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +# LT_AC_PROG_SED +# -------------- +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +AC_DEFUN([LT_AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if AS_EXECUTABLE_P(["$as_dir/$lt_ac_prog$ac_exec_ext"]); then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +]) +## ltdl.m4 - Configure ltdl for the target system. -*-Autoconf-*- +## Copyright (C) 1999-2006 Free Software Foundation, Inc. +## +## This file is free software; the Free Software Foundation gives +## unlimited permission to copy and/or distribute it, with or without +## modifications, as long as this notice is preserved. + +# serial 8 AC_LIB_LTDL + +# AC_WITH_LTDL +# ------------ +# Clients of libltdl can use this macro to allow the installer to +# choose between a shipped copy of the ltdl sources or a preinstalled +# version of the library. +AC_DEFUN([AC_WITH_LTDL], +[AC_REQUIRE([AC_LIB_LTDL]) +AC_SUBST([LIBLTDL]) +AC_SUBST([INCLTDL]) + +# Unless the user asks us to check, assume no installed ltdl exists. +use_installed_libltdl=no + +AC_ARG_WITH([included_ltdl], + [ --with-included-ltdl use the GNU ltdl sources included here]) + +if test "x$with_included_ltdl" != xyes; then + # We are not being forced to use the included libltdl sources, so + # decide whether there is a useful installed version we can use. + AC_CHECK_HEADER([ltdl.h], + [AC_CHECK_LIB([ltdl], [lt_dlcaller_register], + [with_included_ltdl=no], + [with_included_ltdl=yes]) + ]) +fi + +if test "x$enable_ltdl_install" != xyes; then + # If the user did not specify an installable libltdl, then default + # to a convenience lib. + AC_LIBLTDL_CONVENIENCE +fi + +if test "x$with_included_ltdl" = xno; then + # If the included ltdl is not to be used. then Use the + # preinstalled libltdl we found. + AC_DEFINE([HAVE_LTDL], [1], + [Define this if a modern libltdl is already installed]) + LIBLTDL=-lltdl +fi + +# Report our decision... +AC_MSG_CHECKING([whether to use included libltdl]) +AC_MSG_RESULT([$with_included_ltdl]) + +AC_CONFIG_SUBDIRS([libltdl]) +])# AC_WITH_LTDL + + +# AC_LIB_LTDL +# ----------- +# Perform all the checks necessary for compilation of the ltdl objects +# -- including compiler checks and header checks. +AC_DEFUN([AC_LIB_LTDL], +[AC_PREREQ(2.50) +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_C_CONST]) +AC_REQUIRE([AC_HEADER_STDC]) +AC_REQUIRE([AC_HEADER_DIRENT]) +AC_REQUIRE([_LT_AC_CHECK_DLFCN]) +AC_REQUIRE([AC_LTDL_ENABLE_INSTALL]) +AC_REQUIRE([AC_LTDL_SHLIBEXT]) +AC_REQUIRE([AC_LTDL_SHLIBPATH]) +AC_REQUIRE([AC_LTDL_SYSSEARCHPATH]) +AC_REQUIRE([AC_LTDL_OBJDIR]) +AC_REQUIRE([AC_LTDL_DLPREOPEN]) +AC_REQUIRE([AC_LTDL_DLLIB]) +AC_REQUIRE([AC_LTDL_SYMBOL_USCORE]) +AC_REQUIRE([AC_LTDL_DLSYM_USCORE]) +AC_REQUIRE([AC_LTDL_SYS_DLOPEN_DEPLIBS]) +AC_REQUIRE([AC_LTDL_FUNC_ARGZ]) + +AC_CHECK_HEADERS([assert.h ctype.h errno.h malloc.h memory.h stdlib.h \ + stdio.h unistd.h]) +AC_CHECK_HEADERS([dl.h sys/dl.h dld.h mach-o/dyld.h]) +AC_CHECK_HEADERS([string.h strings.h], [break]) + +AC_CHECK_FUNCS([strchr index], [break]) +AC_CHECK_FUNCS([strrchr rindex], [break]) +AC_CHECK_FUNCS([memcpy bcopy], [break]) +AC_CHECK_FUNCS([memmove strcmp]) +AC_CHECK_FUNCS([closedir opendir readdir]) +])# AC_LIB_LTDL + + +# AC_LTDL_ENABLE_INSTALL +# ---------------------- +AC_DEFUN([AC_LTDL_ENABLE_INSTALL], +[AC_ARG_ENABLE([ltdl-install], + [AC_HELP_STRING([--enable-ltdl-install], [install libltdl])]) + +AM_CONDITIONAL(INSTALL_LTDL, test x"${enable_ltdl_install-no}" != xno) +AM_CONDITIONAL(CONVENIENCE_LTDL, test x"${enable_ltdl_convenience-no}" != xno) +])# AC_LTDL_ENABLE_INSTALL + + +# AC_LTDL_SYS_DLOPEN_DEPLIBS +# -------------------------- +AC_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_CACHE_CHECK([whether deplibs are loaded by dlopen], + [libltdl_cv_sys_dlopen_deplibs], + [# PORTME does your system automatically load deplibs for dlopen? + # or its logical equivalent (e.g. shl_load for HP-UX < 11) + # For now, we just catch OSes we know something about -- in the + # future, we'll try test this programmatically. + libltdl_cv_sys_dlopen_deplibs=unknown + case "$host_os" in + aix3*|aix4.1.*|aix4.2.*) + # Unknown whether this is true for these versions of AIX, but + # we want this `case' here to explicitly catch those versions. + libltdl_cv_sys_dlopen_deplibs=unknown + ;; + aix[[45]]*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + darwin*) + # Assuming the user has installed a libdl from somewhere, this is true + # If you are looking for one http://www.opendarwin.org/projects/dlcompat + libltdl_cv_sys_dlopen_deplibs=yes + ;; + freebsd* | dragonfly*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + gnu* | linux* | k*bsd*-gnu) + # GNU and its variants, using gnu ld.so (Glibc) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + hpux10*|hpux11*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + interix*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + irix[[12345]]*|irix6.[[01]]*) + # Catch all versions of IRIX before 6.2, and indicate that we don't + # know how it worked for any of those versions. + libltdl_cv_sys_dlopen_deplibs=unknown + ;; + irix*) + # The case above catches anything before 6.2, and it's known that + # at 6.2 and later dlopen does load deplibs. + libltdl_cv_sys_dlopen_deplibs=yes + ;; + netbsd*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + openbsd*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + osf[[1234]]*) + # dlopen did load deplibs (at least at 4.x), but until the 5.x series, + # it did *not* use an RPATH in a shared library to find objects the + # library depends on, so we explictly say `no'. + libltdl_cv_sys_dlopen_deplibs=no + ;; + osf5.0|osf5.0a|osf5.1) + # dlopen *does* load deplibs and with the right loader patch applied + # it even uses RPATH in a shared library to search for shared objects + # that the library depends on, but there's no easy way to know if that + # patch is installed. Since this is the case, all we can really + # say is unknown -- it depends on the patch being installed. If + # it is, this changes to `yes'. Without it, it would be `no'. + libltdl_cv_sys_dlopen_deplibs=unknown + ;; + osf*) + # the two cases above should catch all versions of osf <= 5.1. Read + # the comments above for what we know about them. + # At > 5.1, deplibs are loaded *and* any RPATH in a shared library + # is used to find them so we can finally say `yes'. + libltdl_cv_sys_dlopen_deplibs=yes + ;; + solaris*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + esac + ]) +if test "$libltdl_cv_sys_dlopen_deplibs" != yes; then + AC_DEFINE([LTDL_DLOPEN_DEPLIBS], [1], + [Define if the OS needs help to load dependent libraries for dlopen().]) +fi +])# AC_LTDL_SYS_DLOPEN_DEPLIBS + + +# AC_LTDL_SHLIBEXT +# ---------------- +AC_DEFUN([AC_LTDL_SHLIBEXT], +[AC_REQUIRE([AC_LIBTOOL_SYS_DYNAMIC_LINKER]) +AC_CACHE_CHECK([which extension is used for loadable modules], + [libltdl_cv_shlibext], +[ +module=yes +eval libltdl_cv_shlibext=$shrext_cmds + ]) +if test -n "$libltdl_cv_shlibext"; then + AC_DEFINE_UNQUOTED([LTDL_SHLIB_EXT], ["$libltdl_cv_shlibext"], + [Define to the extension used for shared libraries, say, ".so".]) +fi +])# AC_LTDL_SHLIBEXT + + +# AC_LTDL_SHLIBPATH +# ----------------- +AC_DEFUN([AC_LTDL_SHLIBPATH], +[AC_REQUIRE([AC_LIBTOOL_SYS_DYNAMIC_LINKER]) +AC_CACHE_CHECK([which variable specifies run-time library path], + [libltdl_cv_shlibpath_var], [libltdl_cv_shlibpath_var="$shlibpath_var"]) +if test -n "$libltdl_cv_shlibpath_var"; then + AC_DEFINE_UNQUOTED([LTDL_SHLIBPATH_VAR], ["$libltdl_cv_shlibpath_var"], + [Define to the name of the environment variable that determines the dynamic library search path.]) +fi +])# AC_LTDL_SHLIBPATH + + +# AC_LTDL_SYSSEARCHPATH +# --------------------- +AC_DEFUN([AC_LTDL_SYSSEARCHPATH], +[AC_REQUIRE([AC_LIBTOOL_SYS_DYNAMIC_LINKER]) +AC_CACHE_CHECK([for the default library search path], + [libltdl_cv_sys_search_path], + [libltdl_cv_sys_search_path="$sys_lib_dlsearch_path_spec"]) +if test -n "$libltdl_cv_sys_search_path"; then + sys_search_path= + for dir in $libltdl_cv_sys_search_path; do + if test -z "$sys_search_path"; then + sys_search_path="$dir" + else + sys_search_path="$sys_search_path$PATH_SEPARATOR$dir" + fi + done + AC_DEFINE_UNQUOTED([LTDL_SYSSEARCHPATH], ["$sys_search_path"], + [Define to the system default library search path.]) +fi +])# AC_LTDL_SYSSEARCHPATH + + +# AC_LTDL_OBJDIR +# -------------- +AC_DEFUN([AC_LTDL_OBJDIR], +[AC_CACHE_CHECK([for objdir], + [libltdl_cv_objdir], + [libltdl_cv_objdir="$objdir" + if test -n "$objdir"; then + : + else + rm -f .libs 2>/dev/null + mkdir .libs 2>/dev/null + if test -d .libs; then + libltdl_cv_objdir=.libs + else + # MS-DOS does not allow filenames that begin with a dot. + libltdl_cv_objdir=_libs + fi + rmdir .libs 2>/dev/null + fi + ]) +AC_DEFINE_UNQUOTED([LTDL_OBJDIR], ["$libltdl_cv_objdir/"], + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# AC_LTDL_OBJDIR + + +# AC_LTDL_DLPREOPEN +# ----------------- +AC_DEFUN([AC_LTDL_DLPREOPEN], +[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE]) +AC_CACHE_CHECK([whether libtool supports -dlopen/-dlpreopen], + [libltdl_cv_preloaded_symbols], + [if test -n "$lt_cv_sys_global_symbol_pipe"; then + libltdl_cv_preloaded_symbols=yes + else + libltdl_cv_preloaded_symbols=no + fi + ]) +if test x"$libltdl_cv_preloaded_symbols" = xyes; then + AC_DEFINE([HAVE_PRELOADED_SYMBOLS], [1], + [Define if libtool can extract symbol lists from object files.]) +fi +])# AC_LTDL_DLPREOPEN + + +# AC_LTDL_DLLIB +# ------------- +AC_DEFUN([AC_LTDL_DLLIB], +[LIBADD_DL= +AC_SUBST(LIBADD_DL) +AC_LANG_PUSH([C]) + +AC_CHECK_FUNC([shl_load], + [AC_DEFINE([HAVE_SHL_LOAD], [1], + [Define if you have the shl_load function.])], + [AC_CHECK_LIB([dld], [shl_load], + [AC_DEFINE([HAVE_SHL_LOAD], [1], + [Define if you have the shl_load function.]) + LIBADD_DL="$LIBADD_DL -ldld"], + [AC_CHECK_LIB([dl], [dlopen], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent.]) + LIBADD_DL="-ldl" libltdl_cv_lib_dl_dlopen="yes"], + [AC_TRY_LINK([#if HAVE_DLFCN_H +# include +#endif + ], + [dlopen(0, 0);], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent.]) libltdl_cv_func_dlopen="yes"], + [AC_CHECK_LIB([svld], [dlopen], + [AC_DEFINE([HAVE_LIBDL], [1], + [Define if you have the libdl library or equivalent.]) + LIBADD_DL="-lsvld" libltdl_cv_func_dlopen="yes"], + [AC_CHECK_LIB([dld], [dld_link], + [AC_DEFINE([HAVE_DLD], [1], + [Define if you have the GNU dld library.]) + LIBADD_DL="$LIBADD_DL -ldld"], + [AC_CHECK_FUNC([_dyld_func_lookup], + [AC_DEFINE([HAVE_DYLD], [1], + [Define if you have the _dyld_func_lookup function.])]) + ]) + ]) + ]) + ]) + ]) +]) + +if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes +then + lt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBADD_DL" + AC_CHECK_FUNCS([dlerror]) + LIBS="$lt_save_LIBS" +fi +AC_LANG_POP +])# AC_LTDL_DLLIB + + +# AC_LTDL_SYMBOL_USCORE +# --------------------- +# does the compiler prefix global symbols with an underscore? +AC_DEFUN([AC_LTDL_SYMBOL_USCORE], +[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE]) +AC_CACHE_CHECK([for _ prefix in compiled symbols], + [ac_cv_sys_symbol_underscore], + [ac_cv_sys_symbol_underscore=no + cat > conftest.$ac_ext < $ac_nlist) && test -s "$ac_nlist"; then + # See whether the symbols have a leading underscore. + if grep '^. _nm_test_func' "$ac_nlist" >/dev/null; then + ac_cv_sys_symbol_underscore=yes + else + if grep '^. nm_test_func ' "$ac_nlist" >/dev/null; then + : + else + echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC + fi + fi + else + echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&AC_FD_CC + fi + else + echo "configure: failed program was:" >&AC_FD_CC + cat conftest.c >&AC_FD_CC + fi + rm -rf conftest* + ]) +])# AC_LTDL_SYMBOL_USCORE + + +# AC_LTDL_DLSYM_USCORE +# -------------------- +AC_DEFUN([AC_LTDL_DLSYM_USCORE], +[AC_REQUIRE([AC_LTDL_SYMBOL_USCORE]) +if test x"$ac_cv_sys_symbol_underscore" = xyes; then + if test x"$libltdl_cv_func_dlopen" = xyes || + test x"$libltdl_cv_lib_dl_dlopen" = xyes ; then + AC_CACHE_CHECK([whether we have to add an underscore for dlsym], + [libltdl_cv_need_uscore], + [libltdl_cv_need_uscore=unknown + save_LIBS="$LIBS" + LIBS="$LIBS $LIBADD_DL" + _LT_AC_TRY_DLOPEN_SELF( + [libltdl_cv_need_uscore=no], [libltdl_cv_need_uscore=yes], + [], [libltdl_cv_need_uscore=cross]) + LIBS="$save_LIBS" + ]) + fi +fi + +if test x"$libltdl_cv_need_uscore" = xyes; then + AC_DEFINE([NEED_USCORE], [1], + [Define if dlsym() requires a leading underscore in symbol names.]) +fi +])# AC_LTDL_DLSYM_USCORE + +# AC_LTDL_FUNC_ARGZ +# ----------------- +AC_DEFUN([AC_LTDL_FUNC_ARGZ], +[AC_CHECK_HEADERS([argz.h]) + +AC_CHECK_TYPES([error_t], + [], + [AC_DEFINE([error_t], [int], + [Define to a type to use for `error_t' if it is not otherwise available.])], + [#if HAVE_ARGZ_H +# include +#endif]) + +AC_CHECK_FUNCS([argz_append argz_create_sep argz_insert argz_next argz_stringify]) +])# AC_LTDL_FUNC_ARGZ diff --git a/libltdl/aclocal.m4 b/libltdl/aclocal.m4 new file mode 100644 index 00000000..fcc414d3 --- /dev/null +++ b/libltdl/aclocal.m4 @@ -0,0 +1,875 @@ +# generated automatically by aclocal 1.10 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_if(m4_PACKAGE_VERSION, [2.61],, +[m4_fatal([this file was generated for autoconf 2.61. +You have another version of autoconf. If you want to use that, +you should regenerate the build system entirely.], [63])]) + +# Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.10' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.10], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.10])dnl +_AM_AUTOCONF_VERSION(m4_PACKAGE_VERSION)]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 3 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. +AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 12 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.60])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputing VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([acinclude.m4]) diff --git a/libltdl/config-h.in b/libltdl/config-h.in new file mode 100644 index 00000000..b8640710 --- /dev/null +++ b/libltdl/config-h.in @@ -0,0 +1,195 @@ +/* config-h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the `argz_append' function. */ +#undef HAVE_ARGZ_APPEND + +/* Define to 1 if you have the `argz_create_sep' function. */ +#undef HAVE_ARGZ_CREATE_SEP + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARGZ_H + +/* Define to 1 if you have the `argz_insert' function. */ +#undef HAVE_ARGZ_INSERT + +/* Define to 1 if you have the `argz_next' function. */ +#undef HAVE_ARGZ_NEXT + +/* Define to 1 if you have the `argz_stringify' function. */ +#undef HAVE_ARGZ_STRINGIFY + +/* Define to 1 if you have the header file. */ +#undef HAVE_ASSERT_H + +/* Define to 1 if you have the `bcopy' function. */ +#undef HAVE_BCOPY + +/* Define to 1 if you have the `closedir' function. */ +#undef HAVE_CLOSEDIR + +/* Define to 1 if you have the header file. */ +#undef HAVE_CTYPE_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_DIRENT_H + +/* Define if you have the GNU dld library. */ +#undef HAVE_DLD + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLD_H + +/* Define to 1 if you have the `dlerror' function. */ +#undef HAVE_DLERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DL_H + +/* Define if you have the _dyld_func_lookup function. */ +#undef HAVE_DYLD + +/* Define to 1 if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define to 1 if the system has the type `error_t'. */ +#undef HAVE_ERROR_T + +/* Define to 1 if you have the `index' function. */ +#undef HAVE_INDEX + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define if you have the libdl library or equivalent. */ +#undef HAVE_LIBDL + +/* Define to 1 if you have the header file. */ +#undef HAVE_MACH_O_DYLD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the `memcpy' function. */ +#undef HAVE_MEMCPY + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +#undef HAVE_NDIR_H + +/* Define to 1 if you have the `opendir' function. */ +#undef HAVE_OPENDIR + +/* Define if libtool can extract symbol lists from object files. */ +#undef HAVE_PRELOADED_SYMBOLS + +/* Define to 1 if you have the `readdir' function. */ +#undef HAVE_READDIR + +/* Define to 1 if you have the `rindex' function. */ +#undef HAVE_RINDEX + +/* Define if you have the shl_load function. */ +#undef HAVE_SHL_LOAD + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the `strcmp' function. */ +#undef HAVE_STRCMP + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strrchr' function. */ +#undef HAVE_STRRCHR + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_DIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_DL_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define if the OS needs help to load dependent libraries for dlopen(). */ +#undef LTDL_DLOPEN_DEPLIBS + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LTDL_OBJDIR + +/* Define to the name of the environment variable that determines the dynamic + library search path. */ +#undef LTDL_SHLIBPATH_VAR + +/* Define to the extension used for shared libraries, say, ".so". */ +#undef LTDL_SHLIB_EXT + +/* Define to the system default library search path. */ +#undef LTDL_SYSSEARCHPATH + +/* Define if dlsym() requires a leading underscore in symbol names. */ +#undef NEED_USCORE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to a type to use for `error_t' if it is not otherwise available. */ +#undef error_t + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif diff --git a/libltdl/config.guess b/libltdl/config.guess new file mode 100755 index 00000000..951383e3 --- /dev/null +++ b/libltdl/config.guess @@ -0,0 +1,1516 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2007-05-17' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:* | ix86xen:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:[3456]*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T | authenticamd) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa:Linux:*:*) + echo xtensa-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/libltdl/config.h b/libltdl/config.h new file mode 100644 index 00000000..0fe3124c --- /dev/null +++ b/libltdl/config.h @@ -0,0 +1,196 @@ +/* config.h. Generated from config-h.in by configure. */ +/* config-h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the `argz_append' function. */ +#define HAVE_ARGZ_APPEND 1 + +/* Define to 1 if you have the `argz_create_sep' function. */ +#define HAVE_ARGZ_CREATE_SEP 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ARGZ_H 1 + +/* Define to 1 if you have the `argz_insert' function. */ +#define HAVE_ARGZ_INSERT 1 + +/* Define to 1 if you have the `argz_next' function. */ +#define HAVE_ARGZ_NEXT 1 + +/* Define to 1 if you have the `argz_stringify' function. */ +#define HAVE_ARGZ_STRINGIFY 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ASSERT_H 1 + +/* Define to 1 if you have the `bcopy' function. */ +/* #undef HAVE_BCOPY */ + +/* Define to 1 if you have the `closedir' function. */ +#define HAVE_CLOSEDIR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_CTYPE_H 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#define HAVE_DIRENT_H 1 + +/* Define if you have the GNU dld library. */ +/* #undef HAVE_DLD */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DLD_H */ + +/* Define to 1 if you have the `dlerror' function. */ +#define HAVE_DLERROR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DL_H */ + +/* Define if you have the _dyld_func_lookup function. */ +/* #undef HAVE_DYLD */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if the system has the type `error_t'. */ +#define HAVE_ERROR_T 1 + +/* Define to 1 if you have the `index' function. */ +/* #undef HAVE_INDEX */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define if you have the libdl library or equivalent. */ +#define HAVE_LIBDL 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MACH_O_DYLD_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define to 1 if you have the `memcpy' function. */ +#define HAVE_MEMCPY 1 + +/* Define to 1 if you have the `memmove' function. */ +#define HAVE_MEMMOVE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +/* #undef HAVE_NDIR_H */ + +/* Define to 1 if you have the `opendir' function. */ +#define HAVE_OPENDIR 1 + +/* Define if libtool can extract symbol lists from object files. */ +#define HAVE_PRELOADED_SYMBOLS 1 + +/* Define to 1 if you have the `readdir' function. */ +#define HAVE_READDIR 1 + +/* Define to 1 if you have the `rindex' function. */ +/* #undef HAVE_RINDEX */ + +/* Define if you have the shl_load function. */ +/* #undef HAVE_SHL_LOAD */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strchr' function. */ +#define HAVE_STRCHR 1 + +/* Define to 1 if you have the `strcmp' function. */ +#define HAVE_STRCMP 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strrchr' function. */ +#define HAVE_STRRCHR 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_DL_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if the OS needs help to load dependent libraries for dlopen(). */ +/* #undef LTDL_DLOPEN_DEPLIBS */ + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LTDL_OBJDIR ".libs/" + +/* Define to the name of the environment variable that determines the dynamic + library search path. */ +#define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" + +/* Define to the extension used for shared libraries, say, ".so". */ +#define LTDL_SHLIB_EXT ".so" + +/* Define to the system default library search path. */ +#define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" + +/* Define if dlsym() requires a leading underscore in symbol names. */ +/* #undef NEED_USCORE */ + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "bug-libtool@gnu.org" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "libltdl" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "libltdl 1.2" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "libltdl" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "1.2" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to a type to use for `error_t' if it is not otherwise available. */ +/* #undef error_t */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif diff --git a/libltdl/config.log b/libltdl/config.log new file mode 100644 index 00000000..1aca1d97 --- /dev/null +++ b/libltdl/config.log @@ -0,0 +1,1609 @@ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by libltdl configure 1.2, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ ./configure + +## --------- ## +## Platform. ## +## --------- ## + +hostname = lambda +uname -m = i686 +uname -r = 2.6.23-0.73.rc2.fc8 +uname -s = Linux +uname -v = #1 SMP Mon Aug 6 20:26:04 EDT 2007 + +/usr/bin/uname -p = unknown +/bin/uname -X = unknown + +/bin/arch = i686 +/usr/bin/arch -k = unknown +/usr/convex/getsysinfo = unknown +/usr/bin/hostinfo = unknown +/bin/machine = unknown +/usr/bin/oslevel = unknown +/bin/universe = unknown + +PATH: /home/lennart/bin +PATH: /usr/lib/qt-3.3/bin +PATH: /usr/kerberos/bin +PATH: /usr/lib/ccache +PATH: /usr/local/bin +PATH: /bin +PATH: /usr/bin + + +## ----------- ## +## Core tests. ## +## ----------- ## + +configure:2017: checking for a BSD-compatible install +configure:2073: result: /usr/bin/install -c +configure:2084: checking whether build environment is sane +configure:2127: result: yes +configure:2155: checking for a thread-safe mkdir -p +configure:2194: result: /bin/mkdir -p +configure:2207: checking for gawk +configure:2223: found /bin/gawk +configure:2234: result: gawk +configure:2245: checking whether make sets $(MAKE) +configure:2266: result: yes +configure:2500: checking for gcc +configure:2516: found /usr/lib/ccache/gcc +configure:2527: result: gcc +configure:2765: checking for C compiler version +configure:2772: gcc --version >&5 +gcc (GCC) 4.1.2 20070723 (Red Hat 4.1.2-17) +Copyright (C) 2006 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +configure:2775: $? = 0 +configure:2782: gcc -v >&5 +Using built-in specs. +Target: i386-redhat-linux +Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-cpu=generic --host=i386-redhat-linux +Thread model: posix +gcc version 4.1.2 20070723 (Red Hat 4.1.2-17) +configure:2785: $? = 0 +configure:2792: gcc -V >&5 +gcc: '-V' option must have argument +configure:2795: $? = 1 +configure:2818: checking for C compiler default output file name +configure:2845: gcc conftest.c >&5 +configure:2848: $? = 0 +configure:2886: result: a.out +configure:2903: checking whether the C compiler works +configure:2913: ./a.out +configure:2916: $? = 0 +configure:2933: result: yes +configure:2940: checking whether we are cross compiling +configure:2942: result: no +configure:2945: checking for suffix of executables +configure:2952: gcc -o conftest conftest.c >&5 +configure:2955: $? = 0 +configure:2979: result: +configure:2985: checking for suffix of object files +configure:3011: gcc -c conftest.c >&5 +configure:3014: $? = 0 +configure:3037: result: o +configure:3041: checking whether we are using the GNU C compiler +configure:3070: gcc -c conftest.c >&5 +configure:3076: $? = 0 +configure:3093: result: yes +configure:3098: checking whether gcc accepts -g +configure:3128: gcc -c -g conftest.c >&5 +configure:3134: $? = 0 +configure:3233: result: yes +configure:3250: checking for gcc option to accept ISO C89 +configure:3324: gcc -c -g -O2 conftest.c >&5 +configure:3330: $? = 0 +configure:3353: result: none needed +configure:3382: checking for style of include used by make +configure:3410: result: GNU +configure:3435: checking dependency style of gcc +configure:3526: result: none +configure:3542: checking for an ANSI C-conforming const +configure:3617: gcc -c -g -O2 conftest.c >&5 +configure:3623: $? = 0 +configure:3638: result: yes +configure:3648: checking for inline +configure:3674: gcc -c -g -O2 conftest.c >&5 +configure:3680: $? = 0 +configure:3698: result: inline +configure:3802: checking build system type +configure:3820: result: i686-pc-linux-gnu +configure:3842: checking host system type +configure:3857: result: i686-pc-linux-gnu +configure:3879: checking for a sed that does not truncate output +configure:3935: result: /bin/sed +configure:3938: checking for grep that handles long lines and -e +configure:4012: result: /bin/grep +configure:4017: checking for egrep +configure:4095: result: /bin/grep -E +configure:4111: checking for ld used by gcc +configure:4178: result: /usr/bin/ld +configure:4187: checking if the linker (/usr/bin/ld) is GNU ld +configure:4202: result: yes +configure:4207: checking for /usr/bin/ld option to reload object files +configure:4214: result: -r +configure:4232: checking for BSD-compatible nm +configure:4281: result: /usr/bin/nm -B +configure:4285: checking whether ln -s works +configure:4289: result: yes +configure:4296: checking how to recognize dependent libraries +configure:4482: result: pass_all +configure:5013: checking how to run the C preprocessor +configure:5053: gcc -E conftest.c +configure:5059: $? = 0 +configure:5090: gcc -E conftest.c +conftest.c:8:28: error: ac_nonexistent.h: No such file or directory +configure:5096: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| #define PACKAGE_NAME "libltdl" +| #define PACKAGE_TARNAME "libltdl" +| #define PACKAGE_VERSION "1.2" +| #define PACKAGE_STRING "libltdl 1.2" +| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" +| /* end confdefs.h. */ +| #include +configure:5129: result: gcc -E +configure:5158: gcc -E conftest.c +configure:5164: $? = 0 +configure:5195: gcc -E conftest.c +conftest.c:8:28: error: ac_nonexistent.h: No such file or directory +configure:5201: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| #define PACKAGE_NAME "libltdl" +| #define PACKAGE_TARNAME "libltdl" +| #define PACKAGE_VERSION "1.2" +| #define PACKAGE_STRING "libltdl 1.2" +| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" +| /* end confdefs.h. */ +| #include +configure:5239: checking for ANSI C header files +configure:5269: gcc -c -g -O2 conftest.c >&5 +configure:5275: $? = 0 +configure:5374: gcc -o conftest -g -O2 conftest.c >&5 +configure:5377: $? = 0 +configure:5383: ./conftest +configure:5386: $? = 0 +configure:5403: result: yes +configure:5427: checking for sys/types.h +configure:5448: gcc -c -g -O2 conftest.c >&5 +configure:5454: $? = 0 +configure:5470: result: yes +configure:5427: checking for sys/stat.h +configure:5448: gcc -c -g -O2 conftest.c >&5 +configure:5454: $? = 0 +configure:5470: result: yes +configure:5427: checking for stdlib.h +configure:5448: gcc -c -g -O2 conftest.c >&5 +configure:5454: $? = 0 +configure:5470: result: yes +configure:5427: checking for string.h +configure:5448: gcc -c -g -O2 conftest.c >&5 +configure:5454: $? = 0 +configure:5470: result: yes +configure:5427: checking for memory.h +configure:5448: gcc -c -g -O2 conftest.c >&5 +configure:5454: $? = 0 +configure:5470: result: yes +configure:5427: checking for strings.h +configure:5448: gcc -c -g -O2 conftest.c >&5 +configure:5454: $? = 0 +configure:5470: result: yes +configure:5427: checking for inttypes.h +configure:5448: gcc -c -g -O2 conftest.c >&5 +configure:5454: $? = 0 +configure:5470: result: yes +configure:5427: checking for stdint.h +configure:5448: gcc -c -g -O2 conftest.c >&5 +configure:5454: $? = 0 +configure:5470: result: yes +configure:5427: checking for unistd.h +configure:5448: gcc -c -g -O2 conftest.c >&5 +configure:5454: $? = 0 +configure:5470: result: yes +configure:5497: checking dlfcn.h usability +configure:5514: gcc -c -g -O2 conftest.c >&5 +configure:5520: $? = 0 +configure:5534: result: yes +configure:5538: checking dlfcn.h presence +configure:5553: gcc -E conftest.c +configure:5559: $? = 0 +configure:5573: result: yes +configure:5606: checking for dlfcn.h +configure:5614: result: yes +configure:5685: checking for g++ +configure:5701: found /usr/lib/ccache/g++ +configure:5712: result: g++ +configure:5743: checking for C++ compiler version +configure:5750: g++ --version >&5 +g++ (GCC) 4.1.2 20070704 (Red Hat 4.1.2-15) +Copyright (C) 2006 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +configure:5753: $? = 0 +configure:5760: g++ -v >&5 +Using built-in specs. +Target: i386-redhat-linux +Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-cpu=generic --host=i386-redhat-linux +Thread model: posix +gcc version 4.1.2 20070704 (Red Hat 4.1.2-15) +configure:5763: $? = 0 +configure:5770: g++ -V >&5 +g++: '-V' option must have argument +configure:5773: $? = 1 +configure:5776: checking whether we are using the GNU C++ compiler +configure:5805: g++ -c conftest.cpp >&5 +configure:5811: $? = 0 +configure:5828: result: yes +configure:5833: checking whether g++ accepts -g +configure:5863: g++ -c -g conftest.cpp >&5 +configure:5869: $? = 0 +configure:5968: result: yes +configure:5993: checking dependency style of g++ +configure:6084: result: none +configure:6109: checking how to run the C++ preprocessor +configure:6145: g++ -E conftest.cpp +configure:6151: $? = 0 +configure:6182: g++ -E conftest.cpp +conftest.cpp:19:28: error: ac_nonexistent.h: No such file or directory +configure:6188: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| #define PACKAGE_NAME "libltdl" +| #define PACKAGE_TARNAME "libltdl" +| #define PACKAGE_VERSION "1.2" +| #define PACKAGE_STRING "libltdl 1.2" +| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_DLFCN_H 1 +| /* end confdefs.h. */ +| #include +configure:6221: result: g++ -E +configure:6250: g++ -E conftest.cpp +configure:6256: $? = 0 +configure:6287: g++ -E conftest.cpp +conftest.cpp:19:28: error: ac_nonexistent.h: No such file or directory +configure:6293: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| #define PACKAGE_NAME "libltdl" +| #define PACKAGE_TARNAME "libltdl" +| #define PACKAGE_VERSION "1.2" +| #define PACKAGE_STRING "libltdl 1.2" +| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_DLFCN_H 1 +| /* end confdefs.h. */ +| #include +configure:6386: checking for g77 +configure:6416: result: no +configure:6386: checking for xlf +configure:6416: result: no +configure:6386: checking for f77 +configure:6416: result: no +configure:6386: checking for frt +configure:6416: result: no +configure:6386: checking for pgf77 +configure:6416: result: no +configure:6386: checking for cf77 +configure:6416: result: no +configure:6386: checking for fort77 +configure:6416: result: no +configure:6386: checking for fl32 +configure:6416: result: no +configure:6386: checking for af77 +configure:6416: result: no +configure:6386: checking for xlf90 +configure:6416: result: no +configure:6386: checking for f90 +configure:6416: result: no +configure:6386: checking for pgf90 +configure:6416: result: no +configure:6386: checking for pghpf +configure:6416: result: no +configure:6386: checking for epcf90 +configure:6416: result: no +configure:6386: checking for gfortran +configure:6402: found /usr/bin/gfortran +configure:6413: result: gfortran +configure:6443: checking for Fortran 77 compiler version +configure:6450: gfortran --version >&5 +GNU Fortran (GCC) 4.1.2 20070704 (Red Hat 4.1.2-15) +Copyright (C) 2007 Free Software Foundation, Inc. + +GNU Fortran comes with NO WARRANTY, to the extent permitted by law. +You may redistribute copies of GNU Fortran +under the terms of the GNU General Public License. +For more information about these matters, see the file named COPYING + +configure:6453: $? = 0 +configure:6460: gfortran -v >&5 +Using built-in specs. +Target: i386-redhat-linux +Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-cpu=generic --host=i386-redhat-linux +Thread model: posix +gcc version 4.1.2 20070704 (Red Hat 4.1.2-15) +configure:6463: $? = 0 +configure:6470: gfortran -V >&5 +gfortran: '-V' option must have argument +configure:6473: $? = 1 +configure:6481: checking whether we are using the GNU Fortran 77 compiler +configure:6500: gfortran -c conftest.F >&5 +configure:6506: $? = 0 +configure:6523: result: yes +configure:6529: checking whether gfortran accepts -g +configure:6546: gfortran -c -g conftest.f >&5 +configure:6552: $? = 0 +configure:6568: result: yes +configure:6598: checking the maximum length of command line arguments +configure:6710: result: 98304 +configure:6722: checking command to parse /usr/bin/nm -B output from gcc object +configure:6827: gcc -c -g -O2 conftest.c >&5 +configure:6830: $? = 0 +configure:6834: /usr/bin/nm -B conftest.o \| sed -n -e 's/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p' \> conftest.nm +configure:6837: $? = 0 +configure:6889: gcc -o conftest -g -O2 conftest.c conftstm.o >&5 +configure:6892: $? = 0 +configure:6930: result: ok +configure:6934: checking for objdir +configure:6949: result: .libs +configure:7041: checking for ar +configure:7057: found /usr/bin/ar +configure:7068: result: ar +configure:7137: checking for ranlib +configure:7153: found /usr/bin/ranlib +configure:7164: result: ranlib +configure:7233: checking for strip +configure:7249: found /usr/bin/strip +configure:7260: result: strip +configure:7550: checking if gcc supports -fno-rtti -fno-exceptions +configure:7568: gcc -c -g -O2 -fno-rtti -fno-exceptions conftest.c >&5 +cc1: warning: command line option "-fno-rtti" is valid for C++/ObjC++ but not for C +cc1: warning: command line option "-fno-rtti" is valid for C++/ObjC++ but not for C +configure:7572: $? = 0 +configure:7585: result: no +configure:7600: checking for gcc option to produce PIC +configure:7832: result: -fPIC +configure:7840: checking if gcc PIC flag -fPIC works +configure:7858: gcc -c -g -O2 -fPIC -DPIC conftest.c >&5 +configure:7862: $? = 0 +configure:7875: result: yes +configure:7903: checking if gcc static flag -static works +configure:7931: result: yes +configure:7941: checking if gcc supports -c -o file.o +configure:7962: gcc -c -g -O2 -o out/conftest2.o conftest.c >&5 +configure:7966: $? = 0 +configure:7988: result: yes +configure:8014: checking whether the gcc linker (/usr/bin/ld) supports shared libraries +configure:8994: result: yes +configure:9015: checking whether -lc should be explicitly linked in +configure:9020: gcc -c -g -O2 conftest.c >&5 +configure:9023: $? = 0 +configure:9038: gcc -shared conftest.o -v -Wl,-soname -Wl,conftest -o conftest 2\>\&1 \| grep -lc \>/dev/null 2\>\&1 +configure:9041: $? = 0 +configure:9053: result: no +configure:9061: checking dynamic linker characteristics +configure:9665: result: GNU/Linux ld.so +configure:9674: checking how to hardcode library paths into programs +configure:9699: result: immediate +configure:9713: checking whether stripping libraries is possible +configure:9718: result: yes +configure:10520: checking if libtool supports shared libraries +configure:10522: result: yes +configure:10525: checking whether to build shared libraries +configure:10546: result: yes +configure:10549: checking whether to build static libraries +configure:10553: result: yes +configure:10646: creating libtool +configure:11234: checking for ld used by g++ +configure:11301: result: /usr/bin/ld +configure:11310: checking if the linker (/usr/bin/ld) is GNU ld +configure:11325: result: yes +configure:11376: checking whether the g++ linker (/usr/bin/ld) supports shared libraries +configure:12350: result: yes +configure:12372: g++ -c -g -O2 conftest.cpp >&5 +configure:12375: $? = 0 +configure:12527: checking for g++ option to produce PIC +configure:12811: result: -fPIC +configure:12819: checking if g++ PIC flag -fPIC works +configure:12837: g++ -c -g -O2 -fPIC -DPIC conftest.cpp >&5 +configure:12841: $? = 0 +configure:12854: result: yes +configure:12882: checking if g++ static flag -static works +configure:12910: result: yes +configure:12920: checking if g++ supports -c -o file.o +configure:12941: g++ -c -g -O2 -o out/conftest2.o conftest.cpp >&5 +configure:12945: $? = 0 +configure:12967: result: yes +configure:12993: checking whether the g++ linker (/usr/bin/ld) supports shared libraries +configure:13018: result: yes +configure:13085: checking dynamic linker characteristics +configure:13637: result: GNU/Linux ld.so +configure:13646: checking how to hardcode library paths into programs +configure:13671: result: immediate +configure:14205: checking if libtool supports shared libraries +configure:14207: result: yes +configure:14210: checking whether to build shared libraries +configure:14230: result: yes +configure:14233: checking whether to build static libraries +configure:14237: result: yes +configure:14247: checking for gfortran option to produce PIC +configure:14479: result: -fPIC +configure:14487: checking if gfortran PIC flag -fPIC works +configure:14505: gfortran -c -g -O2 -fPIC conftest.f >&5 +configure:14509: $? = 0 +configure:14522: result: yes +configure:14550: checking if gfortran static flag -static works +configure:14578: result: yes +configure:14588: checking if gfortran supports -c -o file.o +configure:14609: gfortran -c -g -O2 -o out/conftest2.o conftest.f >&5 +configure:14613: $? = 0 +configure:14635: result: yes +configure:14661: checking whether the gfortran linker (/usr/bin/ld) supports shared libraries +configure:15621: result: yes +configure:15688: checking dynamic linker characteristics +configure:16240: result: GNU/Linux ld.so +configure:16249: checking how to hardcode library paths into programs +configure:16274: result: immediate +configure:19860: checking for dirent.h that defines DIR +configure:19889: gcc -c -g -O2 conftest.c >&5 +configure:19895: $? = 0 +configure:19911: result: yes +configure:19924: checking for library containing opendir +configure:19965: gcc -o conftest -g -O2 conftest.c >&5 +configure:19971: $? = 0 +configure:19999: result: none required +configure:20117: checking which extension is used for loadable modules +configure:20127: result: .so +configure:20138: checking which variable specifies run-time library path +configure:20145: result: LD_LIBRARY_PATH +configure:20156: checking for the default library search path +configure:20163: result: /usr/lib /lib /usr/lib/qt-3.3/lib +configure:20181: checking for objdir +configure:20202: result: .libs +configure:20211: checking whether libtool supports -dlopen/-dlpreopen +configure:20223: result: yes +configure:20242: checking for shl_load +configure:20298: gcc -o conftest -g -O2 conftest.c >&5 +/tmp/ccPBezQi.o: In function `main': +/home/lennart/projects/pulseaudio/libltdl/conftest.c:59: undefined reference to `shl_load' +collect2: ld returned 1 exit status +configure:20304: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| #define PACKAGE_NAME "libltdl" +| #define PACKAGE_TARNAME "libltdl" +| #define PACKAGE_VERSION "1.2" +| #define PACKAGE_STRING "libltdl 1.2" +| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_DLFCN_H 1 +| #define HAVE_DIRENT_H 1 +| #define LTDL_SHLIB_EXT ".so" +| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" +| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" +| #define LTDL_OBJDIR ".libs/" +| #define HAVE_PRELOADED_SYMBOLS 1 +| /* end confdefs.h. */ +| /* Define shl_load to an innocuous variant, in case declares shl_load. +| For example, HP-UX 11i declares gettimeofday. */ +| #define shl_load innocuous_shl_load +| +| /* System header to define __stub macros and hopefully few prototypes, +| which can conflict with char shl_load (); below. +| Prefer to if __STDC__ is defined, since +| exists even on freestanding compilers. */ +| +| #ifdef __STDC__ +| # include +| #else +| # include +| #endif +| +| #undef shl_load +| +| /* Override any GCC internal prototype to avoid an error. +| Use char because int might match the return type of a GCC +| builtin and then its argument prototype would still apply. */ +| #ifdef __cplusplus +| extern "C" +| #endif +| char shl_load (); +| /* The GNU C library defines this for functions which it implements +| to always fail with ENOSYS. Some functions are actually named +| something starting with __ and the normal name is an alias. */ +| #if defined __stub_shl_load || defined __stub___shl_load +| choke me +| #endif +| +| int +| main () +| { +| return shl_load (); +| ; +| return 0; +| } +configure:20321: result: no +configure:20330: checking for shl_load in -ldld +configure:20365: gcc -o conftest -g -O2 conftest.c -ldld >&5 +/usr/bin/ld: cannot find -ldld +collect2: ld returned 1 exit status +configure:20371: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| #define PACKAGE_NAME "libltdl" +| #define PACKAGE_TARNAME "libltdl" +| #define PACKAGE_VERSION "1.2" +| #define PACKAGE_STRING "libltdl 1.2" +| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_DLFCN_H 1 +| #define HAVE_DIRENT_H 1 +| #define LTDL_SHLIB_EXT ".so" +| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" +| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" +| #define LTDL_OBJDIR ".libs/" +| #define HAVE_PRELOADED_SYMBOLS 1 +| /* end confdefs.h. */ +| +| /* Override any GCC internal prototype to avoid an error. +| Use char because int might match the return type of a GCC +| builtin and then its argument prototype would still apply. */ +| #ifdef __cplusplus +| extern "C" +| #endif +| char shl_load (); +| int +| main () +| { +| return shl_load (); +| ; +| return 0; +| } +configure:20389: result: no +configure:20399: checking for dlopen in -ldl +configure:20434: gcc -o conftest -g -O2 conftest.c -ldl >&5 +configure:20440: $? = 0 +configure:20458: result: yes +configure:20769: checking for dlerror +configure:20825: gcc -o conftest -g -O2 conftest.c -ldl >&5 +configure:20831: $? = 0 +configure:20849: result: yes +configure:20869: checking for _ prefix in compiled symbols +configure:20879: gcc -c -g -O2 conftest.c >&5 +configure:20882: $? = 0 +configure:20886: /usr/bin/nm -B conftest.o \| sed -n -e 's/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p' \> conftest.nm +configure:20889: $? = 0 +configure:20911: result: no +configure:21031: checking whether deplibs are loaded by dlopen +configure:21115: result: yes +configure:21140: checking argz.h usability +configure:21157: gcc -c -g -O2 conftest.c >&5 +configure:21163: $? = 0 +configure:21177: result: yes +configure:21181: checking argz.h presence +configure:21196: gcc -E conftest.c +configure:21202: $? = 0 +configure:21216: result: yes +configure:21249: checking for argz.h +configure:21257: result: yes +configure:21271: checking for error_t +configure:21304: gcc -c -g -O2 conftest.c >&5 +configure:21310: $? = 0 +configure:21325: result: yes +configure:21351: checking for argz_append +configure:21407: gcc -o conftest -g -O2 conftest.c >&5 +configure:21413: $? = 0 +configure:21431: result: yes +configure:21351: checking for argz_create_sep +configure:21407: gcc -o conftest -g -O2 conftest.c >&5 +configure:21413: $? = 0 +configure:21431: result: yes +configure:21351: checking for argz_insert +configure:21407: gcc -o conftest -g -O2 conftest.c >&5 +configure:21413: $? = 0 +configure:21431: result: yes +configure:21351: checking for argz_next +configure:21407: gcc -o conftest -g -O2 conftest.c >&5 +configure:21413: $? = 0 +configure:21431: result: yes +configure:21351: checking for argz_stringify +configure:21407: gcc -o conftest -g -O2 conftest.c >&5 +configure:21413: $? = 0 +configure:21431: result: yes +configure:21483: checking assert.h usability +configure:21500: gcc -c -g -O2 conftest.c >&5 +configure:21506: $? = 0 +configure:21520: result: yes +configure:21524: checking assert.h presence +configure:21539: gcc -E conftest.c +configure:21545: $? = 0 +configure:21559: result: yes +configure:21592: checking for assert.h +configure:21600: result: yes +configure:21483: checking ctype.h usability +configure:21500: gcc -c -g -O2 conftest.c >&5 +configure:21506: $? = 0 +configure:21520: result: yes +configure:21524: checking ctype.h presence +configure:21539: gcc -E conftest.c +configure:21545: $? = 0 +configure:21559: result: yes +configure:21592: checking for ctype.h +configure:21600: result: yes +configure:21483: checking errno.h usability +configure:21500: gcc -c -g -O2 conftest.c >&5 +configure:21506: $? = 0 +configure:21520: result: yes +configure:21524: checking errno.h presence +configure:21539: gcc -E conftest.c +configure:21545: $? = 0 +configure:21559: result: yes +configure:21592: checking for errno.h +configure:21600: result: yes +configure:21483: checking malloc.h usability +configure:21500: gcc -c -g -O2 conftest.c >&5 +configure:21506: $? = 0 +configure:21520: result: yes +configure:21524: checking malloc.h presence +configure:21539: gcc -E conftest.c +configure:21545: $? = 0 +configure:21559: result: yes +configure:21592: checking for malloc.h +configure:21600: result: yes +configure:21473: checking for memory.h +configure:21479: result: yes +configure:21473: checking for stdlib.h +configure:21479: result: yes +configure:21483: checking stdio.h usability +configure:21500: gcc -c -g -O2 conftest.c >&5 +configure:21506: $? = 0 +configure:21520: result: yes +configure:21524: checking stdio.h presence +configure:21539: gcc -E conftest.c +configure:21545: $? = 0 +configure:21559: result: yes +configure:21592: checking for stdio.h +configure:21600: result: yes +configure:21473: checking for unistd.h +configure:21479: result: yes +configure:21631: checking dl.h usability +configure:21648: gcc -c -g -O2 conftest.c >&5 +conftest.c:75:16: error: dl.h: No such file or directory +configure:21654: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| #define PACKAGE_NAME "libltdl" +| #define PACKAGE_TARNAME "libltdl" +| #define PACKAGE_VERSION "1.2" +| #define PACKAGE_STRING "libltdl 1.2" +| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_DLFCN_H 1 +| #define HAVE_DIRENT_H 1 +| #define LTDL_SHLIB_EXT ".so" +| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" +| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" +| #define LTDL_OBJDIR ".libs/" +| #define HAVE_PRELOADED_SYMBOLS 1 +| #define HAVE_LIBDL 1 +| #define HAVE_DLERROR 1 +| #define HAVE_ARGZ_H 1 +| #define HAVE_ERROR_T 1 +| #define HAVE_ARGZ_APPEND 1 +| #define HAVE_ARGZ_CREATE_SEP 1 +| #define HAVE_ARGZ_INSERT 1 +| #define HAVE_ARGZ_NEXT 1 +| #define HAVE_ARGZ_STRINGIFY 1 +| #define HAVE_ASSERT_H 1 +| #define HAVE_CTYPE_H 1 +| #define HAVE_ERRNO_H 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STDIO_H 1 +| #define HAVE_UNISTD_H 1 +| /* end confdefs.h. */ +| #include +| #ifdef HAVE_SYS_TYPES_H +| # include +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include +| #endif +| #ifdef STDC_HEADERS +| # include +| # include +| #else +| # ifdef HAVE_STDLIB_H +| # include +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #ifdef HAVE_STRINGS_H +| # include +| #endif +| #ifdef HAVE_INTTYPES_H +| # include +| #endif +| #ifdef HAVE_STDINT_H +| # include +| #endif +| #ifdef HAVE_UNISTD_H +| # include +| #endif +| #include +configure:21668: result: no +configure:21672: checking dl.h presence +configure:21687: gcc -E conftest.c +conftest.c:42:16: error: dl.h: No such file or directory +configure:21693: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| #define PACKAGE_NAME "libltdl" +| #define PACKAGE_TARNAME "libltdl" +| #define PACKAGE_VERSION "1.2" +| #define PACKAGE_STRING "libltdl 1.2" +| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_DLFCN_H 1 +| #define HAVE_DIRENT_H 1 +| #define LTDL_SHLIB_EXT ".so" +| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" +| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" +| #define LTDL_OBJDIR ".libs/" +| #define HAVE_PRELOADED_SYMBOLS 1 +| #define HAVE_LIBDL 1 +| #define HAVE_DLERROR 1 +| #define HAVE_ARGZ_H 1 +| #define HAVE_ERROR_T 1 +| #define HAVE_ARGZ_APPEND 1 +| #define HAVE_ARGZ_CREATE_SEP 1 +| #define HAVE_ARGZ_INSERT 1 +| #define HAVE_ARGZ_NEXT 1 +| #define HAVE_ARGZ_STRINGIFY 1 +| #define HAVE_ASSERT_H 1 +| #define HAVE_CTYPE_H 1 +| #define HAVE_ERRNO_H 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STDIO_H 1 +| #define HAVE_UNISTD_H 1 +| /* end confdefs.h. */ +| #include +configure:21707: result: no +configure:21740: checking for dl.h +configure:21748: result: no +configure:21631: checking sys/dl.h usability +configure:21648: gcc -c -g -O2 conftest.c >&5 +conftest.c:75:20: error: sys/dl.h: No such file or directory +configure:21654: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| #define PACKAGE_NAME "libltdl" +| #define PACKAGE_TARNAME "libltdl" +| #define PACKAGE_VERSION "1.2" +| #define PACKAGE_STRING "libltdl 1.2" +| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_DLFCN_H 1 +| #define HAVE_DIRENT_H 1 +| #define LTDL_SHLIB_EXT ".so" +| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" +| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" +| #define LTDL_OBJDIR ".libs/" +| #define HAVE_PRELOADED_SYMBOLS 1 +| #define HAVE_LIBDL 1 +| #define HAVE_DLERROR 1 +| #define HAVE_ARGZ_H 1 +| #define HAVE_ERROR_T 1 +| #define HAVE_ARGZ_APPEND 1 +| #define HAVE_ARGZ_CREATE_SEP 1 +| #define HAVE_ARGZ_INSERT 1 +| #define HAVE_ARGZ_NEXT 1 +| #define HAVE_ARGZ_STRINGIFY 1 +| #define HAVE_ASSERT_H 1 +| #define HAVE_CTYPE_H 1 +| #define HAVE_ERRNO_H 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STDIO_H 1 +| #define HAVE_UNISTD_H 1 +| /* end confdefs.h. */ +| #include +| #ifdef HAVE_SYS_TYPES_H +| # include +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include +| #endif +| #ifdef STDC_HEADERS +| # include +| # include +| #else +| # ifdef HAVE_STDLIB_H +| # include +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #ifdef HAVE_STRINGS_H +| # include +| #endif +| #ifdef HAVE_INTTYPES_H +| # include +| #endif +| #ifdef HAVE_STDINT_H +| # include +| #endif +| #ifdef HAVE_UNISTD_H +| # include +| #endif +| #include +configure:21668: result: no +configure:21672: checking sys/dl.h presence +configure:21687: gcc -E conftest.c +conftest.c:42:20: error: sys/dl.h: No such file or directory +configure:21693: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| #define PACKAGE_NAME "libltdl" +| #define PACKAGE_TARNAME "libltdl" +| #define PACKAGE_VERSION "1.2" +| #define PACKAGE_STRING "libltdl 1.2" +| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_DLFCN_H 1 +| #define HAVE_DIRENT_H 1 +| #define LTDL_SHLIB_EXT ".so" +| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" +| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" +| #define LTDL_OBJDIR ".libs/" +| #define HAVE_PRELOADED_SYMBOLS 1 +| #define HAVE_LIBDL 1 +| #define HAVE_DLERROR 1 +| #define HAVE_ARGZ_H 1 +| #define HAVE_ERROR_T 1 +| #define HAVE_ARGZ_APPEND 1 +| #define HAVE_ARGZ_CREATE_SEP 1 +| #define HAVE_ARGZ_INSERT 1 +| #define HAVE_ARGZ_NEXT 1 +| #define HAVE_ARGZ_STRINGIFY 1 +| #define HAVE_ASSERT_H 1 +| #define HAVE_CTYPE_H 1 +| #define HAVE_ERRNO_H 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STDIO_H 1 +| #define HAVE_UNISTD_H 1 +| /* end confdefs.h. */ +| #include +configure:21707: result: no +configure:21740: checking for sys/dl.h +configure:21748: result: no +configure:21631: checking dld.h usability +configure:21648: gcc -c -g -O2 conftest.c >&5 +conftest.c:75:17: error: dld.h: No such file or directory +configure:21654: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| #define PACKAGE_NAME "libltdl" +| #define PACKAGE_TARNAME "libltdl" +| #define PACKAGE_VERSION "1.2" +| #define PACKAGE_STRING "libltdl 1.2" +| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_DLFCN_H 1 +| #define HAVE_DIRENT_H 1 +| #define LTDL_SHLIB_EXT ".so" +| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" +| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" +| #define LTDL_OBJDIR ".libs/" +| #define HAVE_PRELOADED_SYMBOLS 1 +| #define HAVE_LIBDL 1 +| #define HAVE_DLERROR 1 +| #define HAVE_ARGZ_H 1 +| #define HAVE_ERROR_T 1 +| #define HAVE_ARGZ_APPEND 1 +| #define HAVE_ARGZ_CREATE_SEP 1 +| #define HAVE_ARGZ_INSERT 1 +| #define HAVE_ARGZ_NEXT 1 +| #define HAVE_ARGZ_STRINGIFY 1 +| #define HAVE_ASSERT_H 1 +| #define HAVE_CTYPE_H 1 +| #define HAVE_ERRNO_H 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STDIO_H 1 +| #define HAVE_UNISTD_H 1 +| /* end confdefs.h. */ +| #include +| #ifdef HAVE_SYS_TYPES_H +| # include +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include +| #endif +| #ifdef STDC_HEADERS +| # include +| # include +| #else +| # ifdef HAVE_STDLIB_H +| # include +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #ifdef HAVE_STRINGS_H +| # include +| #endif +| #ifdef HAVE_INTTYPES_H +| # include +| #endif +| #ifdef HAVE_STDINT_H +| # include +| #endif +| #ifdef HAVE_UNISTD_H +| # include +| #endif +| #include +configure:21668: result: no +configure:21672: checking dld.h presence +configure:21687: gcc -E conftest.c +conftest.c:42:17: error: dld.h: No such file or directory +configure:21693: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| #define PACKAGE_NAME "libltdl" +| #define PACKAGE_TARNAME "libltdl" +| #define PACKAGE_VERSION "1.2" +| #define PACKAGE_STRING "libltdl 1.2" +| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_DLFCN_H 1 +| #define HAVE_DIRENT_H 1 +| #define LTDL_SHLIB_EXT ".so" +| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" +| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" +| #define LTDL_OBJDIR ".libs/" +| #define HAVE_PRELOADED_SYMBOLS 1 +| #define HAVE_LIBDL 1 +| #define HAVE_DLERROR 1 +| #define HAVE_ARGZ_H 1 +| #define HAVE_ERROR_T 1 +| #define HAVE_ARGZ_APPEND 1 +| #define HAVE_ARGZ_CREATE_SEP 1 +| #define HAVE_ARGZ_INSERT 1 +| #define HAVE_ARGZ_NEXT 1 +| #define HAVE_ARGZ_STRINGIFY 1 +| #define HAVE_ASSERT_H 1 +| #define HAVE_CTYPE_H 1 +| #define HAVE_ERRNO_H 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STDIO_H 1 +| #define HAVE_UNISTD_H 1 +| /* end confdefs.h. */ +| #include +configure:21707: result: no +configure:21740: checking for dld.h +configure:21748: result: no +configure:21631: checking mach-o/dyld.h usability +configure:21648: gcc -c -g -O2 conftest.c >&5 +conftest.c:75:25: error: mach-o/dyld.h: No such file or directory +configure:21654: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| #define PACKAGE_NAME "libltdl" +| #define PACKAGE_TARNAME "libltdl" +| #define PACKAGE_VERSION "1.2" +| #define PACKAGE_STRING "libltdl 1.2" +| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_DLFCN_H 1 +| #define HAVE_DIRENT_H 1 +| #define LTDL_SHLIB_EXT ".so" +| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" +| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" +| #define LTDL_OBJDIR ".libs/" +| #define HAVE_PRELOADED_SYMBOLS 1 +| #define HAVE_LIBDL 1 +| #define HAVE_DLERROR 1 +| #define HAVE_ARGZ_H 1 +| #define HAVE_ERROR_T 1 +| #define HAVE_ARGZ_APPEND 1 +| #define HAVE_ARGZ_CREATE_SEP 1 +| #define HAVE_ARGZ_INSERT 1 +| #define HAVE_ARGZ_NEXT 1 +| #define HAVE_ARGZ_STRINGIFY 1 +| #define HAVE_ASSERT_H 1 +| #define HAVE_CTYPE_H 1 +| #define HAVE_ERRNO_H 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STDIO_H 1 +| #define HAVE_UNISTD_H 1 +| /* end confdefs.h. */ +| #include +| #ifdef HAVE_SYS_TYPES_H +| # include +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include +| #endif +| #ifdef STDC_HEADERS +| # include +| # include +| #else +| # ifdef HAVE_STDLIB_H +| # include +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #ifdef HAVE_STRINGS_H +| # include +| #endif +| #ifdef HAVE_INTTYPES_H +| # include +| #endif +| #ifdef HAVE_STDINT_H +| # include +| #endif +| #ifdef HAVE_UNISTD_H +| # include +| #endif +| #include +configure:21668: result: no +configure:21672: checking mach-o/dyld.h presence +configure:21687: gcc -E conftest.c +conftest.c:42:25: error: mach-o/dyld.h: No such file or directory +configure:21693: $? = 1 +configure: failed program was: +| /* confdefs.h. */ +| #define PACKAGE_NAME "libltdl" +| #define PACKAGE_TARNAME "libltdl" +| #define PACKAGE_VERSION "1.2" +| #define PACKAGE_STRING "libltdl 1.2" +| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_DLFCN_H 1 +| #define HAVE_DIRENT_H 1 +| #define LTDL_SHLIB_EXT ".so" +| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" +| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" +| #define LTDL_OBJDIR ".libs/" +| #define HAVE_PRELOADED_SYMBOLS 1 +| #define HAVE_LIBDL 1 +| #define HAVE_DLERROR 1 +| #define HAVE_ARGZ_H 1 +| #define HAVE_ERROR_T 1 +| #define HAVE_ARGZ_APPEND 1 +| #define HAVE_ARGZ_CREATE_SEP 1 +| #define HAVE_ARGZ_INSERT 1 +| #define HAVE_ARGZ_NEXT 1 +| #define HAVE_ARGZ_STRINGIFY 1 +| #define HAVE_ASSERT_H 1 +| #define HAVE_CTYPE_H 1 +| #define HAVE_ERRNO_H 1 +| #define HAVE_MALLOC_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STDIO_H 1 +| #define HAVE_UNISTD_H 1 +| /* end confdefs.h. */ +| #include +configure:21707: result: no +configure:21740: checking for mach-o/dyld.h +configure:21748: result: no +configure:21767: checking for string.h +configure:21773: result: yes +configure:21913: checking for strchr +configure:21969: gcc -o conftest -g -O2 conftest.c >&5 +conftest.c:66: warning: conflicting types for built-in function 'strchr' +configure:21975: $? = 0 +configure:21993: result: yes +configure:22008: checking for strrchr +configure:22064: gcc -o conftest -g -O2 conftest.c >&5 +conftest.c:67: warning: conflicting types for built-in function 'strrchr' +configure:22070: $? = 0 +configure:22088: result: yes +configure:22103: checking for memcpy +configure:22159: gcc -o conftest -g -O2 conftest.c >&5 +conftest.c:68: warning: conflicting types for built-in function 'memcpy' +configure:22165: $? = 0 +configure:22183: result: yes +configure:22198: checking for memmove +configure:22254: gcc -o conftest -g -O2 conftest.c >&5 +conftest.c:69: warning: conflicting types for built-in function 'memmove' +configure:22260: $? = 0 +configure:22278: result: yes +configure:22198: checking for strcmp +configure:22254: gcc -o conftest -g -O2 conftest.c >&5 +conftest.c:70: warning: conflicting types for built-in function 'strcmp' +configure:22260: $? = 0 +configure:22278: result: yes +configure:22294: checking for closedir +configure:22350: gcc -o conftest -g -O2 conftest.c >&5 +configure:22356: $? = 0 +configure:22374: result: yes +configure:22294: checking for opendir +configure:22350: gcc -o conftest -g -O2 conftest.c >&5 +configure:22356: $? = 0 +configure:22374: result: yes +configure:22294: checking for readdir +configure:22350: gcc -o conftest -g -O2 conftest.c >&5 +configure:22356: $? = 0 +configure:22374: result: yes +configure:22527: creating ./config.status + +## ---------------------- ## +## Running config.status. ## +## ---------------------- ## + +This file was extended by libltdl config.status 1.2, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = + CONFIG_HEADERS = + CONFIG_LINKS = + CONFIG_COMMANDS = + $ ./config.status + +on lambda + +config.status:671: creating Makefile +config.status:671: creating config.h +config.status:936: config.h is unchanged +config.status:982: executing depfiles commands + +## ---------------- ## +## Cache variables. ## +## ---------------- ## + +ac_cv_build=i686-pc-linux-gnu +ac_cv_c_compiler_gnu=yes +ac_cv_c_const=yes +ac_cv_c_inline=inline +ac_cv_cxx_compiler_gnu=yes +ac_cv_env_CCC_set= +ac_cv_env_CCC_value= +ac_cv_env_CC_set= +ac_cv_env_CC_value= +ac_cv_env_CFLAGS_set= +ac_cv_env_CFLAGS_value= +ac_cv_env_CPPFLAGS_set= +ac_cv_env_CPPFLAGS_value= +ac_cv_env_CPP_set= +ac_cv_env_CPP_value= +ac_cv_env_CXXCPP_set= +ac_cv_env_CXXCPP_value= +ac_cv_env_CXXFLAGS_set= +ac_cv_env_CXXFLAGS_value= +ac_cv_env_CXX_set= +ac_cv_env_CXX_value= +ac_cv_env_F77_set= +ac_cv_env_F77_value= +ac_cv_env_FFLAGS_set= +ac_cv_env_FFLAGS_value= +ac_cv_env_LDFLAGS_set= +ac_cv_env_LDFLAGS_value= +ac_cv_env_LIBS_set= +ac_cv_env_LIBS_value= +ac_cv_env_build_alias_set= +ac_cv_env_build_alias_value= +ac_cv_env_host_alias_set= +ac_cv_env_host_alias_value= +ac_cv_env_target_alias_set= +ac_cv_env_target_alias_value= +ac_cv_f77_compiler_gnu=yes +ac_cv_func_argz_append=yes +ac_cv_func_argz_create_sep=yes +ac_cv_func_argz_insert=yes +ac_cv_func_argz_next=yes +ac_cv_func_argz_stringify=yes +ac_cv_func_closedir=yes +ac_cv_func_dlerror=yes +ac_cv_func_memcpy=yes +ac_cv_func_memmove=yes +ac_cv_func_opendir=yes +ac_cv_func_readdir=yes +ac_cv_func_shl_load=no +ac_cv_func_strchr=yes +ac_cv_func_strcmp=yes +ac_cv_func_strrchr=yes +ac_cv_header_argz_h=yes +ac_cv_header_assert_h=yes +ac_cv_header_ctype_h=yes +ac_cv_header_dirent_dirent_h=yes +ac_cv_header_dl_h=no +ac_cv_header_dld_h=no +ac_cv_header_dlfcn_h=yes +ac_cv_header_errno_h=yes +ac_cv_header_inttypes_h=yes +ac_cv_header_mach_o_dyld_h=no +ac_cv_header_malloc_h=yes +ac_cv_header_memory_h=yes +ac_cv_header_stdc=yes +ac_cv_header_stdint_h=yes +ac_cv_header_stdio_h=yes +ac_cv_header_stdlib_h=yes +ac_cv_header_string_h=yes +ac_cv_header_strings_h=yes +ac_cv_header_sys_dl_h=no +ac_cv_header_sys_stat_h=yes +ac_cv_header_sys_types_h=yes +ac_cv_header_unistd_h=yes +ac_cv_host=i686-pc-linux-gnu +ac_cv_lib_dl_dlopen=yes +ac_cv_lib_dld_shl_load=no +ac_cv_objext=o +ac_cv_path_EGREP='/bin/grep -E' +ac_cv_path_GREP=/bin/grep +ac_cv_path_install='/usr/bin/install -c' +ac_cv_path_mkdir=/bin/mkdir +ac_cv_prog_AWK=gawk +ac_cv_prog_CPP='gcc -E' +ac_cv_prog_CXXCPP='g++ -E' +ac_cv_prog_ac_ct_AR=ar +ac_cv_prog_ac_ct_CC=gcc +ac_cv_prog_ac_ct_CXX=g++ +ac_cv_prog_ac_ct_F77=gfortran +ac_cv_prog_ac_ct_RANLIB=ranlib +ac_cv_prog_ac_ct_STRIP=strip +ac_cv_prog_cc_c89= +ac_cv_prog_cc_g=yes +ac_cv_prog_cxx_g=yes +ac_cv_prog_f77_g=yes +ac_cv_prog_make_make_set=yes +ac_cv_search_opendir='none required' +ac_cv_sys_symbol_underscore=no +ac_cv_type_error_t=yes +am_cv_CC_dependencies_compiler_type=none +am_cv_CXX_dependencies_compiler_type=none +libltdl_cv_lib_dl_dlopen=yes +libltdl_cv_objdir=.libs +libltdl_cv_preloaded_symbols=yes +libltdl_cv_shlibext=.so +libltdl_cv_shlibpath_var=LD_LIBRARY_PATH +libltdl_cv_sys_dlopen_deplibs=yes +libltdl_cv_sys_search_path='/usr/lib /lib /usr/lib/qt-3.3/lib ' +lt_cv_deplibs_check_method=pass_all +lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_ld_reload_flag=-r +lt_cv_objdir=.libs +lt_cv_path_LD=/usr/bin/ld +lt_cv_path_LDCXX=/usr/bin/ld +lt_cv_path_NM='/usr/bin/nm -B' +lt_cv_path_SED=/bin/sed +lt_cv_prog_compiler_c_o=yes +lt_cv_prog_compiler_c_o_CXX=yes +lt_cv_prog_compiler_c_o_F77=yes +lt_cv_prog_compiler_rtti_exceptions=no +lt_cv_prog_gnu_ld=yes +lt_cv_prog_gnu_ldcxx=yes +lt_cv_sys_global_symbol_pipe='sed -n -e '\''s/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p'\''' +lt_cv_sys_global_symbol_to_c_name_address='sed -n -e '\''s/^: \([^ ]*\) $/ {\"\1\", (lt_ptr) 0},/p'\'' -e '\''s/^[BCDEGRST] \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr) \&\2},/p'\''' +lt_cv_sys_global_symbol_to_cdecl='sed -n -e '\''s/^. .* \(.*\)$/extern int \1;/p'\''' +lt_cv_sys_max_cmd_len=98304 +lt_lt_cv_prog_compiler_c_o='"yes"' +lt_lt_cv_prog_compiler_c_o_CXX='"yes"' +lt_lt_cv_prog_compiler_c_o_F77='"yes"' +lt_lt_cv_sys_global_symbol_pipe='"sed -n -e '\''s/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2 \\2/p'\''"' +lt_lt_cv_sys_global_symbol_to_c_name_address='"sed -n -e '\''s/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p'\'' -e '\''s/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'\''"' +lt_lt_cv_sys_global_symbol_to_cdecl='"sed -n -e '\''s/^. .* \\(.*\\)\$/extern int \\1;/p'\''"' + +## ----------------- ## +## Output variables. ## +## ----------------- ## + +ACLOCAL='${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run aclocal-1.10' +AMDEPBACKSLASH='\' +AMDEP_FALSE='#' +AMDEP_TRUE='' +AMTAR='${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run tar' +AR='ar' +AS='as' +AUTOCONF='${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run autoconf' +AUTOHEADER='${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run autoheader' +AUTOMAKE='${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run automake-1.10' +AWK='gawk' +CC='gcc' +CCDEPMODE='depmode=none' +CFLAGS='-g -O2' +CONVENIENCE_LTDL_FALSE='' +CONVENIENCE_LTDL_TRUE='#' +CPP='gcc -E' +CPPFLAGS='' +CXX='g++' +CXXCPP='g++ -E' +CXXDEPMODE='depmode=none' +CXXFLAGS='-g -O2' +CYGPATH_W='echo' +DEFS='-DHAVE_CONFIG_H' +DEPDIR='.deps' +DLLTOOL='dlltool' +ECHO='echo' +ECHO_C='' +ECHO_N='-n' +ECHO_T='' +EGREP='/bin/grep -E' +EXEEXT='' +F77='gfortran' +FFLAGS='-g -O2' +GREP='/bin/grep' +INSTALL_DATA='${INSTALL} -m 644' +INSTALL_LTDL_FALSE='#' +INSTALL_LTDL_TRUE='' +INSTALL_PROGRAM='${INSTALL}' +INSTALL_SCRIPT='${INSTALL}' +INSTALL_STRIP_PROGRAM='$(install_sh) -c -s' +LDFLAGS='' +LIBADD_DL='-ldl' +LIBOBJS='' +LIBS='' +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +LIBTOOL_DEPS='./ltmain.sh' +LN_S='ln -s' +LTLIBOBJS='' +MAKEINFO='${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run makeinfo' +OBJDUMP='objdump' +OBJEXT='o' +PACKAGE='libltdl' +PACKAGE_BUGREPORT='bug-libtool@gnu.org' +PACKAGE_NAME='libltdl' +PACKAGE_STRING='libltdl 1.2' +PACKAGE_TARNAME='libltdl' +PACKAGE_VERSION='1.2' +PATH_SEPARATOR=':' +RANLIB='ranlib' +SED='/bin/sed' +SET_MAKE='' +SHELL='/bin/sh' +STRIP='strip' +VERSION='1.2' +ac_ct_CC='gcc' +ac_ct_CXX='g++' +ac_ct_F77='gfortran' +am__fastdepCC_FALSE='' +am__fastdepCC_TRUE='#' +am__fastdepCXX_FALSE='' +am__fastdepCXX_TRUE='#' +am__include='include' +am__isrc='' +am__leading_dot='.' +am__quote='' +am__tar='${AMTAR} chof - "$$tardir"' +am__untar='${AMTAR} xf -' +bindir='${exec_prefix}/bin' +build='i686-pc-linux-gnu' +build_alias='' +build_cpu='i686' +build_os='linux-gnu' +build_vendor='pc' +datadir='${datarootdir}' +datarootdir='${prefix}/share' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +dvidir='${docdir}' +exec_prefix='${prefix}' +host='i686-pc-linux-gnu' +host_alias='' +host_cpu='i686' +host_os='linux-gnu' +host_vendor='pc' +htmldir='${docdir}' +includedir='${prefix}/include' +infodir='${datarootdir}/info' +install_sh='$(SHELL) /home/lennart/projects/pulseaudio/libltdl/install-sh' +libdir='${exec_prefix}/lib' +libexecdir='${exec_prefix}/libexec' +localedir='${datarootdir}/locale' +localstatedir='${prefix}/var' +mandir='${datarootdir}/man' +mkdir_p='/bin/mkdir -p' +oldincludedir='/usr/include' +pdfdir='${docdir}' +prefix='/usr/local' +program_transform_name='s,x,x,' +psdir='${docdir}' +sbindir='${exec_prefix}/sbin' +sharedstatedir='${prefix}/com' +sysconfdir='${prefix}/etc' +target_alias='' + +## ----------- ## +## confdefs.h. ## +## ----------- ## + +#define PACKAGE_NAME "libltdl" +#define PACKAGE_TARNAME "libltdl" +#define PACKAGE_VERSION "1.2" +#define PACKAGE_STRING "libltdl 1.2" +#define PACKAGE_BUGREPORT "bug-libtool@gnu.org" +#define STDC_HEADERS 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRING_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_DLFCN_H 1 +#define HAVE_DIRENT_H 1 +#define LTDL_SHLIB_EXT ".so" +#define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" +#define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" +#define LTDL_OBJDIR ".libs/" +#define HAVE_PRELOADED_SYMBOLS 1 +#define HAVE_LIBDL 1 +#define HAVE_DLERROR 1 +#define HAVE_ARGZ_H 1 +#define HAVE_ERROR_T 1 +#define HAVE_ARGZ_APPEND 1 +#define HAVE_ARGZ_CREATE_SEP 1 +#define HAVE_ARGZ_INSERT 1 +#define HAVE_ARGZ_NEXT 1 +#define HAVE_ARGZ_STRINGIFY 1 +#define HAVE_ASSERT_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_ERRNO_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_STRING_H 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_STRCMP 1 +#define HAVE_CLOSEDIR 1 +#define HAVE_OPENDIR 1 +#define HAVE_READDIR 1 + +configure: exit 0 diff --git a/libltdl/config.status b/libltdl/config.status new file mode 100755 index 00000000..c7316a4f --- /dev/null +++ b/libltdl/config.status @@ -0,0 +1,1118 @@ +#! /bin/sh +# Generated by configure. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=${CONFIG_SHELL-/bin/sh} +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by libltdl $as_me 1.2, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +# Files that config.status was made for. +config_files=" Makefile" +config_headers=" config.h:config-h.in" +config_commands=" depfiles" + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +ac_cs_version="\ +libltdl config.status 1.2 +configured by ./configure, generated by GNU Autoconf 2.61, + with options \"\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='/home/lennart/projects/pulseaudio/libltdl' +srcdir='.' +INSTALL='/usr/bin/install -c' +MKDIR_P='/bin/mkdir -p' +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +if $ac_cs_recheck; then + echo "running CONFIG_SHELL=/bin/sh /bin/sh ./configure " $ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=/bin/sh + export CONFIG_SHELL + exec /bin/sh "./configure" $ac_configure_extra_args --no-create --no-recursion +fi + +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +# +# INIT-COMMANDS +# +AMDEP_TRUE="" ac_aux_dir="." + + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:config-h.in" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +cat >"$tmp/subs-1.sed" <<\CEOF +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@SHELL@,|#_!!_#|/bin/sh,g +s,@PATH_SEPARATOR@,|#_!!_#|:,g +s,@PACKAGE_NAME@,|#_!!_#|libltdl,g +s,@PACKAGE_TARNAME@,|#_!!_#|libltdl,g +s,@PACKAGE_VERSION@,|#_!!_#|1.2,g +s,@PACKAGE_STRING@,|#_!!_#|libltdl 1.2,g +s,@PACKAGE_BUGREPORT@,|#_!!_#|bug-libtool@|#_!!_#|gnu.org,g +s,@exec_prefix@,|#_!!_#|${prefix},g +s,@prefix@,|#_!!_#|/usr/local,g +s,@program_transform_name@,|#_!!_#|s\,x\,x\,,g +s,@bindir@,|#_!!_#|${exec_prefix}/bin,g +s,@sbindir@,|#_!!_#|${exec_prefix}/sbin,g +s,@libexecdir@,|#_!!_#|${exec_prefix}/libexec,g +s,@datarootdir@,|#_!!_#|${prefix}/share,g +s,@datadir@,|#_!!_#|${datarootdir},g +s,@sysconfdir@,|#_!!_#|${prefix}/etc,g +s,@sharedstatedir@,|#_!!_#|${prefix}/com,g +s,@localstatedir@,|#_!!_#|${prefix}/var,g +s,@includedir@,|#_!!_#|${prefix}/include,g +s,@oldincludedir@,|#_!!_#|/usr/include,g +s,@docdir@,|#_!!_#|${datarootdir}/doc/${PACKAGE_TARNAME},g +s,@infodir@,|#_!!_#|${datarootdir}/info,g +s,@htmldir@,|#_!!_#|${docdir},g +s,@dvidir@,|#_!!_#|${docdir},g +s,@pdfdir@,|#_!!_#|${docdir},g +s,@psdir@,|#_!!_#|${docdir},g +s,@libdir@,|#_!!_#|${exec_prefix}/lib,g +s,@localedir@,|#_!!_#|${datarootdir}/locale,g +s,@mandir@,|#_!!_#|${datarootdir}/man,g +s,@DEFS@,|#_!!_#|-DHAVE_CONFIG_H,g +s,@ECHO_C@,|#_!!_#|,g +s,@ECHO_N@,|#_!!_#|-n,g +s,@ECHO_T@,|#_!!_#|,g +s,@LIBS@,|#_!!_#|,g +s,@build_alias@,|#_!!_#|,g +s,@host_alias@,|#_!!_#|,g +s,@target_alias@,|#_!!_#|,g +s,@INSTALL_PROGRAM@,|#_!!_#|${INSTALL},g +s,@INSTALL_SCRIPT@,|#_!!_#|${INSTALL},g +s,@INSTALL_DATA@,|#_!!_#|${INSTALL} -m 644,g +s,@am__isrc@,|#_!!_#|,g +s,@CYGPATH_W@,|#_!!_#|echo,g +s,@PACKAGE@,|#_!!_#|libltdl,g +s,@VERSION@,|#_!!_#|1.2,g +s,@ACLOCAL@,|#_!!_#|${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run aclocal-1.10,g +s,@AUTOCONF@,|#_!!_#|${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run autoconf,g +s,@AUTOMAKE@,|#_!!_#|${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run automake-1.10,g +s,@AUTOHEADER@,|#_!!_#|${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run autoheader,g +s,@MAKEINFO@,|#_!!_#|${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run makeinfo,g +s,@install_sh@,|#_!!_#|$(SHELL) /home/lennart/projects/pulseaudio/libltdl/install-sh,g +s,@STRIP@,|#_!!_#|strip,g +s,@INSTALL_STRIP_PROGRAM@,|#_!!_#|$(install_sh) -c -s,g +s,@mkdir_p@,|#_!!_#|/bin/mkdir -p,g +s,@AWK@,|#_!!_#|gawk,g +s,@SET_MAKE@,|#_!!_#|,g +s,@am__leading_dot@,|#_!!_#|.,g +s,@AMTAR@,|#_!!_#|${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run tar,g +s,@am__tar@,|#_!!_#|${AMTAR} chof - "$$tardir",g +s,@am__untar@,|#_!!_#|${AMTAR} xf -,g +s,@CC@,|#_!!_#|gcc,g +s,@CFLAGS@,|#_!!_#|-g -O2,g +s,@LDFLAGS@,|#_!!_#|,g +s,@CPPFLAGS@,|#_!!_#|,g +s,@ac_ct_CC@,|#_!!_#|gcc,g +s,@EXEEXT@,|#_!!_#|,g +s,@OBJEXT@,|#_!!_#|o,g +s,@DEPDIR@,|#_!!_#|.deps,g +s,@am__include@,|#_!!_#|include,g +s,@am__quote@,|#_!!_#|,g +s,@AMDEP_TRUE@,|#_!!_#|,g +s,@AMDEP_FALSE@,|#_!!_#|#,g +s,@AMDEPBACKSLASH@,|#_!!_#|\\,g +s,@CCDEPMODE@,|#_!!_#|depmode=none,g +s,@am__fastdepCC_TRUE@,|#_!!_#|#,g +s,@am__fastdepCC_FALSE@,|#_!!_#|,g +s,@build@,|#_!!_#|i686-pc-linux-gnu,g +s,@build_cpu@,|#_!!_#|i686,g +s,@build_vendor@,|#_!!_#|pc,g +s,@build_os@,|#_!!_#|linux-gnu,g +s,@host@,|#_!!_#|i686-pc-linux-gnu,g +s,@host_cpu@,|#_!!_#|i686,g +s,@host_vendor@,|#_!!_#|pc,g +s,@host_os@,|#_!!_#|linux-gnu,g +s,@SED@,|#_!!_#|/bin/sed,g +s,@GREP@,|#_!!_#|/bin/grep,g +s,@EGREP@,|#_!!_#|/bin/grep -E,g +s,@LN_S@,|#_!!_#|ln -s,g +s,@ECHO@,|#_!!_#|echo,g +s,@AR@,|#_!!_#|ar,g +s,@RANLIB@,|#_!!_#|ranlib,g +s,@DLLTOOL@,|#_!!_#|dlltool,g +s,@AS@,|#_!!_#|as,g +s,@OBJDUMP@,|#_!!_#|objdump,g +s,@CPP@,|#_!!_#|gcc -E,g +s,@CXX@,|#_!!_#|g++,g +s,@CXXFLAGS@,|#_!!_#|-g -O2,g +s,@ac_ct_CXX@,|#_!!_#|g++,g +CEOF +cat >"$tmp/subs-2.sed" <<\CEOF +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +s,@CXXDEPMODE@,|#_!!_#|depmode=none,g +s,@am__fastdepCXX_TRUE@,|#_!!_#|#,g +s,@am__fastdepCXX_FALSE@,|#_!!_#|,g +s,@CXXCPP@,|#_!!_#|g++ -E,g +s,@F77@,|#_!!_#|gfortran,g +s,@FFLAGS@,|#_!!_#|-g -O2,g +s,@ac_ct_F77@,|#_!!_#|gfortran,g +s,@LIBTOOL@,|#_!!_#|$(SHELL) $(top_builddir)/libtool,g +s,@LIBTOOL_DEPS@,|#_!!_#|./ltmain.sh,g +s,@INSTALL_LTDL_TRUE@,|#_!!_#|,g +s,@INSTALL_LTDL_FALSE@,|#_!!_#|#,g +s,@CONVENIENCE_LTDL_TRUE@,|#_!!_#|#,g +s,@CONVENIENCE_LTDL_FALSE@,|#_!!_#|,g +s,@LIBADD_DL@,|#_!!_#|-ldl,g +s,@LIBOBJS@,|#_!!_#|,g +s,@LTLIBOBJS@,|#_!!_#|,g +:end +s/|#_!!_#|//g +CEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} + ac_datarootdir_hack=' + s&@datadir@&${datarootdir}&g + s&@docdir@&${datarootdir}/doc/${PACKAGE_TARNAME}&g + s&@infodir@&${datarootdir}/info&g + s&@localedir@&${datarootdir}/locale&g + s&@mandir@&${datarootdir}/man&g + s&\${datarootdir}&${prefix}/share&g' ;; +esac + sed "/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +} + +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + :H) + # + # CONFIG_HEADER + # + # First, check the format of the line: + cat >"$tmp/defines.sed" <<\CEOF +/^[ ]*#[ ]*undef[ ][ ]*[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*[ ]*$/b def +/^[ ]*#[ ]*define[ ][ ]*[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*[( ]/b def +b +:def +s/$/ / +s,^\([ #]*\)[^ ]*\([ ]*PACKAGE_NAME\)[ (].*,\1define\2 "libltdl" , +s,^\([ #]*\)[^ ]*\([ ]*PACKAGE_TARNAME\)[ (].*,\1define\2 "libltdl" , +s,^\([ #]*\)[^ ]*\([ ]*PACKAGE_VERSION\)[ (].*,\1define\2 "1.2" , +s,^\([ #]*\)[^ ]*\([ ]*PACKAGE_STRING\)[ (].*,\1define\2 "libltdl 1.2" , +s,^\([ #]*\)[^ ]*\([ ]*PACKAGE_BUGREPORT\)[ (].*,\1define\2 "bug-libtool@gnu.org" , +s,^\([ #]*\)[^ ]*\([ ]*STDC_HEADERS\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_SYS_TYPES_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_SYS_STAT_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_STDLIB_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_STRING_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_MEMORY_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_STRINGS_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_INTTYPES_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_STDINT_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_UNISTD_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_DLFCN_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_DIRENT_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*LTDL_SHLIB_EXT\)[ (].*,\1define\2 ".so" , +s,^\([ #]*\)[^ ]*\([ ]*LTDL_SHLIBPATH_VAR\)[ (].*,\1define\2 "LD_LIBRARY_PATH" , +s,^\([ #]*\)[^ ]*\([ ]*LTDL_SYSSEARCHPATH\)[ (].*,\1define\2 "/usr/lib:/lib:/usr/lib/qt-3.3/lib" , +s,^\([ #]*\)[^ ]*\([ ]*LTDL_OBJDIR\)[ (].*,\1define\2 ".libs/" , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_PRELOADED_SYMBOLS\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_LIBDL\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_DLERROR\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_ARGZ_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_ERROR_T\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_ARGZ_APPEND\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_ARGZ_CREATE_SEP\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_ARGZ_INSERT\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_ARGZ_NEXT\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_ARGZ_STRINGIFY\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_ASSERT_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_CTYPE_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_ERRNO_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_MALLOC_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_MEMORY_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_STDLIB_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_STDIO_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_UNISTD_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_STRING_H\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_STRCHR\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_STRRCHR\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_MEMCPY\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_MEMMOVE\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_STRCMP\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_CLOSEDIR\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_OPENDIR\)[ (].*,\1define\2 1 , +s,^\([ #]*\)[^ ]*\([ ]*HAVE_READDIR\)[ (].*,\1define\2 1 , +s/ $// +CEOF + sed -f "$tmp/defines.sed" $ac_file_inputs >"$tmp/out1" + # First, check the format of the line: + cat >"$tmp/defines.sed" <<\CEOF +/^[ ]*#[ ]*undef[ ][ ]*[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*[ ]*$/b def +/^[ ]*#[ ]*define[ ][ ]*[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*[( ]/b def +b +:def +s,^[ #]*u.*,/* & */, +CEOF + sed -f "$tmp/defines.sed" "$tmp/out1" >"$tmp/out2" +ac_result="$tmp/out2" + if test x"$ac_file" != x-; then + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f $ac_file + mv "$tmp/config.h" $ac_file + fi + else + echo "/* $configure_input */" + cat "$ac_result" + fi + rm -f "$tmp/out12" +# Compute $ac_file's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $ac_file | $ac_file:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $ac_file" >`$as_dirname -- $ac_file || +$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X$ac_file : 'X\(//\)[^/]' \| \ + X$ac_file : 'X\(//\)$' \| \ + X$ac_file : 'X\(/\)' \| . 2>/dev/null || +echo X$ac_file | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 +echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir=$dirpart/$fdir + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + + esac +done # for ac_tag + + +{ (exit 0); exit 0; } diff --git a/libltdl/config.sub b/libltdl/config.sub new file mode 100755 index 00000000..c060f448 --- /dev/null +++ b/libltdl/config.sub @@ -0,0 +1,1626 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2007-04-29' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/libltdl/configure b/libltdl/configure new file mode 100755 index 00000000..62dface9 --- /dev/null +++ b/libltdl/configure @@ -0,0 +1,23808 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.61 for libltdl 1.2. +# +# Report bugs to . +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','` + ;; +esac + +echo=${ECHO-echo} +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1 && unset CDPATH + +if test -z "$ECHO"; then +if test "X${echo_test_string+set}" != Xset; then +# find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string=`eval $cmd`) 2>/dev/null && + echo_test_string=`eval $cmd` && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL $0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL $0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "$0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" +fi + + + + +tagnames=${tagnames+${tagnames},}CXX + +tagnames=${tagnames+${tagnames},}F77 + +exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME='libltdl' +PACKAGE_TARNAME='libltdl' +PACKAGE_VERSION='1.2' +PACKAGE_STRING='libltdl 1.2' +PACKAGE_BUGREPORT='bug-libtool@gnu.org' + +ac_unique_file="ltdl.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +am__isrc +CYGPATH_W +PACKAGE +VERSION +ACLOCAL +AUTOCONF +AUTOMAKE +AUTOHEADER +MAKEINFO +install_sh +STRIP +INSTALL_STRIP_PROGRAM +mkdir_p +AWK +SET_MAKE +am__leading_dot +AMTAR +am__tar +am__untar +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +DEPDIR +am__include +am__quote +AMDEP_TRUE +AMDEP_FALSE +AMDEPBACKSLASH +CCDEPMODE +am__fastdepCC_TRUE +am__fastdepCC_FALSE +build +build_cpu +build_vendor +build_os +host +host_cpu +host_vendor +host_os +SED +GREP +EGREP +LN_S +ECHO +AR +RANLIB +DLLTOOL +AS +OBJDUMP +CPP +CXX +CXXFLAGS +ac_ct_CXX +CXXDEPMODE +am__fastdepCXX_TRUE +am__fastdepCXX_FALSE +CXXCPP +F77 +FFLAGS +ac_ct_F77 +LIBTOOL +LIBTOOL_DEPS +INSTALL_LTDL_TRUE +INSTALL_LTDL_FALSE +CONVENIENCE_LTDL_TRUE +CONVENIENCE_LTDL_FALSE +LIBADD_DL +LIBOBJS +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +CXX +CXXFLAGS +CCC +CXXCPP +F77 +FFLAGS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures libltdl 1.2 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/libltdl] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of libltdl 1.2:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --enable-ltdl-install install libltdl + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-pic try to use only PIC/non-PIC objects [default=use + both] + --with-tags[=TAGS] include additional configurations [automatic] + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CXXCPP C++ preprocessor + F77 Fortran 77 compiler command + FFLAGS Fortran 77 compiler flags + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +libltdl configure 1.2 +generated by GNU Autoconf 2.61 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by libltdl $as_me 1.2, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + +## ------------------------------- ## +## Libltdl specific configuration. ## +## ------------------------------- ## + +ac_aux_dir= +for ac_dir in . "$srcdir"/.; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in . \"$srcdir\"/." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in . \"$srcdir\"/." >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + + +if test -z "$enable_ltdl_install$enable_ltdl_convenience"; then + if test -f ${srcdir}/ltmain.sh; then + # if libltdl is libtoolized, it is assumed to be stand-alone and + # installed unless the command line overrides it (tested above) + enable_ltdl_install=yes + else + { echo "$as_me:$LINENO: WARNING: *** The top-level configure must select either" >&5 +echo "$as_me: WARNING: *** The top-level configure must select either" >&2;} + { echo "$as_me:$LINENO: WARNING: *** A\"\"C_LIBLTDL_INSTALLABLE or A\"\"C_LIBLTDL_CONVENIENCE." >&5 +echo "$as_me: WARNING: *** A\"\"C_LIBLTDL_INSTALLABLE or A\"\"C_LIBLTDL_CONVENIENCE." >&2;} + { { echo "$as_me:$LINENO: error: *** Maybe you want to --enable-ltdl-install?" >&5 +echo "$as_me: error: *** Maybe you want to --enable-ltdl-install?" >&2;} + { (exit 1); exit 1; }; } + fi +fi + + +## ------------------------ ## +## Automake Initialisation. ## +## ------------------------ ## +am__api_version='1.10' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm -f conftest.sed + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +{ echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5 +echo $ECHO_N "checking for a thread-safe mkdir -p... $ECHO_C" >&6; } +if test -z "$MKDIR_P"; then + if test "${ac_cv_path_mkdir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done +done +IFS=$as_save_IFS + +fi + + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + test -d ./--version && rmdir ./--version + MKDIR_P="$ac_install_sh -d" + fi +fi +{ echo "$as_me:$LINENO: result: $MKDIR_P" >&5 +echo "${ECHO_T}$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } +set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + SET_MAKE= +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE=libltdl + VERSION=1.2 + + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + +ac_config_headers="$ac_config_headers config.h:config-h.in" + + + +## ------------------ ## +## C compiler checks. ## +## ------------------ ## +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi + + +{ echo "$as_me:$LINENO: result: $_am_result" >&5 +echo "${ECHO_T}$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_const=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for inline" >&5 +echo $ECHO_N "checking for inline... $ECHO_C" >&6; } +if test "${ac_cv_c_inline+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_inline=$ac_kw +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 +echo "${ECHO_T}$ac_cv_c_inline" >&6; } + + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + + + +## ----------------------- ## +## Libtool initialisation. ## +## ----------------------- ## + + +# Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + +# Check whether --enable-static was given. +if test "${enable_static+set}" = set; then + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + +# Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 +echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} + { (exit 1); exit 1; }; } + +{ echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6; } +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 +echo "$as_me: error: invalid value of canonical build" >&2;} + { (exit 1); exit 1; }; };; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6; } +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 +echo "$as_me: error: invalid value of canonical host" >&2;} + { (exit 1); exit 1; }; };; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5 +echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6; } +if test "${lt_cv_path_SED+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$lt_ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$lt_ac_prog$ac_exec_ext"; }; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done + +fi + +SED=$lt_cv_path_SED + +{ echo "$as_me:$LINENO: result: $SED" >&5 +echo "${ECHO_T}$SED" >&6; } + +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_GREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + # Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_GREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_EGREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + # Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_EGREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_EGREP=$EGREP +fi + + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { echo "$as_me:$LINENO: checking for ld used by $CC" >&5 +echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { echo "$as_me:$LINENO: checking for GNU ld" >&5 +echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; } +else + { echo "$as_me:$LINENO: checking for non-GNU ld" >&5 +echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; } +fi +if test "${lt_cv_path_LD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +echo "${ECHO_T}$LD" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi +test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +{ echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 +echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; } +if test "${lt_cv_prog_gnu_ld+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + +{ echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5 +echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6; } +if test "${lt_cv_ld_reload_flag+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5 +echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + +{ echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5 +echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6; } +if test "${lt_cv_path_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi +fi +{ echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5 +echo "${ECHO_T}$lt_cv_path_NM" >&6; } +NM="$lt_cv_path_NM" + +{ echo "$as_me:$LINENO: checking whether ln -s works" >&5 +echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no, using $LN_S" >&5 +echo "${ECHO_T}no, using $LN_S" >&6; } +fi + +{ echo "$as_me:$LINENO: checking how to recognize dependent libraries" >&5 +echo $ECHO_N "checking how to recognize dependent libraries... $ECHO_C" >&6; } +if test "${lt_cv_deplibs_check_method+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix4* | aix5*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +nto-qnx*) + lt_cv_deplibs_check_method=unknown + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 +echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6; } +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 4531 "configure"' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + libsuff=64 + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5 +echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6; } +if test "${lt_cv_cc_needs_belf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + lt_cv_cc_needs_belf=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + lt_cv_cc_needs_belf=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5 +echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) LD="${LD-ld} -64" ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-cygwin* | *-*-mingw* | *-*-pw32*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_DLLTOOL+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { echo "$as_me:$LINENO: result: $DLLTOOL" >&5 +echo "${ECHO_T}$DLLTOOL" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { echo "$as_me:$LINENO: result: $ac_ct_DLLTOOL" >&5 +echo "${ECHO_T}$ac_ct_DLLTOOL" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_AS+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AS="${ac_tool_prefix}as" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AS=$ac_cv_prog_AS +if test -n "$AS"; then + { echo "$as_me:$LINENO: result: $AS" >&5 +echo "${ECHO_T}$AS" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AS"; then + ac_ct_AS=$AS + # Extract the first word of "as", so it can be a program name with args. +set dummy as; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_AS+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_AS"; then + ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AS="as" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_AS=$ac_cv_prog_ac_ct_AS +if test -n "$ac_ct_AS"; then + { echo "$as_me:$LINENO: result: $ac_ct_AS" >&5 +echo "${ECHO_T}$ac_ct_AS" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_AS" = x; then + AS="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + AS=$ac_ct_AS + fi +else + AS="$ac_cv_prog_AS" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_OBJDUMP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { echo "$as_me:$LINENO: result: $OBJDUMP" >&5 +echo "${ECHO_T}$OBJDUMP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { echo "$as_me:$LINENO: result: $ac_ct_OBJDUMP" >&5 +echo "${ECHO_T}$ac_ct_OBJDUMP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + + ;; + +esac + +need_locks="$enable_libtool_lock" + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_header in dlfcn.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ---------------------------------- ## +## Report this to bug-libtool@gnu.org ## +## ---------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { echo "$as_me:$LINENO: result: $CXX" >&5 +echo "${ECHO_T}$CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 +echo "${ECHO_T}$ac_ct_CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C++ compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; } +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; } +GXX=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 +echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CXXFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } +if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + + + +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 +echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6; } +if test -z "$CXXCPP"; then + if test "${ac_cv_prog_CXXCPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ echo "$as_me:$LINENO: result: $CXXCPP" >&5 +echo "${ECHO_T}$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +fi + + +ac_ext=f +ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' +ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_f77_compiler_gnu +if test -n "$ac_tool_prefix"; then + for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$F77"; then + ac_cv_prog_F77="$F77" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_F77="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +F77=$ac_cv_prog_F77 +if test -n "$F77"; then + { echo "$as_me:$LINENO: result: $F77" >&5 +echo "${ECHO_T}$F77" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$F77" && break + done +fi +if test -z "$F77"; then + ac_ct_F77=$F77 + for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_F77"; then + ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_F77="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_F77=$ac_cv_prog_ac_ct_F77 +if test -n "$ac_ct_F77"; then + { echo "$as_me:$LINENO: result: $ac_ct_F77" >&5 +echo "${ECHO_T}$ac_ct_F77" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_F77" && break +done + + if test "x$ac_ct_F77" = x; then + F77="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + F77=$ac_ct_F77 + fi +fi + + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for Fortran 77 compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +rm -f a.out + +# If we don't use `.F' as extension, the preprocessor is not run on the +# input file. (Note that this only needs to work for GNU compilers.) +ac_save_ext=$ac_ext +ac_ext=F +{ echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6; } +if test "${ac_cv_f77_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF + program main +#ifndef __GNUC__ + choke me +#endif + + end +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_f77_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_f77_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6; } +ac_ext=$ac_save_ext +ac_test_FFLAGS=${FFLAGS+set} +ac_save_FFLAGS=$FFLAGS +FFLAGS= +{ echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5 +echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_f77_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + FFLAGS=-g +cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_f77_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_f77_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_prog_f77_g=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5 +echo "${ECHO_T}$ac_cv_prog_f77_g" >&6; } +if test "$ac_test_FFLAGS" = set; then + FFLAGS=$ac_save_FFLAGS +elif test $ac_cv_prog_f77_g = yes; then + if test "x$ac_cv_f77_compiler_gnu" = xyes; then + FFLAGS="-g -O2" + else + FFLAGS="-g" + fi +else + if test "x$ac_cv_f77_compiler_gnu" = xyes; then + FFLAGS="-O2" + else + FFLAGS= + fi +fi + +G77=`test $ac_compiler_gnu = yes && echo yes` +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! + +# find the maximum length of command line arguments +{ echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5 +echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6; } +if test "${lt_cv_sys_max_cmd_len+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \ + = "XX$teststring") >/dev/null 2>&1 && + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5 +echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6; } +else + { echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6; } +fi + + + + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5 +echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6; } +if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32*) + symcode='[ABCDGISTW]' + ;; +hpux*) # Its linker distinguishes data from code symbols + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +linux* | k*bsd*-gnu) + if test "$host_cpu" = ia64; then + symcode='[ABCDGIRSTW]' + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5 + (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if grep ' nm_test_var$' "$nlist" >/dev/null; then + if grep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[] = +{ +EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { echo "$as_me:$LINENO: result: failed" >&5 +echo "${ECHO_T}failed" >&6; } +else + { echo "$as_me:$LINENO: result: ok" >&5 +echo "${ECHO_T}ok" >&6; } +fi + +{ echo "$as_me:$LINENO: checking for objdir" >&5 +echo $ECHO_N "checking for objdir... $ECHO_C" >&6; } +if test "${lt_cv_objdir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5 +echo "${ECHO_T}$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { echo "$as_me:$LINENO: result: $AR" >&5 +echo "${ECHO_T}$AR" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="ar" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 +echo "${ECHO_T}$ac_ct_AR" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$SED" && SED=sed +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5 +echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6; } +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +echo "${ECHO_T}$MAGIC_CMD" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { echo "$as_me:$LINENO: checking for file" >&5 +echo $ECHO_N "checking for file... $ECHO_C" >&6; } +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5 +echo "${ECHO_T}$MAGIC_CMD" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +enable_dlopen=no +enable_win32_dll=yes + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then + withval=$with_pic; pic_mode="$withval" +else + pic_mode=default +fi + +test -z "$pic_mode" && pic_mode=default + +# Use C for the default configuration in the libtool script +tagname= +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + lt_prog_compiler_no_builtin_flag=' -fno-builtin' + + +{ echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:7568: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:7572: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + +lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + +{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic='-qnocommon' + lt_prog_compiler_wl='-Wl,' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + icc* | ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + esac + ;; + esac + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic" >&6; } + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + +{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6; } +if test "${lt_prog_compiler_pic_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:7858: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:7862: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_pic_works=yes + fi + fi + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6; } + +if test x"$lt_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } +if test "${lt_prog_compiler_static_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works=yes + fi + else + lt_prog_compiler_static_works=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works" >&6; } + +if test x"$lt_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + +{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_c_o+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:7962: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:7966: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6; } + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; } + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6; } + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } + + runpath_var= + allow_undefined_flag= + enable_shared_with_static_runtimes=no + archive_cmds= + archive_expsym_cmds= + old_archive_From_new_cmds= + old_archive_from_expsyms_cmds= + export_dynamic_flag_spec= + whole_archive_flag_spec= + thread_safe_flag_spec= + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_direct=no + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + link_all_deplibs=unknown + hardcode_automatic=no + module_cmds= + module_expsym_cmds= + always_export_symbols=no + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | k*bsd*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + *) + tmp_sharedflag='-shared' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_From_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + whole_archive_flag_spec='' + link_all_deplibs=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' + module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs=no + ;; + esac + fi + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + hardcode_direct=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_ld='-rpath $libdir' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + fi + +{ echo "$as_me:$LINENO: result: $ld_shlibs" >&5 +echo "${ECHO_T}$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } + $rm conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc=no + else + archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + { echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5 +echo "${ECHO_T}$archive_cmds_need_lc" >&6; } + ;; + esac + fi + ;; +esac + +{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; } +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$lt_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e 's/;/ /g'` + else + lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`echo $lt_tmp_lt_search_path_spec | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + sys_lib_search_path_spec=`echo $lt_search_path_spec` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var" || \ + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ echo "$as_me:$LINENO: result: $hardcode_action" >&5 +echo "${ECHO_T}$hardcode_action" >&6; } + +if test "$hardcode_action" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +striplib= +old_striplib= +{ echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 +echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + ;; + *) + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + ;; + esac +fi + +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dl_dlopen=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + { echo "$as_me:$LINENO: checking for shl_load" >&5 +echo $ECHO_N "checking for shl_load... $ECHO_C" >&6; } +if test "${ac_cv_func_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define shl_load to an innocuous variant, in case declares shl_load. + For example, HP-UX 11i declares gettimeofday. */ +#define shl_load innocuous_shl_load + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char shl_load (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef shl_load + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_shl_load || defined __stub___shl_load +choke me +#endif + +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_shl_load=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 +echo "${ECHO_T}$ac_cv_func_shl_load" >&6; } +if test $ac_cv_func_shl_load = yes; then + lt_cv_dlopen="shl_load" +else + { echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 +echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6; } +if test "${ac_cv_lib_dld_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_dld_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dld_shl_load=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; } +if test $ac_cv_lib_dld_shl_load = yes; then + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" +else + { echo "$as_me:$LINENO: checking for dlopen" >&5 +echo $ECHO_N "checking for dlopen... $ECHO_C" >&6; } +if test "${ac_cv_func_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define dlopen to an innocuous variant, in case declares dlopen. + For example, HP-UX 11i declares gettimeofday. */ +#define dlopen innocuous_dlopen + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char dlopen (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef dlopen + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_dlopen || defined __stub___dlopen +choke me +#endif + +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_dlopen=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 +echo "${ECHO_T}$ac_cv_func_dlopen" >&6; } +if test $ac_cv_func_dlopen = yes; then + lt_cv_dlopen="dlopen" +else + { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dl_dlopen=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } +if test $ac_cv_lib_dl_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 +echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6; } +if test "${ac_cv_lib_svld_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_svld_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_svld_dlopen=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6; } +if test $ac_cv_lib_svld_dlopen = yes; then + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 +echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6; } +if test "${ac_cv_lib_dld_dld_link+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_dld_dld_link=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dld_dld_link=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6; } +if test $ac_cv_lib_dld_dld_link = yes; then + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 +echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6; } +if test "${lt_cv_dlopen_self+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 +echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6; } +if test "${lt_cv_dlopen_self_static+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 +echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + +# Report which library types will actually be built +{ echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 +echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $can_build_shared" >&5 +echo "${ECHO_T}$can_build_shared" >&6; } + +{ echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 +echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6; } +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +{ echo "$as_me:$LINENO: result: $enable_shared" >&5 +echo "${ECHO_T}$enable_shared" >&6; } + +{ echo "$as_me:$LINENO: checking whether to build static libraries" >&5 +echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6; } +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +{ echo "$as_me:$LINENO: result: $enable_static" >&5 +echo "${ECHO_T}$enable_static" >&6; } + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler \ + CC \ + LD \ + lt_prog_compiler_wl \ + lt_prog_compiler_pic \ + lt_prog_compiler_static \ + lt_prog_compiler_no_builtin_flag \ + export_dynamic_flag_spec \ + thread_safe_flag_spec \ + whole_archive_flag_spec \ + enable_shared_with_static_runtimes \ + old_archive_cmds \ + old_archive_from_new_cmds \ + predep_objects \ + postdep_objects \ + predeps \ + postdeps \ + compiler_lib_search_path \ + archive_cmds \ + archive_expsym_cmds \ + postinstall_cmds \ + postuninstall_cmds \ + old_archive_from_expsyms_cmds \ + allow_undefined_flag \ + no_undefined_flag \ + export_symbols_cmds \ + hardcode_libdir_flag_spec \ + hardcode_libdir_flag_spec_ld \ + hardcode_libdir_separator \ + hardcode_automatic \ + module_cmds \ + module_expsym_cmds \ + lt_cv_prog_compiler_c_o \ + fix_srcfile_path \ + exclude_expsyms \ + include_expsyms; do + + case $var in + old_archive_cmds | \ + old_archive_from_new_cmds | \ + archive_cmds | \ + archive_expsym_cmds | \ + module_cmds | \ + module_expsym_cmds | \ + old_archive_from_expsyms_cmds | \ + export_symbols_cmds | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="${ofile}T" + trap "$rm \"$cfgfile\"; exit 1" 1 2 15 + $rm -f "$cfgfile" + { echo "$as_me:$LINENO: creating $ofile" >&5 +echo "$as_me: creating $ofile" >&6;} + + cat <<__EOF__ >> "$cfgfile" +#! $SHELL + +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="$SED -e 1s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# The names of the tagged configurations supported by this script. +available_tags= + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU C compiler? +with_gcc=$GCC + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_predep_objects + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_postdep_objects + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# ### END LIBTOOL CONFIG + +__EOF__ + + + case $host_os in + aix3*) + cat <<\EOF >> "$cfgfile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || \ + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + +# Check whether --with-tags was given. +if test "${with_tags+set}" = set; then + withval=$with_tags; tagnames="$withval" +fi + + +if test -f "$ltmain" && test -n "$tagnames"; then + if test ! -f "${ofile}"; then + { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not exist" >&5 +echo "$as_me: WARNING: output file \`$ofile' does not exist" >&2;} + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not look like a libtool script" >&5 +echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script" >&2;} + else + { echo "$as_me:$LINENO: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&5 +echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;} + fi + fi + if test -z "$LTCFLAGS"; then + eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" + fi + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for tagname in $tagnames; do + IFS="$lt_save_ifs" + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's:[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]::g'` in + "") ;; + *) { { echo "$as_me:$LINENO: error: invalid tag name: $tagname" >&5 +echo "$as_me: error: invalid tag name: $tagname" >&2;} + { (exit 1); exit 1; }; } + ;; + esac + + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null + then + { { echo "$as_me:$LINENO: error: tag name \"$tagname\" already exists" >&5 +echo "$as_me: error: tag name \"$tagname\" already exists" >&2;} + { (exit 1); exit 1; }; } + fi + + # Update the list of available tags. + if test -n "$tagname"; then + echo appending configuration tag \"$tagname\" to $ofile + + case $tagname in + CXX) + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_flag_spec_ld_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_LD=$LD +lt_save_GCC=$GCC +GCC=$GXX +lt_save_with_gnu_ld=$with_gnu_ld +lt_save_path_LD=$lt_cv_path_LD +if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx +else + $as_unset lt_cv_prog_gnu_ld +fi +if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX +else + $as_unset lt_cv_path_LD +fi +test -z "${LDCXX+set}" || LD=$LDCXX +CC=${CXX-"c++"} +compiler=$CC +compiler_CXX=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# We don't want -fno-exception wen compiling C++ code, so set the +# no_builtin_flag separately +if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' +else + lt_prog_compiler_no_builtin_flag_CXX= +fi + +if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { echo "$as_me:$LINENO: checking for ld used by $CC" >&5 +echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { echo "$as_me:$LINENO: checking for GNU ld" >&5 +echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; } +else + { echo "$as_me:$LINENO: checking for non-GNU ld" >&5 +echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; } +fi +if test "${lt_cv_path_LD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +echo "${ECHO_T}$LD" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi +test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +{ echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 +echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; } +if test "${lt_cv_prog_gnu_ld+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + +else + GXX=no + with_gnu_ld=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } +ld_shlibs_CXX=yes +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag_CXX='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_CXX='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + whole_archive_flag_spec_CXX='' + link_all_deplibs_CXX=yes + + if test "$GXX" = yes ; then + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + archive_cmds_CXX='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' + module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_CXX=no + ;; + esac + fi + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + freebsd[12]*) + # C++ shared libraries reported to be fairly broken before switch to ELF + ld_shlibs_CXX=no + ;; + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + gnu*) + ;; + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + archive_cmds_CXX='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) ;; + *) + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + hardcode_libdir_flag_spec_CXX='${wl}--rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc*) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC*) + # Portland Group C++ compiler + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + else + ld_shlibs_CXX=no + fi + ;; + osf3*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ + $rm $lib.exp' + + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if $CC --version | grep -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + # So that behaviour is only enabled if SCOABSPATH is set to a + # non-empty value in the environment. Most likely only useful for + # creating official distributions of packages. + # This is a hack until libtool officially supports absolute path + # names for shared libraries. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; +esac +{ echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 +echo "${ECHO_T}$ld_shlibs_CXX" >&6; } +test "$ld_shlibs_CXX" = no && can_build_shared=no + +GCC_CXX="$GXX" +LD_CXX="$LD" + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... + +cat > conftest.$ac_ext <&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + # The `*' in the case matches for architectures that use `case' in + # $output_verbose_cmd can trigger glob expansion during the loop + # eval without this substitution. + output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"` + + for p in `eval $output_verbose_link_cmd`; do + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" \ + || test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p in + -L* | -R*) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + postdeps_CXX="${postdeps_CXX} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$rm -f confest.$objext + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + # + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + +lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + +{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic_CXX='-qnocommon' + lt_prog_compiler_wl_CXX='-Wl,' + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + icpc* | ecpc*) + # Intel C++ + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC*) + # Portland Group C++ compiler. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6; } + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + +{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6; } +if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:12837: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:12841: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_pic_works_CXX=yes + fi + fi + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6; } + +if test x"$lt_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } +if test "${lt_prog_compiler_static_works_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works_CXX=yes + fi + else + lt_prog_compiler_static_works_CXX=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_CXX" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works_CXX" >&6; } + +if test x"$lt_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + +{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:12941: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:12945: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6; } + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; } + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6; } + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix4* | aix5*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw*) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +{ echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 +echo "${ECHO_T}$ld_shlibs_CXX" >&6; } +test "$ld_shlibs_CXX" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } + $rm conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_CXX=no + else + archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5 +echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6; } + ;; + esac + fi + ;; +esac + +{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; } +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" + +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || \ + test -n "$runpath_var_CXX" || \ + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5 +echo "${ECHO_T}$hardcode_action_CXX" >&6; } + +if test "$hardcode_action_CXX" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_CXX \ + CC_CXX \ + LD_CXX \ + lt_prog_compiler_wl_CXX \ + lt_prog_compiler_pic_CXX \ + lt_prog_compiler_static_CXX \ + lt_prog_compiler_no_builtin_flag_CXX \ + export_dynamic_flag_spec_CXX \ + thread_safe_flag_spec_CXX \ + whole_archive_flag_spec_CXX \ + enable_shared_with_static_runtimes_CXX \ + old_archive_cmds_CXX \ + old_archive_from_new_cmds_CXX \ + predep_objects_CXX \ + postdep_objects_CXX \ + predeps_CXX \ + postdeps_CXX \ + compiler_lib_search_path_CXX \ + archive_cmds_CXX \ + archive_expsym_cmds_CXX \ + postinstall_cmds_CXX \ + postuninstall_cmds_CXX \ + old_archive_from_expsyms_cmds_CXX \ + allow_undefined_flag_CXX \ + no_undefined_flag_CXX \ + export_symbols_cmds_CXX \ + hardcode_libdir_flag_spec_CXX \ + hardcode_libdir_flag_spec_ld_CXX \ + hardcode_libdir_separator_CXX \ + hardcode_automatic_CXX \ + module_cmds_CXX \ + module_expsym_cmds_CXX \ + lt_cv_prog_compiler_c_o_CXX \ + fix_srcfile_path_CXX \ + exclude_expsyms_CXX \ + include_expsyms_CXX; do + + case $var in + old_archive_cmds_CXX | \ + old_archive_from_new_cmds_CXX | \ + archive_cmds_CXX | \ + archive_expsym_cmds_CXX | \ + module_cmds_CXX | \ + module_expsym_cmds_CXX | \ + old_archive_from_expsyms_cmds_CXX | \ + export_symbols_cmds_CXX | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_CXX + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_CXX + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_CXX +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_predep_objects_CXX + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_postdep_objects_CXX + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_CXX + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC +LDCXX=$LD +LD=$lt_save_LD +GCC=$lt_save_GCC +with_gnu_ldcxx=$with_gnu_ld +with_gnu_ld=$lt_save_with_gnu_ld +lt_cv_path_LDCXX=$lt_cv_path_LD +lt_cv_path_LD=$lt_save_path_LD +lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld +lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld + + else + tagname="" + fi + ;; + + F77) + if test -n "$F77" && test "X$F77" != "Xno"; then + +ac_ext=f +ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' +ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_f77_compiler_gnu + + +archive_cmds_need_lc_F77=no +allow_undefined_flag_F77= +always_export_symbols_F77=no +archive_expsym_cmds_F77= +export_dynamic_flag_spec_F77= +hardcode_direct_F77=no +hardcode_libdir_flag_spec_F77= +hardcode_libdir_flag_spec_ld_F77= +hardcode_libdir_separator_F77= +hardcode_minus_L_F77=no +hardcode_automatic_F77=no +module_cmds_F77= +module_expsym_cmds_F77= +link_all_deplibs_F77=unknown +old_archive_cmds_F77=$old_archive_cmds +no_undefined_flag_F77= +whole_archive_flag_spec_F77= +enable_shared_with_static_runtimes_F77=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +objext_F77=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="\ + subroutine t + return + end +" + +# Code to be used in simple link tests +lt_simple_link_test_code="\ + program t + end +" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${F77-"f77"} +compiler=$CC +compiler_F77=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +{ echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 +echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $can_build_shared" >&5 +echo "${ECHO_T}$can_build_shared" >&6; } + +{ echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 +echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6; } +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +{ echo "$as_me:$LINENO: result: $enable_shared" >&5 +echo "${ECHO_T}$enable_shared" >&6; } + +{ echo "$as_me:$LINENO: checking whether to build static libraries" >&5 +echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6; } +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +{ echo "$as_me:$LINENO: result: $enable_static" >&5 +echo "${ECHO_T}$enable_static" >&6; } + +GCC_F77="$G77" +LD_F77="$LD" + +lt_prog_compiler_wl_F77= +lt_prog_compiler_pic_F77= +lt_prog_compiler_static_F77= + +{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } + + if test "$GCC" = yes; then + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_static_F77='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_F77='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_F77='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_F77='-fno-common' + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared_F77=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_F77=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_F77='-fPIC' + ;; + esac + ;; + + *) + lt_prog_compiler_pic_F77='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl_F77='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_F77='-Bstatic' + else + lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic_F77='-qnocommon' + lt_prog_compiler_wl_F77='-Wl,' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_F77='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl_F77='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_F77='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static_F77='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl_F77='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static_F77='-non_shared' + ;; + + newsos6) + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + icc* | ecc*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-fpic' + lt_prog_compiler_static_F77='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl_F77='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static_F77='-non_shared' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + lt_prog_compiler_wl_F77='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + lt_prog_compiler_wl_F77='' + ;; + esac + ;; + esac + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl_F77='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static_F77='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static_F77='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl_F77='-Qoption ld ';; + *) + lt_prog_compiler_wl_F77='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl_F77='-Qoption ld ' + lt_prog_compiler_pic_F77='-PIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic_F77='-Kconform_pic' + lt_prog_compiler_static_F77='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_can_build_shared_F77=no + ;; + + uts4*) + lt_prog_compiler_pic_F77='-pic' + lt_prog_compiler_static_F77='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared_F77=no + ;; + esac + fi + +{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6; } + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_F77"; then + +{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6; } +if test "${lt_prog_compiler_pic_works_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works_F77=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_F77" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:14505: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:14509: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_pic_works_F77=yes + fi + fi + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6; } + +if test x"$lt_prog_compiler_pic_works_F77" = xyes; then + case $lt_prog_compiler_pic_F77 in + "" | " "*) ;; + *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;; + esac +else + lt_prog_compiler_pic_F77= + lt_prog_compiler_can_build_shared_F77=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_F77= + ;; + *) + lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\" +{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } +if test "${lt_prog_compiler_static_works_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works_F77=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works_F77=yes + fi + else + lt_prog_compiler_static_works_F77=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_F77" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works_F77" >&6; } + +if test x"$lt_prog_compiler_static_works_F77" = xyes; then + : +else + lt_prog_compiler_static_F77= +fi + + +{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o_F77=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:14609: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:14613: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_F77=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6; } + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; } + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6; } + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } + + runpath_var= + allow_undefined_flag_F77= + enable_shared_with_static_runtimes_F77=no + archive_cmds_F77= + archive_expsym_cmds_F77= + old_archive_From_new_cmds_F77= + old_archive_from_expsyms_cmds_F77= + export_dynamic_flag_spec_F77= + whole_archive_flag_spec_F77= + thread_safe_flag_spec_F77= + hardcode_libdir_flag_spec_F77= + hardcode_libdir_flag_spec_ld_F77= + hardcode_libdir_separator_F77= + hardcode_direct_F77=no + hardcode_minus_L_F77=no + hardcode_shlibpath_var_F77=unsupported + link_all_deplibs_F77=unknown + hardcode_automatic_F77=no + module_cmds_F77= + module_expsym_cmds_F77= + always_export_symbols_F77=no + export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms_F77= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms_F77="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs_F77=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_F77='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_F77= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs_F77=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_minus_L_F77=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + ld_shlibs_F77=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_F77=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_F77=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_F77='-L$libdir' + allow_undefined_flag_F77=unsupported + always_export_symbols_F77=no + enable_shared_with_static_runtimes_F77=yes + export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_F77=no + fi + ;; + + interix[3-9]*) + hardcode_direct_F77=no + hardcode_shlibpath_var_F77=no + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + export_dynamic_flag_spec_F77='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | k*bsd*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec_F77='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + *) + tmp_sharedflag='-shared' ;; + esac + archive_cmds_F77='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + ld_shlibs_F77=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs_F77=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs_F77=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + esac + + if test "$ld_shlibs_F77" = no; then + runpath_var= + hardcode_libdir_flag_spec_F77= + export_dynamic_flag_spec_F77= + whole_archive_flag_spec_F77= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag_F77=unsupported + always_export_symbols_F77=yes + archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L_F77=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct_F77=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_F77='' + hardcode_direct_F77=yes + hardcode_libdir_separator_F77=':' + link_all_deplibs_F77=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_F77=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_F77=yes + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_libdir_separator_F77= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_F77=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_F77='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_f77_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_F77="-z nodefs" + archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_f77_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_F77=' ${wl}-bernotok' + allow_undefined_flag_F77=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_F77='$convenience' + archive_cmds_need_lc_F77=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_minus_L_F77=yes + # see comment about different semantics on the GNU ld section + ld_shlibs_F77=no + ;; + + bsdi[45]*) + export_dynamic_flag_spec_F77=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_F77=' ' + allow_undefined_flag_F77=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_From_new_cmds_F77='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds_F77='lib -OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path_F77='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes_F77=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag_F77='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_F77='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc_F77=no + hardcode_direct_F77=no + hardcode_automatic_F77=yes + hardcode_shlibpath_var_F77=unsupported + whole_archive_flag_spec_F77='' + link_all_deplibs_F77=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds_F77='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' + module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_F77=no + ;; + esac + fi + ;; + + dgux*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_shlibpath_var_F77=no + ;; + + freebsd1*) + ld_shlibs_F77=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes + hardcode_minus_L_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds_F77='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + hardcode_direct_F77=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + + hardcode_direct_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld_F77='+b $libdir' + hardcode_direct_F77=no + hardcode_shlibpath_var_F77=no + ;; + *) + hardcode_direct_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_ld_F77='-rpath $libdir' + fi + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_F77=: + link_all_deplibs_F77=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + newsos6) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_F77=: + hardcode_shlibpath_var_F77=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + export_dynamic_flag_spec_F77='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-R$libdir' + ;; + *) + archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs_F77=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_minus_L_F77=yes + allow_undefined_flag_F77=unsupported + archive_cmds_F77='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_From_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag_F77=' -expect_unresolved \*' + archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_F77=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag_F77=' -expect_unresolved \*' + archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec_F77='-rpath $libdir' + fi + hardcode_libdir_separator_F77=: + ;; + + solaris*) + no_undefined_flag_F77=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec_F77='-R$libdir' + hardcode_shlibpath_var_F77=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec_F77='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs_F77=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_direct_F77=yes + hardcode_minus_L_F77=yes + hardcode_shlibpath_var_F77=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds_F77='$CC -r -o $output$reload_objs' + hardcode_direct_F77=no + ;; + motorola) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var_F77=no + ;; + + sysv4.3*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_F77=no + export_dynamic_flag_spec_F77='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_F77=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs_F77=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_F77='${wl}-z,text' + archive_cmds_need_lc_F77=no + hardcode_shlibpath_var_F77=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_F77='${wl}-z,text' + allow_undefined_flag_F77='${wl}-z,nodefs' + archive_cmds_need_lc_F77=no + hardcode_shlibpath_var_F77=no + hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_F77=':' + link_all_deplibs_F77=yes + export_dynamic_flag_spec_F77='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-L$libdir' + hardcode_shlibpath_var_F77=no + ;; + + *) + ld_shlibs_F77=no + ;; + esac + fi + +{ echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5 +echo "${ECHO_T}$ld_shlibs_F77" >&6; } +test "$ld_shlibs_F77" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_F77" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_F77=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_F77 in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } + $rm conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_F77 + pic_flag=$lt_prog_compiler_pic_F77 + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_F77 + allow_undefined_flag_F77= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_F77=no + else + archive_cmds_need_lc_F77=yes + fi + allow_undefined_flag_F77=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5 +echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6; } + ;; + esac + fi + ;; +esac + +{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; } +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" + +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } +hardcode_action_F77= +if test -n "$hardcode_libdir_flag_spec_F77" || \ + test -n "$runpath_var_F77" || \ + test "X$hardcode_automatic_F77" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct_F77" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no && + test "$hardcode_minus_L_F77" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_F77=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_F77=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_F77=unsupported +fi +{ echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5 +echo "${ECHO_T}$hardcode_action_F77" >&6; } + +if test "$hardcode_action_F77" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_F77 \ + CC_F77 \ + LD_F77 \ + lt_prog_compiler_wl_F77 \ + lt_prog_compiler_pic_F77 \ + lt_prog_compiler_static_F77 \ + lt_prog_compiler_no_builtin_flag_F77 \ + export_dynamic_flag_spec_F77 \ + thread_safe_flag_spec_F77 \ + whole_archive_flag_spec_F77 \ + enable_shared_with_static_runtimes_F77 \ + old_archive_cmds_F77 \ + old_archive_from_new_cmds_F77 \ + predep_objects_F77 \ + postdep_objects_F77 \ + predeps_F77 \ + postdeps_F77 \ + compiler_lib_search_path_F77 \ + archive_cmds_F77 \ + archive_expsym_cmds_F77 \ + postinstall_cmds_F77 \ + postuninstall_cmds_F77 \ + old_archive_from_expsyms_cmds_F77 \ + allow_undefined_flag_F77 \ + no_undefined_flag_F77 \ + export_symbols_cmds_F77 \ + hardcode_libdir_flag_spec_F77 \ + hardcode_libdir_flag_spec_ld_F77 \ + hardcode_libdir_separator_F77 \ + hardcode_automatic_F77 \ + module_cmds_F77 \ + module_expsym_cmds_F77 \ + lt_cv_prog_compiler_c_o_F77 \ + fix_srcfile_path_F77 \ + exclude_expsyms_F77 \ + include_expsyms_F77; do + + case $var in + old_archive_cmds_F77 | \ + old_archive_from_new_cmds_F77 | \ + archive_cmds_F77 | \ + archive_expsym_cmds_F77 | \ + module_cmds_F77 | \ + module_expsym_cmds_F77 | \ + old_archive_from_expsyms_cmds_F77 | \ + export_symbols_cmds_F77 | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_F77 + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77 + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_F77 + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_F77 + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_F77 + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_F77 + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_F77 +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77 + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_F77 + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77 + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77 + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77 + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_F77 + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_F77 +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77 + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77 + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_F77 +archive_expsym_cmds=$lt_archive_expsym_cmds_F77 +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_F77 +module_expsym_cmds=$lt_module_expsym_cmds_F77 + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_predep_objects_F77 + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_postdep_objects_F77 + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_F77 + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_F77 + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_F77 + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_F77 + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_F77 + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_F77 + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77 + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77 + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77 + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_F77 + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_F77 + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_F77 + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_F77 + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_F77 + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_F77 + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_F77 + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_F77 + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_F77 + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + else + tagname="" + fi + ;; + + GCJ) + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +objext_GCJ=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${GCJ-"gcj"} +compiler=$CC +compiler_GCJ=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +archive_cmds_need_lc_GCJ=no + +old_archive_cmds_GCJ=$old_archive_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... + +lt_prog_compiler_no_builtin_flag_GCJ= + +if test "$GCC" = yes; then + lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin' + + +{ echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:16802: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:16806: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions" +else + : +fi + +fi + +lt_prog_compiler_wl_GCJ= +lt_prog_compiler_pic_GCJ= +lt_prog_compiler_static_GCJ= + +{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 +echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } + + if test "$GCC" = yes; then + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_static_GCJ='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_GCJ='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_GCJ='-fno-common' + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared_GCJ=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_GCJ=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_GCJ='-fPIC' + ;; + esac + ;; + + *) + lt_prog_compiler_pic_GCJ='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl_GCJ='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_GCJ='-Bstatic' + else + lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + lt_prog_compiler_pic_GCJ='-qnocommon' + lt_prog_compiler_wl_GCJ='-Wl,' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl_GCJ='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_GCJ='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static_GCJ='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl_GCJ='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static_GCJ='-non_shared' + ;; + + newsos6) + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + icc* | ecc*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-fpic' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl_GCJ='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static_GCJ='-non_shared' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + lt_prog_compiler_wl_GCJ='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + lt_prog_compiler_wl_GCJ='' + ;; + esac + ;; + esac + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl_GCJ='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static_GCJ='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static_GCJ='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl_GCJ='-Qoption ld ';; + *) + lt_prog_compiler_wl_GCJ='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl_GCJ='-Qoption ld ' + lt_prog_compiler_pic_GCJ='-PIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic_GCJ='-Kconform_pic' + lt_prog_compiler_static_GCJ='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_can_build_shared_GCJ=no + ;; + + uts4*) + lt_prog_compiler_pic_GCJ='-pic' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared_GCJ=no + ;; + esac + fi + +{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6; } + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_GCJ"; then + +{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5 +echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6; } +if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_pic_works_GCJ=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_GCJ" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:17092: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:17096: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_pic_works_GCJ=yes + fi + fi + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5 +echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6; } + +if test x"$lt_prog_compiler_pic_works_GCJ" = xyes; then + case $lt_prog_compiler_pic_GCJ in + "" | " "*) ;; + *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;; + esac +else + lt_prog_compiler_pic_GCJ= + lt_prog_compiler_can_build_shared_GCJ=no +fi + +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_GCJ= + ;; + *) + lt_prog_compiler_pic_GCJ="$lt_prog_compiler_pic_GCJ" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_GCJ eval lt_tmp_static_flag=\"$lt_prog_compiler_static_GCJ\" +{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } +if test "${lt_prog_compiler_static_works_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_prog_compiler_static_works_GCJ=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_prog_compiler_static_works_GCJ=yes + fi + else + lt_prog_compiler_static_works_GCJ=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_GCJ" >&5 +echo "${ECHO_T}$lt_prog_compiler_static_works_GCJ" >&6; } + +if test x"$lt_prog_compiler_static_works_GCJ" = xyes; then + : +else + lt_prog_compiler_static_GCJ= +fi + + +{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_c_o_GCJ=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:17196: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:17200: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_GCJ=yes + fi + fi + chmod u+w . 2>&5 + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6; } + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5 +echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; } + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { echo "$as_me:$LINENO: result: $hard_links" >&5 +echo "${ECHO_T}$hard_links" >&6; } + if test "$hard_links" = no; then + { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + +{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; } + + runpath_var= + allow_undefined_flag_GCJ= + enable_shared_with_static_runtimes_GCJ=no + archive_cmds_GCJ= + archive_expsym_cmds_GCJ= + old_archive_From_new_cmds_GCJ= + old_archive_from_expsyms_cmds_GCJ= + export_dynamic_flag_spec_GCJ= + whole_archive_flag_spec_GCJ= + thread_safe_flag_spec_GCJ= + hardcode_libdir_flag_spec_GCJ= + hardcode_libdir_flag_spec_ld_GCJ= + hardcode_libdir_separator_GCJ= + hardcode_direct_GCJ=no + hardcode_minus_L_GCJ=no + hardcode_shlibpath_var_GCJ=unsupported + link_all_deplibs_GCJ=unknown + hardcode_automatic_GCJ=no + module_cmds_GCJ= + module_expsym_cmds_GCJ= + always_export_symbols_GCJ=no + export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms_GCJ= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms_GCJ="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs_GCJ=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_GCJ='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_GCJ= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs_GCJ=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_minus_L_GCJ=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + ld_shlibs_GCJ=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_GCJ=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_GCJ='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, GCJ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_GCJ='-L$libdir' + allow_undefined_flag_GCJ=unsupported + always_export_symbols_GCJ=no + enable_shared_with_static_runtimes_GCJ=yes + export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_GCJ=no + fi + ;; + + interix[3-9]*) + hardcode_direct_GCJ=no + hardcode_shlibpath_var_GCJ=no + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + export_dynamic_flag_spec_GCJ='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_GCJ='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | k*bsd*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec_GCJ='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + *) + tmp_sharedflag='-shared' ;; + esac + archive_cmds_GCJ='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + ld_shlibs_GCJ=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs_GCJ=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs_GCJ=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + esac + + if test "$ld_shlibs_GCJ" = no; then + runpath_var= + hardcode_libdir_flag_spec_GCJ= + export_dynamic_flag_spec_GCJ= + whole_archive_flag_spec_GCJ= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag_GCJ=unsupported + always_export_symbols_GCJ=yes + archive_expsym_cmds_GCJ='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L_GCJ=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct_GCJ=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + export_symbols_cmds_GCJ='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_GCJ='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_GCJ='' + hardcode_direct_GCJ=yes + hardcode_libdir_separator_GCJ=':' + link_all_deplibs_GCJ=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_GCJ=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_GCJ=yes + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_libdir_separator_GCJ= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols_GCJ=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_GCJ='-berok' + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_GCJ="-z nodefs" + archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_GCJ=' ${wl}-bernotok' + allow_undefined_flag_GCJ=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_GCJ='$convenience' + archive_cmds_need_lc_GCJ=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_minus_L_GCJ=yes + # see comment about different semantics on the GNU ld section + ld_shlibs_GCJ=no + ;; + + bsdi[45]*) + export_dynamic_flag_spec_GCJ=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_GCJ=' ' + allow_undefined_flag_GCJ=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_From_new_cmds_GCJ='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds_GCJ='lib -OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path_GCJ='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes_GCJ=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[012]) + allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[012]) + allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + allow_undefined_flag_GCJ='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + archive_cmds_need_lc_GCJ=no + hardcode_direct_GCJ=no + hardcode_automatic_GCJ=yes + hardcode_shlibpath_var_GCJ=unsupported + whole_archive_flag_spec_GCJ='' + link_all_deplibs_GCJ=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + archive_cmds_GCJ='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' + module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + ld_shlibs_GCJ=no + ;; + esac + fi + ;; + + dgux*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_shlibpath_var_GCJ=no + ;; + + freebsd1*) + ld_shlibs_GCJ=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes + hardcode_minus_L_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds_GCJ='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + hardcode_direct_GCJ=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + + hardcode_direct_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld_GCJ='+b $libdir' + hardcode_direct_GCJ=no + hardcode_shlibpath_var_GCJ=no + ;; + *) + hardcode_direct_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_GCJ='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_ld_GCJ='-rpath $libdir' + fi + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + link_all_deplibs_GCJ=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds_GCJ='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + newsos6) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + hardcode_shlibpath_var_GCJ=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + export_dynamic_flag_spec_GCJ='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + ;; + *) + archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs_GCJ=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_minus_L_GCJ=yes + allow_undefined_flag_GCJ=unsupported + archive_cmds_GCJ='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_From_new_cmds_GCJ='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag_GCJ=' -expect_unresolved \*' + archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag_GCJ=' -expect_unresolved \*' + archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec_GCJ='-rpath $libdir' + fi + hardcode_libdir_separator_GCJ=: + ;; + + solaris*) + no_undefined_flag_GCJ=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + hardcode_libdir_flag_spec_GCJ='-R$libdir' + hardcode_shlibpath_var_GCJ=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs_GCJ=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds_GCJ='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_direct_GCJ=yes + hardcode_minus_L_GCJ=yes + hardcode_shlibpath_var_GCJ=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds_GCJ='$CC -r -o $output$reload_objs' + hardcode_direct_GCJ=no + ;; + motorola) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct_GCJ=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var_GCJ=no + ;; + + sysv4.3*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_GCJ=no + export_dynamic_flag_spec_GCJ='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var_GCJ=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs_GCJ=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_GCJ='${wl}-z,text' + archive_cmds_need_lc_GCJ=no + hardcode_shlibpath_var_GCJ=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_GCJ='${wl}-z,text' + allow_undefined_flag_GCJ='${wl}-z,nodefs' + archive_cmds_need_lc_GCJ=no + hardcode_shlibpath_var_GCJ=no + hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_GCJ=':' + link_all_deplibs_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-L$libdir' + hardcode_shlibpath_var_GCJ=no + ;; + + *) + ld_shlibs_GCJ=no + ;; + esac + fi + +{ echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5 +echo "${ECHO_T}$ld_shlibs_GCJ" >&6; } +test "$ld_shlibs_GCJ" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_GCJ" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_GCJ=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_GCJ in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 +echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } + $rm conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_GCJ + pic_flag=$lt_prog_compiler_pic_GCJ + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_GCJ + allow_undefined_flag_GCJ= + if { (eval echo "$as_me:$LINENO: \"$archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5 + (eval $archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + then + archive_cmds_need_lc_GCJ=no + else + archive_cmds_need_lc_GCJ=yes + fi + allow_undefined_flag_GCJ=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5 +echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6; } + ;; + esac + fi + ;; +esac + +{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 +echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; } +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" + +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5 +echo "${ECHO_T}$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 +echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } +hardcode_action_GCJ= +if test -n "$hardcode_libdir_flag_spec_GCJ" || \ + test -n "$runpath_var_GCJ" || \ + test "X$hardcode_automatic_GCJ" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct_GCJ" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no && + test "$hardcode_minus_L_GCJ" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_GCJ=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_GCJ=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_GCJ=unsupported +fi +{ echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5 +echo "${ECHO_T}$hardcode_action_GCJ" >&6; } + +if test "$hardcode_action_GCJ" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_GCJ \ + CC_GCJ \ + LD_GCJ \ + lt_prog_compiler_wl_GCJ \ + lt_prog_compiler_pic_GCJ \ + lt_prog_compiler_static_GCJ \ + lt_prog_compiler_no_builtin_flag_GCJ \ + export_dynamic_flag_spec_GCJ \ + thread_safe_flag_spec_GCJ \ + whole_archive_flag_spec_GCJ \ + enable_shared_with_static_runtimes_GCJ \ + old_archive_cmds_GCJ \ + old_archive_from_new_cmds_GCJ \ + predep_objects_GCJ \ + postdep_objects_GCJ \ + predeps_GCJ \ + postdeps_GCJ \ + compiler_lib_search_path_GCJ \ + archive_cmds_GCJ \ + archive_expsym_cmds_GCJ \ + postinstall_cmds_GCJ \ + postuninstall_cmds_GCJ \ + old_archive_from_expsyms_cmds_GCJ \ + allow_undefined_flag_GCJ \ + no_undefined_flag_GCJ \ + export_symbols_cmds_GCJ \ + hardcode_libdir_flag_spec_GCJ \ + hardcode_libdir_flag_spec_ld_GCJ \ + hardcode_libdir_separator_GCJ \ + hardcode_automatic_GCJ \ + module_cmds_GCJ \ + module_expsym_cmds_GCJ \ + lt_cv_prog_compiler_c_o_GCJ \ + fix_srcfile_path_GCJ \ + exclude_expsyms_GCJ \ + include_expsyms_GCJ; do + + case $var in + old_archive_cmds_GCJ | \ + old_archive_from_new_cmds_GCJ | \ + archive_cmds_GCJ | \ + archive_expsym_cmds_GCJ | \ + module_cmds_GCJ | \ + module_expsym_cmds_GCJ | \ + old_archive_from_expsyms_cmds_GCJ | \ + export_symbols_cmds_GCJ | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_GCJ + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_GCJ + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_GCJ + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_GCJ + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_GCJ + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_GCJ + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_GCJ +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_GCJ + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_GCJ + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_GCJ + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_GCJ + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_GCJ + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_GCJ +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_GCJ + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_GCJ + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_GCJ +archive_expsym_cmds=$lt_archive_expsym_cmds_GCJ +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_GCJ +module_expsym_cmds=$lt_module_expsym_cmds_GCJ + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_predep_objects_GCJ + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_postdep_objects_GCJ + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_GCJ + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_GCJ + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_GCJ + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_GCJ + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_GCJ + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_GCJ + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_GCJ + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_GCJ + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_GCJ + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_GCJ + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_GCJ + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_GCJ + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_GCJ + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_GCJ + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_GCJ + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_GCJ + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_GCJ + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_GCJ + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + else + tagname="" + fi + ;; + + RC) + + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +objext_RC=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${RC-"windres"} +compiler=$CC +compiler_RC=$CC +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` + +lt_cv_prog_compiler_c_o_RC=yes + +# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + compiler_RC \ + CC_RC \ + LD_RC \ + lt_prog_compiler_wl_RC \ + lt_prog_compiler_pic_RC \ + lt_prog_compiler_static_RC \ + lt_prog_compiler_no_builtin_flag_RC \ + export_dynamic_flag_spec_RC \ + thread_safe_flag_spec_RC \ + whole_archive_flag_spec_RC \ + enable_shared_with_static_runtimes_RC \ + old_archive_cmds_RC \ + old_archive_from_new_cmds_RC \ + predep_objects_RC \ + postdep_objects_RC \ + predeps_RC \ + postdeps_RC \ + compiler_lib_search_path_RC \ + archive_cmds_RC \ + archive_expsym_cmds_RC \ + postinstall_cmds_RC \ + postuninstall_cmds_RC \ + old_archive_from_expsyms_cmds_RC \ + allow_undefined_flag_RC \ + no_undefined_flag_RC \ + export_symbols_cmds_RC \ + hardcode_libdir_flag_spec_RC \ + hardcode_libdir_flag_spec_ld_RC \ + hardcode_libdir_separator_RC \ + hardcode_automatic_RC \ + module_cmds_RC \ + module_expsym_cmds_RC \ + lt_cv_prog_compiler_c_o_RC \ + fix_srcfile_path_RC \ + exclude_expsyms_RC \ + include_expsyms_RC; do + + case $var in + old_archive_cmds_RC | \ + old_archive_from_new_cmds_RC | \ + archive_cmds_RC | \ + archive_expsym_cmds_RC | \ + module_cmds_RC | \ + module_expsym_cmds_RC | \ + old_archive_from_expsyms_cmds_RC | \ + export_symbols_cmds_RC | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\$0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + +cfgfile="$ofile" + + cat <<__EOF__ >> "$cfgfile" +# ### BEGIN LIBTOOL TAG CONFIG: $tagname + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_RC + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_compiler_RC + +# Is the compiler the GNU C compiler? +with_gcc=$GCC_RC + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_LD_RC + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_RC + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_RC +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_RC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec_RC + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds_RC +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds_RC +archive_expsym_cmds=$lt_archive_expsym_cmds_RC +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_module_cmds_RC +module_expsym_cmds=$lt_module_expsym_cmds_RC + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_predep_objects_RC + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_postdep_objects_RC + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_predeps_RC + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_postdeps_RC + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_RC + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_RC + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_RC + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_RC + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct_RC + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L_RC + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_RC + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$hardcode_automatic_RC + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_RC + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols_RC + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_RC + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_RC + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_RC + +# ### END LIBTOOL TAG CONFIG: $tagname + +__EOF__ + + +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + ;; + + *) + { { echo "$as_me:$LINENO: error: Unsupported tag name: $tagname" >&5 +echo "$as_me: error: Unsupported tag name: $tagname" >&2;} + { (exit 1); exit 1; }; } + ;; + esac + + # Append the new tag name to the list of available tags. + if test -n "$tagname" ; then + available_tags="$available_tags $tagname" + fi + fi + done + IFS="$lt_save_ifs" + + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + else + rm -f "${ofile}T" + { { echo "$as_me:$LINENO: error: unable to update list of available tagged configurations." >&5 +echo "$as_me: error: unable to update list of available tagged configurations." >&2;} + { (exit 1); exit 1; }; } + fi +fi + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + +# Prevent multiple expansion + + + + + + + + + + + + + + + + + + + + + + + + + + + +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do + as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5 +echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include <$ac_hdr> + +int +main () +{ +if ((DIR *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 +_ACEOF + +ac_header_dirent=$ac_hdr; break +fi + +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then + { echo "$as_me:$LINENO: checking for library containing opendir" >&5 +echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; } +if test "${ac_cv_search_opendir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dir; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_search_opendir=$ac_res +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_opendir+set}" = set; then + break +fi +done +if test "${ac_cv_search_opendir+set}" = set; then + : +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 +echo "${ECHO_T}$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +else + { echo "$as_me:$LINENO: checking for library containing opendir" >&5 +echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; } +if test "${ac_cv_search_opendir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' x; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_search_opendir=$ac_res +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_opendir+set}" = set; then + break +fi +done +if test "${ac_cv_search_opendir+set}" = set; then + : +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 +echo "${ECHO_T}$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +fi + +# Check whether --enable-ltdl-install was given. +if test "${enable_ltdl_install+set}" = set; then + enableval=$enable_ltdl_install; +fi + + + if test x"${enable_ltdl_install-no}" != xno; then + INSTALL_LTDL_TRUE= + INSTALL_LTDL_FALSE='#' +else + INSTALL_LTDL_TRUE='#' + INSTALL_LTDL_FALSE= +fi + + if test x"${enable_ltdl_convenience-no}" != xno; then + CONVENIENCE_LTDL_TRUE= + CONVENIENCE_LTDL_FALSE='#' +else + CONVENIENCE_LTDL_TRUE='#' + CONVENIENCE_LTDL_FALSE= +fi + + + +{ echo "$as_me:$LINENO: checking which extension is used for loadable modules" >&5 +echo $ECHO_N "checking which extension is used for loadable modules... $ECHO_C" >&6; } +if test "${libltdl_cv_shlibext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +module=yes +eval libltdl_cv_shlibext=$shrext_cmds + +fi +{ echo "$as_me:$LINENO: result: $libltdl_cv_shlibext" >&5 +echo "${ECHO_T}$libltdl_cv_shlibext" >&6; } +if test -n "$libltdl_cv_shlibext"; then + +cat >>confdefs.h <<_ACEOF +#define LTDL_SHLIB_EXT "$libltdl_cv_shlibext" +_ACEOF + +fi + + +{ echo "$as_me:$LINENO: checking which variable specifies run-time library path" >&5 +echo $ECHO_N "checking which variable specifies run-time library path... $ECHO_C" >&6; } +if test "${libltdl_cv_shlibpath_var+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + libltdl_cv_shlibpath_var="$shlibpath_var" +fi +{ echo "$as_me:$LINENO: result: $libltdl_cv_shlibpath_var" >&5 +echo "${ECHO_T}$libltdl_cv_shlibpath_var" >&6; } +if test -n "$libltdl_cv_shlibpath_var"; then + +cat >>confdefs.h <<_ACEOF +#define LTDL_SHLIBPATH_VAR "$libltdl_cv_shlibpath_var" +_ACEOF + +fi + + +{ echo "$as_me:$LINENO: checking for the default library search path" >&5 +echo $ECHO_N "checking for the default library search path... $ECHO_C" >&6; } +if test "${libltdl_cv_sys_search_path+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + libltdl_cv_sys_search_path="$sys_lib_dlsearch_path_spec" +fi +{ echo "$as_me:$LINENO: result: $libltdl_cv_sys_search_path" >&5 +echo "${ECHO_T}$libltdl_cv_sys_search_path" >&6; } +if test -n "$libltdl_cv_sys_search_path"; then + sys_search_path= + for dir in $libltdl_cv_sys_search_path; do + if test -z "$sys_search_path"; then + sys_search_path="$dir" + else + sys_search_path="$sys_search_path$PATH_SEPARATOR$dir" + fi + done + +cat >>confdefs.h <<_ACEOF +#define LTDL_SYSSEARCHPATH "$sys_search_path" +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for objdir" >&5 +echo $ECHO_N "checking for objdir... $ECHO_C" >&6; } +if test "${libltdl_cv_objdir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + libltdl_cv_objdir="$objdir" + if test -n "$objdir"; then + : + else + rm -f .libs 2>/dev/null + mkdir .libs 2>/dev/null + if test -d .libs; then + libltdl_cv_objdir=.libs + else + # MS-DOS does not allow filenames that begin with a dot. + libltdl_cv_objdir=_libs + fi + rmdir .libs 2>/dev/null + fi + +fi +{ echo "$as_me:$LINENO: result: $libltdl_cv_objdir" >&5 +echo "${ECHO_T}$libltdl_cv_objdir" >&6; } + +cat >>confdefs.h <<_ACEOF +#define LTDL_OBJDIR "$libltdl_cv_objdir/" +_ACEOF + + + +{ echo "$as_me:$LINENO: checking whether libtool supports -dlopen/-dlpreopen" >&5 +echo $ECHO_N "checking whether libtool supports -dlopen/-dlpreopen... $ECHO_C" >&6; } +if test "${libltdl_cv_preloaded_symbols+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$lt_cv_sys_global_symbol_pipe"; then + libltdl_cv_preloaded_symbols=yes + else + libltdl_cv_preloaded_symbols=no + fi + +fi +{ echo "$as_me:$LINENO: result: $libltdl_cv_preloaded_symbols" >&5 +echo "${ECHO_T}$libltdl_cv_preloaded_symbols" >&6; } +if test x"$libltdl_cv_preloaded_symbols" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_PRELOADED_SYMBOLS 1 +_ACEOF + +fi + +LIBADD_DL= + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ echo "$as_me:$LINENO: checking for shl_load" >&5 +echo $ECHO_N "checking for shl_load... $ECHO_C" >&6; } +if test "${ac_cv_func_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define shl_load to an innocuous variant, in case declares shl_load. + For example, HP-UX 11i declares gettimeofday. */ +#define shl_load innocuous_shl_load + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char shl_load (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef shl_load + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_shl_load || defined __stub___shl_load +choke me +#endif + +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_shl_load=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 +echo "${ECHO_T}$ac_cv_func_shl_load" >&6; } +if test $ac_cv_func_shl_load = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SHL_LOAD 1 +_ACEOF + +else + { echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 +echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6; } +if test "${ac_cv_lib_dld_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_dld_shl_load=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dld_shl_load=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; } +if test $ac_cv_lib_dld_shl_load = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SHL_LOAD 1 +_ACEOF + + LIBADD_DL="$LIBADD_DL -ldld" +else + { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dl_dlopen=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } +if test $ac_cv_lib_dl_dlopen = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBDL 1 +_ACEOF + + LIBADD_DL="-ldl" libltdl_cv_lib_dl_dlopen="yes" +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if HAVE_DLFCN_H +# include +#endif + +int +main () +{ +dlopen(0, 0); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBDL 1 +_ACEOF + libltdl_cv_func_dlopen="yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 +echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6; } +if test "${ac_cv_lib_svld_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_svld_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_svld_dlopen=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6; } +if test $ac_cv_lib_svld_dlopen = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIBDL 1 +_ACEOF + + LIBADD_DL="-lsvld" libltdl_cv_func_dlopen="yes" +else + { echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 +echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6; } +if test "${ac_cv_lib_dld_dld_link+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_dld_dld_link=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dld_dld_link=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6; } +if test $ac_cv_lib_dld_dld_link = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DLD 1 +_ACEOF + + LIBADD_DL="$LIBADD_DL -ldld" +else + { echo "$as_me:$LINENO: checking for _dyld_func_lookup" >&5 +echo $ECHO_N "checking for _dyld_func_lookup... $ECHO_C" >&6; } +if test "${ac_cv_func__dyld_func_lookup+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define _dyld_func_lookup to an innocuous variant, in case declares _dyld_func_lookup. + For example, HP-UX 11i declares gettimeofday. */ +#define _dyld_func_lookup innocuous__dyld_func_lookup + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char _dyld_func_lookup (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef _dyld_func_lookup + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char _dyld_func_lookup (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub__dyld_func_lookup || defined __stub____dyld_func_lookup +choke me +#endif + +int +main () +{ +return _dyld_func_lookup (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func__dyld_func_lookup=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func__dyld_func_lookup=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func__dyld_func_lookup" >&5 +echo "${ECHO_T}$ac_cv_func__dyld_func_lookup" >&6; } +if test $ac_cv_func__dyld_func_lookup = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DYLD 1 +_ACEOF + +fi + + +fi + + +fi + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + +fi + + +fi + + +fi + + +if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes +then + lt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBADD_DL" + +for ac_func in dlerror +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + LIBS="$lt_save_LIBS" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +{ echo "$as_me:$LINENO: checking for _ prefix in compiled symbols" >&5 +echo $ECHO_N "checking for _ prefix in compiled symbols... $ECHO_C" >&6; } +if test "${ac_cv_sys_symbol_underscore+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_sys_symbol_underscore=no + cat > conftest.$ac_ext <&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Now try to grab the symbols. + ac_nlist=conftest.nm + if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist\"") >&5 + (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s "$ac_nlist"; then + # See whether the symbols have a leading underscore. + if grep '^. _nm_test_func' "$ac_nlist" >/dev/null; then + ac_cv_sys_symbol_underscore=yes + else + if grep '^. nm_test_func ' "$ac_nlist" >/dev/null; then + : + else + echo "configure: cannot find nm_test_func in $ac_nlist" >&5 + fi + fi + else + echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "configure: failed program was:" >&5 + cat conftest.c >&5 + fi + rm -rf conftest* + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sys_symbol_underscore" >&5 +echo "${ECHO_T}$ac_cv_sys_symbol_underscore" >&6; } + + +if test x"$ac_cv_sys_symbol_underscore" = xyes; then + if test x"$libltdl_cv_func_dlopen" = xyes || + test x"$libltdl_cv_lib_dl_dlopen" = xyes ; then + { echo "$as_me:$LINENO: checking whether we have to add an underscore for dlsym" >&5 +echo $ECHO_N "checking whether we have to add an underscore for dlsym... $ECHO_C" >&6; } +if test "${libltdl_cv_need_uscore+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + libltdl_cv_need_uscore=unknown + save_LIBS="$LIBS" + LIBS="$LIBS $LIBADD_DL" + if test "$cross_compiling" = yes; then : + libltdl_cv_need_uscore=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + exit (status); +} +EOF + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) libltdl_cv_need_uscore=no ;; + x$lt_dlneed_uscore) libltdl_cv_need_uscore=yes ;; + x$lt_dlunknown|x*) ;; + esac + else : + # compilation failed + + fi +fi +rm -fr conftest* + + LIBS="$save_LIBS" + +fi +{ echo "$as_me:$LINENO: result: $libltdl_cv_need_uscore" >&5 +echo "${ECHO_T}$libltdl_cv_need_uscore" >&6; } + fi +fi + +if test x"$libltdl_cv_need_uscore" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define NEED_USCORE 1 +_ACEOF + +fi + + +{ echo "$as_me:$LINENO: checking whether deplibs are loaded by dlopen" >&5 +echo $ECHO_N "checking whether deplibs are loaded by dlopen... $ECHO_C" >&6; } +if test "${libltdl_cv_sys_dlopen_deplibs+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # PORTME does your system automatically load deplibs for dlopen? + # or its logical equivalent (e.g. shl_load for HP-UX < 11) + # For now, we just catch OSes we know something about -- in the + # future, we'll try test this programmatically. + libltdl_cv_sys_dlopen_deplibs=unknown + case "$host_os" in + aix3*|aix4.1.*|aix4.2.*) + # Unknown whether this is true for these versions of AIX, but + # we want this `case' here to explicitly catch those versions. + libltdl_cv_sys_dlopen_deplibs=unknown + ;; + aix[45]*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + darwin*) + # Assuming the user has installed a libdl from somewhere, this is true + # If you are looking for one http://www.opendarwin.org/projects/dlcompat + libltdl_cv_sys_dlopen_deplibs=yes + ;; + freebsd* | dragonfly*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + gnu* | linux* | k*bsd*-gnu) + # GNU and its variants, using gnu ld.so (Glibc) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + hpux10*|hpux11*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + interix*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + irix[12345]*|irix6.[01]*) + # Catch all versions of IRIX before 6.2, and indicate that we don't + # know how it worked for any of those versions. + libltdl_cv_sys_dlopen_deplibs=unknown + ;; + irix*) + # The case above catches anything before 6.2, and it's known that + # at 6.2 and later dlopen does load deplibs. + libltdl_cv_sys_dlopen_deplibs=yes + ;; + netbsd*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + openbsd*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + osf[1234]*) + # dlopen did load deplibs (at least at 4.x), but until the 5.x series, + # it did *not* use an RPATH in a shared library to find objects the + # library depends on, so we explictly say `no'. + libltdl_cv_sys_dlopen_deplibs=no + ;; + osf5.0|osf5.0a|osf5.1) + # dlopen *does* load deplibs and with the right loader patch applied + # it even uses RPATH in a shared library to search for shared objects + # that the library depends on, but there's no easy way to know if that + # patch is installed. Since this is the case, all we can really + # say is unknown -- it depends on the patch being installed. If + # it is, this changes to `yes'. Without it, it would be `no'. + libltdl_cv_sys_dlopen_deplibs=unknown + ;; + osf*) + # the two cases above should catch all versions of osf <= 5.1. Read + # the comments above for what we know about them. + # At > 5.1, deplibs are loaded *and* any RPATH in a shared library + # is used to find them so we can finally say `yes'. + libltdl_cv_sys_dlopen_deplibs=yes + ;; + solaris*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + libltdl_cv_sys_dlopen_deplibs=yes + ;; + esac + +fi +{ echo "$as_me:$LINENO: result: $libltdl_cv_sys_dlopen_deplibs" >&5 +echo "${ECHO_T}$libltdl_cv_sys_dlopen_deplibs" >&6; } +if test "$libltdl_cv_sys_dlopen_deplibs" != yes; then + +cat >>confdefs.h <<\_ACEOF +#define LTDL_DLOPEN_DEPLIBS 1 +_ACEOF + +fi + + +for ac_header in argz.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ---------------------------------- ## +## Report this to bug-libtool@gnu.org ## +## ---------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +{ echo "$as_me:$LINENO: checking for error_t" >&5 +echo $ECHO_N "checking for error_t... $ECHO_C" >&6; } +if test "${ac_cv_type_error_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if HAVE_ARGZ_H +# include +#endif + +typedef error_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_error_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_error_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_error_t" >&5 +echo "${ECHO_T}$ac_cv_type_error_t" >&6; } +if test $ac_cv_type_error_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_ERROR_T 1 +_ACEOF + + +else + +cat >>confdefs.h <<\_ACEOF +#define error_t int +_ACEOF + +fi + + + + + + + +for ac_func in argz_append argz_create_sep argz_insert argz_next argz_stringify +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + + + + + + + + + + + + + + + + + + + + + + + + + + +for ac_header in assert.h ctype.h errno.h malloc.h memory.h stdlib.h \ + stdio.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ---------------------------------- ## +## Report this to bug-libtool@gnu.org ## +## ---------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + +for ac_header in dl.h sys/dl.h dld.h mach-o/dyld.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ---------------------------------- ## +## Report this to bug-libtool@gnu.org ## +## ---------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_header in string.h strings.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ---------------------------------- ## +## Report this to bug-libtool@gnu.org ## +## ---------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + break +fi + +done + + + + +for ac_func in strchr index +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + break +fi +done + + + +for ac_func in strrchr rindex +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + break +fi +done + + + +for ac_func in memcpy bcopy +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + break +fi +done + + + +for ac_func in memmove strcmp +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + + +for ac_func in closedir opendir readdir +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + + +## -------- ## +## Outputs. ## +## -------- ## +ac_config_files="$ac_config_files Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${INSTALL_LTDL_TRUE}" && test -z "${INSTALL_LTDL_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"INSTALL_LTDL\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"INSTALL_LTDL\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${CONVENIENCE_LTDL_TRUE}" && test -z "${CONVENIENCE_LTDL_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"CONVENIENCE_LTDL\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"CONVENIENCE_LTDL\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by libltdl $as_me 1.2, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +libltdl config.status 1.2 +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:config-h.in" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +am__isrc!$am__isrc$ac_delim +CYGPATH_W!$CYGPATH_W$ac_delim +PACKAGE!$PACKAGE$ac_delim +VERSION!$VERSION$ac_delim +ACLOCAL!$ACLOCAL$ac_delim +AUTOCONF!$AUTOCONF$ac_delim +AUTOMAKE!$AUTOMAKE$ac_delim +AUTOHEADER!$AUTOHEADER$ac_delim +MAKEINFO!$MAKEINFO$ac_delim +install_sh!$install_sh$ac_delim +STRIP!$STRIP$ac_delim +INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim +mkdir_p!$mkdir_p$ac_delim +AWK!$AWK$ac_delim +SET_MAKE!$SET_MAKE$ac_delim +am__leading_dot!$am__leading_dot$ac_delim +AMTAR!$AMTAR$ac_delim +am__tar!$am__tar$ac_delim +am__untar!$am__untar$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +DEPDIR!$DEPDIR$ac_delim +am__include!$am__include$ac_delim +am__quote!$am__quote$ac_delim +AMDEP_TRUE!$AMDEP_TRUE$ac_delim +AMDEP_FALSE!$AMDEP_FALSE$ac_delim +AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim +CCDEPMODE!$CCDEPMODE$ac_delim +am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim +am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim +build!$build$ac_delim +build_cpu!$build_cpu$ac_delim +build_vendor!$build_vendor$ac_delim +build_os!$build_os$ac_delim +host!$host$ac_delim +host_cpu!$host_cpu$ac_delim +host_vendor!$host_vendor$ac_delim +host_os!$host_os$ac_delim +SED!$SED$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +LN_S!$LN_S$ac_delim +ECHO!$ECHO$ac_delim +AR!$AR$ac_delim +RANLIB!$RANLIB$ac_delim +DLLTOOL!$DLLTOOL$ac_delim +AS!$AS$ac_delim +OBJDUMP!$OBJDUMP$ac_delim +CPP!$CPP$ac_delim +CXX!$CXX$ac_delim +CXXFLAGS!$CXXFLAGS$ac_delim +ac_ct_CXX!$ac_ct_CXX$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +CEOF$ac_eof +_ACEOF + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +CXXDEPMODE!$CXXDEPMODE$ac_delim +am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim +am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim +CXXCPP!$CXXCPP$ac_delim +F77!$F77$ac_delim +FFLAGS!$FFLAGS$ac_delim +ac_ct_F77!$ac_ct_F77$ac_delim +LIBTOOL!$LIBTOOL$ac_delim +LIBTOOL_DEPS!$LIBTOOL_DEPS$ac_delim +INSTALL_LTDL_TRUE!$INSTALL_LTDL_TRUE$ac_delim +INSTALL_LTDL_FALSE!$INSTALL_LTDL_FALSE$ac_delim +CONVENIENCE_LTDL_TRUE!$CONVENIENCE_LTDL_TRUE$ac_delim +CONVENIENCE_LTDL_FALSE!$CONVENIENCE_LTDL_FALSE$ac_delim +LIBADD_DL!$LIBADD_DL$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 16; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + :H) + # + # CONFIG_HEADER + # +_ACEOF + +# Transform confdefs.h into a sed script `conftest.defines', that +# substitutes the proper values into config.h.in to produce config.h. +rm -f conftest.defines conftest.tail +# First, append a space to every undef/define line, to ease matching. +echo 's/$/ /' >conftest.defines +# Then, protect against being on the right side of a sed subst, or in +# an unquoted here document, in config.status. If some macros were +# called several times there might be several #defines for the same +# symbol, which is useless. But do not sort them, since the last +# AC_DEFINE must be honored. +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +# NAME is the cpp macro being defined, VALUE is the value it is being given. +# PARAMS is the parameter list in the macro definition--in most cases, it's +# just an empty string. +ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +ac_dB='\\)[ (].*,\\1define\\2' +ac_dC=' ' +ac_dD=' ,' + +uniq confdefs.h | + sed -n ' + t rset + :rset + s/^[ ]*#[ ]*define[ ][ ]*// + t ok + d + :ok + s/[\\&,]/\\&/g + s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p + s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p + ' >>conftest.defines + +# Remove the space that was appended to ease matching. +# Then replace #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +# (The regexp can be short, since the line contains either #define or #undef.) +echo 's/ $// +s,^[ #]*u.*,/* & */,' >>conftest.defines + +# Break up conftest.defines: +ac_max_sed_lines=50 + +# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +# et cetera. +ac_in='$ac_file_inputs' +ac_out='"$tmp/out1"' +ac_nxt='"$tmp/out2"' + +while : +do + # Write a here document: + cat >>$CONFIG_STATUS <<_ACEOF + # First, check the format of the line: + cat >"\$tmp/defines.sed" <<\\CEOF +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +b +:def +_ACEOF + sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS + ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in + sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail + grep . conftest.tail >/dev/null || break + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines conftest.tail + +echo "ac_result=$ac_in" >>$CONFIG_STATUS +cat >>$CONFIG_STATUS <<\_ACEOF + if test x"$ac_file" != x-; then + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f $ac_file + mv "$tmp/config.h" $ac_file + fi + else + echo "/* $configure_input */" + cat "$ac_result" + fi + rm -f "$tmp/out12" +# Compute $ac_file's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $ac_file | $ac_file:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $ac_file" >`$as_dirname -- $ac_file || +$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X$ac_file : 'X\(//\)[^/]' \| \ + X$ac_file : 'X\(//\)$' \| \ + X$ac_file : 'X\(/\)' \| . 2>/dev/null || +echo X$ac_file | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 +echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir=$dirpart/$fdir + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + + esac +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/libltdl/configure.ac b/libltdl/configure.ac new file mode 100644 index 00000000..1446efbd --- /dev/null +++ b/libltdl/configure.ac @@ -0,0 +1,79 @@ +## Process this file with autoconf to create configure. -*- autoconf -*- +# Copyright 2001 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + + +dnl FIXME: Is this really new enough? +AC_PREREQ(2.50) + + +## ------------------------ ## +## Autoconf initialisation. ## +## ------------------------ ## +AC_INIT([libltdl], [1.2], [bug-libtool@gnu.org]) +AC_CONFIG_SRCDIR([ltdl.c]) + + +## ------------------------------- ## +## Libltdl specific configuration. ## +## ------------------------------- ## + +AC_CONFIG_AUX_DIR([.]) + +if test -z "$enable_ltdl_install$enable_ltdl_convenience"; then + if test -f ${srcdir}/ltmain.sh; then + # if libltdl is libtoolized, it is assumed to be stand-alone and + # installed unless the command line overrides it (tested above) + enable_ltdl_install=yes + else + AC_MSG_WARN([*** The top-level configure must select either]) + AC_MSG_WARN([*** [A""C_LIBLTDL_INSTALLABLE] or [A""C_LIBLTDL_CONVENIENCE].]) + AC_MSG_ERROR([*** Maybe you want to --enable-ltdl-install?]) + fi +fi + + +## ------------------------ ## +## Automake Initialisation. ## +## ------------------------ ## +AM_INIT_AUTOMAKE(AC_PACKAGE_TARNAME, AC_PACKAGE_VERSION, -) +AM_CONFIG_HEADER([config.h:config-h.in]) + + +## ------------------ ## +## C compiler checks. ## +## ------------------ ## +AC_PROG_CC +AC_C_CONST +AC_C_INLINE + + +## ----------------------- ## +## Libtool initialisation. ## +## ----------------------- ## +AC_LIBTOOL_WIN32_DLL +AC_PROG_LIBTOOL +AC_SUBST([LIBTOOL_DEPS]) + +AC_LIB_LTDL + + +## -------- ## +## Outputs. ## +## -------- ## +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/libltdl/install-sh b/libltdl/install-sh new file mode 100755 index 00000000..a5897de6 --- /dev/null +++ b/libltdl/install-sh @@ -0,0 +1,519 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2006-12-25.00 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/libltdl/libtool b/libltdl/libtool new file mode 100755 index 00000000..24138133 --- /dev/null +++ b/libltdl/libtool @@ -0,0 +1,7895 @@ +#! /bin/sh + +# libtoolT - Provide generalized library-building support services. +# Generated automatically by (GNU libltdl 1.2) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED="/bin/sed" + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="/bin/sed -e 1s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# The names of the tagged configurations supported by this script. +available_tags=" CXX F77" + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host lambda: + +# Shell to use when invoking shell scripts. +SHELL="/bin/sh" + +# Whether or not to build shared libraries. +build_libtool_libs=yes + +# Whether or not to build static libraries. +build_old_libs=yes + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=no + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=no + +# Whether or not to optimize for fast installation. +fast_install=yes + +# The host system. +host_alias= +host=i686-pc-linux-gnu +host_os=linux-gnu + +# The build system. +build_alias= +build=i686-pc-linux-gnu +build_os=linux-gnu + +# An echo program that does not interpret backslashes. +echo="echo" + +# The archiver. +AR="ar" +AR_FLAGS="cru" + +# A C compiler. +LTCC="gcc" + +# LTCC compiler flags. +LTCFLAGS="-g -O2" + +# A language-specific compiler. +CC="gcc" + +# Is the compiler the GNU C compiler? +with_gcc=yes + +# An ERE matcher. +EGREP="/bin/grep -E" + +# The linker used to build libraries. +LD="/usr/bin/ld" + +# Whether we need hard or soft links. +LN_S="ln -s" + +# A BSD-compatible nm program. +NM="/usr/bin/nm -B" + +# A symbol stripping program +STRIP="strip" + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=file + +# Used on cygwin: DLL creation program. +DLLTOOL="dlltool" + +# Used on cygwin: object dumper. +OBJDUMP="objdump" + +# Used on cygwin: assembler. +AS="as" + +# The name of the directory that contains temporary libtool files. +objdir=.libs + +# How to create reloadable object files. +reload_flag=" -r" +reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" + +# How to pass a linker flag through the compiler. +wl="-Wl," + +# Object file suffix (normally "o"). +objext="o" + +# Old archive suffix (normally "a"). +libext="a" + +# Shared library suffix (normally ".so"). +shrext_cmds='.so' + +# Executable file suffix (normally ""). +exeext="" + +# Additional compiler flags for building library objects. +pic_flag=" -fPIC -DPIC" +pic_mode=default + +# What is the maximum length of a command? +max_cmd_len=98304 + +# Does compiler simultaneously support -c and -o options? +compiler_c_o="yes" + +# Must we lock files when doing compilation? +need_locks="no" + +# Do we need the lib prefix for modules? +need_lib_prefix=no + +# Do we need a version for libraries? +need_version=no + +# Whether dlopen is supported. +dlopen_support=unknown + +# Whether dlopen of programs is supported. +dlopen_self=unknown + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=unknown + +# Compiler flag to prevent dynamic linking. +link_static_flag="-static" + +# Compiler flag to turn off builtin functions. +no_builtin_flag=" -fno-builtin" + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec="\${wl}--export-dynamic" + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec="" + +# Library versioning type. +version_type=linux + +# Format of library name prefix. +libname_spec="lib\$name" + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" + +# The coded name of the library, if different from the real name. +soname_spec="\${libname}\${release}\${shared_ext}\$major" + +# Commands used to build and install an old-style archive. +RANLIB="ranlib" +old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs~\$RANLIB \$oldlib" +old_postinstall_cmds="chmod 644 \$oldlib~\$RANLIB \$oldlib" +old_postuninstall_cmds="" + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds="" + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds="" + +# Commands used to build and install a shared archive. +archive_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" +archive_expsym_cmds="\$echo \\\"{ global:\\\" > \$output_objdir/\$libname.ver~ + cat \$export_symbols | sed -e \\\"s/\\\\(.*\\\\)/\\\\1;/\\\" >> \$output_objdir/\$libname.ver~ + \$echo \\\"local: *; };\\\" >> \$output_objdir/\$libname.ver~ + \$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-version-script \${wl}\$output_objdir/\$libname.ver -o \$lib" +postinstall_cmds="" +postuninstall_cmds="" + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds="" +module_expsym_cmds="" + +# Commands to strip libraries. +old_striplib="strip --strip-debug" +striplib="strip --strip-unneeded" + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects="" + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects="" + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps="" + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps="" + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path="" + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method="pass_all" + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd="\$MAGIC_CMD" + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag="" + +# Flag that forces no undefined symbols. +no_undefined_flag="" + +# Commands used to finish a libtool library installation in a directory. +finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval="" + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2 \\2/p'" + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'" + +# This is the shared library runtime path variable. +runpath_var=LD_RUN_PATH + +# This is the shared library path variable. +shlibpath_var=LD_LIBRARY_PATH + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=no + +# How to hardcode a shared library path into an executable. +hardcode_action=immediate + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=yes + +# Flag to hardcode $libdir into a binary during linking. +# This must work even if $libdir does not exist. +hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" + +# If ld is used when linking, flag to hardcode $libdir into +# a binary during linking. This must work even if $libdir does +# not exist. +hardcode_libdir_flag_spec_ld="" + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator="" + +# Set to yes if using DIR/libNAME during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=no + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=no + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=unsupported + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=no + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=unknown + +# Compile-time system search path for libraries +sys_lib_search_path_spec="/usr/lib /lib /usr/local/lib" + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec="/usr/lib /lib /usr/lib/qt-3.3/lib " + +# Fix the shell variable $srcfile for the compiler. +fix_srcfile_path="" + +# Set to yes if exported symbols are required. +always_export_symbols=no + +# The commands to list exported symbols. +export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds="" + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_" + +# Symbols that must always be exported. +include_expsyms="" + +# ### END LIBTOOL CONFIG + +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun configure. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +# 2007 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +basename="s,^.*/,,g" + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + +# The name of this program: +progname=`echo "$progpath" | $SED $basename` +modename="$progname" + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 + +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION=1.5.24 +TIMESTAMP=" (1.1220.2.456 2007/06/24 02:25:32)" + +# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$progpath" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +duplicate_deps=no +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +##################################### +# Shell function definitions: +# This seems to be the best place for them + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $mkdir "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || { + $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2 + exit $EXIT_FAILURE + } + fi + + $echo "X$my_tmpdir" | $Xsed +} + + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +func_win32_libid () +{ + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ + $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | \ + $SED -n -e '1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $echo $win32_libid_type +} + + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case "$@ " in + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + $echo "$modename: unable to infer tagged configuration" + $echo "$modename: specify a tag with \`--tag'" 1>&2 + exit $EXIT_FAILURE +# else +# $echo "$modename: using $tagname tagged configuration" + fi + ;; + esac + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + + $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" + $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $? + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 + exit $EXIT_FAILURE + fi +} + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + my_status="" + + $show "${rm}r $my_gentop" + $run ${rm}r "$my_gentop" + $show "$mkdir $my_gentop" + $run $mkdir "$my_gentop" + my_status=$? + if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then + exit $my_status + fi + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + extracted_serial=`expr $extracted_serial + 1` + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + $show "${rm}r $my_xdir" + $run ${rm}r "$my_xdir" + $show "$mkdir $my_xdir" + $run $mkdir "$my_xdir" + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then + exit $exit_status + fi + case $host in + *-darwin*) + $show "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + if test -z "$run"; then + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` + darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` + if test -n "$darwin_arches"; then + darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + $show "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we have a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` + lipo -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + ${rm}r unfat-$$ + cd "$darwin_orig_dir" + else + cd "$darwin_orig_dir" + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + fi # $run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + func_extract_archives_result="$my_oldobjs" +} +# End of Shell function definitions +##################################### + +# Darwin sucks +eval std_shrext=\"$shrext_cmds\" + +disable_libs=no + +# Parse our command line options once, thoroughly. +while test "$#" -gt 0 +do + arg="$1" + shift + + case $arg in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + execute_dlfiles) + execute_dlfiles="$execute_dlfiles $arg" + ;; + tag) + tagname="$arg" + preserve_args="${preserve_args}=$arg" + + # Check whether tagname contains only valid characters + case $tagname in + *[!-_A-Za-z0-9,/]*) + $echo "$progname: invalid tag name: $tagname" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $tagname in + CC) + # Don't test for the "default" C tag, as we know, it's there, but + # not specially marked. + ;; + *) + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then + taglist="$taglist $tagname" + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" + else + $echo "$progname: ignoring unknown tag $tagname" 1>&2 + fi + ;; + esac + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case $arg in + --help) + show_help=yes + ;; + + --version) + echo "\ +$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP + +Copyright (C) 2007 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + exit $? + ;; + + --config) + ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath + # Now print the configurations for the tags. + for tagname in $taglist; do + ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" + done + exit $? + ;; + + --debug) + $echo "$progname: enabling shell trace mode" + set -x + preserve_args="$preserve_args $arg" + ;; + + --dry-run | -n) + run=: + ;; + + --features) + $echo "host: $host" + if test "$build_libtool_libs" = yes; then + $echo "enable shared libraries" + else + $echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + $echo "enable static libraries" + else + $echo "disable static libraries" + fi + exit $? + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --preserve-dup-deps) duplicate_deps="yes" ;; + + --quiet | --silent) + show=: + preserve_args="$preserve_args $arg" + ;; + + --tag) + prevopt="--tag" + prev=tag + preserve_args="$preserve_args --tag" + ;; + --tag=*) + set tag "$optarg" ${1+"$@"} + shift + prev=tag + preserve_args="$preserve_args --tag" + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE +fi + +case $disable_libs in +no) + ;; +shared) + build_libtool_libs=no + build_old_libs=yes + ;; +static) + build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` + ;; +esac + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 + $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 + case $nonopt in + *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) + mode=link + for arg + do + case $arg in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case $mode in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + if test -n "$libobj" ; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit $EXIT_FAILURE + fi + arg_mode=target + continue + ;; + + -static | -prefer-pic | -prefer-non-pic) + later="$later $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + base_compile="$base_compile $lastarg" + continue + ;; + + * ) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + case $lastarg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, and some SunOS ksh mistreat backslash-escaping + # in scan sets (worked around with variable expansion), + # and furthermore cannot handle '|' '&' '(' ')' in scan sets + # at all, so we specify them separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + lastarg="\"$lastarg\"" + ;; + esac + + base_compile="$base_compile $lastarg" + done # for arg + + case $arg_mode in + arg) + $echo "$modename: you must specify an argument for -Xcompile" + exit $EXIT_FAILURE + ;; + target) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit $EXIT_FAILURE + ;; + *) + # Get the name of the library object. + [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSifmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.ii) xform=ii ;; + *.class) xform=class ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.[fF][09]?) xform=[fF][09]. ;; + *.for) xform=for ;; + *.java) xform=java ;; + *.obj) xform=obj ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case $libobj in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -static) + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` + case $qlibobj in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qlibobj="\"$qlibobj\"" ;; + esac + test "X$libobj" != "X$qlibobj" \ + && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && $echo "$modename: libobj name \`$libobj' may not contain shell special characters." + objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir= + else + xdir=$xdir/ + fi + lobj=${xdir}$objdir/$objname + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $run ln "$progpath" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + $echo "$srcfile" > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` + case $qsrcfile in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qsrcfile="\"$qsrcfile\"" ;; + esac + + $run $rm "$libobj" "${libobj}T" + + # Create a libtool object file (analogous to a ".la" file), + # but don't create it if we're doing a dry run. + test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + $show "$mv $output_obj $lobj" + if $run $mv $output_obj $lobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the PIC object to the libtool object file. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the non-PIC object the libtool object file. + # Only append if the libtool object file exists. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit $EXIT_FAILURE + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat $save_arg` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + done + else + $echo "$modename: link input file \`$save_arg' does not exist" + exit $EXIT_FAILURE + fi + arg=$save_arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + darwin_framework|darwin_framework_skip) + test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + prev= + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: more than one -exported-symbols argument is not allowed" + exit $EXIT_FAILURE + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework|-arch|-isysroot) + case " $CC " in + *" ${arg} ${1} "* | *" ${arg} ${1} "*) + prev=darwin_framework_skip ;; + *) compiler_flags="$compiler_flags $arg" + prev=darwin_framework ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + notinst_path="$notinst_path $dir" + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs -framework System" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + -model) + compile_command="$compile_command $arg" + compiler_flags="$compiler_flags $arg" + finalize_command="$finalize_command $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + compiler_flags="$compiler_flags $arg" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # -64, -mips[0-9] enable 64-bit mode on the SGI compiler + # -r[0-9][0-9]* specifies the processor on the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler + # +DA*, +DD* enable 64-bit mode on the HP compiler + # -q* pass through compiler args for the IBM compiler + # -m* pass through architecture-specific compiler args for GCC + # -m*, -t[45]*, -txscale* pass through architecture-specific + # compiler args for GCC + # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC + # -F/path gives path to uninstalled frameworks, gcc on darwin + # @file GCC response files + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*) + + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + compiler_flags="$compiler_flags $arg" + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done # argument parsing loop + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d "$output_objdir"; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then + exit $exit_status + fi + fi + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + case $host in + *cygwin* | *mingw* | *pw32*) + # don't eliminate duplications in $postdeps and $predeps + duplicate_compiler_generated_deps=yes + ;; + *) + duplicate_compiler_generated_deps=$duplicate_deps + ;; + esac + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if test "X$duplicate_deps" = "Xyes" ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + compiler_flags="$compiler_flags $deplib" + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if (${SED} -e '2q' $lib | + grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + library_names= + old_library= + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + if eval $echo \"$deplib\" 2>/dev/null \ + | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + $echo + $echo "*** Warning: Trying to link with static lib archive $deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because the file extensions .$libext of this argument makes me believe" + $echo "*** that it is just a static archive that I should not used here." + else + $echo + $echo "*** Warning: Linking the shared library $output against the" + $echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test "$found" = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2 + exit $EXIT_FAILURE + fi + + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit $EXIT_FAILURE + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $absdir" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes ; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + # This is a shared library + + # Warn about portability, can't link against -module's on + # some systems (darwin) + if test "$shouldnotlink" = yes && test "$pass" = link ; then + $echo + if test "$linkmode" = prog; then + $echo "*** Warning: Linking the executable $output against the loadable module" + else + $echo "*** Warning: Linking the shared library $output against the loadable module" + fi + $echo "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`$echo $soroot | ${SED} -e 's/^.*\///'` + newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$extract_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$old_archive_from_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a module then we can not link against + # it, someone is ignoring the new warnings I added + if /usr/bin/file -L $add 2> /dev/null | + $EGREP ": [^:]* bundle" >/dev/null ; then + $echo "** Warning, lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + $echo + $echo "** And there doesn't seem to be a static archive available" + $echo "** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit $EXIT_FAILURE + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + $echo + $echo "*** Warning: This system can not link to static lib archive $lib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + $echo "*** But as you try to build a module library, libtool will still create " + $echo "*** a static module, that should work as long as the dlopening application" + $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="$absdir/$objdir" + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="$absdir" + fi + depdepl= + case $host in + *-*-darwin*) + # we do not want to link against static libs, + # but need to link against shared + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$path/$depdepl" ; then + depdepl="$path/$depdepl" + fi + # do not add paths which are already there + case " $newlib_search_path " in + *" $path "*) ;; + *) newlib_search_path="$newlib_search_path $path";; + esac + fi + path="" + ;; + *) + path="-L$path" + ;; + esac + ;; + -l*) + case $host in + *-*-darwin*) + # Again, we only want to link against shared libraries + eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` + for tmp in $newlib_search_path ; do + if test -f "$tmp/lib$tmp_libs.dylib" ; then + eval depdepl="$tmp/lib$tmp_libs.dylib" + break + fi + done + path="" + ;; + *) continue ;; + esac + ;; + *) continue ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + case " $deplibs " in + *" $depdepl "*) ;; + *) deplibs="$depdepl $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit $EXIT_FAILURE + else + $echo + $echo "*** Warning: Linking the shared library $output against the non-libtool" + $echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test "$#" -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$2" + number_minor="$3" + number_revision="$4" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows|none) + current=`expr $number_major + $number_minor` + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + current=`expr $number_major + $number_minor` + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + esac + ;; + no) + current="$2" + revision="$3" + age="$4" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test "$age" -gt "$current"; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + major=`expr $current - $age` + else + major=`expr $current - $age + 1` + fi + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=.`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + fi + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$echo "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + removelist="$removelist $p" + ;; + *) ;; + esac + done + if test -n "$removelist"; then + $show "${rm}r $removelist" + $run ${rm}r $removelist + fi + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"` + # deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"` + # dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for file magic test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a file magic. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name=`expr $a_deplib : '-l\(.*\)'` + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval $echo \"$potent_lib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a regex pattern. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` + done + fi + if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ + | grep . >/dev/null; then + $echo + if test "X$deplibs_check_method" = "Xnone"; then + $echo "*** Warning: inter-library dependencies are not supported in this platform." + else + $echo "*** Warning: inter-library dependencies are not known to be supported." + fi + $echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + $echo + $echo "*** Warning: libtool could not satisfy all declared inter-library" + $echo "*** dependencies of module $libname. Therefore, libtool will create" + $echo "*** a static module, that should work as long as the dlopening" + $echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + $echo "*** The inter-library dependencies that have been dropped here will be" + $echo "*** automatically added whenever a program is linked with this library" + $echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + $echo + $echo "*** Since this library must not contain undefined symbols," + $echo "*** because either the platform does not support them or" + $echo "*** it was explicitly requested with -no-undefined," + $echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + deplibs="$new_libs" + + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + case $archive_cmds in + *\$LD*) eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" ;; + *) eval dep_rpath=\"$hardcode_libdir_flag_spec\" ;; + esac + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + if len=`expr "X$cmd" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + $show "$cmd" + $run eval "$cmd" || exit $? + skipped_export=false + else + # The command line is too long to execute in one step. + $show "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + libobjs="$libobjs $func_extract_archives_result" + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise. + $echo "creating reloadable object files..." + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + output_la=`$echo "X$output" | $Xsed -e "$basename"` + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + delfiles= + last_robj= + k=1 + output=$output_objdir/$output_la-${k}.$objext + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + eval test_cmds=\"$reload_cmds $objlist $last_robj\" + if test "X$objlist" = X || + { len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len"; }; then + objlist="$objlist $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + k=`expr $k + 1` + output=$output_objdir/$output_la-${k}.$objext + objlist=$obj + len=1 + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + + if ${skipped_export-false}; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + libobjs=$output + # Append the command to create the export file. + eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" + fi + + # Set up a command to remove the reloadable object files + # after they are used. + i=0 + while test "$i" -lt "$k" + do + i=`expr $i + 1` + delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" + done + + $echo "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + + # Append the command to remove the reloadable object files + # to the just-reset $cmds. + eval cmds=\"\$cmds~\$rm $delfiles\" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case $output in + *.lo) + if test -n "$objs$old_deplibs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit $EXIT_FAILURE + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$echo "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $run eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; + esac + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + case $host in + *darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + if test "$tagname" = CXX ; then + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + fi + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case $dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $run $rm $export_symbols + $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* ) + $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + $run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + else + $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* ) + $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + $run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` + $run eval '$echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + $echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +" + + case $host in + *cygwin* | *mingw* ) + $echo >> "$output_objdir/$dlsyms" "\ +/* DATA imports from DLLs on WIN32 can't be const, because + runtime relocations are performed -- see ld's documentation + on pseudo-relocs */ +struct { +" + ;; + * ) + $echo >> "$output_objdir/$dlsyms" "\ +const struct { +" + ;; + esac + + + $echo >> "$output_objdir/$dlsyms" "\ + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[] = +{\ +" + + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + case $host in + *cygwin* | *mingw* ) + if test -f "$output_objdir/${outputname}.def" ; then + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` + else + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + fi + ;; + * ) + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + ;; + esac + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` + fi + + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$output"'%g' | $NL2SP` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + exit_status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $exit_status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $SP2NL | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g' | $NL2SP` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then + case $progpath in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; + *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + output_name=`basename $output` + output_path=`dirname $output` + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $rm $cwrappersource $cwrapper + trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + cat > $cwrappersource <> $cwrappersource<<"EOF" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +/* -DDEBUG is fairly common in CFLAGS. */ +#undef DEBUG +#if defined DEBUGWRAPPER +# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__) +#else +# define DEBUG(format, ...) +#endif + +const char *program_name = NULL; + +void * xmalloc (size_t num); +char * xstrdup (const char *string); +const char * base_name (const char *name); +char * find_executable(const char *wrapper); +int check_executable(const char *path); +char * strendzap(char *str, const char *pat); +void lt_fatal (const char *message, ...); + +int +main (int argc, char *argv[]) +{ + char **newargz; + int i; + + program_name = (char *) xstrdup (base_name (argv[0])); + DEBUG("(main) argv[0] : %s\n",argv[0]); + DEBUG("(main) program_name : %s\n",program_name); + newargz = XMALLOC(char *, argc+2); +EOF + + cat >> $cwrappersource <> $cwrappersource <<"EOF" + newargz[1] = find_executable(argv[0]); + if (newargz[1] == NULL) + lt_fatal("Couldn't find %s", argv[0]); + DEBUG("(main) found exe at : %s\n",newargz[1]); + /* we know the script has the same name, without the .exe */ + /* so make sure newargz[1] doesn't end in .exe */ + strendzap(newargz[1],".exe"); + for (i = 1; i < argc; i++) + newargz[i+1] = xstrdup(argv[i]); + newargz[argc+1] = NULL; + + for (i=0; i> $cwrappersource <> $cwrappersource <> $cwrappersource <<"EOF" + return 127; +} + +void * +xmalloc (size_t num) +{ + void * p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL +; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char)name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable(const char * path) +{ + struct stat st; + + DEBUG("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!"); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) && + ( + /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */ +#if defined (S_IXOTH) + ((st.st_mode & S_IXOTH) == S_IXOTH) || +#endif +#if defined (S_IXGRP) + ((st.st_mode & S_IXGRP) == S_IXGRP) || +#endif + ((st.st_mode & S_IXUSR) == S_IXUSR)) + ) + return 1; + else + return 0; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise */ +char * +find_executable (const char* wrapper) +{ + int has_slash = 0; + const char* p; + const char* p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char* concat_name; + + DEBUG("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char* path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char* q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR(*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen(tmp); + concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen(tmp); + concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + return NULL; +} + +char * +strendzap(char *str, const char *pat) +{ + size_t len, patlen; + + assert(str != NULL); + assert(pat != NULL); + + len = strlen(str); + patlen = strlen(pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp(str, pat) == 0) + *str = '\0'; + } + return str; +} + +static void +lt_error_core (int exit_status, const char * mode, + const char * message, va_list ap) +{ + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); +} +EOF + # we should really use a build-platform specific compiler + # here, but OTOH, the wrappers (shell script and this C one) + # are only useful if you want to execute the "real" binary. + # Since the "real" binary is built for $host, then this + # wrapper might as well be built for $host, too. + $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource + ;; + esac + $rm $output + trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='${SED} -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $echo >> $output "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + $echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $echo \"\$relink_command_output\" >&2 + $rm \"\$progdir/\$file\" + exit $EXIT_FAILURE + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + $echo >> $output "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $echo >> $output "\ + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \$*\" + exit $EXIT_FAILURE + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + $echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit $EXIT_FAILURE + fi +fi\ +" + chmod +x $output + fi + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $addlibs + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + $echo "X$obj" | $Xsed -e 's%^.*/%%' + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "copying selected object files to avoid basename conflicts..." + + if test -z "$gentop"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$gentop"; then + exit $exit_status + fi + fi + + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + counter=`expr $counter + 1` + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + $run ln "$obj" "$gentop/$newobj" || + $run cp "$obj" "$gentop/$newobj" + oldobjs="$oldobjs $gentop/$newobj" + ;; + *) oldobjs="$oldobjs $obj" ;; + esac + done + fi + + eval cmds=\"$old_archive_cmds\" + + if len=`expr "X$cmds" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + $echo "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + for obj in $save_oldobjs + do + oldobjs="$objlist $obj" + objlist="$objlist $obj" + eval test_cmds=\"$old_archive_cmds\" + if len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + eval cmd=\"$cmd\" + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlfiles="$newdlfiles $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlprefiles="$newdlprefiles $abs" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $echo >> $output "\ +relink_command=\"$relink_command\"" + fi + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? + ;; + esac + exit $EXIT_SUCCESS + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | grep shtool > /dev/null; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + case " $install_prog " in + *[\\\ /]cp\ *) ;; + *) prev=$arg ;; + esac + ;; + -g | -m | -o) prev=$arg ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test "$#" -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + library_names= + old_library= + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + if test "$inst_prefix_dir" = "$destdir"; then + $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%" | $NL2SP` + else + relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%%" | $NL2SP` + fi + + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + exit $EXIT_FAILURE + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" + $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + cmds=$postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + file=`$echo $file|${SED} 's,.exe$,,'` + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin*|*mingw*) + wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` + ;; + *) + wrapper=$file + ;; + esac + if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # Note that it is not necessary on cygwin/mingw to append a dot to + # foo even if both foo and FILE.exe exist: automatic-append-.exe + # behavior happens only for exec(3), not for open(2)! Also, sourcing + # `FILE.' does not work on cygwin managed mounts. + # + # If there is no directory component, then add one. + case $wrapper in + */* | *\\*) . ${wrapper} ;; + *) . ./${wrapper} ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 + exit $EXIT_FAILURE + fi + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # Note that it is not necessary on cygwin/mingw to append a dot to + # foo even if both foo and FILE.exe exist: automatic-append-.exe + # behavior happens only for exec(3), not for open(2)! Also, sourcing + # `FILE.' does not work on cygwin managed mounts. + # + # If there is no directory component, then add one. + case $wrapper in + */* | *\\*) . ${wrapper} ;; + *) . ./${wrapper} ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir=`func_mktempdir` + file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g' | $NL2SP` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` + ;; + esac + ;; + esac + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + if test -n "$stripme" && test -n "$old_striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + cmds=$old_postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + cmds=$finish_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = : && exit $EXIT_SUCCESS + + $echo "X----------------------------------------------------------------------" | $Xsed + $echo "Libraries have been installed in:" + for libdir in $libdirs; do + $echo " $libdir" + done + $echo + $echo "If you ever happen to want to link against installed libraries" + $echo "in a given directory, LIBDIR, you must either use libtool, and" + $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + $echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + $echo " during execution" + fi + if test -n "$runpath_var"; then + $echo " - add LIBDIR to the \`$runpath_var' environment variable" + $echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + $echo + $echo "See any operating system documentation about shared libraries for" + $echo "more information, such as the ld(1) and ld.so(8) manual pages." + $echo "X----------------------------------------------------------------------" | $Xsed + exit $EXIT_SUCCESS + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit $EXIT_FAILURE + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + if test ! -f "$dir/$dlname"; then + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit $EXIT_FAILURE + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + fi + $echo "$cmd$args" + exit $EXIT_SUCCESS + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + + case "$mode" in + clean) + case " $library_names " in + # " " in the beginning catches empty $dlname + *" $dlname "*) ;; + *) rmfiles="$rmfiles $objdir/$dlname" ;; + esac + test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + cmds=$postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + cmds=$old_postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + + # Read the .lo file + . $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" \ + && test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" \ + && test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + file=`$echo $file|${SED} 's,.exe$,,'` + noexename=`$echo $name|${SED} 's,.exe$,,'` + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$noexename + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + objdir="$origobjdir" + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + fi +fi # test -z "$show_help" + +if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit $EXIT_FAILURE +fi + +# We need to display help for each of the modes. +case $mode in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + --version print version information + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE. + +Report bugs to ." + exit $EXIT_SUCCESS + ;; + +clean) + $echo \ +"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; +esac + +$echo +$echo "Try \`$modename --help' for more information about other modes." + +exit $? + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +disable_libs=shared +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +disable_libs=static +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# Libtool was configured on host lambda: + +# Shell to use when invoking shell scripts. +SHELL="/bin/sh" + +# Whether or not to build shared libraries. +build_libtool_libs=yes + +# Whether or not to build static libraries. +build_old_libs=yes + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=no + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=no + +# Whether or not to optimize for fast installation. +fast_install=yes + +# The host system. +host_alias= +host=i686-pc-linux-gnu +host_os=linux-gnu + +# The build system. +build_alias= +build=i686-pc-linux-gnu +build_os=linux-gnu + +# An echo program that does not interpret backslashes. +echo="echo" + +# The archiver. +AR="ar" +AR_FLAGS="cru" + +# A C compiler. +LTCC="gcc" + +# LTCC compiler flags. +LTCFLAGS="-g -O2" + +# A language-specific compiler. +CC="g++" + +# Is the compiler the GNU C compiler? +with_gcc=yes + +# An ERE matcher. +EGREP="/bin/grep -E" + +# The linker used to build libraries. +LD="/usr/bin/ld" + +# Whether we need hard or soft links. +LN_S="ln -s" + +# A BSD-compatible nm program. +NM="/usr/bin/nm -B" + +# A symbol stripping program +STRIP="strip" + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=file + +# Used on cygwin: DLL creation program. +DLLTOOL="dlltool" + +# Used on cygwin: object dumper. +OBJDUMP="objdump" + +# Used on cygwin: assembler. +AS="as" + +# The name of the directory that contains temporary libtool files. +objdir=.libs + +# How to create reloadable object files. +reload_flag=" -r" +reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" + +# How to pass a linker flag through the compiler. +wl="-Wl," + +# Object file suffix (normally "o"). +objext="o" + +# Old archive suffix (normally "a"). +libext="a" + +# Shared library suffix (normally ".so"). +shrext_cmds='.so' + +# Executable file suffix (normally ""). +exeext="" + +# Additional compiler flags for building library objects. +pic_flag=" -fPIC -DPIC" +pic_mode=default + +# What is the maximum length of a command? +max_cmd_len=98304 + +# Does compiler simultaneously support -c and -o options? +compiler_c_o="yes" + +# Must we lock files when doing compilation? +need_locks="no" + +# Do we need the lib prefix for modules? +need_lib_prefix=no + +# Do we need a version for libraries? +need_version=no + +# Whether dlopen is supported. +dlopen_support=unknown + +# Whether dlopen of programs is supported. +dlopen_self=unknown + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=unknown + +# Compiler flag to prevent dynamic linking. +link_static_flag="-static" + +# Compiler flag to turn off builtin functions. +no_builtin_flag=" -fno-builtin" + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec="\${wl}--export-dynamic" + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec="" + +# Library versioning type. +version_type=linux + +# Format of library name prefix. +libname_spec="lib\$name" + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" + +# The coded name of the library, if different from the real name. +soname_spec="\${libname}\${release}\${shared_ext}\$major" + +# Commands used to build and install an old-style archive. +RANLIB="ranlib" +old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs~\$RANLIB \$oldlib" +old_postinstall_cmds="chmod 644 \$oldlib~\$RANLIB \$oldlib" +old_postuninstall_cmds="" + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds="" + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds="" + +# Commands used to build and install a shared archive. +archive_cmds="\$CC -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" +archive_expsym_cmds="\$CC -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-retain-symbols-file \$wl\$export_symbols -o \$lib" +postinstall_cmds="" +postuninstall_cmds="" + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds="" +module_expsym_cmds="" + +# Commands to strip libraries. +old_striplib="strip --strip-debug" +striplib="strip --strip-unneeded" + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects="/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crti.o /usr/lib/gcc/i386-redhat-linux/4.1.2/crtbeginS.o" + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects="/usr/lib/gcc/i386-redhat-linux/4.1.2/crtendS.o /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crtn.o" + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps="" + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps="-lstdc++ -lm -lgcc_s -lc -lgcc_s" + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path="-L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2/../../.." + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method="pass_all" + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd="\$MAGIC_CMD" + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag="" + +# Flag that forces no undefined symbols. +no_undefined_flag="" + +# Commands used to finish a libtool library installation in a directory. +finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval="" + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2 \\2/p'" + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'" + +# This is the shared library runtime path variable. +runpath_var=LD_RUN_PATH + +# This is the shared library path variable. +shlibpath_var=LD_LIBRARY_PATH + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=no + +# How to hardcode a shared library path into an executable. +hardcode_action=immediate + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=yes + +# Flag to hardcode $libdir into a binary during linking. +# This must work even if $libdir does not exist. +hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" + +# If ld is used when linking, flag to hardcode $libdir into +# a binary during linking. This must work even if $libdir does +# not exist. +hardcode_libdir_flag_spec_ld="" + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator="" + +# Set to yes if using DIR/libNAME during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=no + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=no + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=unsupported + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=no + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=unknown + +# Compile-time system search path for libraries +sys_lib_search_path_spec="/usr/lib /lib /usr/local/lib" + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec="/usr/lib /lib /usr/lib/qt-3.3/lib " + +# Fix the shell variable $srcfile for the compiler. +fix_srcfile_path="" + +# Set to yes if exported symbols are required. +always_export_symbols=no + +# The commands to list exported symbols. +export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds="" + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms="" + +# Symbols that must always be exported. +include_expsyms="" + +# ### END LIBTOOL TAG CONFIG: CXX + +# ### BEGIN LIBTOOL TAG CONFIG: F77 + +# Libtool was configured on host lambda: + +# Shell to use when invoking shell scripts. +SHELL="/bin/sh" + +# Whether or not to build shared libraries. +build_libtool_libs=yes + +# Whether or not to build static libraries. +build_old_libs=yes + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=no + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=no + +# Whether or not to optimize for fast installation. +fast_install=yes + +# The host system. +host_alias= +host=i686-pc-linux-gnu +host_os=linux-gnu + +# The build system. +build_alias= +build=i686-pc-linux-gnu +build_os=linux-gnu + +# An echo program that does not interpret backslashes. +echo="echo" + +# The archiver. +AR="ar" +AR_FLAGS="cru" + +# A C compiler. +LTCC="gcc" + +# LTCC compiler flags. +LTCFLAGS="-g -O2" + +# A language-specific compiler. +CC="gfortran" + +# Is the compiler the GNU C compiler? +with_gcc=yes + +# An ERE matcher. +EGREP="/bin/grep -E" + +# The linker used to build libraries. +LD="/usr/bin/ld" + +# Whether we need hard or soft links. +LN_S="ln -s" + +# A BSD-compatible nm program. +NM="/usr/bin/nm -B" + +# A symbol stripping program +STRIP="strip" + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=file + +# Used on cygwin: DLL creation program. +DLLTOOL="dlltool" + +# Used on cygwin: object dumper. +OBJDUMP="objdump" + +# Used on cygwin: assembler. +AS="as" + +# The name of the directory that contains temporary libtool files. +objdir=.libs + +# How to create reloadable object files. +reload_flag=" -r" +reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" + +# How to pass a linker flag through the compiler. +wl="-Wl," + +# Object file suffix (normally "o"). +objext="o" + +# Old archive suffix (normally "a"). +libext="a" + +# Shared library suffix (normally ".so"). +shrext_cmds='.so' + +# Executable file suffix (normally ""). +exeext="" + +# Additional compiler flags for building library objects. +pic_flag=" -fPIC" +pic_mode=default + +# What is the maximum length of a command? +max_cmd_len=98304 + +# Does compiler simultaneously support -c and -o options? +compiler_c_o="yes" + +# Must we lock files when doing compilation? +need_locks="no" + +# Do we need the lib prefix for modules? +need_lib_prefix=no + +# Do we need a version for libraries? +need_version=no + +# Whether dlopen is supported. +dlopen_support=unknown + +# Whether dlopen of programs is supported. +dlopen_self=unknown + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=unknown + +# Compiler flag to prevent dynamic linking. +link_static_flag="-static" + +# Compiler flag to turn off builtin functions. +no_builtin_flag="" + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec="\${wl}--export-dynamic" + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec="" + +# Library versioning type. +version_type=linux + +# Format of library name prefix. +libname_spec="lib\$name" + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" + +# The coded name of the library, if different from the real name. +soname_spec="\${libname}\${release}\${shared_ext}\$major" + +# Commands used to build and install an old-style archive. +RANLIB="ranlib" +old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs~\$RANLIB \$oldlib" +old_postinstall_cmds="chmod 644 \$oldlib~\$RANLIB \$oldlib" +old_postuninstall_cmds="" + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds="" + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds="" + +# Commands used to build and install a shared archive. +archive_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" +archive_expsym_cmds="\$echo \\\"{ global:\\\" > \$output_objdir/\$libname.ver~ + cat \$export_symbols | sed -e \\\"s/\\\\(.*\\\\)/\\\\1;/\\\" >> \$output_objdir/\$libname.ver~ + \$echo \\\"local: *; };\\\" >> \$output_objdir/\$libname.ver~ + \$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-version-script \${wl}\$output_objdir/\$libname.ver -o \$lib" +postinstall_cmds="" +postuninstall_cmds="" + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds="" +module_expsym_cmds="" + +# Commands to strip libraries. +old_striplib="strip --strip-debug" +striplib="strip --strip-unneeded" + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects="" + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects="" + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps="" + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps="" + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path="" + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method="pass_all" + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd="\$MAGIC_CMD" + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag="" + +# Flag that forces no undefined symbols. +no_undefined_flag="" + +# Commands used to finish a libtool library installation in a directory. +finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval="" + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2 \\2/p'" + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'" + +# This is the shared library runtime path variable. +runpath_var=LD_RUN_PATH + +# This is the shared library path variable. +shlibpath_var=LD_LIBRARY_PATH + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=no + +# How to hardcode a shared library path into an executable. +hardcode_action=immediate + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=yes + +# Flag to hardcode $libdir into a binary during linking. +# This must work even if $libdir does not exist. +hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" + +# If ld is used when linking, flag to hardcode $libdir into +# a binary during linking. This must work even if $libdir does +# not exist. +hardcode_libdir_flag_spec_ld="" + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator="" + +# Set to yes if using DIR/libNAME during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=no + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=no + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=unsupported + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=no + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=unknown + +# Compile-time system search path for libraries +sys_lib_search_path_spec="/usr/lib /lib /usr/local/lib" + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec="/usr/lib /lib /usr/lib/qt-3.3/lib " + +# Fix the shell variable $srcfile for the compiler. +fix_srcfile_path="" + +# Set to yes if exported symbols are required. +always_export_symbols=no + +# The commands to list exported symbols. +export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds="" + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_" + +# Symbols that must always be exported. +include_expsyms="" + +# ### END LIBTOOL TAG CONFIG: F77 + diff --git a/libltdl/ltdl.c b/libltdl/ltdl.c new file mode 100644 index 00000000..5f56fbbb --- /dev/null +++ b/libltdl/ltdl.c @@ -0,0 +1,4543 @@ +/* ltdl.c -- system independent dlopen wrapper + Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + Originally by Thomas Tanner + This file is part of GNU Libtool. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU libtool, you may include it under the same +distribution terms that you use for the rest of that program. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA + +*/ + +#if HAVE_CONFIG_H +# include +#endif + +#if HAVE_UNISTD_H +# include +#endif + +#if HAVE_STDIO_H +# include +#endif + +/* Include the header defining malloc. On K&R C compilers, + that's , on ANSI C and ISO C compilers, that's . */ +#if HAVE_STDLIB_H +# include +#else +# if HAVE_MALLOC_H +# include +# endif +#endif + +#if HAVE_STRING_H +# include +#else +# if HAVE_STRINGS_H +# include +# endif +#endif + +#if HAVE_CTYPE_H +# include +#endif + +#if HAVE_MEMORY_H +# include +#endif + +#if HAVE_ERRNO_H +# include +#endif + + +#ifndef __WINDOWS__ +# ifdef __WIN32__ +# define __WINDOWS__ +# endif +#endif + + +#undef LT_USE_POSIX_DIRENT +#ifdef HAVE_CLOSEDIR +# ifdef HAVE_OPENDIR +# ifdef HAVE_READDIR +# ifdef HAVE_DIRENT_H +# define LT_USE_POSIX_DIRENT +# endif /* HAVE_DIRENT_H */ +# endif /* HAVE_READDIR */ +# endif /* HAVE_OPENDIR */ +#endif /* HAVE_CLOSEDIR */ + + +#undef LT_USE_WINDOWS_DIRENT_EMULATION +#ifndef LT_USE_POSIX_DIRENT +# ifdef __WINDOWS__ +# define LT_USE_WINDOWS_DIRENT_EMULATION +# endif /* __WINDOWS__ */ +#endif /* LT_USE_POSIX_DIRENT */ + + +#ifdef LT_USE_POSIX_DIRENT +# include +# define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name)) +#else +# ifdef LT_USE_WINDOWS_DIRENT_EMULATION +# define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name)) +# else +# define dirent direct +# define LT_D_NAMLEN(dirent) ((dirent)->d_namlen) +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +# endif +#endif + +#if HAVE_ARGZ_H +# include +#endif + +#if HAVE_ASSERT_H +# include +#else +# define assert(arg) ((void) 0) +#endif + +#include "ltdl.h" + +#if WITH_DMALLOC +# include +#endif + + + + +/* --- WINDOWS SUPPORT --- */ + +/* DLL building support on win32 hosts; mostly to workaround their + ridiculous implementation of data symbol exporting. */ +#ifndef LT_GLOBAL_DATA +# if defined(__WINDOWS__) || defined(__CYGWIN__) +# ifdef DLL_EXPORT /* defined by libtool (if required) */ +# define LT_GLOBAL_DATA __declspec(dllexport) +# endif +# endif +# ifndef LT_GLOBAL_DATA /* static linking or !__WINDOWS__ */ +# define LT_GLOBAL_DATA +# endif +#endif + +/* fopen() mode flags for reading a text file */ +#undef LT_READTEXT_MODE +#if defined(__WINDOWS__) || defined(__CYGWIN__) +# define LT_READTEXT_MODE "rt" +#else +# define LT_READTEXT_MODE "r" +#endif + +#ifdef LT_USE_WINDOWS_DIRENT_EMULATION + +#include + +#define dirent lt_dirent +#define DIR lt_DIR + +struct dirent +{ + char d_name[2048]; + int d_namlen; +}; + +typedef struct _DIR +{ + HANDLE hSearch; + WIN32_FIND_DATA Win32FindData; + BOOL firsttime; + struct dirent file_info; +} DIR; + +#endif /* LT_USE_WINDOWS_DIRENT_EMULATION */ + + +/* --- MANIFEST CONSTANTS --- */ + + +/* Standard libltdl search path environment variable name */ +#undef LTDL_SEARCHPATH_VAR +#define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH" + +/* Standard libtool archive file extension. */ +#undef LTDL_ARCHIVE_EXT +#define LTDL_ARCHIVE_EXT ".la" + +/* max. filename length */ +#ifndef LT_FILENAME_MAX +# define LT_FILENAME_MAX 1024 +#endif + +/* This is the maximum symbol size that won't require malloc/free */ +#undef LT_SYMBOL_LENGTH +#define LT_SYMBOL_LENGTH 128 + +/* This accounts for the _LTX_ separator */ +#undef LT_SYMBOL_OVERHEAD +#define LT_SYMBOL_OVERHEAD 5 + + + + +/* --- MEMORY HANDLING --- */ + + +/* These are the functions used internally. In addition to making + use of the associated function pointers above, they also perform + error handling. */ +static char *lt_estrdup LT_PARAMS((const char *str)); +static lt_ptr lt_emalloc LT_PARAMS((size_t size)); +static lt_ptr lt_erealloc LT_PARAMS((lt_ptr addr, size_t size)); + +/* static lt_ptr rpl_realloc LT_PARAMS((lt_ptr ptr, size_t size)); */ +#define rpl_realloc realloc + +/* These are the pointers that can be changed by the caller: */ +LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size)) + = (lt_ptr (*) LT_PARAMS((size_t))) malloc; +LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size)) + = (lt_ptr (*) LT_PARAMS((lt_ptr, size_t))) rpl_realloc; +LT_GLOBAL_DATA void (*lt_dlfree) LT_PARAMS((lt_ptr ptr)) + = (void (*) LT_PARAMS((lt_ptr))) free; + +/* The following macros reduce the amount of typing needed to cast + assigned memory. */ +#if WITH_DMALLOC + +#define LT_DLMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp))) +#define LT_DLREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp))) +#define LT_DLFREE(p) \ + LT_STMT_START { if (p) (p) = (xfree (p), (lt_ptr) 0); } LT_STMT_END + +#define LT_EMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp))) +#define LT_EREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp))) + +#else + +#define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp))) +#define LT_DLREALLOC(tp, p, n) ((tp *) lt_dlrealloc ((p), (n) * sizeof(tp))) +#define LT_DLFREE(p) \ + LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END + +#define LT_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp))) +#define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp))) + +#endif + +#define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \ + if ((p) != (q)) { if (p) lt_dlfree (p); (p) = (q); (q) = 0; } \ + } LT_STMT_END + + +/* --- REPLACEMENT FUNCTIONS --- */ + + +#undef strdup +#define strdup rpl_strdup + +static char *strdup LT_PARAMS((const char *str)); + +static char * +strdup(str) + const char *str; +{ + char *tmp = 0; + + if (str) + { + tmp = LT_DLMALLOC (char, 1+ strlen (str)); + if (tmp) + { + strcpy(tmp, str); + } + } + + return tmp; +} + + +#if ! HAVE_STRCMP + +#undef strcmp +#define strcmp rpl_strcmp + +static int strcmp LT_PARAMS((const char *str1, const char *str2)); + +static int +strcmp (str1, str2) + const char *str1; + const char *str2; +{ + if (str1 == str2) + return 0; + if (str1 == 0) + return -1; + if (str2 == 0) + return 1; + + for (;*str1 && *str2; ++str1, ++str2) + { + if (*str1 != *str2) + break; + } + + return (int)(*str1 - *str2); +} +#endif + + +#if ! HAVE_STRCHR + +# if HAVE_INDEX +# define strchr index +# else +# define strchr rpl_strchr + +static const char *strchr LT_PARAMS((const char *str, int ch)); + +static const char* +strchr(str, ch) + const char *str; + int ch; +{ + const char *p; + + for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p) + /*NOWORK*/; + + return (*p == (char)ch) ? p : 0; +} + +# endif +#endif /* !HAVE_STRCHR */ + + +#if ! HAVE_STRRCHR + +# if HAVE_RINDEX +# define strrchr rindex +# else +# define strrchr rpl_strrchr + +static const char *strrchr LT_PARAMS((const char *str, int ch)); + +static const char* +strrchr(str, ch) + const char *str; + int ch; +{ + const char *p, *q = 0; + + for (p = str; *p != LT_EOS_CHAR; ++p) + { + if (*p == (char) ch) + { + q = p; + } + } + + return q; +} + +# endif +#endif + +/* NOTE: Neither bcopy nor the memcpy implementation below can + reliably handle copying in overlapping areas of memory. Use + memmove (for which there is a fallback implmentation below) + if you need that behaviour. */ +#if ! HAVE_MEMCPY + +# if HAVE_BCOPY +# define memcpy(dest, src, size) bcopy (src, dest, size) +# else +# define memcpy rpl_memcpy + +static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size)); + +static lt_ptr +memcpy (dest, src, size) + lt_ptr dest; + const lt_ptr src; + size_t size; +{ + const char * s = src; + char * d = dest; + size_t i = 0; + + for (i = 0; i < size; ++i) + { + d[i] = s[i]; + } + + return dest; +} + +# endif /* !HAVE_BCOPY */ +#endif /* !HAVE_MEMCPY */ + +#if ! HAVE_MEMMOVE +# define memmove rpl_memmove + +static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size)); + +static lt_ptr +memmove (dest, src, size) + lt_ptr dest; + const lt_ptr src; + size_t size; +{ + const char * s = src; + char * d = dest; + size_t i; + + if (d < s) + for (i = 0; i < size; ++i) + { + d[i] = s[i]; + } + else if (d > s && size > 0) + for (i = size -1; ; --i) + { + d[i] = s[i]; + if (i == 0) + break; + } + + return dest; +} + +#endif /* !HAVE_MEMMOVE */ + +#ifdef LT_USE_WINDOWS_DIRENT_EMULATION + +static void closedir LT_PARAMS((DIR *entry)); + +static void +closedir(entry) + DIR *entry; +{ + assert(entry != (DIR *) NULL); + FindClose(entry->hSearch); + lt_dlfree((lt_ptr)entry); +} + + +static DIR * opendir LT_PARAMS((const char *path)); + +static DIR* +opendir (path) + const char *path; +{ + char file_specification[LT_FILENAME_MAX]; + DIR *entry; + + assert(path != (char *) NULL); + /* allow space for: path + '\\' '\\' '*' '.' '*' + '\0' */ + (void) strncpy (file_specification, path, LT_FILENAME_MAX-6); + file_specification[LT_FILENAME_MAX-6] = LT_EOS_CHAR; + (void) strcat(file_specification,"\\"); + entry = LT_DLMALLOC (DIR,sizeof(DIR)); + if (entry != (DIR *) 0) + { + entry->firsttime = TRUE; + entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData); + } + if (entry->hSearch == INVALID_HANDLE_VALUE) + { + (void) strcat(file_specification,"\\*.*"); + entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData); + if (entry->hSearch == INVALID_HANDLE_VALUE) + { + LT_DLFREE (entry); + return (DIR *) 0; + } + } + return(entry); +} + + +static struct dirent *readdir LT_PARAMS((DIR *entry)); + +static struct dirent *readdir(entry) + DIR *entry; +{ + int + status; + + if (entry == (DIR *) 0) + return((struct dirent *) 0); + if (!entry->firsttime) + { + status = FindNextFile(entry->hSearch,&entry->Win32FindData); + if (status == 0) + return((struct dirent *) 0); + } + entry->firsttime = FALSE; + (void) strncpy(entry->file_info.d_name,entry->Win32FindData.cFileName, + LT_FILENAME_MAX-1); + entry->file_info.d_name[LT_FILENAME_MAX - 1] = LT_EOS_CHAR; + entry->file_info.d_namlen = strlen(entry->file_info.d_name); + return(&entry->file_info); +} + +#endif /* LT_USE_WINDOWS_DIRENT_EMULATION */ + +/* According to Alexandre Oliva , + ``realloc is not entirely portable'' + In any case we want to use the allocator supplied by the user without + burdening them with an lt_dlrealloc function pointer to maintain. + Instead implement our own version (with known boundary conditions) + using lt_dlmalloc and lt_dlfree. */ + +/* #undef realloc + #define realloc rpl_realloc +*/ +#if 0 + /* You can't (re)define realloc unless you also (re)define malloc. + Right now, this code uses the size of the *destination* to decide + how much to copy. That's not right, but you can't know the size + of the source unless you know enough about, or wrote malloc. So + this code is disabled... */ + +static lt_ptr +realloc (ptr, size) + lt_ptr ptr; + size_t size; +{ + if (size == 0) + { + /* For zero or less bytes, free the original memory */ + if (ptr != 0) + { + lt_dlfree (ptr); + } + + return (lt_ptr) 0; + } + else if (ptr == 0) + { + /* Allow reallocation of a NULL pointer. */ + return lt_dlmalloc (size); + } + else + { + /* Allocate a new block, copy and free the old block. */ + lt_ptr mem = lt_dlmalloc (size); + + if (mem) + { + memcpy (mem, ptr, size); + lt_dlfree (ptr); + } + + /* Note that the contents of PTR are not damaged if there is + insufficient memory to realloc. */ + return mem; + } +} +#endif + + +#if ! HAVE_ARGZ_APPEND +# define argz_append rpl_argz_append + +static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len, + const char *buf, size_t buf_len)); + +static error_t +argz_append (pargz, pargz_len, buf, buf_len) + char **pargz; + size_t *pargz_len; + const char *buf; + size_t buf_len; +{ + size_t argz_len; + char *argz; + + assert (pargz); + assert (pargz_len); + assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len)); + + /* If nothing needs to be appended, no more work is required. */ + if (buf_len == 0) + return 0; + + /* Ensure there is enough room to append BUF_LEN. */ + argz_len = *pargz_len + buf_len; + argz = LT_DLREALLOC (char, *pargz, argz_len); + if (!argz) + return ENOMEM; + + /* Copy characters from BUF after terminating '\0' in ARGZ. */ + memcpy (argz + *pargz_len, buf, buf_len); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + + return 0; +} +#endif /* !HAVE_ARGZ_APPEND */ + + +#if ! HAVE_ARGZ_CREATE_SEP +# define argz_create_sep rpl_argz_create_sep + +static error_t argz_create_sep LT_PARAMS((const char *str, int delim, + char **pargz, size_t *pargz_len)); + +static error_t +argz_create_sep (str, delim, pargz, pargz_len) + const char *str; + int delim; + char **pargz; + size_t *pargz_len; +{ + size_t argz_len; + char *argz = 0; + + assert (str); + assert (pargz); + assert (pargz_len); + + /* Make a copy of STR, but replacing each occurrence of + DELIM with '\0'. */ + argz_len = 1+ LT_STRLEN (str); + if (argz_len) + { + const char *p; + char *q; + + argz = LT_DLMALLOC (char, argz_len); + if (!argz) + return ENOMEM; + + for (p = str, q = argz; *p != LT_EOS_CHAR; ++p) + { + if (*p == delim) + { + /* Ignore leading delimiters, and fold consecutive + delimiters in STR into a single '\0' in ARGZ. */ + if ((q > argz) && (q[-1] != LT_EOS_CHAR)) + *q++ = LT_EOS_CHAR; + else + --argz_len; + } + else + *q++ = *p; + } + /* Copy terminating LT_EOS_CHAR. */ + *q = *p; + } + + /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */ + if (!argz_len) + LT_DLFREE (argz); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + + return 0; +} +#endif /* !HAVE_ARGZ_CREATE_SEP */ + + +#if ! HAVE_ARGZ_INSERT +# define argz_insert rpl_argz_insert + +static error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len, + char *before, const char *entry)); + +static error_t +argz_insert (pargz, pargz_len, before, entry) + char **pargz; + size_t *pargz_len; + char *before; + const char *entry; +{ + assert (pargz); + assert (pargz_len); + assert (entry && *entry); + + /* No BEFORE address indicates ENTRY should be inserted after the + current last element. */ + if (!before) + return argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry)); + + /* This probably indicates a programmer error, but to preserve + semantics, scan back to the start of an entry if BEFORE points + into the middle of it. */ + while ((before > *pargz) && (before[-1] != LT_EOS_CHAR)) + --before; + + { + size_t entry_len = 1+ LT_STRLEN (entry); + size_t argz_len = *pargz_len + entry_len; + size_t offset = before - *pargz; + char *argz = LT_DLREALLOC (char, *pargz, argz_len); + + if (!argz) + return ENOMEM; + + /* Make BEFORE point to the equivalent offset in ARGZ that it + used to have in *PARGZ incase realloc() moved the block. */ + before = argz + offset; + + /* Move the ARGZ entries starting at BEFORE up into the new + space at the end -- making room to copy ENTRY into the + resulting gap. */ + memmove (before + entry_len, before, *pargz_len - offset); + memcpy (before, entry, entry_len); + + /* Assign new values. */ + *pargz = argz; + *pargz_len = argz_len; + } + + return 0; +} +#endif /* !HAVE_ARGZ_INSERT */ + + +#if ! HAVE_ARGZ_NEXT +# define argz_next rpl_argz_next + +static char *argz_next LT_PARAMS((char *argz, size_t argz_len, + const char *entry)); + +static char * +argz_next (argz, argz_len, entry) + char *argz; + size_t argz_len; + const char *entry; +{ + assert ((argz && argz_len) || (!argz && !argz_len)); + + if (entry) + { + /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address + within the ARGZ vector. */ + assert ((!argz && !argz_len) + || ((argz <= entry) && (entry < (argz + argz_len)))); + + /* Move to the char immediately after the terminating + '\0' of ENTRY. */ + entry = 1+ strchr (entry, LT_EOS_CHAR); + + /* Return either the new ENTRY, or else NULL if ARGZ is + exhausted. */ + return (entry >= argz + argz_len) ? 0 : (char *) entry; + } + else + { + /* This should probably be flagged as a programmer error, + since starting an argz_next loop with the iterator set + to ARGZ is safer. To preserve semantics, handle the NULL + case by returning the start of ARGZ (if any). */ + if (argz_len > 0) + return argz; + else + return 0; + } +} +#endif /* !HAVE_ARGZ_NEXT */ + + + +#if ! HAVE_ARGZ_STRINGIFY +# define argz_stringify rpl_argz_stringify + +static void argz_stringify LT_PARAMS((char *argz, size_t argz_len, + int sep)); + +static void +argz_stringify (argz, argz_len, sep) + char *argz; + size_t argz_len; + int sep; +{ + assert ((argz && argz_len) || (!argz && !argz_len)); + + if (sep) + { + --argz_len; /* don't stringify the terminating EOS */ + while (--argz_len > 0) + { + if (argz[argz_len] == LT_EOS_CHAR) + argz[argz_len] = sep; + } + } +} +#endif /* !HAVE_ARGZ_STRINGIFY */ + + + + +/* --- TYPE DEFINITIONS -- */ + + +/* This type is used for the array of caller data sets in each handler. */ +typedef struct { + lt_dlcaller_id key; + lt_ptr data; +} lt_caller_data; + + + + +/* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */ + + +/* Extract the diagnostic strings from the error table macro in the same + order as the enumerated indices in ltdl.h. */ + +static const char *lt_dlerror_strings[] = + { +#define LT_ERROR(name, diagnostic) (diagnostic), + lt_dlerror_table +#undef LT_ERROR + + 0 + }; + +/* This structure is used for the list of registered loaders. */ +struct lt_dlloader { + struct lt_dlloader *next; + const char *loader_name; /* identifying name for each loader */ + const char *sym_prefix; /* prefix for symbols */ + lt_module_open *module_open; + lt_module_close *module_close; + lt_find_sym *find_sym; + lt_dlloader_exit *dlloader_exit; + lt_user_data dlloader_data; +}; + +struct lt_dlhandle_struct { + struct lt_dlhandle_struct *next; + lt_dlloader *loader; /* dlopening interface */ + lt_dlinfo info; + int depcount; /* number of dependencies */ + lt_dlhandle *deplibs; /* dependencies */ + lt_module module; /* system module handle */ + lt_ptr system; /* system specific data */ + lt_caller_data *caller_data; /* per caller associated data */ + int flags; /* various boolean stats */ +}; + +/* Various boolean flags can be stored in the flags field of an + lt_dlhandle_struct... */ +#define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag)) +#define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag)) + +#define LT_DLRESIDENT_FLAG (0x01 << 0) +/* ...add more flags here... */ + +#define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG) + + +#define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)] + +static const char objdir[] = LTDL_OBJDIR; +static const char archive_ext[] = LTDL_ARCHIVE_EXT; +#ifdef LTDL_SHLIB_EXT +static const char shlib_ext[] = LTDL_SHLIB_EXT; +#endif +#ifdef LTDL_SYSSEARCHPATH +static const char sys_search_path[] = LTDL_SYSSEARCHPATH; +#endif + + + + +/* --- MUTEX LOCKING --- */ + + +/* Macros to make it easier to run the lock functions only if they have + been registered. The reason for the complicated lock macro is to + ensure that the stored error message from the last error is not + accidentally erased if the current function doesn't generate an + error of its own. */ +#define LT_DLMUTEX_LOCK() LT_STMT_START { \ + if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)(); \ + } LT_STMT_END +#define LT_DLMUTEX_UNLOCK() LT_STMT_START { \ + if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\ + } LT_STMT_END +#define LT_DLMUTEX_SETERROR(errormsg) LT_STMT_START { \ + if (lt_dlmutex_seterror_func) \ + (*lt_dlmutex_seterror_func) (errormsg); \ + else lt_dllast_error = (errormsg); } LT_STMT_END +#define LT_DLMUTEX_GETERROR(errormsg) LT_STMT_START { \ + if (lt_dlmutex_geterror_func) \ + (errormsg) = (*lt_dlmutex_geterror_func) (); \ + else (errormsg) = lt_dllast_error; } LT_STMT_END + +/* The mutex functions stored here are global, and are necessarily the + same for all threads that wish to share access to libltdl. */ +static lt_dlmutex_lock *lt_dlmutex_lock_func = 0; +static lt_dlmutex_unlock *lt_dlmutex_unlock_func = 0; +static lt_dlmutex_seterror *lt_dlmutex_seterror_func = 0; +static lt_dlmutex_geterror *lt_dlmutex_geterror_func = 0; +static const char *lt_dllast_error = 0; + + +/* Either set or reset the mutex functions. Either all the arguments must + be valid functions, or else all can be NULL to turn off locking entirely. + The registered functions should be manipulating a static global lock + from the lock() and unlock() callbacks, which needs to be reentrant. */ +int +lt_dlmutex_register (lock, unlock, seterror, geterror) + lt_dlmutex_lock *lock; + lt_dlmutex_unlock *unlock; + lt_dlmutex_seterror *seterror; + lt_dlmutex_geterror *geterror; +{ + lt_dlmutex_unlock *old_unlock = lt_dlmutex_unlock_func; + int errors = 0; + + /* Lock using the old lock() callback, if any. */ + LT_DLMUTEX_LOCK (); + + if ((lock && unlock && seterror && geterror) + || !(lock || unlock || seterror || geterror)) + { + lt_dlmutex_lock_func = lock; + lt_dlmutex_unlock_func = unlock; + lt_dlmutex_seterror_func = seterror; + lt_dlmutex_geterror_func = geterror; + } + else + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS)); + ++errors; + } + + /* Use the old unlock() callback we saved earlier, if any. Otherwise + record any errors using internal storage. */ + if (old_unlock) + (*old_unlock) (); + + /* Return the number of errors encountered during the execution of + this function. */ + return errors; +} + + + + +/* --- ERROR HANDLING --- */ + + +static const char **user_error_strings = 0; +static int errorcount = LT_ERROR_MAX; + +int +lt_dladderror (diagnostic) + const char *diagnostic; +{ + int errindex = 0; + int result = -1; + const char **temp = (const char **) 0; + + assert (diagnostic); + + LT_DLMUTEX_LOCK (); + + errindex = errorcount - LT_ERROR_MAX; + temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex); + if (temp) + { + user_error_strings = temp; + user_error_strings[errindex] = diagnostic; + result = errorcount++; + } + + LT_DLMUTEX_UNLOCK (); + + return result; +} + +int +lt_dlseterror (errindex) + int errindex; +{ + int errors = 0; + + LT_DLMUTEX_LOCK (); + + if (errindex >= errorcount || errindex < 0) + { + /* Ack! Error setting the error message! */ + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE)); + ++errors; + } + else if (errindex < LT_ERROR_MAX) + { + /* No error setting the error message! */ + LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]); + } + else + { + /* No error setting the error message! */ + LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]); + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +static lt_ptr +lt_emalloc (size) + size_t size; +{ + lt_ptr mem = lt_dlmalloc (size); + if (size && !mem) + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + return mem; +} + +static lt_ptr +lt_erealloc (addr, size) + lt_ptr addr; + size_t size; +{ + lt_ptr mem = lt_dlrealloc (addr, size); + if (size && !mem) + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + return mem; +} + +static char * +lt_estrdup (str) + const char *str; +{ + char *copy = strdup (str); + if (LT_STRLEN (str) && !copy) + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + return copy; +} + + + + +/* --- DLOPEN() INTERFACE LOADER --- */ + + +#if HAVE_LIBDL + +/* dynamic linking with dlopen/dlsym */ + +#if HAVE_DLFCN_H +# include +#endif + +#if HAVE_SYS_DL_H +# include +#endif + +#ifdef RTLD_GLOBAL +# define LT_GLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_GLOBAL DL_GLOBAL +# endif +#endif /* !RTLD_GLOBAL */ +#ifndef LT_GLOBAL +# define LT_GLOBAL 0 +#endif /* !LT_GLOBAL */ + +/* We may have to define LT_LAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_LAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_LAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_LAZY_OR_NOW DL_LAZY +# endif +# endif /* !RTLD_LAZY */ +#endif +#ifndef LT_LAZY_OR_NOW +# ifdef RTLD_NOW +# define LT_LAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_LAZY_OR_NOW DL_NOW +# endif +# endif /* !RTLD_NOW */ +#endif +#ifndef LT_LAZY_OR_NOW +# define LT_LAZY_OR_NOW 0 +#endif /* !LT_LAZY_OR_NOW */ + +#if HAVE_DLERROR +# define DLERROR(arg) dlerror () +#else +# define DLERROR(arg) LT_DLSTRERROR (arg) +#endif + +static lt_module +sys_dl_open (loader_data, filename) + lt_user_data loader_data; + const char *filename; +{ + lt_module module = dlopen (filename, LT_GLOBAL | LT_LAZY_OR_NOW); + + if (!module) + { + LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN)); + } + + return module; +} + +static int +sys_dl_close (loader_data, module) + lt_user_data loader_data; + lt_module module; +{ + int errors = 0; + + if (dlclose (module) != 0) + { + LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE)); + ++errors; + } + + return errors; +} + +static lt_ptr +sys_dl_sym (loader_data, module, symbol) + lt_user_data loader_data; + lt_module module; + const char *symbol; +{ + lt_ptr address = dlsym (module, symbol); + + if (!address) + { + LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND)); + } + + return address; +} + +static struct lt_user_dlloader sys_dl = + { +# ifdef NEED_USCORE + "_", +# else + 0, +# endif + sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 }; + + +#endif /* HAVE_LIBDL */ + + + +/* --- SHL_LOAD() INTERFACE LOADER --- */ + +#if HAVE_SHL_LOAD + +/* dynamic linking with shl_load (HP-UX) (comments from gmodule) */ + +#ifdef HAVE_DL_H +# include +#endif + +/* some flags are missing on some systems, so we provide + * harmless defaults. + * + * Mandatory: + * BIND_IMMEDIATE - Resolve symbol references when the library is loaded. + * BIND_DEFERRED - Delay code symbol resolution until actual reference. + * + * Optionally: + * BIND_FIRST - Place the library at the head of the symbol search + * order. + * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all + * unsatisfied symbols as fatal. This flag allows + * binding of unsatisfied code symbols to be deferred + * until use. + * [Perl: For certain libraries, like DCE, deferred + * binding often causes run time problems. Adding + * BIND_NONFATAL to BIND_IMMEDIATE still allows + * unresolved references in situations like this.] + * BIND_NOSTART - Do not call the initializer for the shared library + * when the library is loaded, nor on a future call to + * shl_unload(). + * BIND_VERBOSE - Print verbose messages concerning possible + * unsatisfied symbols. + * + * hp9000s700/hp9000s800: + * BIND_RESTRICTED - Restrict symbols visible by the library to those + * present at library load time. + * DYNAMIC_PATH - Allow the loader to dynamically search for the + * library specified by the path argument. + */ + +#ifndef DYNAMIC_PATH +# define DYNAMIC_PATH 0 +#endif +#ifndef BIND_RESTRICTED +# define BIND_RESTRICTED 0 +#endif + +#define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH) + +static lt_module +sys_shl_open (loader_data, filename) + lt_user_data loader_data; + const char *filename; +{ + static shl_t self = (shl_t) 0; + lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L); + + /* Since searching for a symbol against a NULL module handle will also + look in everything else that was already loaded and exported with + the -E compiler flag, we always cache a handle saved before any + modules are loaded. */ + if (!self) + { + lt_ptr address; + shl_findsym (&self, "main", TYPE_UNDEFINED, &address); + } + + if (!filename) + { + module = self; + } + else + { + module = shl_load (filename, LT_BIND_FLAGS, 0L); + + if (!module) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + } + } + + return module; +} + +static int +sys_shl_close (loader_data, module) + lt_user_data loader_data; + lt_module module; +{ + int errors = 0; + + if (module && (shl_unload ((shl_t) (module)) != 0)) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + ++errors; + } + + return errors; +} + +static lt_ptr +sys_shl_sym (loader_data, module, symbol) + lt_user_data loader_data; + lt_module module; + const char *symbol; +{ + lt_ptr address = 0; + + /* sys_shl_open should never return a NULL module handle */ + if (module == (lt_module) 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + } + else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address)) + { + if (!address) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + } + } + + return address; +} + +static struct lt_user_dlloader sys_shl = { + 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0 +}; + +#endif /* HAVE_SHL_LOAD */ + + + + +/* --- LOADLIBRARY() INTERFACE LOADER --- */ + +#ifdef __WINDOWS__ + +/* dynamic linking for Win32 */ + +#include + +/* Forward declaration; required to implement handle search below. */ +static lt_dlhandle handles; + +static lt_module +sys_wll_open (loader_data, filename) + lt_user_data loader_data; + const char *filename; +{ + lt_dlhandle cur; + lt_module module = 0; + const char *errormsg = 0; + char *searchname = 0; + char *ext; + char self_name_buf[MAX_PATH]; + + if (!filename) + { + /* Get the name of main module */ + *self_name_buf = 0; + GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf)); + filename = ext = self_name_buf; + } + else + { + ext = strrchr (filename, '.'); + } + + if (ext) + { + /* FILENAME already has an extension. */ + searchname = lt_estrdup (filename); + } + else + { + /* Append a `.' to stop Windows from adding an + implicit `.dll' extension. */ + searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename)); + if (searchname) + sprintf (searchname, "%s.", filename); + } + if (!searchname) + return 0; + + { + /* Silence dialog from LoadLibrary on some failures. + No way to get the error mode, but to set it, + so set it twice to preserve any previous flags. */ + UINT errormode = SetErrorMode(SEM_FAILCRITICALERRORS); + SetErrorMode(errormode | SEM_FAILCRITICALERRORS); + +#if defined(__CYGWIN__) + { + char wpath[MAX_PATH]; + cygwin_conv_to_full_win32_path (searchname, wpath); + module = LoadLibrary (wpath); + } +#else + module = LoadLibrary (searchname); +#endif + + /* Restore the error mode. */ + SetErrorMode(errormode); + } + + LT_DLFREE (searchname); + + /* libltdl expects this function to fail if it is unable + to physically load the library. Sadly, LoadLibrary + will search the loaded libraries for a match and return + one of them if the path search load fails. + + We check whether LoadLibrary is returning a handle to + an already loaded module, and simulate failure if we + find one. */ + LT_DLMUTEX_LOCK (); + cur = handles; + while (cur) + { + if (!cur->module) + { + cur = 0; + break; + } + + if (cur->module == module) + { + break; + } + + cur = cur->next; + } + LT_DLMUTEX_UNLOCK (); + + if (cur || !module) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + module = 0; + } + + return module; +} + +static int +sys_wll_close (loader_data, module) + lt_user_data loader_data; + lt_module module; +{ + int errors = 0; + + if (FreeLibrary(module) == 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + ++errors; + } + + return errors; +} + +static lt_ptr +sys_wll_sym (loader_data, module, symbol) + lt_user_data loader_data; + lt_module module; + const char *symbol; +{ + lt_ptr address = GetProcAddress (module, symbol); + + if (!address) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + } + + return address; +} + +static struct lt_user_dlloader sys_wll = { + 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0 +}; + +#endif /* __WINDOWS__ */ + + + + +/* --- LOAD_ADD_ON() INTERFACE LOADER --- */ + + +#ifdef __BEOS__ + +/* dynamic linking for BeOS */ + +#include + +static lt_module +sys_bedl_open (loader_data, filename) + lt_user_data loader_data; + const char *filename; +{ + image_id image = 0; + + if (filename) + { + image = load_add_on (filename); + } + else + { + image_info info; + int32 cookie = 0; + if (get_next_image_info (0, &cookie, &info) == B_OK) + image = load_add_on (info.name); + } + + if (image <= 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + image = 0; + } + + return (lt_module) image; +} + +static int +sys_bedl_close (loader_data, module) + lt_user_data loader_data; + lt_module module; +{ + int errors = 0; + + if (unload_add_on ((image_id) module) != B_OK) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + ++errors; + } + + return errors; +} + +static lt_ptr +sys_bedl_sym (loader_data, module, symbol) + lt_user_data loader_data; + lt_module module; + const char *symbol; +{ + lt_ptr address = 0; + image_id image = (image_id) module; + + if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + address = 0; + } + + return address; +} + +static struct lt_user_dlloader sys_bedl = { + 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0 +}; + +#endif /* __BEOS__ */ + + + + +/* --- DLD_LINK() INTERFACE LOADER --- */ + + +#if HAVE_DLD + +/* dynamic linking with dld */ + +#if HAVE_DLD_H +#include +#endif + +static lt_module +sys_dld_open (loader_data, filename) + lt_user_data loader_data; + const char *filename; +{ + lt_module module = strdup (filename); + + if (dld_link (filename) != 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); + LT_DLFREE (module); + module = 0; + } + + return module; +} + +static int +sys_dld_close (loader_data, module) + lt_user_data loader_data; + lt_module module; +{ + int errors = 0; + + if (dld_unlink_by_file ((char*)(module), 1) != 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); + ++errors; + } + else + { + LT_DLFREE (module); + } + + return errors; +} + +static lt_ptr +sys_dld_sym (loader_data, module, symbol) + lt_user_data loader_data; + lt_module module; + const char *symbol; +{ + lt_ptr address = dld_get_func (symbol); + + if (!address) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + } + + return address; +} + +static struct lt_user_dlloader sys_dld = { + 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0 +}; + +#endif /* HAVE_DLD */ + +/* --- DYLD() MACOSX/DARWIN INTERFACE LOADER --- */ +#if HAVE_DYLD + + +#if HAVE_MACH_O_DYLD_H +#if !defined(__APPLE_CC__) && !defined(__MWERKS__) && !defined(__private_extern__) +/* Is this correct? Does it still function properly? */ +#define __private_extern__ extern +#endif +# include +#endif +#include + +/* We have to put some stuff here that isn't in older dyld.h files */ +#ifndef ENUM_DYLD_BOOL +# define ENUM_DYLD_BOOL +# undef FALSE +# undef TRUE + enum DYLD_BOOL { + FALSE, + TRUE + }; +#endif +#ifndef LC_REQ_DYLD +# define LC_REQ_DYLD 0x80000000 +#endif +#ifndef LC_LOAD_WEAK_DYLIB +# define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD) +#endif +static const struct mach_header * (*ltdl_NSAddImage)(const char *image_name, unsigned long options) = 0; +static NSSymbol (*ltdl_NSLookupSymbolInImage)(const struct mach_header *image,const char *symbolName, unsigned long options) = 0; +static enum DYLD_BOOL (*ltdl_NSIsSymbolNameDefinedInImage)(const struct mach_header *image, const char *symbolName) = 0; +static enum DYLD_BOOL (*ltdl_NSMakePrivateModulePublic)(NSModule module) = 0; + +#ifndef NSADDIMAGE_OPTION_NONE +#define NSADDIMAGE_OPTION_NONE 0x0 +#endif +#ifndef NSADDIMAGE_OPTION_RETURN_ON_ERROR +#define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1 +#endif +#ifndef NSADDIMAGE_OPTION_WITH_SEARCHING +#define NSADDIMAGE_OPTION_WITH_SEARCHING 0x2 +#endif +#ifndef NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED +#define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4 +#endif +#ifndef NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME +#define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8 +#endif +#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND +#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0 +#endif +#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW +#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 0x1 +#endif +#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY +#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 0x2 +#endif +#ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR +#define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4 +#endif + + +static const char * +lt_int_dyld_error(othererror) + char* othererror; +{ +/* return the dyld error string, or the passed in error string if none */ + NSLinkEditErrors ler; + int lerno; + const char *errstr; + const char *file; + NSLinkEditError(&ler,&lerno,&file,&errstr); + if (!errstr || !strlen(errstr)) errstr = othererror; + return errstr; +} + +static const struct mach_header * +lt_int_dyld_get_mach_header_from_nsmodule(module) + NSModule module; +{ +/* There should probably be an apple dyld api for this */ + int i=_dyld_image_count(); + int j; + const char *modname=NSNameOfModule(module); + const struct mach_header *mh=NULL; + if (!modname) return NULL; + for (j = 0; j < i; j++) + { + if (!strcmp(_dyld_get_image_name(j),modname)) + { + mh=_dyld_get_image_header(j); + break; + } + } + return mh; +} + +static const char* lt_int_dyld_lib_install_name(mh) + const struct mach_header *mh; +{ +/* NSAddImage is also used to get the loaded image, but it only works if the lib + is installed, for uninstalled libs we need to check the install_names against + each other. Note that this is still broken if DYLD_IMAGE_SUFFIX is set and a + different lib was loaded as a result +*/ + int j; + struct load_command *lc; + unsigned long offset = sizeof(struct mach_header); + const char* retStr=NULL; + for (j = 0; j < mh->ncmds; j++) + { + lc = (struct load_command*)(((unsigned long)mh) + offset); + if (LC_ID_DYLIB == lc->cmd) + { + retStr=(char*)(((struct dylib_command*)lc)->dylib.name.offset + + (unsigned long)lc); + } + offset += lc->cmdsize; + } + return retStr; +} + +static const struct mach_header * +lt_int_dyld_match_loaded_lib_by_install_name(const char *name) +{ + int i=_dyld_image_count(); + int j; + const struct mach_header *mh=NULL; + const char *id=NULL; + for (j = 0; j < i; j++) + { + id=lt_int_dyld_lib_install_name(_dyld_get_image_header(j)); + if ((id) && (!strcmp(id,name))) + { + mh=_dyld_get_image_header(j); + break; + } + } + return mh; +} + +static NSSymbol +lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol,mh) + const char *symbol; + const struct mach_header *mh; +{ + /* Safe to assume our mh is good */ + int j; + struct load_command *lc; + unsigned long offset = sizeof(struct mach_header); + NSSymbol retSym = 0; + const struct mach_header *mh1; + if ((ltdl_NSLookupSymbolInImage) && NSIsSymbolNameDefined(symbol) ) + { + for (j = 0; j < mh->ncmds; j++) + { + lc = (struct load_command*)(((unsigned long)mh) + offset); + if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd)) + { + mh1=lt_int_dyld_match_loaded_lib_by_install_name((char*)(((struct dylib_command*)lc)->dylib.name.offset + + (unsigned long)lc)); + if (!mh1) + { + /* Maybe NSAddImage can find it */ + mh1=ltdl_NSAddImage((char*)(((struct dylib_command*)lc)->dylib.name.offset + + (unsigned long)lc), + NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED + + NSADDIMAGE_OPTION_WITH_SEARCHING + + NSADDIMAGE_OPTION_RETURN_ON_ERROR ); + } + if (mh1) + { + retSym = ltdl_NSLookupSymbolInImage(mh1, + symbol, + NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW + | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR + ); + if (retSym) break; + } + } + offset += lc->cmdsize; + } + } + return retSym; +} + +static int +sys_dyld_init() +{ + int retCode = 0; + int err = 0; + if (!_dyld_present()) { + retCode=1; + } + else { + err = _dyld_func_lookup("__dyld_NSAddImage",(unsigned long*)<dl_NSAddImage); + err = _dyld_func_lookup("__dyld_NSLookupSymbolInImage",(unsigned long*)<dl_NSLookupSymbolInImage); + err = _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage",(unsigned long*)<dl_NSIsSymbolNameDefinedInImage); + err = _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",(unsigned long*)<dl_NSMakePrivateModulePublic); + } + return retCode; +} + +static lt_module +sys_dyld_open (loader_data, filename) + lt_user_data loader_data; + const char *filename; +{ + lt_module module = 0; + NSObjectFileImage ofi = 0; + NSObjectFileImageReturnCode ofirc; + + if (!filename) + return (lt_module)-1; + ofirc = NSCreateObjectFileImageFromFile(filename, &ofi); + switch (ofirc) + { + case NSObjectFileImageSuccess: + module = NSLinkModule(ofi, filename, + NSLINKMODULE_OPTION_RETURN_ON_ERROR + | NSLINKMODULE_OPTION_PRIVATE + | NSLINKMODULE_OPTION_BINDNOW); + NSDestroyObjectFileImage(ofi); + if (module) + ltdl_NSMakePrivateModulePublic(module); + break; + case NSObjectFileImageInappropriateFile: + if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage) + { + module = (lt_module)ltdl_NSAddImage(filename, NSADDIMAGE_OPTION_RETURN_ON_ERROR); + break; + } + default: + LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN))); + return 0; + } + if (!module) LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN))); + return module; +} + +static int +sys_dyld_close (loader_data, module) + lt_user_data loader_data; + lt_module module; +{ + int retCode = 0; + int flags = 0; + if (module == (lt_module)-1) return 0; +#ifdef __BIG_ENDIAN__ + if (((struct mach_header *)module)->magic == MH_MAGIC) +#else + if (((struct mach_header *)module)->magic == MH_CIGAM) +#endif + { + LT_DLMUTEX_SETERROR("Can not close a dylib"); + retCode = 1; + } + else + { +#if 1 +/* Currently, if a module contains c++ static destructors and it is unloaded, we + get a segfault in atexit(), due to compiler and dynamic loader differences of + opinion, this works around that. +*/ + if ((const struct section *)NULL != + getsectbynamefromheader(lt_int_dyld_get_mach_header_from_nsmodule(module), + "__DATA","__mod_term_func")) + { + flags += NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED; + } +#endif +#ifdef __ppc__ + flags += NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES; +#endif + if (!NSUnLinkModule(module,flags)) + { + retCode=1; + LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_CLOSE))); + } + } + + return retCode; +} + +static lt_ptr +sys_dyld_sym (loader_data, module, symbol) + lt_user_data loader_data; + lt_module module; + const char *symbol; +{ + lt_ptr address = 0; + NSSymbol *nssym = 0; + void *unused; + const struct mach_header *mh=NULL; + char saveError[256] = "Symbol not found"; + if (module == (lt_module)-1) + { + _dyld_lookup_and_bind(symbol,(unsigned long*)&address,&unused); + return address; + } +#ifdef __BIG_ENDIAN__ + if (((struct mach_header *)module)->magic == MH_MAGIC) +#else + if (((struct mach_header *)module)->magic == MH_CIGAM) +#endif + { + if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage) + { + mh=module; + if (ltdl_NSIsSymbolNameDefinedInImage((struct mach_header*)module,symbol)) + { + nssym = ltdl_NSLookupSymbolInImage((struct mach_header*)module, + symbol, + NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW + | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR + ); + } + } + + } + else { + nssym = NSLookupSymbolInModule(module, symbol); + } + if (!nssym) + { + strncpy(saveError, lt_int_dyld_error(LT_DLSTRERROR(SYMBOL_NOT_FOUND)), 255); + saveError[255] = 0; + if (!mh) mh=lt_int_dyld_get_mach_header_from_nsmodule(module); + nssym = lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol,mh); + } + if (!nssym) + { + LT_DLMUTEX_SETERROR (saveError); + return NULL; + } + return NSAddressOfSymbol(nssym); +} + +static struct lt_user_dlloader sys_dyld = + { "_", sys_dyld_open, sys_dyld_close, sys_dyld_sym, 0, 0 }; + + +#endif /* HAVE_DYLD */ + + +/* --- DLPREOPEN() INTERFACE LOADER --- */ + + +/* emulate dynamic linking using preloaded_symbols */ + +typedef struct lt_dlsymlists_t +{ + struct lt_dlsymlists_t *next; + const lt_dlsymlist *syms; +} lt_dlsymlists_t; + +static const lt_dlsymlist *default_preloaded_symbols = 0; +static lt_dlsymlists_t *preloaded_symbols = 0; + +static int +presym_init (loader_data) + lt_user_data loader_data; +{ + int errors = 0; + + LT_DLMUTEX_LOCK (); + + preloaded_symbols = 0; + if (default_preloaded_symbols) + { + errors = lt_dlpreload (default_preloaded_symbols); + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +static int +presym_free_symlists () +{ + lt_dlsymlists_t *lists; + + LT_DLMUTEX_LOCK (); + + lists = preloaded_symbols; + while (lists) + { + lt_dlsymlists_t *tmp = lists; + + lists = lists->next; + LT_DLFREE (tmp); + } + preloaded_symbols = 0; + + LT_DLMUTEX_UNLOCK (); + + return 0; +} + +static int +presym_exit (loader_data) + lt_user_data loader_data; +{ + presym_free_symlists (); + return 0; +} + +static int +presym_add_symlist (preloaded) + const lt_dlsymlist *preloaded; +{ + lt_dlsymlists_t *tmp; + lt_dlsymlists_t *lists; + int errors = 0; + + LT_DLMUTEX_LOCK (); + + lists = preloaded_symbols; + while (lists) + { + if (lists->syms == preloaded) + { + goto done; + } + lists = lists->next; + } + + tmp = LT_EMALLOC (lt_dlsymlists_t, 1); + if (tmp) + { + memset (tmp, 0, sizeof(lt_dlsymlists_t)); + tmp->syms = preloaded; + tmp->next = preloaded_symbols; + preloaded_symbols = tmp; + } + else + { + ++errors; + } + + done: + LT_DLMUTEX_UNLOCK (); + return errors; +} + +static lt_module +presym_open (loader_data, filename) + lt_user_data loader_data; + const char *filename; +{ + lt_dlsymlists_t *lists; + lt_module module = (lt_module) 0; + + LT_DLMUTEX_LOCK (); + lists = preloaded_symbols; + + if (!lists) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS)); + goto done; + } + + /* Can't use NULL as the reflective symbol header, as NULL is + used to mark the end of the entire symbol list. Self-dlpreopened + symbols follow this magic number, chosen to be an unlikely + clash with a real module name. */ + if (!filename) + { + filename = "@PROGRAM@"; + } + + while (lists) + { + const lt_dlsymlist *syms = lists->syms; + + while (syms->name) + { + if (!syms->address && strcmp(syms->name, filename) == 0) + { + module = (lt_module) syms; + goto done; + } + ++syms; + } + + lists = lists->next; + } + + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + + done: + LT_DLMUTEX_UNLOCK (); + return module; +} + +static int +presym_close (loader_data, module) + lt_user_data loader_data; + lt_module module; +{ + /* Just to silence gcc -Wall */ + module = 0; + return 0; +} + +static lt_ptr +presym_sym (loader_data, module, symbol) + lt_user_data loader_data; + lt_module module; + const char *symbol; +{ + lt_dlsymlist *syms = (lt_dlsymlist*) module; + + ++syms; + while (syms->address) + { + if (strcmp(syms->name, symbol) == 0) + { + return syms->address; + } + + ++syms; + } + + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + + return 0; +} + +static struct lt_user_dlloader presym = { + 0, presym_open, presym_close, presym_sym, presym_exit, 0 +}; + + + + + +/* --- DYNAMIC MODULE LOADING --- */ + + +/* The type of a function used at each iteration of foreach_dirinpath(). */ +typedef int foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1, + lt_ptr data2)); + +static int foreach_dirinpath LT_PARAMS((const char *search_path, + const char *base_name, + foreach_callback_func *func, + lt_ptr data1, lt_ptr data2)); + +static int find_file_callback LT_PARAMS((char *filename, lt_ptr data, + lt_ptr ignored)); +static int find_handle_callback LT_PARAMS((char *filename, lt_ptr data, + lt_ptr ignored)); +static int foreachfile_callback LT_PARAMS((char *filename, lt_ptr data1, + lt_ptr data2)); + + +static int canonicalize_path LT_PARAMS((const char *path, + char **pcanonical)); +static int argzize_path LT_PARAMS((const char *path, + char **pargz, + size_t *pargz_len)); +static FILE *find_file LT_PARAMS((const char *search_path, + const char *base_name, + char **pdir)); +static lt_dlhandle *find_handle LT_PARAMS((const char *search_path, + const char *base_name, + lt_dlhandle *handle)); +static int find_module LT_PARAMS((lt_dlhandle *handle, + const char *dir, + const char *libdir, + const char *dlname, + const char *old_name, + int installed)); +static int free_vars LT_PARAMS((char *dlname, char *oldname, + char *libdir, char *deplibs)); +static int load_deplibs LT_PARAMS((lt_dlhandle handle, + char *deplibs)); +static int trim LT_PARAMS((char **dest, + const char *str)); +static int try_dlopen LT_PARAMS((lt_dlhandle *handle, + const char *filename)); +static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle, + const char *filename)); +static int unload_deplibs LT_PARAMS((lt_dlhandle handle)); +static int lt_argz_insert LT_PARAMS((char **pargz, + size_t *pargz_len, + char *before, + const char *entry)); +static int lt_argz_insertinorder LT_PARAMS((char **pargz, + size_t *pargz_len, + const char *entry)); +static int lt_argz_insertdir LT_PARAMS((char **pargz, + size_t *pargz_len, + const char *dirnam, + struct dirent *dp)); +static int lt_dlpath_insertdir LT_PARAMS((char **ppath, + char *before, + const char *dir)); +static int list_files_by_dir LT_PARAMS((const char *dirnam, + char **pargz, + size_t *pargz_len)); +static int file_not_found LT_PARAMS((void)); + +static char *user_search_path= 0; +static lt_dlloader *loaders = 0; +static lt_dlhandle handles = 0; +static int initialized = 0; + +/* Initialize libltdl. */ +int +lt_dlinit () +{ + int errors = 0; + + LT_DLMUTEX_LOCK (); + + /* Initialize only at first call. */ + if (++initialized == 1) + { + handles = 0; + user_search_path = 0; /* empty search path */ + +#if HAVE_LIBDL + errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen"); +#endif +#if HAVE_SHL_LOAD + errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen"); +#endif +#ifdef __WINDOWS__ + errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen"); +#endif +#ifdef __BEOS__ + errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen"); +#endif +#if HAVE_DLD + errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld"); +#endif +#if HAVE_DYLD + errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dyld, "dyld"); + errors += sys_dyld_init(); +#endif + errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload"); + + if (presym_init (presym.dlloader_data)) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER)); + ++errors; + } + else if (errors != 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED)); + ++errors; + } + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +int +lt_dlpreload (preloaded) + const lt_dlsymlist *preloaded; +{ + int errors = 0; + + if (preloaded) + { + errors = presym_add_symlist (preloaded); + } + else + { + presym_free_symlists(); + + LT_DLMUTEX_LOCK (); + if (default_preloaded_symbols) + { + errors = lt_dlpreload (default_preloaded_symbols); + } + LT_DLMUTEX_UNLOCK (); + } + + return errors; +} + +int +lt_dlpreload_default (preloaded) + const lt_dlsymlist *preloaded; +{ + LT_DLMUTEX_LOCK (); + default_preloaded_symbols = preloaded; + LT_DLMUTEX_UNLOCK (); + return 0; +} + +int +lt_dlexit () +{ + /* shut down libltdl */ + lt_dlloader *loader; + int errors = 0; + + LT_DLMUTEX_LOCK (); + loader = loaders; + + if (!initialized) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN)); + ++errors; + goto done; + } + + /* shut down only at last call. */ + if (--initialized == 0) + { + int level; + + while (handles && LT_DLIS_RESIDENT (handles)) + { + handles = handles->next; + } + + /* close all modules */ + for (level = 1; handles; ++level) + { + lt_dlhandle cur = handles; + int saw_nonresident = 0; + + while (cur) + { + lt_dlhandle tmp = cur; + cur = cur->next; + if (!LT_DLIS_RESIDENT (tmp)) + saw_nonresident = 1; + if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level) + { + if (lt_dlclose (tmp)) + { + ++errors; + } + /* Make sure that the handle pointed to by 'cur' still exists. + lt_dlclose recursively closes dependent libraries which removes + them from the linked list. One of these might be the one + pointed to by 'cur'. */ + if (cur) + { + for (tmp = handles; tmp; tmp = tmp->next) + if (tmp == cur) + break; + if (! tmp) + cur = handles; + } + } + } + /* done if only resident modules are left */ + if (!saw_nonresident) + break; + } + + /* close all loaders */ + while (loader) + { + lt_dlloader *next = loader->next; + lt_user_data data = loader->dlloader_data; + if (loader->dlloader_exit && loader->dlloader_exit (data)) + { + ++errors; + } + + LT_DLMEM_REASSIGN (loader, next); + } + loaders = 0; + } + + done: + LT_DLMUTEX_UNLOCK (); + return errors; +} + +static int +tryall_dlopen (handle, filename) + lt_dlhandle *handle; + const char *filename; +{ + lt_dlhandle cur; + lt_dlloader *loader; + const char *saved_error; + int errors = 0; + + LT_DLMUTEX_GETERROR (saved_error); + LT_DLMUTEX_LOCK (); + + cur = handles; + loader = loaders; + + /* check whether the module was already opened */ + while (cur) + { + /* try to dlopen the program itself? */ + if (!cur->info.filename && !filename) + { + break; + } + + if (cur->info.filename && filename + && strcmp (cur->info.filename, filename) == 0) + { + break; + } + + cur = cur->next; + } + + if (cur) + { + ++cur->info.ref_count; + *handle = cur; + goto done; + } + + cur = *handle; + if (filename) + { + /* Comment out the check of file permissions using access. + This call seems to always return -1 with error EACCES. + */ + /* We need to catch missing file errors early so that + file_not_found() can detect what happened. + if (access (filename, R_OK) != 0) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + ++errors; + goto done; + } */ + + cur->info.filename = lt_estrdup (filename); + if (!cur->info.filename) + { + ++errors; + goto done; + } + } + else + { + cur->info.filename = 0; + } + + while (loader) + { + lt_user_data data = loader->dlloader_data; + + cur->module = loader->module_open (data, filename); + + if (cur->module != 0) + { + break; + } + loader = loader->next; + } + + if (!loader) + { + LT_DLFREE (cur->info.filename); + ++errors; + goto done; + } + + cur->loader = loader; + LT_DLMUTEX_SETERROR (saved_error); + + done: + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +static int +tryall_dlopen_module (handle, prefix, dirname, dlname) + lt_dlhandle *handle; + const char *prefix; + const char *dirname; + const char *dlname; +{ + int error = 0; + char *filename = 0; + size_t filename_len = 0; + size_t dirname_len = LT_STRLEN (dirname); + + assert (handle); + assert (dirname); + assert (dlname); +#ifdef LT_DIRSEP_CHAR + /* Only canonicalized names (i.e. with DIRSEP chars already converted) + should make it into this function: */ + assert (strchr (dirname, LT_DIRSEP_CHAR) == 0); +#endif + + if (dirname_len > 0) + if (dirname[dirname_len -1] == '/') + --dirname_len; + filename_len = dirname_len + 1 + LT_STRLEN (dlname); + + /* Allocate memory, and combine DIRNAME and MODULENAME into it. + The PREFIX (if any) is handled below. */ + filename = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1); + if (!filename) + return 1; + + sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname); + + /* Now that we have combined DIRNAME and MODULENAME, if there is + also a PREFIX to contend with, simply recurse with the arguments + shuffled. Otherwise, attempt to open FILENAME as a module. */ + if (prefix) + { + error += tryall_dlopen_module (handle, + (const char *) 0, prefix, filename); + } + else if (tryall_dlopen (handle, filename) != 0) + { + ++error; + } + + LT_DLFREE (filename); + return error; +} + +static int +find_module (handle, dir, libdir, dlname, old_name, installed) + lt_dlhandle *handle; + const char *dir; + const char *libdir; + const char *dlname; + const char *old_name; + int installed; +{ + /* Try to open the old library first; if it was dlpreopened, + we want the preopened version of it, even if a dlopenable + module is available. */ + if (old_name && tryall_dlopen (handle, old_name) == 0) + { + return 0; + } + + /* Try to open the dynamic library. */ + if (dlname) + { + /* try to open the installed module */ + if (installed && libdir) + { + if (tryall_dlopen_module (handle, + (const char *) 0, libdir, dlname) == 0) + return 0; + } + + /* try to open the not-installed module */ + if (!installed) + { + if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0) + return 0; + } + + /* maybe it was moved to another directory */ + { + if (dir && (tryall_dlopen_module (handle, + (const char *) 0, dir, dlname) == 0)) + return 0; + } + } + + return 1; +} + + +static int +canonicalize_path (path, pcanonical) + const char *path; + char **pcanonical; +{ + char *canonical = 0; + + assert (path && *path); + assert (pcanonical); + + canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path)); + if (!canonical) + return 1; + + { + size_t dest = 0; + size_t src; + for (src = 0; path[src] != LT_EOS_CHAR; ++src) + { + /* Path separators are not copied to the beginning or end of + the destination, or if another separator would follow + immediately. */ + if (path[src] == LT_PATHSEP_CHAR) + { + if ((dest == 0) + || (path[1+ src] == LT_PATHSEP_CHAR) + || (path[1+ src] == LT_EOS_CHAR)) + continue; + } + + /* Anything other than a directory separator is copied verbatim. */ + if ((path[src] != '/') +#ifdef LT_DIRSEP_CHAR + && (path[src] != LT_DIRSEP_CHAR) +#endif + ) + { + canonical[dest++] = path[src]; + } + /* Directory separators are converted and copied only if they are + not at the end of a path -- i.e. before a path separator or + NULL terminator. */ + else if ((path[1+ src] != LT_PATHSEP_CHAR) + && (path[1+ src] != LT_EOS_CHAR) +#ifdef LT_DIRSEP_CHAR + && (path[1+ src] != LT_DIRSEP_CHAR) +#endif + && (path[1+ src] != '/')) + { + canonical[dest++] = '/'; + } + } + + /* Add an end-of-string marker at the end. */ + canonical[dest] = LT_EOS_CHAR; + } + + /* Assign new value. */ + *pcanonical = canonical; + + return 0; +} + +static int +argzize_path (path, pargz, pargz_len) + const char *path; + char **pargz; + size_t *pargz_len; +{ + error_t error; + + assert (path); + assert (pargz); + assert (pargz_len); + + if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len))) + { + switch (error) + { + case ENOMEM: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + break; + default: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN)); + break; + } + + return 1; + } + + return 0; +} + +/* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element + of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns + non-zero or all elements are exhausted. If BASE_NAME is non-NULL, + it is appended to each SEARCH_PATH element before FUNC is called. */ +static int +foreach_dirinpath (search_path, base_name, func, data1, data2) + const char *search_path; + const char *base_name; + foreach_callback_func *func; + lt_ptr data1; + lt_ptr data2; +{ + int result = 0; + int filenamesize = 0; + size_t lenbase = LT_STRLEN (base_name); + size_t argz_len = 0; + char *argz = 0; + char *filename = 0; + char *canonical = 0; + + LT_DLMUTEX_LOCK (); + + if (!search_path || !*search_path) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + goto cleanup; + } + + if (canonicalize_path (search_path, &canonical) != 0) + goto cleanup; + + if (argzize_path (canonical, &argz, &argz_len) != 0) + goto cleanup; + + { + char *dir_name = 0; + while ((dir_name = argz_next (argz, argz_len, dir_name))) + { + size_t lendir = LT_STRLEN (dir_name); + + if (lendir +1 +lenbase >= filenamesize) + { + LT_DLFREE (filename); + filenamesize = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */ + filename = LT_EMALLOC (char, filenamesize); + if (!filename) + goto cleanup; + } + + assert (filenamesize > lendir); + strcpy (filename, dir_name); + + if (base_name && *base_name) + { + if (filename[lendir -1] != '/') + filename[lendir++] = '/'; + strcpy (filename +lendir, base_name); + } + + if ((result = (*func) (filename, data1, data2))) + { + break; + } + } + } + + cleanup: + LT_DLFREE (argz); + LT_DLFREE (canonical); + LT_DLFREE (filename); + + LT_DLMUTEX_UNLOCK (); + + return result; +} + +/* If FILEPATH can be opened, store the name of the directory component + in DATA1, and the opened FILE* structure address in DATA2. Otherwise + DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */ +static int +find_file_callback (filename, data1, data2) + char *filename; + lt_ptr data1; + lt_ptr data2; +{ + char **pdir = (char **) data1; + FILE **pfile = (FILE **) data2; + int is_done = 0; + + assert (filename && *filename); + assert (pdir); + assert (pfile); + + if ((*pfile = fopen (filename, LT_READTEXT_MODE))) + { + char *dirend = strrchr (filename, '/'); + + if (dirend > filename) + *dirend = LT_EOS_CHAR; + + LT_DLFREE (*pdir); + *pdir = lt_estrdup (filename); + is_done = (*pdir == 0) ? -1 : 1; + } + + return is_done; +} + +static FILE * +find_file (search_path, base_name, pdir) + const char *search_path; + const char *base_name; + char **pdir; +{ + FILE *file = 0; + + foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file); + + return file; +} + +static int +find_handle_callback (filename, data, ignored) + char *filename; + lt_ptr data; + lt_ptr ignored; +{ + lt_dlhandle *handle = (lt_dlhandle *) data; + int notfound = access (filename, R_OK); + + /* Bail out if file cannot be read... */ + if (notfound) + return 0; + + /* Try to dlopen the file, but do not continue searching in any + case. */ + if (tryall_dlopen (handle, filename) != 0) + *handle = 0; + + return 1; +} + +/* If HANDLE was found return it, otherwise return 0. If HANDLE was + found but could not be opened, *HANDLE will be set to 0. */ +static lt_dlhandle * +find_handle (search_path, base_name, handle) + const char *search_path; + const char *base_name; + lt_dlhandle *handle; +{ + if (!search_path) + return 0; + + if (!foreach_dirinpath (search_path, base_name, find_handle_callback, + handle, 0)) + return 0; + + return handle; +} + +static int +load_deplibs (handle, deplibs) + lt_dlhandle handle; + char *deplibs; +{ +#if LTDL_DLOPEN_DEPLIBS + char *p, *save_search_path = 0; + int depcount = 0; + int i; + char **names = 0; +#endif + int errors = 0; + + handle->depcount = 0; + +#if LTDL_DLOPEN_DEPLIBS + if (!deplibs) + { + return errors; + } + ++errors; + + LT_DLMUTEX_LOCK (); + if (user_search_path) + { + save_search_path = lt_estrdup (user_search_path); + if (!save_search_path) + goto cleanup; + } + + /* extract search paths and count deplibs */ + p = deplibs; + while (*p) + { + if (!isspace ((int) *p)) + { + char *end = p+1; + while (*end && !isspace((int) *end)) + { + ++end; + } + + if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0) + { + char save = *end; + *end = 0; /* set a temporary string terminator */ + if (lt_dladdsearchdir(p+2)) + { + goto cleanup; + } + *end = save; + } + else + { + ++depcount; + } + + p = end; + } + else + { + ++p; + } + } + + if (!depcount) + { + errors = 0; + goto cleanup; + } + + names = LT_EMALLOC (char *, depcount * sizeof (char*)); + if (!names) + goto cleanup; + + /* now only extract the actual deplibs */ + depcount = 0; + p = deplibs; + while (*p) + { + if (isspace ((int) *p)) + { + ++p; + } + else + { + char *end = p+1; + while (*end && !isspace ((int) *end)) + { + ++end; + } + + if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0) + { + char *name; + char save = *end; + *end = 0; /* set a temporary string terminator */ + if (strncmp(p, "-l", 2) == 0) + { + size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2); + name = LT_EMALLOC (char, 1+ name_len); + if (name) + sprintf (name, "lib%s", p+2); + } + else + name = lt_estrdup(p); + + if (!name) + goto cleanup_names; + + names[depcount++] = name; + *end = save; + } + p = end; + } + } + + /* load the deplibs (in reverse order) + At this stage, don't worry if the deplibs do not load correctly, + they may already be statically linked into the loading application + for instance. There will be a more enlightening error message + later on if the loaded module cannot resolve all of its symbols. */ + if (depcount) + { + int j = 0; + + handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount); + if (!handle->deplibs) + goto cleanup_names; + + for (i = 0; i < depcount; ++i) + { + handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]); + if (handle->deplibs[j]) + { + ++j; + } + } + + handle->depcount = j; /* Number of successfully loaded deplibs */ + errors = 0; + } + + cleanup_names: + for (i = 0; i < depcount; ++i) + { + LT_DLFREE (names[i]); + } + + cleanup: + LT_DLFREE (names); + /* restore the old search path */ + if (user_search_path) { + LT_DLFREE (user_search_path); + user_search_path = save_search_path; + } + LT_DLMUTEX_UNLOCK (); + +#endif + + return errors; +} + +static int +unload_deplibs (handle) + lt_dlhandle handle; +{ + int i; + int errors = 0; + + if (handle->depcount) + { + for (i = 0; i < handle->depcount; ++i) + { + if (!LT_DLIS_RESIDENT (handle->deplibs[i])) + { + errors += lt_dlclose (handle->deplibs[i]); + } + } + LT_DLFREE (handle->deplibs); + } + + return errors; +} + +static int +trim (dest, str) + char **dest; + const char *str; +{ + /* remove the leading and trailing "'" from str + and store the result in dest */ + const char *end = strrchr (str, '\''); + size_t len = LT_STRLEN (str); + char *tmp; + + LT_DLFREE (*dest); + + if (!end) + return 1; + + if (len > 3 && str[0] == '\'') + { + tmp = LT_EMALLOC (char, end - str); + if (!tmp) + return 1; + + strncpy(tmp, &str[1], (end - str) - 1); + tmp[len-3] = LT_EOS_CHAR; + *dest = tmp; + } + else + { + *dest = 0; + } + + return 0; +} + +static int +free_vars (dlname, oldname, libdir, deplibs) + char *dlname; + char *oldname; + char *libdir; + char *deplibs; +{ + LT_DLFREE (dlname); + LT_DLFREE (oldname); + LT_DLFREE (libdir); + LT_DLFREE (deplibs); + + return 0; +} + +static int +try_dlopen (phandle, filename) + lt_dlhandle *phandle; + const char *filename; +{ + const char * ext = 0; + const char * saved_error = 0; + char * canonical = 0; + char * base_name = 0; + char * dir = 0; + char * name = 0; + int errors = 0; + lt_dlhandle newhandle; + + assert (phandle); + assert (*phandle == 0); + + LT_DLMUTEX_GETERROR (saved_error); + + /* dlopen self? */ + if (!filename) + { + *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + if (*phandle == 0) + return 1; + + memset (*phandle, 0, sizeof(struct lt_dlhandle_struct)); + newhandle = *phandle; + + /* lt_dlclose()ing yourself is very bad! Disallow it. */ + LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG); + + if (tryall_dlopen (&newhandle, 0) != 0) + { + LT_DLFREE (*phandle); + return 1; + } + + goto register_handle; + } + + assert (filename && *filename); + + /* Doing this immediately allows internal functions to safely + assume only canonicalized paths are passed. */ + if (canonicalize_path (filename, &canonical) != 0) + { + ++errors; + goto cleanup; + } + + /* If the canonical module name is a path (relative or absolute) + then split it into a directory part and a name part. */ + base_name = strrchr (canonical, '/'); + if (base_name) + { + size_t dirlen = (1+ base_name) - canonical; + + dir = LT_EMALLOC (char, 1+ dirlen); + if (!dir) + { + ++errors; + goto cleanup; + } + + strncpy (dir, canonical, dirlen); + dir[dirlen] = LT_EOS_CHAR; + + ++base_name; + } + else + base_name = canonical; + + assert (base_name && *base_name); + + /* Check whether we are opening a libtool module (.la extension). */ + ext = strrchr (base_name, '.'); + if (ext && strcmp (ext, archive_ext) == 0) + { + /* this seems to be a libtool module */ + FILE * file = 0; + char * dlname = 0; + char * old_name = 0; + char * libdir = 0; + char * deplibs = 0; + char * line = 0; + size_t line_len; + + /* if we can't find the installed flag, it is probably an + installed libtool archive, produced with an old version + of libtool */ + int installed = 1; + + /* extract the module name from the file name */ + name = LT_EMALLOC (char, ext - base_name + 1); + if (!name) + { + ++errors; + goto cleanup; + } + + /* canonicalize the module name */ + { + size_t i; + for (i = 0; i < ext - base_name; ++i) + { + if (isalnum ((int)(base_name[i]))) + { + name[i] = base_name[i]; + } + else + { + name[i] = '_'; + } + } + name[ext - base_name] = LT_EOS_CHAR; + } + + /* Now try to open the .la file. If there is no directory name + component, try to find it first in user_search_path and then other + prescribed paths. Otherwise (or in any case if the module was not + yet found) try opening just the module name as passed. */ + if (!dir) + { + const char *search_path; + + LT_DLMUTEX_LOCK (); + search_path = user_search_path; + if (search_path) + file = find_file (user_search_path, base_name, &dir); + LT_DLMUTEX_UNLOCK (); + + if (!file) + { + search_path = getenv (LTDL_SEARCHPATH_VAR); + if (search_path) + file = find_file (search_path, base_name, &dir); + } + +#ifdef LTDL_SHLIBPATH_VAR + if (!file) + { + search_path = getenv (LTDL_SHLIBPATH_VAR); + if (search_path) + file = find_file (search_path, base_name, &dir); + } +#endif +#ifdef LTDL_SYSSEARCHPATH + if (!file && sys_search_path) + { + file = find_file (sys_search_path, base_name, &dir); + } +#endif + } + if (!file) + { + /* don't open .la files in current directory, root might get tricked to run a binary in a prepared directory */ + if(!strncmp((filename + strlen(filename) - 3), LTDL_ARCHIVE_EXT,3) || strstr(filename,"/")) + file = fopen (filename, LT_READTEXT_MODE); + } + + /* If we didn't find the file by now, it really isn't there. Set + the status flag, and bail out. */ + if (!file) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + ++errors; + goto cleanup; + } + + line_len = LT_FILENAME_MAX; + line = LT_EMALLOC (char, line_len); + if (!line) + { + fclose (file); + ++errors; + goto cleanup; + } + + /* read the .la file */ + while (!feof (file)) + { + if (!fgets (line, (int) line_len, file)) + { + break; + } + + /* Handle the case where we occasionally need to read a line + that is longer than the initial buffer size. */ + while ((line[LT_STRLEN(line) -1] != '\n') && (!feof (file))) + { + line = LT_DLREALLOC (char, line, line_len *2); + if (!fgets (&line[line_len -1], (int) line_len +1, file)) + { + break; + } + line_len *= 2; + } + + if (line[0] == '\n' || line[0] == '#') + { + continue; + } + +#undef STR_DLNAME +#define STR_DLNAME "dlname=" + if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0) + { + errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]); + } + +#undef STR_OLD_LIBRARY +#define STR_OLD_LIBRARY "old_library=" + else if (strncmp (line, STR_OLD_LIBRARY, + sizeof (STR_OLD_LIBRARY) - 1) == 0) + { + errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]); + } +#undef STR_LIBDIR +#define STR_LIBDIR "libdir=" + else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0) + { + errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]); + } + +#undef STR_DL_DEPLIBS +#define STR_DL_DEPLIBS "dependency_libs=" + else if (strncmp (line, STR_DL_DEPLIBS, + sizeof (STR_DL_DEPLIBS) - 1) == 0) + { + errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]); + } + else if (strcmp (line, "installed=yes\n") == 0) + { + installed = 1; + } + else if (strcmp (line, "installed=no\n") == 0) + { + installed = 0; + } + +#undef STR_LIBRARY_NAMES +#define STR_LIBRARY_NAMES "library_names=" + else if (! dlname && strncmp (line, STR_LIBRARY_NAMES, + sizeof (STR_LIBRARY_NAMES) - 1) == 0) + { + char *last_libname; + errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]); + if (!errors + && dlname + && (last_libname = strrchr (dlname, ' ')) != 0) + { + last_libname = lt_estrdup (last_libname + 1); + if (!last_libname) + { + ++errors; + goto cleanup; + } + LT_DLMEM_REASSIGN (dlname, last_libname); + } + } + + if (errors) + break; + } + + fclose (file); + LT_DLFREE (line); + + /* allocate the handle */ + *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + if (*phandle == 0) + ++errors; + + if (errors) + { + free_vars (dlname, old_name, libdir, deplibs); + LT_DLFREE (*phandle); + goto cleanup; + } + + assert (*phandle); + + memset (*phandle, 0, sizeof(struct lt_dlhandle_struct)); + if (load_deplibs (*phandle, deplibs) == 0) + { + newhandle = *phandle; + /* find_module may replace newhandle */ + if (find_module (&newhandle, dir, libdir, dlname, old_name, installed)) + { + unload_deplibs (*phandle); + ++errors; + } + } + else + { + ++errors; + } + + free_vars (dlname, old_name, libdir, deplibs); + if (errors) + { + LT_DLFREE (*phandle); + goto cleanup; + } + + if (*phandle != newhandle) + { + unload_deplibs (*phandle); + } + } + else + { + /* not a libtool module */ + *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + if (*phandle == 0) + { + ++errors; + goto cleanup; + } + + memset (*phandle, 0, sizeof (struct lt_dlhandle_struct)); + newhandle = *phandle; + + /* If the module has no directory name component, try to find it + first in user_search_path and then other prescribed paths. + Otherwise (or in any case if the module was not yet found) try + opening just the module name as passed. */ + if ((dir || (!find_handle (user_search_path, base_name, &newhandle) + && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name, + &newhandle) +#ifdef LTDL_SHLIBPATH_VAR + && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name, + &newhandle) +#endif +#ifdef LTDL_SYSSEARCHPATH + && !find_handle (sys_search_path, base_name, &newhandle) +#endif + ))) + { + if (tryall_dlopen (&newhandle, filename) != 0) + { + newhandle = NULL; + } + } + + if (!newhandle) + { + LT_DLFREE (*phandle); + ++errors; + goto cleanup; + } + } + + register_handle: + LT_DLMEM_REASSIGN (*phandle, newhandle); + + if ((*phandle)->info.ref_count == 0) + { + (*phandle)->info.ref_count = 1; + LT_DLMEM_REASSIGN ((*phandle)->info.name, name); + + LT_DLMUTEX_LOCK (); + (*phandle)->next = handles; + handles = *phandle; + LT_DLMUTEX_UNLOCK (); + } + + LT_DLMUTEX_SETERROR (saved_error); + + cleanup: + LT_DLFREE (dir); + LT_DLFREE (name); + LT_DLFREE (canonical); + + return errors; +} + +lt_dlhandle +lt_dlopen (filename) + const char *filename; +{ + lt_dlhandle handle = 0; + + /* Just incase we missed a code path in try_dlopen() that reports + an error, but forgets to reset handle... */ + if (try_dlopen (&handle, filename) != 0) + return 0; + + return handle; +} + +/* If the last error messge store was `FILE_NOT_FOUND', then return + non-zero. */ +static int +file_not_found () +{ + const char *error = 0; + + LT_DLMUTEX_GETERROR (error); + if (error == LT_DLSTRERROR (FILE_NOT_FOUND)) + return 1; + + return 0; +} + +/* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to + open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT, + and if a file is still not found try again with SHLIB_EXT appended + instead. */ +lt_dlhandle +lt_dlopenext (filename) + const char *filename; +{ + lt_dlhandle handle = 0; + char * tmp = 0; + char * ext = 0; + size_t len; + int errors = 0; + + if (!filename) + { + return lt_dlopen (filename); + } + + assert (filename); + + len = LT_STRLEN (filename); + ext = strrchr (filename, '.'); + + /* If FILENAME already bears a suitable extension, there is no need + to try appending additional extensions. */ + if (ext && ((strcmp (ext, archive_ext) == 0) +#ifdef LTDL_SHLIB_EXT + || (strcmp (ext, shlib_ext) == 0) +#endif + )) + { + return lt_dlopen (filename); + } + + /* First try appending ARCHIVE_EXT. */ + tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1); + if (!tmp) + return 0; + + strcpy (tmp, filename); + strcat (tmp, archive_ext); + errors = try_dlopen (&handle, tmp); + + /* If we found FILENAME, stop searching -- whether we were able to + load the file as a module or not. If the file exists but loading + failed, it is better to return an error message here than to + report FILE_NOT_FOUND when the alternatives (foo.so etc) are not + in the module search path. */ + if (handle || ((errors > 0) && !file_not_found ())) + { + LT_DLFREE (tmp); + return handle; + } + +#ifdef LTDL_SHLIB_EXT + /* Try appending SHLIB_EXT. */ + if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext)) + { + LT_DLFREE (tmp); + tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1); + if (!tmp) + return 0; + + strcpy (tmp, filename); + } + else + { + tmp[len] = LT_EOS_CHAR; + } + + strcat(tmp, shlib_ext); + errors = try_dlopen (&handle, tmp); + + /* As before, if the file was found but loading failed, return now + with the current error message. */ + if (handle || ((errors > 0) && !file_not_found ())) + { + LT_DLFREE (tmp); + return handle; + } +#endif + + /* Still here? Then we really did fail to locate any of the file + names we tried. */ + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + LT_DLFREE (tmp); + return 0; +} + + +static int +lt_argz_insert (pargz, pargz_len, before, entry) + char **pargz; + size_t *pargz_len; + char *before; + const char *entry; +{ + error_t error; + + /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz, + pargz_len, NULL, entry) failed with EINVAL. */ + if (before) + error = argz_insert (pargz, pargz_len, before, entry); + else + error = argz_append (pargz, pargz_len, entry, 1 + LT_STRLEN (entry)); + + if (error) + { + switch (error) + { + case ENOMEM: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + break; + default: + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN)); + break; + } + return 1; + } + + return 0; +} + +static int +lt_argz_insertinorder (pargz, pargz_len, entry) + char **pargz; + size_t *pargz_len; + const char *entry; +{ + char *before = 0; + + assert (pargz); + assert (pargz_len); + assert (entry && *entry); + + if (*pargz) + while ((before = argz_next (*pargz, *pargz_len, before))) + { + int cmp = strcmp (entry, before); + + if (cmp < 0) break; + if (cmp == 0) return 0; /* No duplicates! */ + } + + return lt_argz_insert (pargz, pargz_len, before, entry); +} + +static int +lt_argz_insertdir (pargz, pargz_len, dirnam, dp) + char **pargz; + size_t *pargz_len; + const char *dirnam; + struct dirent *dp; +{ + char *buf = 0; + size_t buf_len = 0; + char *end = 0; + size_t end_offset = 0; + size_t dir_len = 0; + int errors = 0; + + assert (pargz); + assert (pargz_len); + assert (dp); + + dir_len = LT_STRLEN (dirnam); + end = dp->d_name + LT_D_NAMLEN(dp); + + /* Ignore version numbers. */ + { + char *p; + for (p = end; p -1 > dp->d_name; --p) + if (strchr (".0123456789", p[-1]) == 0) + break; + + if (*p == '.') + end = p; + } + + /* Ignore filename extension. */ + { + char *p; + for (p = end -1; p > dp->d_name; --p) + if (*p == '.') + { + end = p; + break; + } + } + + /* Prepend the directory name. */ + end_offset = end - dp->d_name; + buf_len = dir_len + 1+ end_offset; + buf = LT_EMALLOC (char, 1+ buf_len); + if (!buf) + return ++errors; + + assert (buf); + + strcpy (buf, dirnam); + strcat (buf, "/"); + strncat (buf, dp->d_name, end_offset); + buf[buf_len] = LT_EOS_CHAR; + + /* Try to insert (in order) into ARGZ/ARGZ_LEN. */ + if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0) + ++errors; + + LT_DLFREE (buf); + + return errors; +} + +static int +list_files_by_dir (dirnam, pargz, pargz_len) + const char *dirnam; + char **pargz; + size_t *pargz_len; +{ + DIR *dirp = 0; + int errors = 0; + + assert (dirnam && *dirnam); + assert (pargz); + assert (pargz_len); + assert (dirnam[LT_STRLEN(dirnam) -1] != '/'); + + dirp = opendir (dirnam); + if (dirp) + { + struct dirent *dp = 0; + + while ((dp = readdir (dirp))) + if (dp->d_name[0] != '.') + if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp)) + { + ++errors; + break; + } + + closedir (dirp); + } + else + ++errors; + + return errors; +} + + +/* If there are any files in DIRNAME, call the function passed in + DATA1 (with the name of each file and DATA2 as arguments). */ +static int +foreachfile_callback (dirname, data1, data2) + char *dirname; + lt_ptr data1; + lt_ptr data2; +{ + int (*func) LT_PARAMS((const char *filename, lt_ptr data)) + = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1; + + int is_done = 0; + char *argz = 0; + size_t argz_len = 0; + + if (list_files_by_dir (dirname, &argz, &argz_len) != 0) + goto cleanup; + if (!argz) + goto cleanup; + + { + char *filename = 0; + while ((filename = argz_next (argz, argz_len, filename))) + if ((is_done = (*func) (filename, data2))) + break; + } + + cleanup: + LT_DLFREE (argz); + + return is_done; +} + + +/* Call FUNC for each unique extensionless file in SEARCH_PATH, along + with DATA. The filenames passed to FUNC would be suitable for + passing to lt_dlopenext. The extensions are stripped so that + individual modules do not generate several entries (e.g. libfoo.la, + libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL, + then the same directories that lt_dlopen would search are examined. */ +int +lt_dlforeachfile (search_path, func, data) + const char *search_path; + int (*func) LT_PARAMS ((const char *filename, lt_ptr data)); + lt_ptr data; +{ + int is_done = 0; + + if (search_path) + { + /* If a specific path was passed, search only the directories + listed in it. */ + is_done = foreach_dirinpath (search_path, 0, + foreachfile_callback, func, data); + } + else + { + /* Otherwise search the default paths. */ + is_done = foreach_dirinpath (user_search_path, 0, + foreachfile_callback, func, data); + if (!is_done) + { + is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0, + foreachfile_callback, func, data); + } + +#ifdef LTDL_SHLIBPATH_VAR + if (!is_done) + { + is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0, + foreachfile_callback, func, data); + } +#endif +#ifdef LTDL_SYSSEARCHPATH + if (!is_done) + { + is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0, + foreachfile_callback, func, data); + } +#endif + } + + return is_done; +} + +int +lt_dlclose (handle) + lt_dlhandle handle; +{ + lt_dlhandle cur, last; + int errors = 0; + + LT_DLMUTEX_LOCK (); + + /* check whether the handle is valid */ + last = cur = handles; + while (cur && handle != cur) + { + last = cur; + cur = cur->next; + } + + if (!cur) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + ++errors; + goto done; + } + + handle->info.ref_count--; + + /* Note that even with resident modules, we must track the ref_count + correctly incase the user decides to reset the residency flag + later (even though the API makes no provision for that at the + moment). */ + if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle)) + { + lt_user_data data = handle->loader->dlloader_data; + + if (handle != handles) + { + last->next = handle->next; + } + else + { + handles = handle->next; + } + + errors += handle->loader->module_close (data, handle->module); + errors += unload_deplibs(handle); + + /* It is up to the callers to free the data itself. */ + LT_DLFREE (handle->caller_data); + + LT_DLFREE (handle->info.filename); + LT_DLFREE (handle->info.name); + LT_DLFREE (handle); + + goto done; + } + + if (LT_DLIS_RESIDENT (handle)) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE)); + ++errors; + } + + done: + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +lt_ptr +lt_dlsym (handle, symbol) + lt_dlhandle handle; + const char *symbol; +{ + size_t lensym; + char lsym[LT_SYMBOL_LENGTH]; + char *sym; + lt_ptr address; + lt_user_data data; + + if (!handle) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + return 0; + } + + if (!symbol) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + return 0; + } + + lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix) + + LT_STRLEN (handle->info.name); + + if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH) + { + sym = lsym; + } + else + { + sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1); + if (!sym) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW)); + return 0; + } + } + + data = handle->loader->dlloader_data; + if (handle->info.name) + { + const char *saved_error; + + LT_DLMUTEX_GETERROR (saved_error); + + /* this is a libtool module */ + if (handle->loader->sym_prefix) + { + strcpy(sym, handle->loader->sym_prefix); + strcat(sym, handle->info.name); + } + else + { + strcpy(sym, handle->info.name); + } + + strcat(sym, "_LTX_"); + strcat(sym, symbol); + + /* try "modulename_LTX_symbol" */ + address = handle->loader->find_sym (data, handle->module, sym); + if (address) + { + if (sym != lsym) + { + LT_DLFREE (sym); + } + return address; + } + LT_DLMUTEX_SETERROR (saved_error); + } + + /* otherwise try "symbol" */ + if (handle->loader->sym_prefix) + { + strcpy(sym, handle->loader->sym_prefix); + strcat(sym, symbol); + } + else + { + strcpy(sym, symbol); + } + + address = handle->loader->find_sym (data, handle->module, sym); + if (sym != lsym) + { + LT_DLFREE (sym); + } + + return address; +} + +const char * +lt_dlerror () +{ + const char *error; + + LT_DLMUTEX_GETERROR (error); + LT_DLMUTEX_SETERROR (0); + + return error ? error : NULL; +} + +static int +lt_dlpath_insertdir (ppath, before, dir) + char **ppath; + char *before; + const char *dir; +{ + int errors = 0; + char *canonical = 0; + char *argz = 0; + size_t argz_len = 0; + + assert (ppath); + assert (dir && *dir); + + if (canonicalize_path (dir, &canonical) != 0) + { + ++errors; + goto cleanup; + } + + assert (canonical && *canonical); + + /* If *PPATH is empty, set it to DIR. */ + if (*ppath == 0) + { + assert (!before); /* BEFORE cannot be set without PPATH. */ + assert (dir); /* Without DIR, don't call this function! */ + + *ppath = lt_estrdup (dir); + if (*ppath == 0) + ++errors; + + return errors; + } + + assert (ppath && *ppath); + + if (argzize_path (*ppath, &argz, &argz_len) != 0) + { + ++errors; + goto cleanup; + } + + /* Convert BEFORE into an equivalent offset into ARGZ. This only works + if *PPATH is already canonicalized, and hence does not change length + with respect to ARGZ. We canonicalize each entry as it is added to + the search path, and don't call this function with (uncanonicalized) + user paths, so this is a fair assumption. */ + if (before) + { + assert (*ppath <= before); + assert (before - *ppath <= strlen (*ppath)); + + before = before - *ppath + argz; + } + + if (lt_argz_insert (&argz, &argz_len, before, dir) != 0) + { + ++errors; + goto cleanup; + } + + argz_stringify (argz, argz_len, LT_PATHSEP_CHAR); + LT_DLMEM_REASSIGN (*ppath, argz); + + cleanup: + LT_DLFREE (canonical); + LT_DLFREE (argz); + + return errors; +} + +int +lt_dladdsearchdir (search_dir) + const char *search_dir; +{ + int errors = 0; + + if (search_dir && *search_dir) + { + LT_DLMUTEX_LOCK (); + if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0) + ++errors; + LT_DLMUTEX_UNLOCK (); + } + + return errors; +} + +int +lt_dlinsertsearchdir (before, search_dir) + const char *before; + const char *search_dir; +{ + int errors = 0; + + if (before) + { + LT_DLMUTEX_LOCK (); + if ((before < user_search_path) + || (before >= user_search_path + LT_STRLEN (user_search_path))) + { + LT_DLMUTEX_UNLOCK (); + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION)); + return 1; + } + LT_DLMUTEX_UNLOCK (); + } + + if (search_dir && *search_dir) + { + LT_DLMUTEX_LOCK (); + if (lt_dlpath_insertdir (&user_search_path, + (char *) before, search_dir) != 0) + { + ++errors; + } + LT_DLMUTEX_UNLOCK (); + } + + return errors; +} + +int +lt_dlsetsearchpath (search_path) + const char *search_path; +{ + int errors = 0; + + LT_DLMUTEX_LOCK (); + LT_DLFREE (user_search_path); + LT_DLMUTEX_UNLOCK (); + + if (!search_path || !LT_STRLEN (search_path)) + { + return errors; + } + + LT_DLMUTEX_LOCK (); + if (canonicalize_path (search_path, &user_search_path) != 0) + ++errors; + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +const char * +lt_dlgetsearchpath () +{ + const char *saved_path; + + LT_DLMUTEX_LOCK (); + saved_path = user_search_path; + LT_DLMUTEX_UNLOCK (); + + return saved_path; +} + +int +lt_dlmakeresident (handle) + lt_dlhandle handle; +{ + int errors = 0; + + if (!handle) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + ++errors; + } + else + { + LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG); + } + + return errors; +} + +int +lt_dlisresident (handle) + lt_dlhandle handle; +{ + if (!handle) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + return -1; + } + + return LT_DLIS_RESIDENT (handle); +} + + + + +/* --- MODULE INFORMATION --- */ + +const lt_dlinfo * +lt_dlgetinfo (handle) + lt_dlhandle handle; +{ + if (!handle) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + return 0; + } + + return &(handle->info); +} + +lt_dlhandle +lt_dlhandle_next (place) + lt_dlhandle place; +{ + return place ? place->next : handles; +} + +int +lt_dlforeach (func, data) + int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data)); + lt_ptr data; +{ + int errors = 0; + lt_dlhandle cur; + + LT_DLMUTEX_LOCK (); + + cur = handles; + while (cur) + { + lt_dlhandle tmp = cur; + + cur = cur->next; + if ((*func) (tmp, data)) + { + ++errors; + break; + } + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +lt_dlcaller_id +lt_dlcaller_register () +{ + static lt_dlcaller_id last_caller_id = 0; + int result; + + LT_DLMUTEX_LOCK (); + result = ++last_caller_id; + LT_DLMUTEX_UNLOCK (); + + return result; +} + +lt_ptr +lt_dlcaller_set_data (key, handle, data) + lt_dlcaller_id key; + lt_dlhandle handle; + lt_ptr data; +{ + int n_elements = 0; + lt_ptr stale = (lt_ptr) 0; + int i; + + /* This needs to be locked so that the caller data can be updated + simultaneously by different threads. */ + LT_DLMUTEX_LOCK (); + + if (handle->caller_data) + while (handle->caller_data[n_elements].key) + ++n_elements; + + for (i = 0; i < n_elements; ++i) + { + if (handle->caller_data[i].key == key) + { + stale = handle->caller_data[i].data; + break; + } + } + + /* Ensure that there is enough room in this handle's caller_data + array to accept a new element (and an empty end marker). */ + if (i == n_elements) + { + lt_caller_data *temp + = LT_DLREALLOC (lt_caller_data, handle->caller_data, 2+ n_elements); + + if (!temp) + { + stale = 0; + goto done; + } + + handle->caller_data = temp; + + /* We only need this if we needed to allocate a new caller_data. */ + handle->caller_data[i].key = key; + handle->caller_data[1+ i].key = 0; + } + + handle->caller_data[i].data = data; + + done: + LT_DLMUTEX_UNLOCK (); + + return stale; +} + +lt_ptr +lt_dlcaller_get_data (key, handle) + lt_dlcaller_id key; + lt_dlhandle handle; +{ + lt_ptr result = (lt_ptr) 0; + + /* This needs to be locked so that the caller data isn't updated by + another thread part way through this function. */ + LT_DLMUTEX_LOCK (); + + /* Locate the index of the element with a matching KEY. */ + { + int i; + for (i = 0; handle->caller_data[i].key; ++i) + { + if (handle->caller_data[i].key == key) + { + result = handle->caller_data[i].data; + break; + } + } + } + + LT_DLMUTEX_UNLOCK (); + + return result; +} + + + +/* --- USER MODULE LOADER API --- */ + + +int +lt_dlloader_add (place, dlloader, loader_name) + lt_dlloader *place; + const struct lt_user_dlloader *dlloader; + const char *loader_name; +{ + int errors = 0; + lt_dlloader *node = 0, *ptr = 0; + + if ((dlloader == 0) /* diagnose null parameters */ + || (dlloader->module_open == 0) + || (dlloader->module_close == 0) + || (dlloader->find_sym == 0)) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + return 1; + } + + /* Create a new dlloader node with copies of the user callbacks. */ + node = LT_EMALLOC (lt_dlloader, 1); + if (!node) + return 1; + + node->next = 0; + node->loader_name = loader_name; + node->sym_prefix = dlloader->sym_prefix; + node->dlloader_exit = dlloader->dlloader_exit; + node->module_open = dlloader->module_open; + node->module_close = dlloader->module_close; + node->find_sym = dlloader->find_sym; + node->dlloader_data = dlloader->dlloader_data; + + LT_DLMUTEX_LOCK (); + if (!loaders) + { + /* If there are no loaders, NODE becomes the list! */ + loaders = node; + } + else if (!place) + { + /* If PLACE is not set, add NODE to the end of the + LOADERS list. */ + for (ptr = loaders; ptr->next; ptr = ptr->next) + { + /*NOWORK*/; + } + + ptr->next = node; + } + else if (loaders == place) + { + /* If PLACE is the first loader, NODE goes first. */ + node->next = place; + loaders = node; + } + else + { + /* Find the node immediately preceding PLACE. */ + for (ptr = loaders; ptr->next != place; ptr = ptr->next) + { + /*NOWORK*/; + } + + if (ptr->next != place) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + ++errors; + } + else + { + /* Insert NODE between PTR and PLACE. */ + node->next = place; + ptr->next = node; + } + } + + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +int +lt_dlloader_remove (loader_name) + const char *loader_name; +{ + lt_dlloader *place = lt_dlloader_find (loader_name); + lt_dlhandle handle; + int errors = 0; + + if (!place) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + return 1; + } + + LT_DLMUTEX_LOCK (); + + /* Fail if there are any open modules which use this loader. */ + for (handle = handles; handle; handle = handle->next) + { + if (handle->loader == place) + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER)); + ++errors; + goto done; + } + } + + if (place == loaders) + { + /* PLACE is the first loader in the list. */ + loaders = loaders->next; + } + else + { + /* Find the loader before the one being removed. */ + lt_dlloader *prev; + for (prev = loaders; prev->next; prev = prev->next) + { + if (!strcmp (prev->next->loader_name, loader_name)) + { + break; + } + } + + place = prev->next; + prev->next = prev->next->next; + } + + if (place->dlloader_exit) + { + errors = place->dlloader_exit (place->dlloader_data); + } + + LT_DLFREE (place); + + done: + LT_DLMUTEX_UNLOCK (); + + return errors; +} + +lt_dlloader * +lt_dlloader_next (place) + lt_dlloader *place; +{ + lt_dlloader *next; + + LT_DLMUTEX_LOCK (); + next = place ? place->next : loaders; + LT_DLMUTEX_UNLOCK (); + + return next; +} + +const char * +lt_dlloader_name (place) + lt_dlloader *place; +{ + const char *name = 0; + + if (place) + { + LT_DLMUTEX_LOCK (); + name = place ? place->loader_name : 0; + LT_DLMUTEX_UNLOCK (); + } + else + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + } + + return name; +} + +lt_user_data * +lt_dlloader_data (place) + lt_dlloader *place; +{ + lt_user_data *data = 0; + + if (place) + { + LT_DLMUTEX_LOCK (); + data = place ? &(place->dlloader_data) : 0; + LT_DLMUTEX_UNLOCK (); + } + else + { + LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + } + + return data; +} + +lt_dlloader * +lt_dlloader_find (loader_name) + const char *loader_name; +{ + lt_dlloader *place = 0; + + LT_DLMUTEX_LOCK (); + for (place = loaders; place; place = place->next) + { + if (strcmp (place->loader_name, loader_name) == 0) + { + break; + } + } + LT_DLMUTEX_UNLOCK (); + + return place; +} diff --git a/libltdl/ltdl.h b/libltdl/ltdl.h new file mode 100644 index 00000000..a180245b --- /dev/null +++ b/libltdl/ltdl.h @@ -0,0 +1,367 @@ +/* ltdl.h -- generic dlopen functions + Copyright (C) 1998-2001, 2003, 2004, 2007 Free Software Foundation, Inc. + Originally by Thomas Tanner + This file is part of GNU Libtool. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU libtool, you may include it under the same +distribution terms that you use for the rest of that program. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free +Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA +*/ + +/* Only include this header file once. */ +#ifndef LTDL_H +#define LTDL_H 1 + +#include /* for size_t declaration */ + + +/* --- MACROS FOR PORTABILITY --- */ + + +/* Saves on those hard to debug '\0' typos.... */ +#define LT_EOS_CHAR '\0' + +/* LTDL_BEGIN_C_DECLS should be used at the beginning of your declarations, + so that C++ compilers don't mangle their names. Use LTDL_END_C_DECLS at + the end of C declarations. */ +#ifdef __cplusplus +# define LT_BEGIN_C_DECLS extern "C" { +# define LT_END_C_DECLS } +#else +# define LT_BEGIN_C_DECLS /* empty */ +# define LT_END_C_DECLS /* empty */ +#endif + +LT_BEGIN_C_DECLS + + +/* LT_PARAMS is a macro used to wrap function prototypes, so that compilers + that don't understand ANSI C prototypes still work, and ANSI C + compilers can issue warnings about type mismatches. */ +#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32) || defined(__cplusplus) +# define LT_PARAMS(protos) protos +# define lt_ptr void* +#else +# define LT_PARAMS(protos) () +# define lt_ptr char* +#endif + +/* LT_STMT_START/END are used to create macros which expand to a + a single compound statement in a portable way. */ +#if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus) +# define LT_STMT_START (void)( +# define LT_STMT_END ) +#else +# if (defined (sun) || defined (__sun__)) +# define LT_STMT_START if (1) +# define LT_STMT_END else (void)0 +# else +# define LT_STMT_START do +# define LT_STMT_END while (0) +# endif +#endif + +/* LT_CONC creates a new concatenated symbol for the compiler + in a portable way. */ +#if defined(__STDC__) || defined(__cplusplus) || defined(_MSC_VER) || defined(_AIX) +# define LT_CONC(s,t) s##t +#else +# define LT_CONC(s,t) s/**/t +#endif + +/* LT_STRLEN can be used safely on NULL pointers. */ +#define LT_STRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0) + + + +/* --- WINDOWS SUPPORT --- */ + + +/* Canonicalise Windows and Cygwin recognition macros. */ +#ifdef __CYGWIN32__ +# ifndef __CYGWIN__ +# define __CYGWIN__ __CYGWIN32__ +# endif +#endif +#if defined(_WIN32) || defined(WIN32) +# ifndef __WINDOWS__ +# ifdef _WIN32 +# define __WINDOWS__ _WIN32 +# else +# ifdef WIN32 +# define __WINDOWS__ WIN32 +# endif +# endif +# endif +#endif + + +#ifdef __WINDOWS__ +# ifndef __CYGWIN__ +/* LT_DIRSEP_CHAR is accepted *in addition* to '/' as a directory + separator when it is set. */ +# define LT_DIRSEP_CHAR '\\' +# define LT_PATHSEP_CHAR ';' +# endif +#endif +#ifndef LT_PATHSEP_CHAR +# define LT_PATHSEP_CHAR ':' +#endif + +/* DLL building support on win32 hosts; mostly to workaround their + ridiculous implementation of data symbol exporting. */ +#ifndef LT_SCOPE +# if defined(__WINDOWS__) || defined(__CYGWIN__) +# ifdef DLL_EXPORT /* defined by libtool (if required) */ +# define LT_SCOPE __declspec(dllexport) +# endif +# ifdef LIBLTDL_DLL_IMPORT /* define if linking with this dll */ + /* note: cygwin/mingw compilers can rely instead on auto-import */ +# define LT_SCOPE extern __declspec(dllimport) +# endif +# endif +# ifndef LT_SCOPE /* static linking or !__WINDOWS__ */ +# define LT_SCOPE extern +# endif +#endif + + +#if defined(_MSC_VER) /* Visual Studio */ +# define R_OK 4 +#endif + + + +/* --- DYNAMIC MODULE LOADING API --- */ + + +typedef struct lt_dlhandle_struct *lt_dlhandle; /* A loaded module. */ + +/* Initialisation and finalisation functions for libltdl. */ +LT_SCOPE int lt_dlinit LT_PARAMS((void)); +LT_SCOPE int lt_dlexit LT_PARAMS((void)); + +/* Module search path manipulation. */ +LT_SCOPE int lt_dladdsearchdir LT_PARAMS((const char *search_dir)); +LT_SCOPE int lt_dlinsertsearchdir LT_PARAMS((const char *before, + const char *search_dir)); +LT_SCOPE int lt_dlsetsearchpath LT_PARAMS((const char *search_path)); +LT_SCOPE const char *lt_dlgetsearchpath LT_PARAMS((void)); +LT_SCOPE int lt_dlforeachfile LT_PARAMS(( + const char *search_path, + int (*func) (const char *filename, lt_ptr data), + lt_ptr data)); + +/* Portable libltdl versions of the system dlopen() API. */ +LT_SCOPE lt_dlhandle lt_dlopen LT_PARAMS((const char *filename)); +LT_SCOPE lt_dlhandle lt_dlopenext LT_PARAMS((const char *filename)); +LT_SCOPE lt_ptr lt_dlsym LT_PARAMS((lt_dlhandle handle, + const char *name)); +LT_SCOPE const char *lt_dlerror LT_PARAMS((void)); +LT_SCOPE int lt_dlclose LT_PARAMS((lt_dlhandle handle)); + +/* Module residency management. */ +LT_SCOPE int lt_dlmakeresident LT_PARAMS((lt_dlhandle handle)); +LT_SCOPE int lt_dlisresident LT_PARAMS((lt_dlhandle handle)); + + + + +/* --- MUTEX LOCKING --- */ + + +typedef void lt_dlmutex_lock LT_PARAMS((void)); +typedef void lt_dlmutex_unlock LT_PARAMS((void)); +typedef void lt_dlmutex_seterror LT_PARAMS((const char *errmsg)); +typedef const char *lt_dlmutex_geterror LT_PARAMS((void)); + +LT_SCOPE int lt_dlmutex_register LT_PARAMS((lt_dlmutex_lock *lock, + lt_dlmutex_unlock *unlock, + lt_dlmutex_seterror *seterror, + lt_dlmutex_geterror *geterror)); + + + + +/* --- MEMORY HANDLING --- */ + + +/* By default, the realloc function pointer is set to our internal + realloc implementation which iself uses lt_dlmalloc and lt_dlfree. + libltdl relies on a featureful realloc, but if you are sure yours + has the right semantics then you can assign it directly. Generally, + it is safe to assign just a malloc() and a free() function. */ +LT_SCOPE lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size)); +LT_SCOPE lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size)); +LT_SCOPE void (*lt_dlfree) LT_PARAMS((lt_ptr ptr)); + + + + +/* --- PRELOADED MODULE SUPPORT --- */ + + +/* A preopened symbol. Arrays of this type comprise the exported + symbols for a dlpreopened module. */ +typedef struct { + const char *name; + lt_ptr address; +} lt_dlsymlist; + +LT_SCOPE int lt_dlpreload LT_PARAMS((const lt_dlsymlist *preloaded)); +LT_SCOPE int lt_dlpreload_default + LT_PARAMS((const lt_dlsymlist *preloaded)); + +#define LTDL_SET_PRELOADED_SYMBOLS() LT_STMT_START{ \ + extern const lt_dlsymlist lt_preloaded_symbols[]; \ + lt_dlpreload_default(lt_preloaded_symbols); \ + }LT_STMT_END + + + + +/* --- MODULE INFORMATION --- */ + + +/* Read only information pertaining to a loaded module. */ +typedef struct { + char *filename; /* file name */ + char *name; /* module name */ + int ref_count; /* number of times lt_dlopened minus + number of times lt_dlclosed. */ +} lt_dlinfo; + +LT_SCOPE const lt_dlinfo *lt_dlgetinfo LT_PARAMS((lt_dlhandle handle)); +LT_SCOPE lt_dlhandle lt_dlhandle_next LT_PARAMS((lt_dlhandle place)); +LT_SCOPE int lt_dlforeach LT_PARAMS(( + int (*func) (lt_dlhandle handle, lt_ptr data), + lt_ptr data)); + +/* Associating user data with loaded modules. */ +typedef unsigned lt_dlcaller_id; + +LT_SCOPE lt_dlcaller_id lt_dlcaller_register LT_PARAMS((void)); +LT_SCOPE lt_ptr lt_dlcaller_set_data LT_PARAMS((lt_dlcaller_id key, + lt_dlhandle handle, + lt_ptr data)); +LT_SCOPE lt_ptr lt_dlcaller_get_data LT_PARAMS((lt_dlcaller_id key, + lt_dlhandle handle)); + + + +/* --- USER MODULE LOADER API --- */ + + +typedef struct lt_dlloader lt_dlloader; +typedef lt_ptr lt_user_data; +typedef lt_ptr lt_module; + +/* Function pointer types for creating user defined module loaders. */ +typedef lt_module lt_module_open LT_PARAMS((lt_user_data loader_data, + const char *filename)); +typedef int lt_module_close LT_PARAMS((lt_user_data loader_data, + lt_module handle)); +typedef lt_ptr lt_find_sym LT_PARAMS((lt_user_data loader_data, + lt_module handle, + const char *symbol)); +typedef int lt_dlloader_exit LT_PARAMS((lt_user_data loader_data)); + +struct lt_user_dlloader { + const char *sym_prefix; + lt_module_open *module_open; + lt_module_close *module_close; + lt_find_sym *find_sym; + lt_dlloader_exit *dlloader_exit; + lt_user_data dlloader_data; +}; + +LT_SCOPE lt_dlloader *lt_dlloader_next LT_PARAMS((lt_dlloader *place)); +LT_SCOPE lt_dlloader *lt_dlloader_find LT_PARAMS(( + const char *loader_name)); +LT_SCOPE const char *lt_dlloader_name LT_PARAMS((lt_dlloader *place)); +LT_SCOPE lt_user_data *lt_dlloader_data LT_PARAMS((lt_dlloader *place)); +LT_SCOPE int lt_dlloader_add LT_PARAMS((lt_dlloader *place, + const struct lt_user_dlloader *dlloader, + const char *loader_name)); +LT_SCOPE int lt_dlloader_remove LT_PARAMS(( + const char *loader_name)); + + + +/* --- ERROR MESSAGE HANDLING --- */ + + +/* Defining error strings alongside their symbolic names in a macro in + this way allows us to expand the macro in different contexts with + confidence that the enumeration of symbolic names will map correctly + onto the table of error strings. */ +#define lt_dlerror_table \ + LT_ERROR(UNKNOWN, "unknown error") \ + LT_ERROR(DLOPEN_NOT_SUPPORTED, "dlopen support not available") \ + LT_ERROR(INVALID_LOADER, "invalid loader") \ + LT_ERROR(INIT_LOADER, "loader initialization failed") \ + LT_ERROR(REMOVE_LOADER, "loader removal failed") \ + LT_ERROR(FILE_NOT_FOUND, "file not found") \ + LT_ERROR(DEPLIB_NOT_FOUND, "dependency library not found") \ + LT_ERROR(NO_SYMBOLS, "no symbols defined") \ + LT_ERROR(CANNOT_OPEN, "can't open the module") \ + LT_ERROR(CANNOT_CLOSE, "can't close the module") \ + LT_ERROR(SYMBOL_NOT_FOUND, "symbol not found") \ + LT_ERROR(NO_MEMORY, "not enough memory") \ + LT_ERROR(INVALID_HANDLE, "invalid module handle") \ + LT_ERROR(BUFFER_OVERFLOW, "internal buffer overflow") \ + LT_ERROR(INVALID_ERRORCODE, "invalid errorcode") \ + LT_ERROR(SHUTDOWN, "library already shutdown") \ + LT_ERROR(CLOSE_RESIDENT_MODULE, "can't close resident module") \ + LT_ERROR(INVALID_MUTEX_ARGS, "invalid mutex handler registration") \ + LT_ERROR(INVALID_POSITION, "invalid search path insert position") + +/* Enumerate the symbolic error names. */ +enum { +#define LT_ERROR(name, diagnostic) LT_CONC(LT_ERROR_, name), + lt_dlerror_table +#undef LT_ERROR + + LT_ERROR_MAX +}; + +/* These functions are only useful from inside custom module loaders. */ +LT_SCOPE int lt_dladderror LT_PARAMS((const char *diagnostic)); +LT_SCOPE int lt_dlseterror LT_PARAMS((int errorcode)); + + + + +/* --- SOURCE COMPATIBILITY WITH OLD LIBLTDL --- */ + + +#ifdef LT_NON_POSIX_NAMESPACE +# define lt_ptr_t lt_ptr +# define lt_module_t lt_module +# define lt_module_open_t lt_module_open +# define lt_module_close_t lt_module_close +# define lt_find_sym_t lt_find_sym +# define lt_dlloader_exit_t lt_dlloader_exit +# define lt_dlloader_t lt_dlloader +# define lt_dlloader_data_t lt_user_data +#endif + +LT_END_C_DECLS + +#endif /* !LTDL_H */ diff --git a/libltdl/ltmain.sh b/libltdl/ltmain.sh new file mode 100644 index 00000000..8e5a9304 --- /dev/null +++ b/libltdl/ltmain.sh @@ -0,0 +1,6930 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun configure. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +# 2007 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +basename="s,^.*/,,g" + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + +# The name of this program: +progname=`echo "$progpath" | $SED $basename` +modename="$progname" + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 + +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION=1.5.24 +TIMESTAMP=" (1.1220.2.456 2007/06/24 02:25:32)" + +# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$progpath" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +duplicate_deps=no +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +##################################### +# Shell function definitions: +# This seems to be the best place for them + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $mkdir "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || { + $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2 + exit $EXIT_FAILURE + } + fi + + $echo "X$my_tmpdir" | $Xsed +} + + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +func_win32_libid () +{ + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ + $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | \ + $SED -n -e '1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $echo $win32_libid_type +} + + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case "$@ " in + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + $echo "$modename: unable to infer tagged configuration" + $echo "$modename: specify a tag with \`--tag'" 1>&2 + exit $EXIT_FAILURE +# else +# $echo "$modename: using $tagname tagged configuration" + fi + ;; + esac + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + + $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" + $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $? + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 + exit $EXIT_FAILURE + fi +} + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + my_status="" + + $show "${rm}r $my_gentop" + $run ${rm}r "$my_gentop" + $show "$mkdir $my_gentop" + $run $mkdir "$my_gentop" + my_status=$? + if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then + exit $my_status + fi + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + extracted_serial=`expr $extracted_serial + 1` + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + $show "${rm}r $my_xdir" + $run ${rm}r "$my_xdir" + $show "$mkdir $my_xdir" + $run $mkdir "$my_xdir" + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then + exit $exit_status + fi + case $host in + *-darwin*) + $show "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + if test -z "$run"; then + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` + darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` + if test -n "$darwin_arches"; then + darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + $show "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we have a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` + lipo -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + ${rm}r unfat-$$ + cd "$darwin_orig_dir" + else + cd "$darwin_orig_dir" + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + fi # $run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + func_extract_archives_result="$my_oldobjs" +} +# End of Shell function definitions +##################################### + +# Darwin sucks +eval std_shrext=\"$shrext_cmds\" + +disable_libs=no + +# Parse our command line options once, thoroughly. +while test "$#" -gt 0 +do + arg="$1" + shift + + case $arg in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + execute_dlfiles) + execute_dlfiles="$execute_dlfiles $arg" + ;; + tag) + tagname="$arg" + preserve_args="${preserve_args}=$arg" + + # Check whether tagname contains only valid characters + case $tagname in + *[!-_A-Za-z0-9,/]*) + $echo "$progname: invalid tag name: $tagname" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $tagname in + CC) + # Don't test for the "default" C tag, as we know, it's there, but + # not specially marked. + ;; + *) + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then + taglist="$taglist $tagname" + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" + else + $echo "$progname: ignoring unknown tag $tagname" 1>&2 + fi + ;; + esac + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case $arg in + --help) + show_help=yes + ;; + + --version) + echo "\ +$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP + +Copyright (C) 2007 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + exit $? + ;; + + --config) + ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath + # Now print the configurations for the tags. + for tagname in $taglist; do + ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" + done + exit $? + ;; + + --debug) + $echo "$progname: enabling shell trace mode" + set -x + preserve_args="$preserve_args $arg" + ;; + + --dry-run | -n) + run=: + ;; + + --features) + $echo "host: $host" + if test "$build_libtool_libs" = yes; then + $echo "enable shared libraries" + else + $echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + $echo "enable static libraries" + else + $echo "disable static libraries" + fi + exit $? + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --preserve-dup-deps) duplicate_deps="yes" ;; + + --quiet | --silent) + show=: + preserve_args="$preserve_args $arg" + ;; + + --tag) + prevopt="--tag" + prev=tag + preserve_args="$preserve_args --tag" + ;; + --tag=*) + set tag "$optarg" ${1+"$@"} + shift + prev=tag + preserve_args="$preserve_args --tag" + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE +fi + +case $disable_libs in +no) + ;; +shared) + build_libtool_libs=no + build_old_libs=yes + ;; +static) + build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` + ;; +esac + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 + $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 + case $nonopt in + *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) + mode=link + for arg + do + case $arg in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case $mode in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + if test -n "$libobj" ; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit $EXIT_FAILURE + fi + arg_mode=target + continue + ;; + + -static | -prefer-pic | -prefer-non-pic) + later="$later $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + base_compile="$base_compile $lastarg" + continue + ;; + + * ) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + case $lastarg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, and some SunOS ksh mistreat backslash-escaping + # in scan sets (worked around with variable expansion), + # and furthermore cannot handle '|' '&' '(' ')' in scan sets + # at all, so we specify them separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + lastarg="\"$lastarg\"" + ;; + esac + + base_compile="$base_compile $lastarg" + done # for arg + + case $arg_mode in + arg) + $echo "$modename: you must specify an argument for -Xcompile" + exit $EXIT_FAILURE + ;; + target) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit $EXIT_FAILURE + ;; + *) + # Get the name of the library object. + [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSifmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.ii) xform=ii ;; + *.class) xform=class ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.[fF][09]?) xform=[fF][09]. ;; + *.for) xform=for ;; + *.java) xform=java ;; + *.obj) xform=obj ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case $libobj in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -static) + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` + case $qlibobj in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qlibobj="\"$qlibobj\"" ;; + esac + test "X$libobj" != "X$qlibobj" \ + && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && $echo "$modename: libobj name \`$libobj' may not contain shell special characters." + objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir= + else + xdir=$xdir/ + fi + lobj=${xdir}$objdir/$objname + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $run ln "$progpath" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + $echo "$srcfile" > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` + case $qsrcfile in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qsrcfile="\"$qsrcfile\"" ;; + esac + + $run $rm "$libobj" "${libobj}T" + + # Create a libtool object file (analogous to a ".la" file), + # but don't create it if we're doing a dry run. + test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + $show "$mv $output_obj $lobj" + if $run $mv $output_obj $lobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the PIC object to the libtool object file. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the non-PIC object the libtool object file. + # Only append if the libtool object file exists. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit $EXIT_FAILURE + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat $save_arg` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + done + else + $echo "$modename: link input file \`$save_arg' does not exist" + exit $EXIT_FAILURE + fi + arg=$save_arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + darwin_framework|darwin_framework_skip) + test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + prev= + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: more than one -exported-symbols argument is not allowed" + exit $EXIT_FAILURE + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework|-arch|-isysroot) + case " $CC " in + *" ${arg} ${1} "* | *" ${arg} ${1} "*) + prev=darwin_framework_skip ;; + *) compiler_flags="$compiler_flags $arg" + prev=darwin_framework ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + notinst_path="$notinst_path $dir" + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs -framework System" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + -model) + compile_command="$compile_command $arg" + compiler_flags="$compiler_flags $arg" + finalize_command="$finalize_command $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + compiler_flags="$compiler_flags $arg" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # -64, -mips[0-9] enable 64-bit mode on the SGI compiler + # -r[0-9][0-9]* specifies the processor on the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler + # +DA*, +DD* enable 64-bit mode on the HP compiler + # -q* pass through compiler args for the IBM compiler + # -m* pass through architecture-specific compiler args for GCC + # -m*, -t[45]*, -txscale* pass through architecture-specific + # compiler args for GCC + # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC + # -F/path gives path to uninstalled frameworks, gcc on darwin + # @file GCC response files + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*) + + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + compiler_flags="$compiler_flags $arg" + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done # argument parsing loop + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d "$output_objdir"; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then + exit $exit_status + fi + fi + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + case $host in + *cygwin* | *mingw* | *pw32*) + # don't eliminate duplications in $postdeps and $predeps + duplicate_compiler_generated_deps=yes + ;; + *) + duplicate_compiler_generated_deps=$duplicate_deps + ;; + esac + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if test "X$duplicate_deps" = "Xyes" ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + compiler_flags="$compiler_flags $deplib" + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if (${SED} -e '2q' $lib | + grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + library_names= + old_library= + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + if eval $echo \"$deplib\" 2>/dev/null \ + | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + $echo + $echo "*** Warning: Trying to link with static lib archive $deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because the file extensions .$libext of this argument makes me believe" + $echo "*** that it is just a static archive that I should not used here." + else + $echo + $echo "*** Warning: Linking the shared library $output against the" + $echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test "$found" = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2 + exit $EXIT_FAILURE + fi + + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit $EXIT_FAILURE + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $absdir" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes ; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + # This is a shared library + + # Warn about portability, can't link against -module's on + # some systems (darwin) + if test "$shouldnotlink" = yes && test "$pass" = link ; then + $echo + if test "$linkmode" = prog; then + $echo "*** Warning: Linking the executable $output against the loadable module" + else + $echo "*** Warning: Linking the shared library $output against the loadable module" + fi + $echo "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`$echo $soroot | ${SED} -e 's/^.*\///'` + newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$extract_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$old_archive_from_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a module then we can not link against + # it, someone is ignoring the new warnings I added + if /usr/bin/file -L $add 2> /dev/null | + $EGREP ": [^:]* bundle" >/dev/null ; then + $echo "** Warning, lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + $echo + $echo "** And there doesn't seem to be a static archive available" + $echo "** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit $EXIT_FAILURE + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + $echo + $echo "*** Warning: This system can not link to static lib archive $lib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + $echo "*** But as you try to build a module library, libtool will still create " + $echo "*** a static module, that should work as long as the dlopening application" + $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="$absdir/$objdir" + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="$absdir" + fi + depdepl= + case $host in + *-*-darwin*) + # we do not want to link against static libs, + # but need to link against shared + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$path/$depdepl" ; then + depdepl="$path/$depdepl" + fi + # do not add paths which are already there + case " $newlib_search_path " in + *" $path "*) ;; + *) newlib_search_path="$newlib_search_path $path";; + esac + fi + path="" + ;; + *) + path="-L$path" + ;; + esac + ;; + -l*) + case $host in + *-*-darwin*) + # Again, we only want to link against shared libraries + eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` + for tmp in $newlib_search_path ; do + if test -f "$tmp/lib$tmp_libs.dylib" ; then + eval depdepl="$tmp/lib$tmp_libs.dylib" + break + fi + done + path="" + ;; + *) continue ;; + esac + ;; + *) continue ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + case " $deplibs " in + *" $depdepl "*) ;; + *) deplibs="$depdepl $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit $EXIT_FAILURE + else + $echo + $echo "*** Warning: Linking the shared library $output against the non-libtool" + $echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test "$#" -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$2" + number_minor="$3" + number_revision="$4" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows|none) + current=`expr $number_major + $number_minor` + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + current=`expr $number_major + $number_minor` + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + esac + ;; + no) + current="$2" + revision="$3" + age="$4" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test "$age" -gt "$current"; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + major=`expr $current - $age` + else + major=`expr $current - $age + 1` + fi + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=.`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + fi + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$echo "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + removelist="$removelist $p" + ;; + *) ;; + esac + done + if test -n "$removelist"; then + $show "${rm}r $removelist" + $run ${rm}r $removelist + fi + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"` + # deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"` + # dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for file magic test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a file magic. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name=`expr $a_deplib : '-l\(.*\)'` + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval $echo \"$potent_lib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a regex pattern. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` + done + fi + if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ + | grep . >/dev/null; then + $echo + if test "X$deplibs_check_method" = "Xnone"; then + $echo "*** Warning: inter-library dependencies are not supported in this platform." + else + $echo "*** Warning: inter-library dependencies are not known to be supported." + fi + $echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + $echo + $echo "*** Warning: libtool could not satisfy all declared inter-library" + $echo "*** dependencies of module $libname. Therefore, libtool will create" + $echo "*** a static module, that should work as long as the dlopening" + $echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + $echo "*** The inter-library dependencies that have been dropped here will be" + $echo "*** automatically added whenever a program is linked with this library" + $echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + $echo + $echo "*** Since this library must not contain undefined symbols," + $echo "*** because either the platform does not support them or" + $echo "*** it was explicitly requested with -no-undefined," + $echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + deplibs="$new_libs" + + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + case $archive_cmds in + *\$LD*) eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" ;; + *) eval dep_rpath=\"$hardcode_libdir_flag_spec\" ;; + esac + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + if len=`expr "X$cmd" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + $show "$cmd" + $run eval "$cmd" || exit $? + skipped_export=false + else + # The command line is too long to execute in one step. + $show "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + libobjs="$libobjs $func_extract_archives_result" + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise. + $echo "creating reloadable object files..." + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + output_la=`$echo "X$output" | $Xsed -e "$basename"` + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + delfiles= + last_robj= + k=1 + output=$output_objdir/$output_la-${k}.$objext + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + eval test_cmds=\"$reload_cmds $objlist $last_robj\" + if test "X$objlist" = X || + { len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len"; }; then + objlist="$objlist $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + k=`expr $k + 1` + output=$output_objdir/$output_la-${k}.$objext + objlist=$obj + len=1 + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + + if ${skipped_export-false}; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + libobjs=$output + # Append the command to create the export file. + eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" + fi + + # Set up a command to remove the reloadable object files + # after they are used. + i=0 + while test "$i" -lt "$k" + do + i=`expr $i + 1` + delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" + done + + $echo "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + + # Append the command to remove the reloadable object files + # to the just-reset $cmds. + eval cmds=\"\$cmds~\$rm $delfiles\" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case $output in + *.lo) + if test -n "$objs$old_deplibs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit $EXIT_FAILURE + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$echo "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $run eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; + esac + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + case $host in + *darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + if test "$tagname" = CXX ; then + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + fi + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + new_libs="$new_libs -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$new_libs $deplib" ;; + esac + ;; + *) new_libs="$new_libs $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + *) dllsearchpath="$dllsearchpath:$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case $dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $run $rm $export_symbols + $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* ) + $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + $run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + else + $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* ) + $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + $run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` + $run eval '$echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + $echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +" + + case $host in + *cygwin* | *mingw* ) + $echo >> "$output_objdir/$dlsyms" "\ +/* DATA imports from DLLs on WIN32 can't be const, because + runtime relocations are performed -- see ld's documentation + on pseudo-relocs */ +struct { +" + ;; + * ) + $echo >> "$output_objdir/$dlsyms" "\ +const struct { +" + ;; + esac + + + $echo >> "$output_objdir/$dlsyms" "\ + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[] = +{\ +" + + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + case $host in + *cygwin* | *mingw* ) + if test -f "$output_objdir/${outputname}.def" ; then + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` + else + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + fi + ;; + * ) + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` + ;; + esac + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` + fi + + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$output"'%g' | $NL2SP` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + exit_status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $exit_status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $SP2NL | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g' | $NL2SP` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then + case $progpath in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; + *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + output_name=`basename $output` + output_path=`dirname $output` + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $rm $cwrappersource $cwrapper + trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + cat > $cwrappersource <> $cwrappersource<<"EOF" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +/* -DDEBUG is fairly common in CFLAGS. */ +#undef DEBUG +#if defined DEBUGWRAPPER +# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__) +#else +# define DEBUG(format, ...) +#endif + +const char *program_name = NULL; + +void * xmalloc (size_t num); +char * xstrdup (const char *string); +const char * base_name (const char *name); +char * find_executable(const char *wrapper); +int check_executable(const char *path); +char * strendzap(char *str, const char *pat); +void lt_fatal (const char *message, ...); + +int +main (int argc, char *argv[]) +{ + char **newargz; + int i; + + program_name = (char *) xstrdup (base_name (argv[0])); + DEBUG("(main) argv[0] : %s\n",argv[0]); + DEBUG("(main) program_name : %s\n",program_name); + newargz = XMALLOC(char *, argc+2); +EOF + + cat >> $cwrappersource <> $cwrappersource <<"EOF" + newargz[1] = find_executable(argv[0]); + if (newargz[1] == NULL) + lt_fatal("Couldn't find %s", argv[0]); + DEBUG("(main) found exe at : %s\n",newargz[1]); + /* we know the script has the same name, without the .exe */ + /* so make sure newargz[1] doesn't end in .exe */ + strendzap(newargz[1],".exe"); + for (i = 1; i < argc; i++) + newargz[i+1] = xstrdup(argv[i]); + newargz[argc+1] = NULL; + + for (i=0; i> $cwrappersource <> $cwrappersource <> $cwrappersource <<"EOF" + return 127; +} + +void * +xmalloc (size_t num) +{ + void * p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL +; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char)name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable(const char * path) +{ + struct stat st; + + DEBUG("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!"); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) && + ( + /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */ +#if defined (S_IXOTH) + ((st.st_mode & S_IXOTH) == S_IXOTH) || +#endif +#if defined (S_IXGRP) + ((st.st_mode & S_IXGRP) == S_IXGRP) || +#endif + ((st.st_mode & S_IXUSR) == S_IXUSR)) + ) + return 1; + else + return 0; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise */ +char * +find_executable (const char* wrapper) +{ + int has_slash = 0; + const char* p; + const char* p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char* concat_name; + + DEBUG("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char* path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char* q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR(*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen(tmp); + concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + tmp_len = strlen(tmp); + concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable(concat_name)) + return concat_name; + XFREE(concat_name); + return NULL; +} + +char * +strendzap(char *str, const char *pat) +{ + size_t len, patlen; + + assert(str != NULL); + assert(pat != NULL); + + len = strlen(str); + patlen = strlen(pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp(str, pat) == 0) + *str = '\0'; + } + return str; +} + +static void +lt_error_core (int exit_status, const char * mode, + const char * message, va_list ap) +{ + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); +} +EOF + # we should really use a build-platform specific compiler + # here, but OTOH, the wrappers (shell script and this C one) + # are only useful if you want to execute the "real" binary. + # Since the "real" binary is built for $host, then this + # wrapper might as well be built for $host, too. + $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource + ;; + esac + $rm $output + trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='${SED} -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $echo >> $output "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + $echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $echo \"\$relink_command_output\" >&2 + $rm \"\$progdir/\$file\" + exit $EXIT_FAILURE + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + $echo >> $output "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $echo >> $output "\ + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \$*\" + exit $EXIT_FAILURE + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + $echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit $EXIT_FAILURE + fi +fi\ +" + chmod +x $output + fi + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $addlibs + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + $echo "X$obj" | $Xsed -e 's%^.*/%%' + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "copying selected object files to avoid basename conflicts..." + + if test -z "$gentop"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + exit_status=$? + if test "$exit_status" -ne 0 && test ! -d "$gentop"; then + exit $exit_status + fi + fi + + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + counter=`expr $counter + 1` + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + $run ln "$obj" "$gentop/$newobj" || + $run cp "$obj" "$gentop/$newobj" + oldobjs="$oldobjs $gentop/$newobj" + ;; + *) oldobjs="$oldobjs $obj" ;; + esac + done + fi + + eval cmds=\"$old_archive_cmds\" + + if len=`expr "X$cmds" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + $echo "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + for obj in $save_oldobjs + do + oldobjs="$objlist $obj" + objlist="$objlist $obj" + eval test_cmds=\"$old_archive_cmds\" + if len=`expr "X$test_cmds" : ".*" 2>/dev/null` && + test "$len" -le "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + eval cmd=\"$cmd\" + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlfiles="$newdlfiles $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlprefiles="$newdlprefiles $abs" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $echo >> $output "\ +relink_command=\"$relink_command\"" + fi + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? + ;; + esac + exit $EXIT_SUCCESS + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | grep shtool > /dev/null; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + case " $install_prog " in + *[\\\ /]cp\ *) ;; + *) prev=$arg ;; + esac + ;; + -g | -m | -o) prev=$arg ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test "$#" -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + library_names= + old_library= + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + if test "$inst_prefix_dir" = "$destdir"; then + $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%" | $NL2SP` + else + relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%%" | $NL2SP` + fi + + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + exit $EXIT_FAILURE + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" + $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + cmds=$postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + file=`$echo $file|${SED} 's,.exe$,,'` + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin*|*mingw*) + wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` + ;; + *) + wrapper=$file + ;; + esac + if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # Note that it is not necessary on cygwin/mingw to append a dot to + # foo even if both foo and FILE.exe exist: automatic-append-.exe + # behavior happens only for exec(3), not for open(2)! Also, sourcing + # `FILE.' does not work on cygwin managed mounts. + # + # If there is no directory component, then add one. + case $wrapper in + */* | *\\*) . ${wrapper} ;; + *) . ./${wrapper} ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 + exit $EXIT_FAILURE + fi + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # Note that it is not necessary on cygwin/mingw to append a dot to + # foo even if both foo and FILE.exe exist: automatic-append-.exe + # behavior happens only for exec(3), not for open(2)! Also, sourcing + # `FILE.' does not work on cygwin managed mounts. + # + # If there is no directory component, then add one. + case $wrapper in + */* | *\\*) . ${wrapper} ;; + *) . ./${wrapper} ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir=`func_mktempdir` + file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g' | $NL2SP` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` + ;; + esac + ;; + esac + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + if test -n "$stripme" && test -n "$old_striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + cmds=$old_postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + cmds=$finish_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = : && exit $EXIT_SUCCESS + + $echo "X----------------------------------------------------------------------" | $Xsed + $echo "Libraries have been installed in:" + for libdir in $libdirs; do + $echo " $libdir" + done + $echo + $echo "If you ever happen to want to link against installed libraries" + $echo "in a given directory, LIBDIR, you must either use libtool, and" + $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + $echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + $echo " during execution" + fi + if test -n "$runpath_var"; then + $echo " - add LIBDIR to the \`$runpath_var' environment variable" + $echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + $echo + $echo "See any operating system documentation about shared libraries for" + $echo "more information, such as the ld(1) and ld.so(8) manual pages." + $echo "X----------------------------------------------------------------------" | $Xsed + exit $EXIT_SUCCESS + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit $EXIT_FAILURE + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + if test ! -f "$dir/$dlname"; then + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit $EXIT_FAILURE + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + fi + $echo "$cmd$args" + exit $EXIT_SUCCESS + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + + case "$mode" in + clean) + case " $library_names " in + # " " in the beginning catches empty $dlname + *" $dlname "*) ;; + *) rmfiles="$rmfiles $objdir/$dlname" ;; + esac + test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + cmds=$postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + cmds=$old_postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + + # Read the .lo file + . $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" \ + && test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" \ + && test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + file=`$echo $file|${SED} 's,.exe$,,'` + noexename=`$echo $name|${SED} 's,.exe$,,'` + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$noexename + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + objdir="$origobjdir" + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + fi +fi # test -z "$show_help" + +if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit $EXIT_FAILURE +fi + +# We need to display help for each of the modes. +case $mode in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + --version print version information + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE. + +Report bugs to ." + exit $EXIT_SUCCESS + ;; + +clean) + $echo \ +"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; +esac + +$echo +$echo "Try \`$modename --help' for more information about other modes." + +exit $? + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +disable_libs=shared +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +disable_libs=static +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/libltdl/missing b/libltdl/missing new file mode 100755 index 00000000..894e786e --- /dev/null +++ b/libltdl/missing @@ -0,0 +1,360 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2005-06-08.21 + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). +case "$1" in + lex|yacc) + # Not GNU programs, they don't have --version. + ;; + + tar) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/libltdl/mkinstalldirs b/libltdl/mkinstalldirs new file mode 100755 index 00000000..ef7e16fd --- /dev/null +++ b/libltdl/mkinstalldirs @@ -0,0 +1,161 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy + +scriptversion=2006-05-11.19 + +# Original author: Noah Friedman +# Created: 1993-05-16 +# Public domain. +# +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' +IFS=" "" $nl" +errstatus=0 +dirmode= + +usage="\ +Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... + +Create each directory DIR (with mode MODE, if specified), including all +leading file name components. + +Report bugs to ." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" + exit $? + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --version) + echo "$0 $scriptversion" + exit $? + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and +# mkdir -p a/c at the same time, both will detect that a is missing, +# one will create a, then the other will try to create a and die with +# a "File exists" error. This is a problem when calling mkinstalldirs +# from a parallel make. We use --version in the probe to restrict +# ourselves to GNU mkdir, which is thread-safe. +case $dirmode in + '') + if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + test -d ./-p && rmdir ./-p + test -d ./--version && rmdir ./--version + fi + ;; + *) + if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && + test ! -d ./--version; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + else + # Clean up after NextStep and OpenStep mkdir. + for d in ./-m ./-p ./--version "./$dirmode"; + do + test -d $d && rmdir $d + done + fi + ;; +esac + +for file +do + case $file in + /*) pathcomp=/ ;; + *) pathcomp= ;; + esac + oIFS=$IFS + IFS=/ + set fnord $file + shift + IFS=$oIFS + + for d + do + test "x$d" = x && continue + + pathcomp=$pathcomp$d + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr= + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp=$pathcomp/ + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/libltdl/stamp-h1 b/libltdl/stamp-h1 new file mode 100644 index 00000000..4547fe1b --- /dev/null +++ b/libltdl/stamp-h1 @@ -0,0 +1 @@ +timestamp for config.h -- cgit From db7fdf6e32f795188f3f1bdae56114cfc4dc166b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 12 Aug 2007 20:35:05 +0000 Subject: make make dist work git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1652 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 2d3af078..a10fe732 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -79,7 +79,8 @@ PA_THREAD_OBJS = \ pulsecore/once-win32.c pulsecore/once.h \ pulsecore/mutex-win32.c pulsecore/mutex.h \ pulsecore/thread-win32.c pulsecore/thread.h \ - pulsecore/semaphore-win32.c pulsecore/semaphore.h + pulsecore/semaphore.h +#pulsecore/semaphore-win32.c pulsecore/semaphore.h else PA_THREAD_OBJS = \ pulsecore/atomic.h \ @@ -660,7 +661,7 @@ libpulsecore_la_SOURCES += \ pulsecore/hook-list.c pulsecore/hook-list.h \ pulsecore/shm.c pulsecore/shm.h \ pulsecore/flist.c pulsecore/flist.h \ - pulsecore/asyncmsgq.c pulsecore/asyncmsgqq.h \ + pulsecore/asyncmsgq.c pulsecore/asyncmsgq.h \ pulsecore/asyncq.c pulsecore/asyncq.h \ pulsecore/thread-mq.c pulsecore/thread-mq.h \ pulsecore/fdsem.c pulsecore/fdsem.h \ -- cgit From e6714e1cb188b0058dfc785d683a979edfb84426 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 12 Aug 2007 20:51:58 +0000 Subject: make make distcheck pass git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1653 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 3 +- libltdl/Makefile | 656 ---- libltdl/config.log | 1609 ---------- libltdl/config.status | 1118 ------- libltdl/libtool | 7895 ------------------------------------------------- src/Makefile.am | 1 + 6 files changed, 2 insertions(+), 11280 deletions(-) delete mode 100644 libltdl/Makefile delete mode 100644 libltdl/config.log delete mode 100755 libltdl/config.status delete mode 100755 libltdl/libtool diff --git a/configure.ac b/configure.ac index 6d7f0bec..1bde5cc7 100644 --- a/configure.ac +++ b/configure.ac @@ -115,6 +115,7 @@ AC_LIBTOOL_WIN32_DLL AC_PROG_LIBTOOL AC_SUBST(LTDLINCL) AC_SUBST(LIBLTDL) +AC_CONFIG_SUBDIRS(libltdl) if test "x$enable_ltdl_install" = "xno" && test "x$ac_cv_lib_ltdl_lt_dlinit" = "xno" ; then AC_MSG_ERROR([[ @@ -782,8 +783,6 @@ src/pulse/version.h ]) AC_OUTPUT -AC_CONFIG_SUBDIRS(libltdl) - # ========================================================================== ENABLE_X11=no if test "x$HAVE_X11" = "x1" ; then diff --git a/libltdl/Makefile b/libltdl/Makefile deleted file mode 100644 index 90fddd7b..00000000 --- a/libltdl/Makefile +++ /dev/null @@ -1,656 +0,0 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. -# Makefile. Generated from Makefile.in by configure. - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - - - - - -pkgdatadir = $(datadir)/libltdl -pkglibdir = $(libdir)/libltdl -pkgincludedir = $(includedir)/libltdl -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = i686-pc-linux-gnu -host_triplet = i686-pc-linux-gnu -subdir = . -DIST_COMMON = README $(am__configure_deps) $(am__include_HEADERS_DIST) \ - $(am__noinst_HEADERS_DIST) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(srcdir)/config-h.in \ - $(top_srcdir)/configure COPYING.LIB config.guess config.sub \ - install-sh ltmain.sh missing mkinstalldirs -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno config.status.lineno -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = config.h -CONFIG_CLEAN_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" -libLTLIBRARIES_INSTALL = $(INSTALL) -LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) -am__DEPENDENCIES_1 = -libltdl_la_DEPENDENCIES = $(am__DEPENDENCIES_1) -am_libltdl_la_OBJECTS = ltdl.lo -libltdl_la_OBJECTS = $(am_libltdl_la_OBJECTS) -libltdl_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libltdl_la_LDFLAGS) $(LDFLAGS) -o $@ -am_libltdl_la_rpath = -rpath $(libdir) -libltdlc_la_DEPENDENCIES = $(am__DEPENDENCIES_1) -am_libltdlc_la_OBJECTS = ltdl.lo -libltdlc_la_OBJECTS = $(am_libltdlc_la_OBJECTS) -#am_libltdlc_la_rpath = -DEFAULT_INCLUDES = -I. -depcomp = -am__depfiles_maybe = -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -SOURCES = $(libltdl_la_SOURCES) $(libltdlc_la_SOURCES) -DIST_SOURCES = $(libltdl_la_SOURCES) $(libltdlc_la_SOURCES) -am__include_HEADERS_DIST = ltdl.h -includeHEADERS_INSTALL = $(INSTALL_HEADER) -am__noinst_HEADERS_DIST = ltdl.h -HEADERS = $(include_HEADERS) $(noinst_HEADERS) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - { test ! -d $(distdir) \ - || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -fr $(distdir); }; } -DIST_ARCHIVES = $(distdir).tar.gz -GZIP_ENV = --best -distuninstallcheck_listfiles = find . -type f -print -distcleancheck_listfiles = find . -type f -print -ACLOCAL = ${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run aclocal-1.10 -AMTAR = ${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run tar -AR = ar -AS = as -AUTOCONF = ${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run autoconf -AUTOHEADER = ${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run autoheader -AUTOMAKE = ${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run automake-1.10 -AWK = gawk -CC = gcc -CCDEPMODE = depmode=none -CFLAGS = -g -O2 -CPP = gcc -E -CPPFLAGS = -CXX = g++ -CXXCPP = g++ -E -CXXDEPMODE = depmode=none -CXXFLAGS = -g -O2 -CYGPATH_W = echo -DEFS = -DHAVE_CONFIG_H -DEPDIR = .deps -DLLTOOL = dlltool -ECHO = echo -ECHO_C = -ECHO_N = -n -ECHO_T = -EGREP = /bin/grep -E -EXEEXT = -F77 = gfortran -FFLAGS = -g -O2 -GREP = /bin/grep -INSTALL = /usr/bin/install -c -INSTALL_DATA = ${INSTALL} -m 644 -INSTALL_PROGRAM = ${INSTALL} -INSTALL_SCRIPT = ${INSTALL} -INSTALL_STRIP_PROGRAM = $(install_sh) -c -s -LDFLAGS = -LIBADD_DL = -ldl -LIBOBJS = -LIBS = -LIBTOOL = $(SHELL) $(top_builddir)/libtool -LIBTOOL_DEPS = ./ltmain.sh -LN_S = ln -s -LTLIBOBJS = -MAKEINFO = ${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run makeinfo -MKDIR_P = /bin/mkdir -p -OBJDUMP = objdump -OBJEXT = o -PACKAGE = libltdl -PACKAGE_BUGREPORT = bug-libtool@gnu.org -PACKAGE_NAME = libltdl -PACKAGE_STRING = libltdl 1.2 -PACKAGE_TARNAME = libltdl -PACKAGE_VERSION = 1.2 -PATH_SEPARATOR = : -RANLIB = ranlib -SED = /bin/sed -SET_MAKE = -SHELL = /bin/sh -STRIP = strip -VERSION = 1.2 -abs_builddir = /home/lennart/projects/pulseaudio/libltdl -abs_srcdir = /home/lennart/projects/pulseaudio/libltdl -abs_top_builddir = /home/lennart/projects/pulseaudio/libltdl -abs_top_srcdir = /home/lennart/projects/pulseaudio/libltdl -ac_ct_CC = gcc -ac_ct_CXX = g++ -ac_ct_F77 = gfortran -am__include = include -am__leading_dot = . -am__quote = -am__tar = ${AMTAR} chof - "$$tardir" -am__untar = ${AMTAR} xf - -bindir = ${exec_prefix}/bin -build = i686-pc-linux-gnu -build_alias = -build_cpu = i686 -build_os = linux-gnu -build_vendor = pc -builddir = . -datadir = ${datarootdir} -datarootdir = ${prefix}/share -docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} -dvidir = ${docdir} -exec_prefix = ${prefix} -host = i686-pc-linux-gnu -host_alias = -host_cpu = i686 -host_os = linux-gnu -host_vendor = pc -htmldir = ${docdir} -includedir = ${prefix}/include -infodir = ${datarootdir}/info -install_sh = $(SHELL) /home/lennart/projects/pulseaudio/libltdl/install-sh -libdir = ${exec_prefix}/lib -libexecdir = ${exec_prefix}/libexec -localedir = ${datarootdir}/locale -localstatedir = ${prefix}/var -mandir = ${datarootdir}/man -mkdir_p = /bin/mkdir -p -oldincludedir = /usr/include -pdfdir = ${docdir} -prefix = /usr/local -program_transform_name = s,x,x, -psdir = ${docdir} -sbindir = ${exec_prefix}/sbin -sharedstatedir = ${prefix}/com -srcdir = . -sysconfdir = ${prefix}/etc -target_alias = -top_builddir = . -top_srcdir = . -AUTOMAKE_OPTIONS = no-dependencies foreign -include_HEADERS = ltdl.h -lib_LTLIBRARIES = libltdl.la -#noinst_HEADERS = ltdl.h -#noinst_LTLIBRARIES = libltdlc.la -CLEANFILES = libltdl.la libltdlc.la -libltdl_la_SOURCES = ltdl.c -libltdl_la_LDFLAGS = -no-undefined -version-info 4:5:1 -libltdl_la_LIBADD = $(LIBADD_DL) -libltdlc_la_SOURCES = ltdl.c -libltdlc_la_LIBADD = $(LIBADD_DL) -all: config.h - $(MAKE) $(AM_MAKEFLAGS) all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -am--refresh: - @: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \ - cd $(srcdir) && $(AUTOMAKE) --foreign \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --foreign Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) - -config.h: stamp-h1 - @if test ! -f $@; then \ - rm -f stamp-h1; \ - $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ - else :; fi - -stamp-h1: $(srcdir)/config-h.in $(top_builddir)/config.status - @rm -f stamp-h1 - cd $(top_builddir) && $(SHELL) ./config.status config.h -$(srcdir)/config-h.in: $(am__configure_deps) - cd $(top_srcdir) && $(AUTOHEADER) - rm -f stamp-h1 - touch $@ - -distclean-hdr: - -rm -f config.h stamp-h1 -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - if test -f $$p; then \ - f=$(am__strip_dir) \ - echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ - else :; fi; \ - done - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - p=$(am__strip_dir) \ - echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ - $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -libltdl.la: $(libltdl_la_OBJECTS) $(libltdl_la_DEPENDENCIES) - $(libltdl_la_LINK) $(am_libltdl_la_rpath) $(libltdl_la_OBJECTS) $(libltdl_la_LIBADD) $(LIBS) -libltdlc.la: $(libltdlc_la_OBJECTS) $(libltdlc_la_DEPENDENCIES) - $(LINK) $(am_libltdlc_la_rpath) $(libltdlc_la_OBJECTS) $(libltdlc_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -.c.o: - $(COMPILE) -c $< - -.c.obj: - $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: - $(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool -install-includeHEADERS: $(include_HEADERS) - @$(NORMAL_INSTALL) - test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" - @list='$(include_HEADERS)'; for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - f=$(am__strip_dir) \ - echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ - $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ - done - -uninstall-includeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(include_HEADERS)'; for p in $$list; do \ - f=$(am__strip_dir) \ - echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ - rm -f "$(DESTDIR)$(includedir)/$$f"; \ - done - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) config-h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) config-h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) config-h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) config-h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - $(am__remove_distdir) - test -d $(distdir) || mkdir $(distdir) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done - -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r $(distdir) -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) - -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 - $(am__remove_distdir) - -dist-tarZ: distdir - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__remove_distdir) - -dist-shar: distdir - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__remove_distdir) - -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__remove_distdir) - -dist dist-all: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac - chmod -R a-w $(distdir); chmod a+w $(distdir) - mkdir $(distdir)/_build - mkdir $(distdir)/_inst - chmod a-w $(distdir) - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && cd $(distdir)/_build \ - && ../configure --srcdir=.. --prefix="$$dc_install_base" \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck - $(am__remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' -distuninstallcheck: - @cd $(distuninstallcheck_dir) \ - && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) config.h -installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ - clean-noinstLTLIBRARIES mostlyclean-am - -distclean: distclean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-hdr distclean-libtool distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -info: info-am - -info-am: - -install-data-am: install-includeHEADERS - -install-dvi: install-dvi-am - -install-exec-am: install-libLTLIBRARIES - -install-html: install-html-am - -install-info: install-info-am - -install-man: - -install-pdf: install-pdf-am - -install-ps: install-ps-am - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \ - clean-generic clean-libLTLIBRARIES clean-libtool \ - clean-noinstLTLIBRARIES ctags dist dist-all dist-bzip2 \ - dist-gzip dist-shar dist-tarZ dist-zip distcheck distclean \ - distclean-compile distclean-generic distclean-hdr \ - distclean-libtool distclean-tags distcleancheck distdir \ - distuninstallcheck dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-includeHEADERS install-info \ - install-info-am install-libLTLIBRARIES install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-includeHEADERS \ - uninstall-libLTLIBRARIES - - -ltdl.lo: ltdl.h config.h - -$(libltdl_la_OBJECTS) $(libltdlc_la_OBJECTS): libtool -libtool: $(LIBTOOL_DEPS) - $(SHELL) ./config.status --recheck -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/libltdl/config.log b/libltdl/config.log deleted file mode 100644 index 1aca1d97..00000000 --- a/libltdl/config.log +++ /dev/null @@ -1,1609 +0,0 @@ -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by libltdl configure 1.2, which was -generated by GNU Autoconf 2.61. Invocation command line was - - $ ./configure - -## --------- ## -## Platform. ## -## --------- ## - -hostname = lambda -uname -m = i686 -uname -r = 2.6.23-0.73.rc2.fc8 -uname -s = Linux -uname -v = #1 SMP Mon Aug 6 20:26:04 EDT 2007 - -/usr/bin/uname -p = unknown -/bin/uname -X = unknown - -/bin/arch = i686 -/usr/bin/arch -k = unknown -/usr/convex/getsysinfo = unknown -/usr/bin/hostinfo = unknown -/bin/machine = unknown -/usr/bin/oslevel = unknown -/bin/universe = unknown - -PATH: /home/lennart/bin -PATH: /usr/lib/qt-3.3/bin -PATH: /usr/kerberos/bin -PATH: /usr/lib/ccache -PATH: /usr/local/bin -PATH: /bin -PATH: /usr/bin - - -## ----------- ## -## Core tests. ## -## ----------- ## - -configure:2017: checking for a BSD-compatible install -configure:2073: result: /usr/bin/install -c -configure:2084: checking whether build environment is sane -configure:2127: result: yes -configure:2155: checking for a thread-safe mkdir -p -configure:2194: result: /bin/mkdir -p -configure:2207: checking for gawk -configure:2223: found /bin/gawk -configure:2234: result: gawk -configure:2245: checking whether make sets $(MAKE) -configure:2266: result: yes -configure:2500: checking for gcc -configure:2516: found /usr/lib/ccache/gcc -configure:2527: result: gcc -configure:2765: checking for C compiler version -configure:2772: gcc --version >&5 -gcc (GCC) 4.1.2 20070723 (Red Hat 4.1.2-17) -Copyright (C) 2006 Free Software Foundation, Inc. -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -configure:2775: $? = 0 -configure:2782: gcc -v >&5 -Using built-in specs. -Target: i386-redhat-linux -Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-cpu=generic --host=i386-redhat-linux -Thread model: posix -gcc version 4.1.2 20070723 (Red Hat 4.1.2-17) -configure:2785: $? = 0 -configure:2792: gcc -V >&5 -gcc: '-V' option must have argument -configure:2795: $? = 1 -configure:2818: checking for C compiler default output file name -configure:2845: gcc conftest.c >&5 -configure:2848: $? = 0 -configure:2886: result: a.out -configure:2903: checking whether the C compiler works -configure:2913: ./a.out -configure:2916: $? = 0 -configure:2933: result: yes -configure:2940: checking whether we are cross compiling -configure:2942: result: no -configure:2945: checking for suffix of executables -configure:2952: gcc -o conftest conftest.c >&5 -configure:2955: $? = 0 -configure:2979: result: -configure:2985: checking for suffix of object files -configure:3011: gcc -c conftest.c >&5 -configure:3014: $? = 0 -configure:3037: result: o -configure:3041: checking whether we are using the GNU C compiler -configure:3070: gcc -c conftest.c >&5 -configure:3076: $? = 0 -configure:3093: result: yes -configure:3098: checking whether gcc accepts -g -configure:3128: gcc -c -g conftest.c >&5 -configure:3134: $? = 0 -configure:3233: result: yes -configure:3250: checking for gcc option to accept ISO C89 -configure:3324: gcc -c -g -O2 conftest.c >&5 -configure:3330: $? = 0 -configure:3353: result: none needed -configure:3382: checking for style of include used by make -configure:3410: result: GNU -configure:3435: checking dependency style of gcc -configure:3526: result: none -configure:3542: checking for an ANSI C-conforming const -configure:3617: gcc -c -g -O2 conftest.c >&5 -configure:3623: $? = 0 -configure:3638: result: yes -configure:3648: checking for inline -configure:3674: gcc -c -g -O2 conftest.c >&5 -configure:3680: $? = 0 -configure:3698: result: inline -configure:3802: checking build system type -configure:3820: result: i686-pc-linux-gnu -configure:3842: checking host system type -configure:3857: result: i686-pc-linux-gnu -configure:3879: checking for a sed that does not truncate output -configure:3935: result: /bin/sed -configure:3938: checking for grep that handles long lines and -e -configure:4012: result: /bin/grep -configure:4017: checking for egrep -configure:4095: result: /bin/grep -E -configure:4111: checking for ld used by gcc -configure:4178: result: /usr/bin/ld -configure:4187: checking if the linker (/usr/bin/ld) is GNU ld -configure:4202: result: yes -configure:4207: checking for /usr/bin/ld option to reload object files -configure:4214: result: -r -configure:4232: checking for BSD-compatible nm -configure:4281: result: /usr/bin/nm -B -configure:4285: checking whether ln -s works -configure:4289: result: yes -configure:4296: checking how to recognize dependent libraries -configure:4482: result: pass_all -configure:5013: checking how to run the C preprocessor -configure:5053: gcc -E conftest.c -configure:5059: $? = 0 -configure:5090: gcc -E conftest.c -conftest.c:8:28: error: ac_nonexistent.h: No such file or directory -configure:5096: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| #define PACKAGE_NAME "libltdl" -| #define PACKAGE_TARNAME "libltdl" -| #define PACKAGE_VERSION "1.2" -| #define PACKAGE_STRING "libltdl 1.2" -| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" -| /* end confdefs.h. */ -| #include -configure:5129: result: gcc -E -configure:5158: gcc -E conftest.c -configure:5164: $? = 0 -configure:5195: gcc -E conftest.c -conftest.c:8:28: error: ac_nonexistent.h: No such file or directory -configure:5201: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| #define PACKAGE_NAME "libltdl" -| #define PACKAGE_TARNAME "libltdl" -| #define PACKAGE_VERSION "1.2" -| #define PACKAGE_STRING "libltdl 1.2" -| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" -| /* end confdefs.h. */ -| #include -configure:5239: checking for ANSI C header files -configure:5269: gcc -c -g -O2 conftest.c >&5 -configure:5275: $? = 0 -configure:5374: gcc -o conftest -g -O2 conftest.c >&5 -configure:5377: $? = 0 -configure:5383: ./conftest -configure:5386: $? = 0 -configure:5403: result: yes -configure:5427: checking for sys/types.h -configure:5448: gcc -c -g -O2 conftest.c >&5 -configure:5454: $? = 0 -configure:5470: result: yes -configure:5427: checking for sys/stat.h -configure:5448: gcc -c -g -O2 conftest.c >&5 -configure:5454: $? = 0 -configure:5470: result: yes -configure:5427: checking for stdlib.h -configure:5448: gcc -c -g -O2 conftest.c >&5 -configure:5454: $? = 0 -configure:5470: result: yes -configure:5427: checking for string.h -configure:5448: gcc -c -g -O2 conftest.c >&5 -configure:5454: $? = 0 -configure:5470: result: yes -configure:5427: checking for memory.h -configure:5448: gcc -c -g -O2 conftest.c >&5 -configure:5454: $? = 0 -configure:5470: result: yes -configure:5427: checking for strings.h -configure:5448: gcc -c -g -O2 conftest.c >&5 -configure:5454: $? = 0 -configure:5470: result: yes -configure:5427: checking for inttypes.h -configure:5448: gcc -c -g -O2 conftest.c >&5 -configure:5454: $? = 0 -configure:5470: result: yes -configure:5427: checking for stdint.h -configure:5448: gcc -c -g -O2 conftest.c >&5 -configure:5454: $? = 0 -configure:5470: result: yes -configure:5427: checking for unistd.h -configure:5448: gcc -c -g -O2 conftest.c >&5 -configure:5454: $? = 0 -configure:5470: result: yes -configure:5497: checking dlfcn.h usability -configure:5514: gcc -c -g -O2 conftest.c >&5 -configure:5520: $? = 0 -configure:5534: result: yes -configure:5538: checking dlfcn.h presence -configure:5553: gcc -E conftest.c -configure:5559: $? = 0 -configure:5573: result: yes -configure:5606: checking for dlfcn.h -configure:5614: result: yes -configure:5685: checking for g++ -configure:5701: found /usr/lib/ccache/g++ -configure:5712: result: g++ -configure:5743: checking for C++ compiler version -configure:5750: g++ --version >&5 -g++ (GCC) 4.1.2 20070704 (Red Hat 4.1.2-15) -Copyright (C) 2006 Free Software Foundation, Inc. -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -configure:5753: $? = 0 -configure:5760: g++ -v >&5 -Using built-in specs. -Target: i386-redhat-linux -Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-cpu=generic --host=i386-redhat-linux -Thread model: posix -gcc version 4.1.2 20070704 (Red Hat 4.1.2-15) -configure:5763: $? = 0 -configure:5770: g++ -V >&5 -g++: '-V' option must have argument -configure:5773: $? = 1 -configure:5776: checking whether we are using the GNU C++ compiler -configure:5805: g++ -c conftest.cpp >&5 -configure:5811: $? = 0 -configure:5828: result: yes -configure:5833: checking whether g++ accepts -g -configure:5863: g++ -c -g conftest.cpp >&5 -configure:5869: $? = 0 -configure:5968: result: yes -configure:5993: checking dependency style of g++ -configure:6084: result: none -configure:6109: checking how to run the C++ preprocessor -configure:6145: g++ -E conftest.cpp -configure:6151: $? = 0 -configure:6182: g++ -E conftest.cpp -conftest.cpp:19:28: error: ac_nonexistent.h: No such file or directory -configure:6188: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| #define PACKAGE_NAME "libltdl" -| #define PACKAGE_TARNAME "libltdl" -| #define PACKAGE_VERSION "1.2" -| #define PACKAGE_STRING "libltdl 1.2" -| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" -| #define STDC_HEADERS 1 -| #define HAVE_SYS_TYPES_H 1 -| #define HAVE_SYS_STAT_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STRING_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STRINGS_H 1 -| #define HAVE_INTTYPES_H 1 -| #define HAVE_STDINT_H 1 -| #define HAVE_UNISTD_H 1 -| #define HAVE_DLFCN_H 1 -| /* end confdefs.h. */ -| #include -configure:6221: result: g++ -E -configure:6250: g++ -E conftest.cpp -configure:6256: $? = 0 -configure:6287: g++ -E conftest.cpp -conftest.cpp:19:28: error: ac_nonexistent.h: No such file or directory -configure:6293: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| #define PACKAGE_NAME "libltdl" -| #define PACKAGE_TARNAME "libltdl" -| #define PACKAGE_VERSION "1.2" -| #define PACKAGE_STRING "libltdl 1.2" -| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" -| #define STDC_HEADERS 1 -| #define HAVE_SYS_TYPES_H 1 -| #define HAVE_SYS_STAT_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STRING_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STRINGS_H 1 -| #define HAVE_INTTYPES_H 1 -| #define HAVE_STDINT_H 1 -| #define HAVE_UNISTD_H 1 -| #define HAVE_DLFCN_H 1 -| /* end confdefs.h. */ -| #include -configure:6386: checking for g77 -configure:6416: result: no -configure:6386: checking for xlf -configure:6416: result: no -configure:6386: checking for f77 -configure:6416: result: no -configure:6386: checking for frt -configure:6416: result: no -configure:6386: checking for pgf77 -configure:6416: result: no -configure:6386: checking for cf77 -configure:6416: result: no -configure:6386: checking for fort77 -configure:6416: result: no -configure:6386: checking for fl32 -configure:6416: result: no -configure:6386: checking for af77 -configure:6416: result: no -configure:6386: checking for xlf90 -configure:6416: result: no -configure:6386: checking for f90 -configure:6416: result: no -configure:6386: checking for pgf90 -configure:6416: result: no -configure:6386: checking for pghpf -configure:6416: result: no -configure:6386: checking for epcf90 -configure:6416: result: no -configure:6386: checking for gfortran -configure:6402: found /usr/bin/gfortran -configure:6413: result: gfortran -configure:6443: checking for Fortran 77 compiler version -configure:6450: gfortran --version >&5 -GNU Fortran (GCC) 4.1.2 20070704 (Red Hat 4.1.2-15) -Copyright (C) 2007 Free Software Foundation, Inc. - -GNU Fortran comes with NO WARRANTY, to the extent permitted by law. -You may redistribute copies of GNU Fortran -under the terms of the GNU General Public License. -For more information about these matters, see the file named COPYING - -configure:6453: $? = 0 -configure:6460: gfortran -v >&5 -Using built-in specs. -Target: i386-redhat-linux -Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-cpu=generic --host=i386-redhat-linux -Thread model: posix -gcc version 4.1.2 20070704 (Red Hat 4.1.2-15) -configure:6463: $? = 0 -configure:6470: gfortran -V >&5 -gfortran: '-V' option must have argument -configure:6473: $? = 1 -configure:6481: checking whether we are using the GNU Fortran 77 compiler -configure:6500: gfortran -c conftest.F >&5 -configure:6506: $? = 0 -configure:6523: result: yes -configure:6529: checking whether gfortran accepts -g -configure:6546: gfortran -c -g conftest.f >&5 -configure:6552: $? = 0 -configure:6568: result: yes -configure:6598: checking the maximum length of command line arguments -configure:6710: result: 98304 -configure:6722: checking command to parse /usr/bin/nm -B output from gcc object -configure:6827: gcc -c -g -O2 conftest.c >&5 -configure:6830: $? = 0 -configure:6834: /usr/bin/nm -B conftest.o \| sed -n -e 's/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p' \> conftest.nm -configure:6837: $? = 0 -configure:6889: gcc -o conftest -g -O2 conftest.c conftstm.o >&5 -configure:6892: $? = 0 -configure:6930: result: ok -configure:6934: checking for objdir -configure:6949: result: .libs -configure:7041: checking for ar -configure:7057: found /usr/bin/ar -configure:7068: result: ar -configure:7137: checking for ranlib -configure:7153: found /usr/bin/ranlib -configure:7164: result: ranlib -configure:7233: checking for strip -configure:7249: found /usr/bin/strip -configure:7260: result: strip -configure:7550: checking if gcc supports -fno-rtti -fno-exceptions -configure:7568: gcc -c -g -O2 -fno-rtti -fno-exceptions conftest.c >&5 -cc1: warning: command line option "-fno-rtti" is valid for C++/ObjC++ but not for C -cc1: warning: command line option "-fno-rtti" is valid for C++/ObjC++ but not for C -configure:7572: $? = 0 -configure:7585: result: no -configure:7600: checking for gcc option to produce PIC -configure:7832: result: -fPIC -configure:7840: checking if gcc PIC flag -fPIC works -configure:7858: gcc -c -g -O2 -fPIC -DPIC conftest.c >&5 -configure:7862: $? = 0 -configure:7875: result: yes -configure:7903: checking if gcc static flag -static works -configure:7931: result: yes -configure:7941: checking if gcc supports -c -o file.o -configure:7962: gcc -c -g -O2 -o out/conftest2.o conftest.c >&5 -configure:7966: $? = 0 -configure:7988: result: yes -configure:8014: checking whether the gcc linker (/usr/bin/ld) supports shared libraries -configure:8994: result: yes -configure:9015: checking whether -lc should be explicitly linked in -configure:9020: gcc -c -g -O2 conftest.c >&5 -configure:9023: $? = 0 -configure:9038: gcc -shared conftest.o -v -Wl,-soname -Wl,conftest -o conftest 2\>\&1 \| grep -lc \>/dev/null 2\>\&1 -configure:9041: $? = 0 -configure:9053: result: no -configure:9061: checking dynamic linker characteristics -configure:9665: result: GNU/Linux ld.so -configure:9674: checking how to hardcode library paths into programs -configure:9699: result: immediate -configure:9713: checking whether stripping libraries is possible -configure:9718: result: yes -configure:10520: checking if libtool supports shared libraries -configure:10522: result: yes -configure:10525: checking whether to build shared libraries -configure:10546: result: yes -configure:10549: checking whether to build static libraries -configure:10553: result: yes -configure:10646: creating libtool -configure:11234: checking for ld used by g++ -configure:11301: result: /usr/bin/ld -configure:11310: checking if the linker (/usr/bin/ld) is GNU ld -configure:11325: result: yes -configure:11376: checking whether the g++ linker (/usr/bin/ld) supports shared libraries -configure:12350: result: yes -configure:12372: g++ -c -g -O2 conftest.cpp >&5 -configure:12375: $? = 0 -configure:12527: checking for g++ option to produce PIC -configure:12811: result: -fPIC -configure:12819: checking if g++ PIC flag -fPIC works -configure:12837: g++ -c -g -O2 -fPIC -DPIC conftest.cpp >&5 -configure:12841: $? = 0 -configure:12854: result: yes -configure:12882: checking if g++ static flag -static works -configure:12910: result: yes -configure:12920: checking if g++ supports -c -o file.o -configure:12941: g++ -c -g -O2 -o out/conftest2.o conftest.cpp >&5 -configure:12945: $? = 0 -configure:12967: result: yes -configure:12993: checking whether the g++ linker (/usr/bin/ld) supports shared libraries -configure:13018: result: yes -configure:13085: checking dynamic linker characteristics -configure:13637: result: GNU/Linux ld.so -configure:13646: checking how to hardcode library paths into programs -configure:13671: result: immediate -configure:14205: checking if libtool supports shared libraries -configure:14207: result: yes -configure:14210: checking whether to build shared libraries -configure:14230: result: yes -configure:14233: checking whether to build static libraries -configure:14237: result: yes -configure:14247: checking for gfortran option to produce PIC -configure:14479: result: -fPIC -configure:14487: checking if gfortran PIC flag -fPIC works -configure:14505: gfortran -c -g -O2 -fPIC conftest.f >&5 -configure:14509: $? = 0 -configure:14522: result: yes -configure:14550: checking if gfortran static flag -static works -configure:14578: result: yes -configure:14588: checking if gfortran supports -c -o file.o -configure:14609: gfortran -c -g -O2 -o out/conftest2.o conftest.f >&5 -configure:14613: $? = 0 -configure:14635: result: yes -configure:14661: checking whether the gfortran linker (/usr/bin/ld) supports shared libraries -configure:15621: result: yes -configure:15688: checking dynamic linker characteristics -configure:16240: result: GNU/Linux ld.so -configure:16249: checking how to hardcode library paths into programs -configure:16274: result: immediate -configure:19860: checking for dirent.h that defines DIR -configure:19889: gcc -c -g -O2 conftest.c >&5 -configure:19895: $? = 0 -configure:19911: result: yes -configure:19924: checking for library containing opendir -configure:19965: gcc -o conftest -g -O2 conftest.c >&5 -configure:19971: $? = 0 -configure:19999: result: none required -configure:20117: checking which extension is used for loadable modules -configure:20127: result: .so -configure:20138: checking which variable specifies run-time library path -configure:20145: result: LD_LIBRARY_PATH -configure:20156: checking for the default library search path -configure:20163: result: /usr/lib /lib /usr/lib/qt-3.3/lib -configure:20181: checking for objdir -configure:20202: result: .libs -configure:20211: checking whether libtool supports -dlopen/-dlpreopen -configure:20223: result: yes -configure:20242: checking for shl_load -configure:20298: gcc -o conftest -g -O2 conftest.c >&5 -/tmp/ccPBezQi.o: In function `main': -/home/lennart/projects/pulseaudio/libltdl/conftest.c:59: undefined reference to `shl_load' -collect2: ld returned 1 exit status -configure:20304: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| #define PACKAGE_NAME "libltdl" -| #define PACKAGE_TARNAME "libltdl" -| #define PACKAGE_VERSION "1.2" -| #define PACKAGE_STRING "libltdl 1.2" -| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" -| #define STDC_HEADERS 1 -| #define HAVE_SYS_TYPES_H 1 -| #define HAVE_SYS_STAT_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STRING_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STRINGS_H 1 -| #define HAVE_INTTYPES_H 1 -| #define HAVE_STDINT_H 1 -| #define HAVE_UNISTD_H 1 -| #define HAVE_DLFCN_H 1 -| #define HAVE_DIRENT_H 1 -| #define LTDL_SHLIB_EXT ".so" -| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" -| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" -| #define LTDL_OBJDIR ".libs/" -| #define HAVE_PRELOADED_SYMBOLS 1 -| /* end confdefs.h. */ -| /* Define shl_load to an innocuous variant, in case declares shl_load. -| For example, HP-UX 11i declares gettimeofday. */ -| #define shl_load innocuous_shl_load -| -| /* System header to define __stub macros and hopefully few prototypes, -| which can conflict with char shl_load (); below. -| Prefer to if __STDC__ is defined, since -| exists even on freestanding compilers. */ -| -| #ifdef __STDC__ -| # include -| #else -| # include -| #endif -| -| #undef shl_load -| -| /* Override any GCC internal prototype to avoid an error. -| Use char because int might match the return type of a GCC -| builtin and then its argument prototype would still apply. */ -| #ifdef __cplusplus -| extern "C" -| #endif -| char shl_load (); -| /* The GNU C library defines this for functions which it implements -| to always fail with ENOSYS. Some functions are actually named -| something starting with __ and the normal name is an alias. */ -| #if defined __stub_shl_load || defined __stub___shl_load -| choke me -| #endif -| -| int -| main () -| { -| return shl_load (); -| ; -| return 0; -| } -configure:20321: result: no -configure:20330: checking for shl_load in -ldld -configure:20365: gcc -o conftest -g -O2 conftest.c -ldld >&5 -/usr/bin/ld: cannot find -ldld -collect2: ld returned 1 exit status -configure:20371: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| #define PACKAGE_NAME "libltdl" -| #define PACKAGE_TARNAME "libltdl" -| #define PACKAGE_VERSION "1.2" -| #define PACKAGE_STRING "libltdl 1.2" -| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" -| #define STDC_HEADERS 1 -| #define HAVE_SYS_TYPES_H 1 -| #define HAVE_SYS_STAT_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STRING_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STRINGS_H 1 -| #define HAVE_INTTYPES_H 1 -| #define HAVE_STDINT_H 1 -| #define HAVE_UNISTD_H 1 -| #define HAVE_DLFCN_H 1 -| #define HAVE_DIRENT_H 1 -| #define LTDL_SHLIB_EXT ".so" -| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" -| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" -| #define LTDL_OBJDIR ".libs/" -| #define HAVE_PRELOADED_SYMBOLS 1 -| /* end confdefs.h. */ -| -| /* Override any GCC internal prototype to avoid an error. -| Use char because int might match the return type of a GCC -| builtin and then its argument prototype would still apply. */ -| #ifdef __cplusplus -| extern "C" -| #endif -| char shl_load (); -| int -| main () -| { -| return shl_load (); -| ; -| return 0; -| } -configure:20389: result: no -configure:20399: checking for dlopen in -ldl -configure:20434: gcc -o conftest -g -O2 conftest.c -ldl >&5 -configure:20440: $? = 0 -configure:20458: result: yes -configure:20769: checking for dlerror -configure:20825: gcc -o conftest -g -O2 conftest.c -ldl >&5 -configure:20831: $? = 0 -configure:20849: result: yes -configure:20869: checking for _ prefix in compiled symbols -configure:20879: gcc -c -g -O2 conftest.c >&5 -configure:20882: $? = 0 -configure:20886: /usr/bin/nm -B conftest.o \| sed -n -e 's/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p' \> conftest.nm -configure:20889: $? = 0 -configure:20911: result: no -configure:21031: checking whether deplibs are loaded by dlopen -configure:21115: result: yes -configure:21140: checking argz.h usability -configure:21157: gcc -c -g -O2 conftest.c >&5 -configure:21163: $? = 0 -configure:21177: result: yes -configure:21181: checking argz.h presence -configure:21196: gcc -E conftest.c -configure:21202: $? = 0 -configure:21216: result: yes -configure:21249: checking for argz.h -configure:21257: result: yes -configure:21271: checking for error_t -configure:21304: gcc -c -g -O2 conftest.c >&5 -configure:21310: $? = 0 -configure:21325: result: yes -configure:21351: checking for argz_append -configure:21407: gcc -o conftest -g -O2 conftest.c >&5 -configure:21413: $? = 0 -configure:21431: result: yes -configure:21351: checking for argz_create_sep -configure:21407: gcc -o conftest -g -O2 conftest.c >&5 -configure:21413: $? = 0 -configure:21431: result: yes -configure:21351: checking for argz_insert -configure:21407: gcc -o conftest -g -O2 conftest.c >&5 -configure:21413: $? = 0 -configure:21431: result: yes -configure:21351: checking for argz_next -configure:21407: gcc -o conftest -g -O2 conftest.c >&5 -configure:21413: $? = 0 -configure:21431: result: yes -configure:21351: checking for argz_stringify -configure:21407: gcc -o conftest -g -O2 conftest.c >&5 -configure:21413: $? = 0 -configure:21431: result: yes -configure:21483: checking assert.h usability -configure:21500: gcc -c -g -O2 conftest.c >&5 -configure:21506: $? = 0 -configure:21520: result: yes -configure:21524: checking assert.h presence -configure:21539: gcc -E conftest.c -configure:21545: $? = 0 -configure:21559: result: yes -configure:21592: checking for assert.h -configure:21600: result: yes -configure:21483: checking ctype.h usability -configure:21500: gcc -c -g -O2 conftest.c >&5 -configure:21506: $? = 0 -configure:21520: result: yes -configure:21524: checking ctype.h presence -configure:21539: gcc -E conftest.c -configure:21545: $? = 0 -configure:21559: result: yes -configure:21592: checking for ctype.h -configure:21600: result: yes -configure:21483: checking errno.h usability -configure:21500: gcc -c -g -O2 conftest.c >&5 -configure:21506: $? = 0 -configure:21520: result: yes -configure:21524: checking errno.h presence -configure:21539: gcc -E conftest.c -configure:21545: $? = 0 -configure:21559: result: yes -configure:21592: checking for errno.h -configure:21600: result: yes -configure:21483: checking malloc.h usability -configure:21500: gcc -c -g -O2 conftest.c >&5 -configure:21506: $? = 0 -configure:21520: result: yes -configure:21524: checking malloc.h presence -configure:21539: gcc -E conftest.c -configure:21545: $? = 0 -configure:21559: result: yes -configure:21592: checking for malloc.h -configure:21600: result: yes -configure:21473: checking for memory.h -configure:21479: result: yes -configure:21473: checking for stdlib.h -configure:21479: result: yes -configure:21483: checking stdio.h usability -configure:21500: gcc -c -g -O2 conftest.c >&5 -configure:21506: $? = 0 -configure:21520: result: yes -configure:21524: checking stdio.h presence -configure:21539: gcc -E conftest.c -configure:21545: $? = 0 -configure:21559: result: yes -configure:21592: checking for stdio.h -configure:21600: result: yes -configure:21473: checking for unistd.h -configure:21479: result: yes -configure:21631: checking dl.h usability -configure:21648: gcc -c -g -O2 conftest.c >&5 -conftest.c:75:16: error: dl.h: No such file or directory -configure:21654: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| #define PACKAGE_NAME "libltdl" -| #define PACKAGE_TARNAME "libltdl" -| #define PACKAGE_VERSION "1.2" -| #define PACKAGE_STRING "libltdl 1.2" -| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" -| #define STDC_HEADERS 1 -| #define HAVE_SYS_TYPES_H 1 -| #define HAVE_SYS_STAT_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STRING_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STRINGS_H 1 -| #define HAVE_INTTYPES_H 1 -| #define HAVE_STDINT_H 1 -| #define HAVE_UNISTD_H 1 -| #define HAVE_DLFCN_H 1 -| #define HAVE_DIRENT_H 1 -| #define LTDL_SHLIB_EXT ".so" -| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" -| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" -| #define LTDL_OBJDIR ".libs/" -| #define HAVE_PRELOADED_SYMBOLS 1 -| #define HAVE_LIBDL 1 -| #define HAVE_DLERROR 1 -| #define HAVE_ARGZ_H 1 -| #define HAVE_ERROR_T 1 -| #define HAVE_ARGZ_APPEND 1 -| #define HAVE_ARGZ_CREATE_SEP 1 -| #define HAVE_ARGZ_INSERT 1 -| #define HAVE_ARGZ_NEXT 1 -| #define HAVE_ARGZ_STRINGIFY 1 -| #define HAVE_ASSERT_H 1 -| #define HAVE_CTYPE_H 1 -| #define HAVE_ERRNO_H 1 -| #define HAVE_MALLOC_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STDIO_H 1 -| #define HAVE_UNISTD_H 1 -| /* end confdefs.h. */ -| #include -| #ifdef HAVE_SYS_TYPES_H -| # include -| #endif -| #ifdef HAVE_SYS_STAT_H -| # include -| #endif -| #ifdef STDC_HEADERS -| # include -| # include -| #else -| # ifdef HAVE_STDLIB_H -| # include -| # endif -| #endif -| #ifdef HAVE_STRING_H -| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H -| # include -| # endif -| # include -| #endif -| #ifdef HAVE_STRINGS_H -| # include -| #endif -| #ifdef HAVE_INTTYPES_H -| # include -| #endif -| #ifdef HAVE_STDINT_H -| # include -| #endif -| #ifdef HAVE_UNISTD_H -| # include -| #endif -| #include -configure:21668: result: no -configure:21672: checking dl.h presence -configure:21687: gcc -E conftest.c -conftest.c:42:16: error: dl.h: No such file or directory -configure:21693: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| #define PACKAGE_NAME "libltdl" -| #define PACKAGE_TARNAME "libltdl" -| #define PACKAGE_VERSION "1.2" -| #define PACKAGE_STRING "libltdl 1.2" -| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" -| #define STDC_HEADERS 1 -| #define HAVE_SYS_TYPES_H 1 -| #define HAVE_SYS_STAT_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STRING_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STRINGS_H 1 -| #define HAVE_INTTYPES_H 1 -| #define HAVE_STDINT_H 1 -| #define HAVE_UNISTD_H 1 -| #define HAVE_DLFCN_H 1 -| #define HAVE_DIRENT_H 1 -| #define LTDL_SHLIB_EXT ".so" -| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" -| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" -| #define LTDL_OBJDIR ".libs/" -| #define HAVE_PRELOADED_SYMBOLS 1 -| #define HAVE_LIBDL 1 -| #define HAVE_DLERROR 1 -| #define HAVE_ARGZ_H 1 -| #define HAVE_ERROR_T 1 -| #define HAVE_ARGZ_APPEND 1 -| #define HAVE_ARGZ_CREATE_SEP 1 -| #define HAVE_ARGZ_INSERT 1 -| #define HAVE_ARGZ_NEXT 1 -| #define HAVE_ARGZ_STRINGIFY 1 -| #define HAVE_ASSERT_H 1 -| #define HAVE_CTYPE_H 1 -| #define HAVE_ERRNO_H 1 -| #define HAVE_MALLOC_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STDIO_H 1 -| #define HAVE_UNISTD_H 1 -| /* end confdefs.h. */ -| #include -configure:21707: result: no -configure:21740: checking for dl.h -configure:21748: result: no -configure:21631: checking sys/dl.h usability -configure:21648: gcc -c -g -O2 conftest.c >&5 -conftest.c:75:20: error: sys/dl.h: No such file or directory -configure:21654: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| #define PACKAGE_NAME "libltdl" -| #define PACKAGE_TARNAME "libltdl" -| #define PACKAGE_VERSION "1.2" -| #define PACKAGE_STRING "libltdl 1.2" -| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" -| #define STDC_HEADERS 1 -| #define HAVE_SYS_TYPES_H 1 -| #define HAVE_SYS_STAT_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STRING_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STRINGS_H 1 -| #define HAVE_INTTYPES_H 1 -| #define HAVE_STDINT_H 1 -| #define HAVE_UNISTD_H 1 -| #define HAVE_DLFCN_H 1 -| #define HAVE_DIRENT_H 1 -| #define LTDL_SHLIB_EXT ".so" -| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" -| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" -| #define LTDL_OBJDIR ".libs/" -| #define HAVE_PRELOADED_SYMBOLS 1 -| #define HAVE_LIBDL 1 -| #define HAVE_DLERROR 1 -| #define HAVE_ARGZ_H 1 -| #define HAVE_ERROR_T 1 -| #define HAVE_ARGZ_APPEND 1 -| #define HAVE_ARGZ_CREATE_SEP 1 -| #define HAVE_ARGZ_INSERT 1 -| #define HAVE_ARGZ_NEXT 1 -| #define HAVE_ARGZ_STRINGIFY 1 -| #define HAVE_ASSERT_H 1 -| #define HAVE_CTYPE_H 1 -| #define HAVE_ERRNO_H 1 -| #define HAVE_MALLOC_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STDIO_H 1 -| #define HAVE_UNISTD_H 1 -| /* end confdefs.h. */ -| #include -| #ifdef HAVE_SYS_TYPES_H -| # include -| #endif -| #ifdef HAVE_SYS_STAT_H -| # include -| #endif -| #ifdef STDC_HEADERS -| # include -| # include -| #else -| # ifdef HAVE_STDLIB_H -| # include -| # endif -| #endif -| #ifdef HAVE_STRING_H -| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H -| # include -| # endif -| # include -| #endif -| #ifdef HAVE_STRINGS_H -| # include -| #endif -| #ifdef HAVE_INTTYPES_H -| # include -| #endif -| #ifdef HAVE_STDINT_H -| # include -| #endif -| #ifdef HAVE_UNISTD_H -| # include -| #endif -| #include -configure:21668: result: no -configure:21672: checking sys/dl.h presence -configure:21687: gcc -E conftest.c -conftest.c:42:20: error: sys/dl.h: No such file or directory -configure:21693: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| #define PACKAGE_NAME "libltdl" -| #define PACKAGE_TARNAME "libltdl" -| #define PACKAGE_VERSION "1.2" -| #define PACKAGE_STRING "libltdl 1.2" -| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" -| #define STDC_HEADERS 1 -| #define HAVE_SYS_TYPES_H 1 -| #define HAVE_SYS_STAT_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STRING_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STRINGS_H 1 -| #define HAVE_INTTYPES_H 1 -| #define HAVE_STDINT_H 1 -| #define HAVE_UNISTD_H 1 -| #define HAVE_DLFCN_H 1 -| #define HAVE_DIRENT_H 1 -| #define LTDL_SHLIB_EXT ".so" -| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" -| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" -| #define LTDL_OBJDIR ".libs/" -| #define HAVE_PRELOADED_SYMBOLS 1 -| #define HAVE_LIBDL 1 -| #define HAVE_DLERROR 1 -| #define HAVE_ARGZ_H 1 -| #define HAVE_ERROR_T 1 -| #define HAVE_ARGZ_APPEND 1 -| #define HAVE_ARGZ_CREATE_SEP 1 -| #define HAVE_ARGZ_INSERT 1 -| #define HAVE_ARGZ_NEXT 1 -| #define HAVE_ARGZ_STRINGIFY 1 -| #define HAVE_ASSERT_H 1 -| #define HAVE_CTYPE_H 1 -| #define HAVE_ERRNO_H 1 -| #define HAVE_MALLOC_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STDIO_H 1 -| #define HAVE_UNISTD_H 1 -| /* end confdefs.h. */ -| #include -configure:21707: result: no -configure:21740: checking for sys/dl.h -configure:21748: result: no -configure:21631: checking dld.h usability -configure:21648: gcc -c -g -O2 conftest.c >&5 -conftest.c:75:17: error: dld.h: No such file or directory -configure:21654: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| #define PACKAGE_NAME "libltdl" -| #define PACKAGE_TARNAME "libltdl" -| #define PACKAGE_VERSION "1.2" -| #define PACKAGE_STRING "libltdl 1.2" -| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" -| #define STDC_HEADERS 1 -| #define HAVE_SYS_TYPES_H 1 -| #define HAVE_SYS_STAT_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STRING_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STRINGS_H 1 -| #define HAVE_INTTYPES_H 1 -| #define HAVE_STDINT_H 1 -| #define HAVE_UNISTD_H 1 -| #define HAVE_DLFCN_H 1 -| #define HAVE_DIRENT_H 1 -| #define LTDL_SHLIB_EXT ".so" -| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" -| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" -| #define LTDL_OBJDIR ".libs/" -| #define HAVE_PRELOADED_SYMBOLS 1 -| #define HAVE_LIBDL 1 -| #define HAVE_DLERROR 1 -| #define HAVE_ARGZ_H 1 -| #define HAVE_ERROR_T 1 -| #define HAVE_ARGZ_APPEND 1 -| #define HAVE_ARGZ_CREATE_SEP 1 -| #define HAVE_ARGZ_INSERT 1 -| #define HAVE_ARGZ_NEXT 1 -| #define HAVE_ARGZ_STRINGIFY 1 -| #define HAVE_ASSERT_H 1 -| #define HAVE_CTYPE_H 1 -| #define HAVE_ERRNO_H 1 -| #define HAVE_MALLOC_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STDIO_H 1 -| #define HAVE_UNISTD_H 1 -| /* end confdefs.h. */ -| #include -| #ifdef HAVE_SYS_TYPES_H -| # include -| #endif -| #ifdef HAVE_SYS_STAT_H -| # include -| #endif -| #ifdef STDC_HEADERS -| # include -| # include -| #else -| # ifdef HAVE_STDLIB_H -| # include -| # endif -| #endif -| #ifdef HAVE_STRING_H -| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H -| # include -| # endif -| # include -| #endif -| #ifdef HAVE_STRINGS_H -| # include -| #endif -| #ifdef HAVE_INTTYPES_H -| # include -| #endif -| #ifdef HAVE_STDINT_H -| # include -| #endif -| #ifdef HAVE_UNISTD_H -| # include -| #endif -| #include -configure:21668: result: no -configure:21672: checking dld.h presence -configure:21687: gcc -E conftest.c -conftest.c:42:17: error: dld.h: No such file or directory -configure:21693: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| #define PACKAGE_NAME "libltdl" -| #define PACKAGE_TARNAME "libltdl" -| #define PACKAGE_VERSION "1.2" -| #define PACKAGE_STRING "libltdl 1.2" -| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" -| #define STDC_HEADERS 1 -| #define HAVE_SYS_TYPES_H 1 -| #define HAVE_SYS_STAT_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STRING_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STRINGS_H 1 -| #define HAVE_INTTYPES_H 1 -| #define HAVE_STDINT_H 1 -| #define HAVE_UNISTD_H 1 -| #define HAVE_DLFCN_H 1 -| #define HAVE_DIRENT_H 1 -| #define LTDL_SHLIB_EXT ".so" -| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" -| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" -| #define LTDL_OBJDIR ".libs/" -| #define HAVE_PRELOADED_SYMBOLS 1 -| #define HAVE_LIBDL 1 -| #define HAVE_DLERROR 1 -| #define HAVE_ARGZ_H 1 -| #define HAVE_ERROR_T 1 -| #define HAVE_ARGZ_APPEND 1 -| #define HAVE_ARGZ_CREATE_SEP 1 -| #define HAVE_ARGZ_INSERT 1 -| #define HAVE_ARGZ_NEXT 1 -| #define HAVE_ARGZ_STRINGIFY 1 -| #define HAVE_ASSERT_H 1 -| #define HAVE_CTYPE_H 1 -| #define HAVE_ERRNO_H 1 -| #define HAVE_MALLOC_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STDIO_H 1 -| #define HAVE_UNISTD_H 1 -| /* end confdefs.h. */ -| #include -configure:21707: result: no -configure:21740: checking for dld.h -configure:21748: result: no -configure:21631: checking mach-o/dyld.h usability -configure:21648: gcc -c -g -O2 conftest.c >&5 -conftest.c:75:25: error: mach-o/dyld.h: No such file or directory -configure:21654: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| #define PACKAGE_NAME "libltdl" -| #define PACKAGE_TARNAME "libltdl" -| #define PACKAGE_VERSION "1.2" -| #define PACKAGE_STRING "libltdl 1.2" -| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" -| #define STDC_HEADERS 1 -| #define HAVE_SYS_TYPES_H 1 -| #define HAVE_SYS_STAT_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STRING_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STRINGS_H 1 -| #define HAVE_INTTYPES_H 1 -| #define HAVE_STDINT_H 1 -| #define HAVE_UNISTD_H 1 -| #define HAVE_DLFCN_H 1 -| #define HAVE_DIRENT_H 1 -| #define LTDL_SHLIB_EXT ".so" -| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" -| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" -| #define LTDL_OBJDIR ".libs/" -| #define HAVE_PRELOADED_SYMBOLS 1 -| #define HAVE_LIBDL 1 -| #define HAVE_DLERROR 1 -| #define HAVE_ARGZ_H 1 -| #define HAVE_ERROR_T 1 -| #define HAVE_ARGZ_APPEND 1 -| #define HAVE_ARGZ_CREATE_SEP 1 -| #define HAVE_ARGZ_INSERT 1 -| #define HAVE_ARGZ_NEXT 1 -| #define HAVE_ARGZ_STRINGIFY 1 -| #define HAVE_ASSERT_H 1 -| #define HAVE_CTYPE_H 1 -| #define HAVE_ERRNO_H 1 -| #define HAVE_MALLOC_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STDIO_H 1 -| #define HAVE_UNISTD_H 1 -| /* end confdefs.h. */ -| #include -| #ifdef HAVE_SYS_TYPES_H -| # include -| #endif -| #ifdef HAVE_SYS_STAT_H -| # include -| #endif -| #ifdef STDC_HEADERS -| # include -| # include -| #else -| # ifdef HAVE_STDLIB_H -| # include -| # endif -| #endif -| #ifdef HAVE_STRING_H -| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H -| # include -| # endif -| # include -| #endif -| #ifdef HAVE_STRINGS_H -| # include -| #endif -| #ifdef HAVE_INTTYPES_H -| # include -| #endif -| #ifdef HAVE_STDINT_H -| # include -| #endif -| #ifdef HAVE_UNISTD_H -| # include -| #endif -| #include -configure:21668: result: no -configure:21672: checking mach-o/dyld.h presence -configure:21687: gcc -E conftest.c -conftest.c:42:25: error: mach-o/dyld.h: No such file or directory -configure:21693: $? = 1 -configure: failed program was: -| /* confdefs.h. */ -| #define PACKAGE_NAME "libltdl" -| #define PACKAGE_TARNAME "libltdl" -| #define PACKAGE_VERSION "1.2" -| #define PACKAGE_STRING "libltdl 1.2" -| #define PACKAGE_BUGREPORT "bug-libtool@gnu.org" -| #define STDC_HEADERS 1 -| #define HAVE_SYS_TYPES_H 1 -| #define HAVE_SYS_STAT_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STRING_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STRINGS_H 1 -| #define HAVE_INTTYPES_H 1 -| #define HAVE_STDINT_H 1 -| #define HAVE_UNISTD_H 1 -| #define HAVE_DLFCN_H 1 -| #define HAVE_DIRENT_H 1 -| #define LTDL_SHLIB_EXT ".so" -| #define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" -| #define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" -| #define LTDL_OBJDIR ".libs/" -| #define HAVE_PRELOADED_SYMBOLS 1 -| #define HAVE_LIBDL 1 -| #define HAVE_DLERROR 1 -| #define HAVE_ARGZ_H 1 -| #define HAVE_ERROR_T 1 -| #define HAVE_ARGZ_APPEND 1 -| #define HAVE_ARGZ_CREATE_SEP 1 -| #define HAVE_ARGZ_INSERT 1 -| #define HAVE_ARGZ_NEXT 1 -| #define HAVE_ARGZ_STRINGIFY 1 -| #define HAVE_ASSERT_H 1 -| #define HAVE_CTYPE_H 1 -| #define HAVE_ERRNO_H 1 -| #define HAVE_MALLOC_H 1 -| #define HAVE_MEMORY_H 1 -| #define HAVE_STDLIB_H 1 -| #define HAVE_STDIO_H 1 -| #define HAVE_UNISTD_H 1 -| /* end confdefs.h. */ -| #include -configure:21707: result: no -configure:21740: checking for mach-o/dyld.h -configure:21748: result: no -configure:21767: checking for string.h -configure:21773: result: yes -configure:21913: checking for strchr -configure:21969: gcc -o conftest -g -O2 conftest.c >&5 -conftest.c:66: warning: conflicting types for built-in function 'strchr' -configure:21975: $? = 0 -configure:21993: result: yes -configure:22008: checking for strrchr -configure:22064: gcc -o conftest -g -O2 conftest.c >&5 -conftest.c:67: warning: conflicting types for built-in function 'strrchr' -configure:22070: $? = 0 -configure:22088: result: yes -configure:22103: checking for memcpy -configure:22159: gcc -o conftest -g -O2 conftest.c >&5 -conftest.c:68: warning: conflicting types for built-in function 'memcpy' -configure:22165: $? = 0 -configure:22183: result: yes -configure:22198: checking for memmove -configure:22254: gcc -o conftest -g -O2 conftest.c >&5 -conftest.c:69: warning: conflicting types for built-in function 'memmove' -configure:22260: $? = 0 -configure:22278: result: yes -configure:22198: checking for strcmp -configure:22254: gcc -o conftest -g -O2 conftest.c >&5 -conftest.c:70: warning: conflicting types for built-in function 'strcmp' -configure:22260: $? = 0 -configure:22278: result: yes -configure:22294: checking for closedir -configure:22350: gcc -o conftest -g -O2 conftest.c >&5 -configure:22356: $? = 0 -configure:22374: result: yes -configure:22294: checking for opendir -configure:22350: gcc -o conftest -g -O2 conftest.c >&5 -configure:22356: $? = 0 -configure:22374: result: yes -configure:22294: checking for readdir -configure:22350: gcc -o conftest -g -O2 conftest.c >&5 -configure:22356: $? = 0 -configure:22374: result: yes -configure:22527: creating ./config.status - -## ---------------------- ## -## Running config.status. ## -## ---------------------- ## - -This file was extended by libltdl config.status 1.2, which was -generated by GNU Autoconf 2.61. Invocation command line was - - CONFIG_FILES = - CONFIG_HEADERS = - CONFIG_LINKS = - CONFIG_COMMANDS = - $ ./config.status - -on lambda - -config.status:671: creating Makefile -config.status:671: creating config.h -config.status:936: config.h is unchanged -config.status:982: executing depfiles commands - -## ---------------- ## -## Cache variables. ## -## ---------------- ## - -ac_cv_build=i686-pc-linux-gnu -ac_cv_c_compiler_gnu=yes -ac_cv_c_const=yes -ac_cv_c_inline=inline -ac_cv_cxx_compiler_gnu=yes -ac_cv_env_CCC_set= -ac_cv_env_CCC_value= -ac_cv_env_CC_set= -ac_cv_env_CC_value= -ac_cv_env_CFLAGS_set= -ac_cv_env_CFLAGS_value= -ac_cv_env_CPPFLAGS_set= -ac_cv_env_CPPFLAGS_value= -ac_cv_env_CPP_set= -ac_cv_env_CPP_value= -ac_cv_env_CXXCPP_set= -ac_cv_env_CXXCPP_value= -ac_cv_env_CXXFLAGS_set= -ac_cv_env_CXXFLAGS_value= -ac_cv_env_CXX_set= -ac_cv_env_CXX_value= -ac_cv_env_F77_set= -ac_cv_env_F77_value= -ac_cv_env_FFLAGS_set= -ac_cv_env_FFLAGS_value= -ac_cv_env_LDFLAGS_set= -ac_cv_env_LDFLAGS_value= -ac_cv_env_LIBS_set= -ac_cv_env_LIBS_value= -ac_cv_env_build_alias_set= -ac_cv_env_build_alias_value= -ac_cv_env_host_alias_set= -ac_cv_env_host_alias_value= -ac_cv_env_target_alias_set= -ac_cv_env_target_alias_value= -ac_cv_f77_compiler_gnu=yes -ac_cv_func_argz_append=yes -ac_cv_func_argz_create_sep=yes -ac_cv_func_argz_insert=yes -ac_cv_func_argz_next=yes -ac_cv_func_argz_stringify=yes -ac_cv_func_closedir=yes -ac_cv_func_dlerror=yes -ac_cv_func_memcpy=yes -ac_cv_func_memmove=yes -ac_cv_func_opendir=yes -ac_cv_func_readdir=yes -ac_cv_func_shl_load=no -ac_cv_func_strchr=yes -ac_cv_func_strcmp=yes -ac_cv_func_strrchr=yes -ac_cv_header_argz_h=yes -ac_cv_header_assert_h=yes -ac_cv_header_ctype_h=yes -ac_cv_header_dirent_dirent_h=yes -ac_cv_header_dl_h=no -ac_cv_header_dld_h=no -ac_cv_header_dlfcn_h=yes -ac_cv_header_errno_h=yes -ac_cv_header_inttypes_h=yes -ac_cv_header_mach_o_dyld_h=no -ac_cv_header_malloc_h=yes -ac_cv_header_memory_h=yes -ac_cv_header_stdc=yes -ac_cv_header_stdint_h=yes -ac_cv_header_stdio_h=yes -ac_cv_header_stdlib_h=yes -ac_cv_header_string_h=yes -ac_cv_header_strings_h=yes -ac_cv_header_sys_dl_h=no -ac_cv_header_sys_stat_h=yes -ac_cv_header_sys_types_h=yes -ac_cv_header_unistd_h=yes -ac_cv_host=i686-pc-linux-gnu -ac_cv_lib_dl_dlopen=yes -ac_cv_lib_dld_shl_load=no -ac_cv_objext=o -ac_cv_path_EGREP='/bin/grep -E' -ac_cv_path_GREP=/bin/grep -ac_cv_path_install='/usr/bin/install -c' -ac_cv_path_mkdir=/bin/mkdir -ac_cv_prog_AWK=gawk -ac_cv_prog_CPP='gcc -E' -ac_cv_prog_CXXCPP='g++ -E' -ac_cv_prog_ac_ct_AR=ar -ac_cv_prog_ac_ct_CC=gcc -ac_cv_prog_ac_ct_CXX=g++ -ac_cv_prog_ac_ct_F77=gfortran -ac_cv_prog_ac_ct_RANLIB=ranlib -ac_cv_prog_ac_ct_STRIP=strip -ac_cv_prog_cc_c89= -ac_cv_prog_cc_g=yes -ac_cv_prog_cxx_g=yes -ac_cv_prog_f77_g=yes -ac_cv_prog_make_make_set=yes -ac_cv_search_opendir='none required' -ac_cv_sys_symbol_underscore=no -ac_cv_type_error_t=yes -am_cv_CC_dependencies_compiler_type=none -am_cv_CXX_dependencies_compiler_type=none -libltdl_cv_lib_dl_dlopen=yes -libltdl_cv_objdir=.libs -libltdl_cv_preloaded_symbols=yes -libltdl_cv_shlibext=.so -libltdl_cv_shlibpath_var=LD_LIBRARY_PATH -libltdl_cv_sys_dlopen_deplibs=yes -libltdl_cv_sys_search_path='/usr/lib /lib /usr/lib/qt-3.3/lib ' -lt_cv_deplibs_check_method=pass_all -lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_ld_reload_flag=-r -lt_cv_objdir=.libs -lt_cv_path_LD=/usr/bin/ld -lt_cv_path_LDCXX=/usr/bin/ld -lt_cv_path_NM='/usr/bin/nm -B' -lt_cv_path_SED=/bin/sed -lt_cv_prog_compiler_c_o=yes -lt_cv_prog_compiler_c_o_CXX=yes -lt_cv_prog_compiler_c_o_F77=yes -lt_cv_prog_compiler_rtti_exceptions=no -lt_cv_prog_gnu_ld=yes -lt_cv_prog_gnu_ldcxx=yes -lt_cv_sys_global_symbol_pipe='sed -n -e '\''s/^.*[ ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[ ][ ]*\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2 \2/p'\''' -lt_cv_sys_global_symbol_to_c_name_address='sed -n -e '\''s/^: \([^ ]*\) $/ {\"\1\", (lt_ptr) 0},/p'\'' -e '\''s/^[BCDEGRST] \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr) \&\2},/p'\''' -lt_cv_sys_global_symbol_to_cdecl='sed -n -e '\''s/^. .* \(.*\)$/extern int \1;/p'\''' -lt_cv_sys_max_cmd_len=98304 -lt_lt_cv_prog_compiler_c_o='"yes"' -lt_lt_cv_prog_compiler_c_o_CXX='"yes"' -lt_lt_cv_prog_compiler_c_o_F77='"yes"' -lt_lt_cv_sys_global_symbol_pipe='"sed -n -e '\''s/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2 \\2/p'\''"' -lt_lt_cv_sys_global_symbol_to_c_name_address='"sed -n -e '\''s/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p'\'' -e '\''s/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'\''"' -lt_lt_cv_sys_global_symbol_to_cdecl='"sed -n -e '\''s/^. .* \\(.*\\)\$/extern int \\1;/p'\''"' - -## ----------------- ## -## Output variables. ## -## ----------------- ## - -ACLOCAL='${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run aclocal-1.10' -AMDEPBACKSLASH='\' -AMDEP_FALSE='#' -AMDEP_TRUE='' -AMTAR='${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run tar' -AR='ar' -AS='as' -AUTOCONF='${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run autoconf' -AUTOHEADER='${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run autoheader' -AUTOMAKE='${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run automake-1.10' -AWK='gawk' -CC='gcc' -CCDEPMODE='depmode=none' -CFLAGS='-g -O2' -CONVENIENCE_LTDL_FALSE='' -CONVENIENCE_LTDL_TRUE='#' -CPP='gcc -E' -CPPFLAGS='' -CXX='g++' -CXXCPP='g++ -E' -CXXDEPMODE='depmode=none' -CXXFLAGS='-g -O2' -CYGPATH_W='echo' -DEFS='-DHAVE_CONFIG_H' -DEPDIR='.deps' -DLLTOOL='dlltool' -ECHO='echo' -ECHO_C='' -ECHO_N='-n' -ECHO_T='' -EGREP='/bin/grep -E' -EXEEXT='' -F77='gfortran' -FFLAGS='-g -O2' -GREP='/bin/grep' -INSTALL_DATA='${INSTALL} -m 644' -INSTALL_LTDL_FALSE='#' -INSTALL_LTDL_TRUE='' -INSTALL_PROGRAM='${INSTALL}' -INSTALL_SCRIPT='${INSTALL}' -INSTALL_STRIP_PROGRAM='$(install_sh) -c -s' -LDFLAGS='' -LIBADD_DL='-ldl' -LIBOBJS='' -LIBS='' -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -LIBTOOL_DEPS='./ltmain.sh' -LN_S='ln -s' -LTLIBOBJS='' -MAKEINFO='${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run makeinfo' -OBJDUMP='objdump' -OBJEXT='o' -PACKAGE='libltdl' -PACKAGE_BUGREPORT='bug-libtool@gnu.org' -PACKAGE_NAME='libltdl' -PACKAGE_STRING='libltdl 1.2' -PACKAGE_TARNAME='libltdl' -PACKAGE_VERSION='1.2' -PATH_SEPARATOR=':' -RANLIB='ranlib' -SED='/bin/sed' -SET_MAKE='' -SHELL='/bin/sh' -STRIP='strip' -VERSION='1.2' -ac_ct_CC='gcc' -ac_ct_CXX='g++' -ac_ct_F77='gfortran' -am__fastdepCC_FALSE='' -am__fastdepCC_TRUE='#' -am__fastdepCXX_FALSE='' -am__fastdepCXX_TRUE='#' -am__include='include' -am__isrc='' -am__leading_dot='.' -am__quote='' -am__tar='${AMTAR} chof - "$$tardir"' -am__untar='${AMTAR} xf -' -bindir='${exec_prefix}/bin' -build='i686-pc-linux-gnu' -build_alias='' -build_cpu='i686' -build_os='linux-gnu' -build_vendor='pc' -datadir='${datarootdir}' -datarootdir='${prefix}/share' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -dvidir='${docdir}' -exec_prefix='${prefix}' -host='i686-pc-linux-gnu' -host_alias='' -host_cpu='i686' -host_os='linux-gnu' -host_vendor='pc' -htmldir='${docdir}' -includedir='${prefix}/include' -infodir='${datarootdir}/info' -install_sh='$(SHELL) /home/lennart/projects/pulseaudio/libltdl/install-sh' -libdir='${exec_prefix}/lib' -libexecdir='${exec_prefix}/libexec' -localedir='${datarootdir}/locale' -localstatedir='${prefix}/var' -mandir='${datarootdir}/man' -mkdir_p='/bin/mkdir -p' -oldincludedir='/usr/include' -pdfdir='${docdir}' -prefix='/usr/local' -program_transform_name='s,x,x,' -psdir='${docdir}' -sbindir='${exec_prefix}/sbin' -sharedstatedir='${prefix}/com' -sysconfdir='${prefix}/etc' -target_alias='' - -## ----------- ## -## confdefs.h. ## -## ----------- ## - -#define PACKAGE_NAME "libltdl" -#define PACKAGE_TARNAME "libltdl" -#define PACKAGE_VERSION "1.2" -#define PACKAGE_STRING "libltdl 1.2" -#define PACKAGE_BUGREPORT "bug-libtool@gnu.org" -#define STDC_HEADERS 1 -#define HAVE_SYS_TYPES_H 1 -#define HAVE_SYS_STAT_H 1 -#define HAVE_STDLIB_H 1 -#define HAVE_STRING_H 1 -#define HAVE_MEMORY_H 1 -#define HAVE_STRINGS_H 1 -#define HAVE_INTTYPES_H 1 -#define HAVE_STDINT_H 1 -#define HAVE_UNISTD_H 1 -#define HAVE_DLFCN_H 1 -#define HAVE_DIRENT_H 1 -#define LTDL_SHLIB_EXT ".so" -#define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" -#define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" -#define LTDL_OBJDIR ".libs/" -#define HAVE_PRELOADED_SYMBOLS 1 -#define HAVE_LIBDL 1 -#define HAVE_DLERROR 1 -#define HAVE_ARGZ_H 1 -#define HAVE_ERROR_T 1 -#define HAVE_ARGZ_APPEND 1 -#define HAVE_ARGZ_CREATE_SEP 1 -#define HAVE_ARGZ_INSERT 1 -#define HAVE_ARGZ_NEXT 1 -#define HAVE_ARGZ_STRINGIFY 1 -#define HAVE_ASSERT_H 1 -#define HAVE_CTYPE_H 1 -#define HAVE_ERRNO_H 1 -#define HAVE_MALLOC_H 1 -#define HAVE_MEMORY_H 1 -#define HAVE_STDLIB_H 1 -#define HAVE_STDIO_H 1 -#define HAVE_UNISTD_H 1 -#define HAVE_STRING_H 1 -#define HAVE_STRCHR 1 -#define HAVE_STRRCHR 1 -#define HAVE_MEMCPY 1 -#define HAVE_MEMMOVE 1 -#define HAVE_STRCMP 1 -#define HAVE_CLOSEDIR 1 -#define HAVE_OPENDIR 1 -#define HAVE_READDIR 1 - -configure: exit 0 diff --git a/libltdl/config.status b/libltdl/config.status deleted file mode 100755 index c7316a4f..00000000 --- a/libltdl/config.status +++ /dev/null @@ -1,1118 +0,0 @@ -#! /bin/sh -# Generated by configure. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false -SHELL=${CONFIG_SHELL-/bin/sh} -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - -fi - - - - -# PATH needs CR -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -as_nl=' -' -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - { (exit 1); exit 1; } -fi - -# Work around bugs in pre-3.0 UWIN ksh. -for as_var in ENV MAIL MAILPATH -do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# CDPATH. -$as_unset CDPATH - - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line after each line using $LINENO; the second 'sed' - # does the real work. The second script uses 'N' to pair each - # line-number line with the line containing $LINENO, and appends - # trailing '-' during substitution so that $LINENO is not a special - # case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # scripts with optimization help from Paolo Bonzini. Blame Lee - # E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in --n*) - case `echo 'x\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - *) ECHO_C='\c';; - esac;; -*) - ECHO_N='-n';; -esac - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir -fi -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 - -# Save the log message, to keep $[0] and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by libltdl $as_me 1.2, which was -generated by GNU Autoconf 2.61. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -# Files that config.status was made for. -config_files=" Makefile" -config_headers=" config.h:config-h.in" -config_commands=" depfiles" - -ac_cs_usage="\ -\`$as_me' instantiates files from templates according to the -current configuration. - -Usage: $0 [OPTIONS] [FILE]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Configuration commands: -$config_commands - -Report bugs to ." - -ac_cs_version="\ -libltdl config.status 1.2 -configured by ./configure, generated by GNU Autoconf 2.61, - with options \"\" - -Copyright (C) 2006 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='/home/lennart/projects/pulseaudio/libltdl' -srcdir='.' -INSTALL='/usr/bin/install -c' -MKDIR_P='/bin/mkdir -p' -# If no file are specified by the user, then we need to provide default -# value. By we need to know if files were specified by the user. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - echo "$ac_cs_version"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - CONFIG_FILES="$CONFIG_FILES $ac_optarg" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - { echo "$as_me: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; };; - --help | --hel | -h ) - echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) { echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } ;; - - *) ac_config_targets="$ac_config_targets $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -if $ac_cs_recheck; then - echo "running CONFIG_SHELL=/bin/sh /bin/sh ./configure " $ac_configure_extra_args " --no-create --no-recursion" >&6 - CONFIG_SHELL=/bin/sh - export CONFIG_SHELL - exec /bin/sh "./configure" $ac_configure_extra_args --no-create --no-recursion -fi - -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - echo "$ac_log" -} >&5 - -# -# INIT-COMMANDS -# -AMDEP_TRUE="" ac_aux_dir="." - - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:config-h.in" ;; - "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - - *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -echo "$as_me: error: invalid argument: $ac_config_target" >&2;} - { (exit 1); exit 1; }; };; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= - trap 'exit_status=$? - { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status -' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || -{ - echo "$me: cannot create a temporary directory in ." >&2 - { (exit 1); exit 1; } -} - -# -# Set up the sed scripts for CONFIG_FILES section. -# - -# No need to generate the scripts if there are no CONFIG_FILES. -# This happens for instance when ./config.status config.h -if test -n "$CONFIG_FILES"; then - -cat >"$tmp/subs-1.sed" <<\CEOF -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s,@SHELL@,|#_!!_#|/bin/sh,g -s,@PATH_SEPARATOR@,|#_!!_#|:,g -s,@PACKAGE_NAME@,|#_!!_#|libltdl,g -s,@PACKAGE_TARNAME@,|#_!!_#|libltdl,g -s,@PACKAGE_VERSION@,|#_!!_#|1.2,g -s,@PACKAGE_STRING@,|#_!!_#|libltdl 1.2,g -s,@PACKAGE_BUGREPORT@,|#_!!_#|bug-libtool@|#_!!_#|gnu.org,g -s,@exec_prefix@,|#_!!_#|${prefix},g -s,@prefix@,|#_!!_#|/usr/local,g -s,@program_transform_name@,|#_!!_#|s\,x\,x\,,g -s,@bindir@,|#_!!_#|${exec_prefix}/bin,g -s,@sbindir@,|#_!!_#|${exec_prefix}/sbin,g -s,@libexecdir@,|#_!!_#|${exec_prefix}/libexec,g -s,@datarootdir@,|#_!!_#|${prefix}/share,g -s,@datadir@,|#_!!_#|${datarootdir},g -s,@sysconfdir@,|#_!!_#|${prefix}/etc,g -s,@sharedstatedir@,|#_!!_#|${prefix}/com,g -s,@localstatedir@,|#_!!_#|${prefix}/var,g -s,@includedir@,|#_!!_#|${prefix}/include,g -s,@oldincludedir@,|#_!!_#|/usr/include,g -s,@docdir@,|#_!!_#|${datarootdir}/doc/${PACKAGE_TARNAME},g -s,@infodir@,|#_!!_#|${datarootdir}/info,g -s,@htmldir@,|#_!!_#|${docdir},g -s,@dvidir@,|#_!!_#|${docdir},g -s,@pdfdir@,|#_!!_#|${docdir},g -s,@psdir@,|#_!!_#|${docdir},g -s,@libdir@,|#_!!_#|${exec_prefix}/lib,g -s,@localedir@,|#_!!_#|${datarootdir}/locale,g -s,@mandir@,|#_!!_#|${datarootdir}/man,g -s,@DEFS@,|#_!!_#|-DHAVE_CONFIG_H,g -s,@ECHO_C@,|#_!!_#|,g -s,@ECHO_N@,|#_!!_#|-n,g -s,@ECHO_T@,|#_!!_#|,g -s,@LIBS@,|#_!!_#|,g -s,@build_alias@,|#_!!_#|,g -s,@host_alias@,|#_!!_#|,g -s,@target_alias@,|#_!!_#|,g -s,@INSTALL_PROGRAM@,|#_!!_#|${INSTALL},g -s,@INSTALL_SCRIPT@,|#_!!_#|${INSTALL},g -s,@INSTALL_DATA@,|#_!!_#|${INSTALL} -m 644,g -s,@am__isrc@,|#_!!_#|,g -s,@CYGPATH_W@,|#_!!_#|echo,g -s,@PACKAGE@,|#_!!_#|libltdl,g -s,@VERSION@,|#_!!_#|1.2,g -s,@ACLOCAL@,|#_!!_#|${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run aclocal-1.10,g -s,@AUTOCONF@,|#_!!_#|${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run autoconf,g -s,@AUTOMAKE@,|#_!!_#|${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run automake-1.10,g -s,@AUTOHEADER@,|#_!!_#|${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run autoheader,g -s,@MAKEINFO@,|#_!!_#|${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run makeinfo,g -s,@install_sh@,|#_!!_#|$(SHELL) /home/lennart/projects/pulseaudio/libltdl/install-sh,g -s,@STRIP@,|#_!!_#|strip,g -s,@INSTALL_STRIP_PROGRAM@,|#_!!_#|$(install_sh) -c -s,g -s,@mkdir_p@,|#_!!_#|/bin/mkdir -p,g -s,@AWK@,|#_!!_#|gawk,g -s,@SET_MAKE@,|#_!!_#|,g -s,@am__leading_dot@,|#_!!_#|.,g -s,@AMTAR@,|#_!!_#|${SHELL} /home/lennart/projects/pulseaudio/libltdl/missing --run tar,g -s,@am__tar@,|#_!!_#|${AMTAR} chof - "$$tardir",g -s,@am__untar@,|#_!!_#|${AMTAR} xf -,g -s,@CC@,|#_!!_#|gcc,g -s,@CFLAGS@,|#_!!_#|-g -O2,g -s,@LDFLAGS@,|#_!!_#|,g -s,@CPPFLAGS@,|#_!!_#|,g -s,@ac_ct_CC@,|#_!!_#|gcc,g -s,@EXEEXT@,|#_!!_#|,g -s,@OBJEXT@,|#_!!_#|o,g -s,@DEPDIR@,|#_!!_#|.deps,g -s,@am__include@,|#_!!_#|include,g -s,@am__quote@,|#_!!_#|,g -s,@AMDEP_TRUE@,|#_!!_#|,g -s,@AMDEP_FALSE@,|#_!!_#|#,g -s,@AMDEPBACKSLASH@,|#_!!_#|\\,g -s,@CCDEPMODE@,|#_!!_#|depmode=none,g -s,@am__fastdepCC_TRUE@,|#_!!_#|#,g -s,@am__fastdepCC_FALSE@,|#_!!_#|,g -s,@build@,|#_!!_#|i686-pc-linux-gnu,g -s,@build_cpu@,|#_!!_#|i686,g -s,@build_vendor@,|#_!!_#|pc,g -s,@build_os@,|#_!!_#|linux-gnu,g -s,@host@,|#_!!_#|i686-pc-linux-gnu,g -s,@host_cpu@,|#_!!_#|i686,g -s,@host_vendor@,|#_!!_#|pc,g -s,@host_os@,|#_!!_#|linux-gnu,g -s,@SED@,|#_!!_#|/bin/sed,g -s,@GREP@,|#_!!_#|/bin/grep,g -s,@EGREP@,|#_!!_#|/bin/grep -E,g -s,@LN_S@,|#_!!_#|ln -s,g -s,@ECHO@,|#_!!_#|echo,g -s,@AR@,|#_!!_#|ar,g -s,@RANLIB@,|#_!!_#|ranlib,g -s,@DLLTOOL@,|#_!!_#|dlltool,g -s,@AS@,|#_!!_#|as,g -s,@OBJDUMP@,|#_!!_#|objdump,g -s,@CPP@,|#_!!_#|gcc -E,g -s,@CXX@,|#_!!_#|g++,g -s,@CXXFLAGS@,|#_!!_#|-g -O2,g -s,@ac_ct_CXX@,|#_!!_#|g++,g -CEOF -cat >"$tmp/subs-2.sed" <<\CEOF -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end -s,@CXXDEPMODE@,|#_!!_#|depmode=none,g -s,@am__fastdepCXX_TRUE@,|#_!!_#|#,g -s,@am__fastdepCXX_FALSE@,|#_!!_#|,g -s,@CXXCPP@,|#_!!_#|g++ -E,g -s,@F77@,|#_!!_#|gfortran,g -s,@FFLAGS@,|#_!!_#|-g -O2,g -s,@ac_ct_F77@,|#_!!_#|gfortran,g -s,@LIBTOOL@,|#_!!_#|$(SHELL) $(top_builddir)/libtool,g -s,@LIBTOOL_DEPS@,|#_!!_#|./ltmain.sh,g -s,@INSTALL_LTDL_TRUE@,|#_!!_#|,g -s,@INSTALL_LTDL_FALSE@,|#_!!_#|#,g -s,@CONVENIENCE_LTDL_TRUE@,|#_!!_#|#,g -s,@CONVENIENCE_LTDL_FALSE@,|#_!!_#|,g -s,@LIBADD_DL@,|#_!!_#|-ldl,g -s,@LIBOBJS@,|#_!!_#|,g -s,@LTLIBOBJS@,|#_!!_#|,g -:end -s/|#_!!_#|//g -CEOF -fi # test -n "$CONFIG_FILES" - - -for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 -echo "$as_me: error: Invalid tag $ac_tag." >&2;} - { (exit 1); exit 1; }; };; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 -echo "$as_me: error: cannot find input file: $ac_f" >&2;} - { (exit 1); exit 1; }; };; - esac - ac_file_inputs="$ac_file_inputs $ac_f" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input="Generated from "`IFS=: - echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - fi - - case $ac_tag in - *:-:* | *:-) cat >"$tmp/stdin";; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - { as_dir="$ac_dir" - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 -echo "$as_me: error: cannot create directory $as_dir" >&2;} - { (exit 1); exit 1; }; }; } - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac - ac_MKDIR_P=$MKDIR_P - case $MKDIR_P in - [\\/$]* | ?:[\\/]* ) ;; - */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; - esac -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= - -case `sed -n '/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p -' $ac_file_inputs` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} - ac_datarootdir_hack=' - s&@datadir@&${datarootdir}&g - s&@docdir@&${datarootdir}/doc/${PACKAGE_TARNAME}&g - s&@infodir@&${datarootdir}/info&g - s&@localedir@&${datarootdir}/locale&g - s&@mandir@&${datarootdir}/man&g - s&\${datarootdir}&${prefix}/share&g' ;; -esac - sed "/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/ -s/:*\${srcdir}:*/:/ -s/:*@srcdir@:*/:/ -s/^\([^=]*=[ ]*\):*/\1/ -s/:*$// -s/^[^=]*=[ ]*$// -} - -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s&@configure_input@&$configure_input&;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -s&@MKDIR_P@&$ac_MKDIR_P&;t t -$ac_datarootdir_hack -" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && - { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&5 -echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&2;} - - rm -f "$tmp/stdin" - case $ac_file in - -) cat "$tmp/out"; rm -f "$tmp/out";; - *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; - esac - ;; - :H) - # - # CONFIG_HEADER - # - # First, check the format of the line: - cat >"$tmp/defines.sed" <<\CEOF -/^[ ]*#[ ]*undef[ ][ ]*[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*[ ]*$/b def -/^[ ]*#[ ]*define[ ][ ]*[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*[( ]/b def -b -:def -s/$/ / -s,^\([ #]*\)[^ ]*\([ ]*PACKAGE_NAME\)[ (].*,\1define\2 "libltdl" , -s,^\([ #]*\)[^ ]*\([ ]*PACKAGE_TARNAME\)[ (].*,\1define\2 "libltdl" , -s,^\([ #]*\)[^ ]*\([ ]*PACKAGE_VERSION\)[ (].*,\1define\2 "1.2" , -s,^\([ #]*\)[^ ]*\([ ]*PACKAGE_STRING\)[ (].*,\1define\2 "libltdl 1.2" , -s,^\([ #]*\)[^ ]*\([ ]*PACKAGE_BUGREPORT\)[ (].*,\1define\2 "bug-libtool@gnu.org" , -s,^\([ #]*\)[^ ]*\([ ]*STDC_HEADERS\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_SYS_TYPES_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_SYS_STAT_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_STDLIB_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_STRING_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_MEMORY_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_STRINGS_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_INTTYPES_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_STDINT_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_UNISTD_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_DLFCN_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_DIRENT_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*LTDL_SHLIB_EXT\)[ (].*,\1define\2 ".so" , -s,^\([ #]*\)[^ ]*\([ ]*LTDL_SHLIBPATH_VAR\)[ (].*,\1define\2 "LD_LIBRARY_PATH" , -s,^\([ #]*\)[^ ]*\([ ]*LTDL_SYSSEARCHPATH\)[ (].*,\1define\2 "/usr/lib:/lib:/usr/lib/qt-3.3/lib" , -s,^\([ #]*\)[^ ]*\([ ]*LTDL_OBJDIR\)[ (].*,\1define\2 ".libs/" , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_PRELOADED_SYMBOLS\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_LIBDL\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_DLERROR\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_ARGZ_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_ERROR_T\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_ARGZ_APPEND\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_ARGZ_CREATE_SEP\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_ARGZ_INSERT\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_ARGZ_NEXT\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_ARGZ_STRINGIFY\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_ASSERT_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_CTYPE_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_ERRNO_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_MALLOC_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_MEMORY_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_STDLIB_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_STDIO_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_UNISTD_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_STRING_H\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_STRCHR\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_STRRCHR\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_MEMCPY\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_MEMMOVE\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_STRCMP\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_CLOSEDIR\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_OPENDIR\)[ (].*,\1define\2 1 , -s,^\([ #]*\)[^ ]*\([ ]*HAVE_READDIR\)[ (].*,\1define\2 1 , -s/ $// -CEOF - sed -f "$tmp/defines.sed" $ac_file_inputs >"$tmp/out1" - # First, check the format of the line: - cat >"$tmp/defines.sed" <<\CEOF -/^[ ]*#[ ]*undef[ ][ ]*[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*[ ]*$/b def -/^[ ]*#[ ]*define[ ][ ]*[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*[( ]/b def -b -:def -s,^[ #]*u.*,/* & */, -CEOF - sed -f "$tmp/defines.sed" "$tmp/out1" >"$tmp/out2" -ac_result="$tmp/out2" - if test x"$ac_file" != x-; then - echo "/* $configure_input */" >"$tmp/config.h" - cat "$ac_result" >>"$tmp/config.h" - if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then - { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 -echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f $ac_file - mv "$tmp/config.h" $ac_file - fi - else - echo "/* $configure_input */" - cat "$ac_result" - fi - rm -f "$tmp/out12" -# Compute $ac_file's index in $config_headers. -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $ac_file | $ac_file:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $ac_file" >`$as_dirname -- $ac_file || -$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X$ac_file : 'X\(//\)[^/]' \| \ - X$ac_file : 'X\(//\)$' \| \ - X$ac_file : 'X\(/\)' \| . 2>/dev/null || -echo X$ac_file | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'`/stamp-h$_am_stamp_count - ;; - - :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 -echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -echo X"$mf" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - { as_dir=$dirpart/$fdir - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 -echo "$as_me: error: cannot create directory $as_dir" >&2;} - { (exit 1); exit 1; }; }; } - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done -done - ;; - - esac -done # for ac_tag - - -{ (exit 0); exit 0; } diff --git a/libltdl/libtool b/libltdl/libtool deleted file mode 100755 index 24138133..00000000 --- a/libltdl/libtool +++ /dev/null @@ -1,7895 +0,0 @@ -#! /bin/sh - -# libtoolT - Provide generalized library-building support services. -# Generated automatically by (GNU libltdl 1.2) -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 -# Free Software Foundation, Inc. -# -# This file is part of GNU Libtool: -# Originally by Gordon Matzigkeit , 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# A sed program that does not truncate output. -SED="/bin/sed" - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="/bin/sed -e 1s/^X//" - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# The names of the tagged configurations supported by this script. -available_tags=" CXX F77" - -# ### BEGIN LIBTOOL CONFIG - -# Libtool was configured on host lambda: - -# Shell to use when invoking shell scripts. -SHELL="/bin/sh" - -# Whether or not to build shared libraries. -build_libtool_libs=yes - -# Whether or not to build static libraries. -build_old_libs=yes - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=no - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=no - -# Whether or not to optimize for fast installation. -fast_install=yes - -# The host system. -host_alias= -host=i686-pc-linux-gnu -host_os=linux-gnu - -# The build system. -build_alias= -build=i686-pc-linux-gnu -build_os=linux-gnu - -# An echo program that does not interpret backslashes. -echo="echo" - -# The archiver. -AR="ar" -AR_FLAGS="cru" - -# A C compiler. -LTCC="gcc" - -# LTCC compiler flags. -LTCFLAGS="-g -O2" - -# A language-specific compiler. -CC="gcc" - -# Is the compiler the GNU C compiler? -with_gcc=yes - -# An ERE matcher. -EGREP="/bin/grep -E" - -# The linker used to build libraries. -LD="/usr/bin/ld" - -# Whether we need hard or soft links. -LN_S="ln -s" - -# A BSD-compatible nm program. -NM="/usr/bin/nm -B" - -# A symbol stripping program -STRIP="strip" - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=file - -# Used on cygwin: DLL creation program. -DLLTOOL="dlltool" - -# Used on cygwin: object dumper. -OBJDUMP="objdump" - -# Used on cygwin: assembler. -AS="as" - -# The name of the directory that contains temporary libtool files. -objdir=.libs - -# How to create reloadable object files. -reload_flag=" -r" -reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" - -# How to pass a linker flag through the compiler. -wl="-Wl," - -# Object file suffix (normally "o"). -objext="o" - -# Old archive suffix (normally "a"). -libext="a" - -# Shared library suffix (normally ".so"). -shrext_cmds='.so' - -# Executable file suffix (normally ""). -exeext="" - -# Additional compiler flags for building library objects. -pic_flag=" -fPIC -DPIC" -pic_mode=default - -# What is the maximum length of a command? -max_cmd_len=98304 - -# Does compiler simultaneously support -c and -o options? -compiler_c_o="yes" - -# Must we lock files when doing compilation? -need_locks="no" - -# Do we need the lib prefix for modules? -need_lib_prefix=no - -# Do we need a version for libraries? -need_version=no - -# Whether dlopen is supported. -dlopen_support=unknown - -# Whether dlopen of programs is supported. -dlopen_self=unknown - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=unknown - -# Compiler flag to prevent dynamic linking. -link_static_flag="-static" - -# Compiler flag to turn off builtin functions. -no_builtin_flag=" -fno-builtin" - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec="\${wl}--export-dynamic" - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec="" - -# Library versioning type. -version_type=linux - -# Format of library name prefix. -libname_spec="lib\$name" - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" - -# The coded name of the library, if different from the real name. -soname_spec="\${libname}\${release}\${shared_ext}\$major" - -# Commands used to build and install an old-style archive. -RANLIB="ranlib" -old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs~\$RANLIB \$oldlib" -old_postinstall_cmds="chmod 644 \$oldlib~\$RANLIB \$oldlib" -old_postuninstall_cmds="" - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds="" - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds="" - -# Commands used to build and install a shared archive. -archive_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" -archive_expsym_cmds="\$echo \\\"{ global:\\\" > \$output_objdir/\$libname.ver~ - cat \$export_symbols | sed -e \\\"s/\\\\(.*\\\\)/\\\\1;/\\\" >> \$output_objdir/\$libname.ver~ - \$echo \\\"local: *; };\\\" >> \$output_objdir/\$libname.ver~ - \$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-version-script \${wl}\$output_objdir/\$libname.ver -o \$lib" -postinstall_cmds="" -postuninstall_cmds="" - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds="" -module_expsym_cmds="" - -# Commands to strip libraries. -old_striplib="strip --strip-debug" -striplib="strip --strip-unneeded" - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects="" - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects="" - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps="" - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps="" - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path="" - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method="pass_all" - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd="\$MAGIC_CMD" - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag="" - -# Flag that forces no undefined symbols. -no_undefined_flag="" - -# Commands used to finish a libtool library installation in a directory. -finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval="" - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2 \\2/p'" - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'" - -# This is the shared library runtime path variable. -runpath_var=LD_RUN_PATH - -# This is the shared library path variable. -shlibpath_var=LD_LIBRARY_PATH - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=no - -# How to hardcode a shared library path into an executable. -hardcode_action=immediate - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=yes - -# Flag to hardcode $libdir into a binary during linking. -# This must work even if $libdir does not exist. -hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" - -# If ld is used when linking, flag to hardcode $libdir into -# a binary during linking. This must work even if $libdir does -# not exist. -hardcode_libdir_flag_spec_ld="" - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator="" - -# Set to yes if using DIR/libNAME during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=no - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=no - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=unsupported - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=no - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=unknown - -# Compile-time system search path for libraries -sys_lib_search_path_spec="/usr/lib /lib /usr/local/lib" - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec="/usr/lib /lib /usr/lib/qt-3.3/lib " - -# Fix the shell variable $srcfile for the compiler. -fix_srcfile_path="" - -# Set to yes if exported symbols are required. -always_export_symbols=no - -# The commands to list exported symbols. -export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds="" - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms="_GLOBAL_OFFSET_TABLE_" - -# Symbols that must always be exported. -include_expsyms="" - -# ### END LIBTOOL CONFIG - -# ltmain.sh - Provide generalized library-building support services. -# NOTE: Changing this file will not affect anything until you rerun configure. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, -# 2007 Free Software Foundation, Inc. -# Originally by Gordon Matzigkeit , 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -basename="s,^.*/,,g" - -# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh -# is ksh but when the shell is invoked as "sh" and the current value of -# the _XPG environment variable is not equal to 1 (one), the special -# positional parameter $0, within a function call, is the name of the -# function. -progpath="$0" - -# The name of this program: -progname=`echo "$progpath" | $SED $basename` -modename="$progname" - -# Global variables: -EXIT_SUCCESS=0 -EXIT_FAILURE=1 - -PROGRAM=ltmain.sh -PACKAGE=libtool -VERSION=1.5.24 -TIMESTAMP=" (1.1220.2.456 2007/06/24 02:25:32)" - -# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -# Check that we have a working $echo. -if test "X$1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X$1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then - # Yippee, $echo works! - : -else - # Restart under the correct shell, and then maybe $echo will work. - exec $SHELL "$progpath" --no-reexec ${1+"$@"} -fi - -if test "X$1" = X--fallback-echo; then - # used as fallback echo - shift - cat <&2 - $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit $EXIT_FAILURE -fi - -# Global variables. -mode=$default_mode -nonopt= -prev= -prevopt= -run= -show="$echo" -show_help= -execute_dlfiles= -duplicate_deps=no -preserve_args= -lo2o="s/\\.lo\$/.${objext}/" -o2lo="s/\\.${objext}\$/.lo/" -extracted_archives= -extracted_serial=0 - -##################################### -# Shell function definitions: -# This seems to be the best place for them - -# func_mktempdir [string] -# Make a temporary directory that won't clash with other running -# libtool processes, and avoids race conditions if possible. If -# given, STRING is the basename for that directory. -func_mktempdir () -{ - my_template="${TMPDIR-/tmp}/${1-$progname}" - - if test "$run" = ":"; then - # Return a directory name, but don't create it in dry-run mode - my_tmpdir="${my_template}-$$" - else - - # If mktemp works, use that first and foremost - my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` - - if test ! -d "$my_tmpdir"; then - # Failing that, at least try and use $RANDOM to avoid a race - my_tmpdir="${my_template}-${RANDOM-0}$$" - - save_mktempdir_umask=`umask` - umask 0077 - $mkdir "$my_tmpdir" - umask $save_mktempdir_umask - fi - - # If we're not in dry-run mode, bomb out on failure - test -d "$my_tmpdir" || { - $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2 - exit $EXIT_FAILURE - } - fi - - $echo "X$my_tmpdir" | $Xsed -} - - -# func_win32_libid arg -# return the library type of file 'arg' -# -# Need a lot of goo to handle *both* DLLs and import libs -# Has to be a shell function in order to 'eat' the argument -# that is supplied when $file_magic_command is called. -func_win32_libid () -{ - win32_libid_type="unknown" - win32_fileres=`file -L $1 2>/dev/null` - case $win32_fileres in - *ar\ archive\ import\ library*) # definitely import - win32_libid_type="x86 archive import" - ;; - *ar\ archive*) # could be an import, or static - if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ - $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then - win32_nmres=`eval $NM -f posix -A $1 | \ - $SED -n -e '1,100{ - / I /{ - s,.*,import, - p - q - } - }'` - case $win32_nmres in - import*) win32_libid_type="x86 archive import";; - *) win32_libid_type="x86 archive static";; - esac - fi - ;; - *DLL*) - win32_libid_type="x86 DLL" - ;; - *executable*) # but shell scripts are "executable" too... - case $win32_fileres in - *MS\ Windows\ PE\ Intel*) - win32_libid_type="x86 DLL" - ;; - esac - ;; - esac - $echo $win32_libid_type -} - - -# func_infer_tag arg -# Infer tagged configuration to use if any are available and -# if one wasn't chosen via the "--tag" command line option. -# Only attempt this if the compiler in the base compile -# command doesn't match the default compiler. -# arg is usually of the form 'gcc ...' -func_infer_tag () -{ - if test -n "$available_tags" && test -z "$tagname"; then - CC_quoted= - for arg in $CC; do - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - CC_quoted="$CC_quoted $arg" - done - case $@ in - # Blanks in the command may have been stripped by the calling shell, - # but not from the CC environment variable when configure was run. - " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; - # Blanks at the start of $base_compile will cause this to fail - # if we don't check for them as well. - *) - for z in $available_tags; do - if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then - # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" - CC_quoted= - for arg in $CC; do - # Double-quote args containing other shell metacharacters. - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - CC_quoted="$CC_quoted $arg" - done - case "$@ " in - " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) - # The compiler in the base compile command matches - # the one in the tagged configuration. - # Assume this is the tagged configuration we want. - tagname=$z - break - ;; - esac - fi - done - # If $tagname still isn't set, then no tagged configuration - # was found and let the user know that the "--tag" command - # line option must be used. - if test -z "$tagname"; then - $echo "$modename: unable to infer tagged configuration" - $echo "$modename: specify a tag with \`--tag'" 1>&2 - exit $EXIT_FAILURE -# else -# $echo "$modename: using $tagname tagged configuration" - fi - ;; - esac - fi -} - - -# func_extract_an_archive dir oldlib -func_extract_an_archive () -{ - f_ex_an_ar_dir="$1"; shift - f_ex_an_ar_oldlib="$1" - - $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" - $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $? - if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then - : - else - $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 - exit $EXIT_FAILURE - fi -} - -# func_extract_archives gentop oldlib ... -func_extract_archives () -{ - my_gentop="$1"; shift - my_oldlibs=${1+"$@"} - my_oldobjs="" - my_xlib="" - my_xabs="" - my_xdir="" - my_status="" - - $show "${rm}r $my_gentop" - $run ${rm}r "$my_gentop" - $show "$mkdir $my_gentop" - $run $mkdir "$my_gentop" - my_status=$? - if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then - exit $my_status - fi - - for my_xlib in $my_oldlibs; do - # Extract the objects. - case $my_xlib in - [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; - *) my_xabs=`pwd`"/$my_xlib" ;; - esac - my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` - my_xlib_u=$my_xlib - while :; do - case " $extracted_archives " in - *" $my_xlib_u "*) - extracted_serial=`expr $extracted_serial + 1` - my_xlib_u=lt$extracted_serial-$my_xlib ;; - *) break ;; - esac - done - extracted_archives="$extracted_archives $my_xlib_u" - my_xdir="$my_gentop/$my_xlib_u" - - $show "${rm}r $my_xdir" - $run ${rm}r "$my_xdir" - $show "$mkdir $my_xdir" - $run $mkdir "$my_xdir" - exit_status=$? - if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then - exit $exit_status - fi - case $host in - *-darwin*) - $show "Extracting $my_xabs" - # Do not bother doing anything if just a dry run - if test -z "$run"; then - darwin_orig_dir=`pwd` - cd $my_xdir || exit $? - darwin_archive=$my_xabs - darwin_curdir=`pwd` - darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` - darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` - if test -n "$darwin_arches"; then - darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` - darwin_arch= - $show "$darwin_base_archive has multiple architectures $darwin_arches" - for darwin_arch in $darwin_arches ; do - mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" - lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" - cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" - func_extract_an_archive "`pwd`" "${darwin_base_archive}" - cd "$darwin_curdir" - $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" - done # $darwin_arches - ## Okay now we have a bunch of thin objects, gotta fatten them up :) - darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP` - darwin_file= - darwin_files= - for darwin_file in $darwin_filelist; do - darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` - lipo -create -output "$darwin_file" $darwin_files - done # $darwin_filelist - ${rm}r unfat-$$ - cd "$darwin_orig_dir" - else - cd "$darwin_orig_dir" - func_extract_an_archive "$my_xdir" "$my_xabs" - fi # $darwin_arches - fi # $run - ;; - *) - func_extract_an_archive "$my_xdir" "$my_xabs" - ;; - esac - my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` - done - func_extract_archives_result="$my_oldobjs" -} -# End of Shell function definitions -##################################### - -# Darwin sucks -eval std_shrext=\"$shrext_cmds\" - -disable_libs=no - -# Parse our command line options once, thoroughly. -while test "$#" -gt 0 -do - arg="$1" - shift - - case $arg in - -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; - *) optarg= ;; - esac - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - execute_dlfiles) - execute_dlfiles="$execute_dlfiles $arg" - ;; - tag) - tagname="$arg" - preserve_args="${preserve_args}=$arg" - - # Check whether tagname contains only valid characters - case $tagname in - *[!-_A-Za-z0-9,/]*) - $echo "$progname: invalid tag name: $tagname" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - case $tagname in - CC) - # Don't test for the "default" C tag, as we know, it's there, but - # not specially marked. - ;; - *) - if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then - taglist="$taglist $tagname" - # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" - else - $echo "$progname: ignoring unknown tag $tagname" 1>&2 - fi - ;; - esac - ;; - *) - eval "$prev=\$arg" - ;; - esac - - prev= - prevopt= - continue - fi - - # Have we seen a non-optional argument yet? - case $arg in - --help) - show_help=yes - ;; - - --version) - echo "\ -$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP - -Copyright (C) 2007 Free Software Foundation, Inc. -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - exit $? - ;; - - --config) - ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath - # Now print the configurations for the tags. - for tagname in $taglist; do - ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" - done - exit $? - ;; - - --debug) - $echo "$progname: enabling shell trace mode" - set -x - preserve_args="$preserve_args $arg" - ;; - - --dry-run | -n) - run=: - ;; - - --features) - $echo "host: $host" - if test "$build_libtool_libs" = yes; then - $echo "enable shared libraries" - else - $echo "disable shared libraries" - fi - if test "$build_old_libs" = yes; then - $echo "enable static libraries" - else - $echo "disable static libraries" - fi - exit $? - ;; - - --finish) mode="finish" ;; - - --mode) prevopt="--mode" prev=mode ;; - --mode=*) mode="$optarg" ;; - - --preserve-dup-deps) duplicate_deps="yes" ;; - - --quiet | --silent) - show=: - preserve_args="$preserve_args $arg" - ;; - - --tag) - prevopt="--tag" - prev=tag - preserve_args="$preserve_args --tag" - ;; - --tag=*) - set tag "$optarg" ${1+"$@"} - shift - prev=tag - preserve_args="$preserve_args --tag" - ;; - - -dlopen) - prevopt="-dlopen" - prev=execute_dlfiles - ;; - - -*) - $echo "$modename: unrecognized option \`$arg'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; - - *) - nonopt="$arg" - break - ;; - esac -done - -if test -n "$prevopt"; then - $echo "$modename: option \`$prevopt' requires an argument" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE -fi - -case $disable_libs in -no) - ;; -shared) - build_libtool_libs=no - build_old_libs=yes - ;; -static) - build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` - ;; -esac - -# If this variable is set in any of the actions, the command in it -# will be execed at the end. This prevents here-documents from being -# left over by shells. -exec_cmd= - -if test -z "$show_help"; then - - # Infer the operation mode. - if test -z "$mode"; then - $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 - $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 - case $nonopt in - *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) - mode=link - for arg - do - case $arg in - -c) - mode=compile - break - ;; - esac - done - ;; - *db | *dbx | *strace | *truss) - mode=execute - ;; - *install*|cp|mv) - mode=install - ;; - *rm) - mode=uninstall - ;; - *) - # If we have no mode, but dlfiles were specified, then do execute mode. - test -n "$execute_dlfiles" && mode=execute - - # Just use the default operation mode. - if test -z "$mode"; then - if test -n "$nonopt"; then - $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 - else - $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 - fi - fi - ;; - esac - fi - - # Only execute mode is allowed to have -dlopen flags. - if test -n "$execute_dlfiles" && test "$mode" != execute; then - $echo "$modename: unrecognized option \`-dlopen'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Change the help message to a mode-specific one. - generic_help="$help" - help="Try \`$modename --help --mode=$mode' for more information." - - # These modes are in order of execution frequency so that they run quickly. - case $mode in - # libtool compile mode - compile) - modename="$modename: compile" - # Get the compilation command and the source file. - base_compile= - srcfile="$nonopt" # always keep a non-empty value in "srcfile" - suppress_opt=yes - suppress_output= - arg_mode=normal - libobj= - later= - - for arg - do - case $arg_mode in - arg ) - # do not "continue". Instead, add this to base_compile - lastarg="$arg" - arg_mode=normal - ;; - - target ) - libobj="$arg" - arg_mode=normal - continue - ;; - - normal ) - # Accept any command-line options. - case $arg in - -o) - if test -n "$libobj" ; then - $echo "$modename: you cannot specify \`-o' more than once" 1>&2 - exit $EXIT_FAILURE - fi - arg_mode=target - continue - ;; - - -static | -prefer-pic | -prefer-non-pic) - later="$later $arg" - continue - ;; - - -no-suppress) - suppress_opt=no - continue - ;; - - -Xcompiler) - arg_mode=arg # the next one goes into the "base_compile" arg list - continue # The current "srcfile" will either be retained or - ;; # replaced later. I would guess that would be a bug. - - -Wc,*) - args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` - lastarg= - save_ifs="$IFS"; IFS=',' - for arg in $args; do - IFS="$save_ifs" - - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - lastarg="$lastarg $arg" - done - IFS="$save_ifs" - lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` - - # Add the arguments to base_compile. - base_compile="$base_compile $lastarg" - continue - ;; - - * ) - # Accept the current argument as the source file. - # The previous "srcfile" becomes the current argument. - # - lastarg="$srcfile" - srcfile="$arg" - ;; - esac # case $arg - ;; - esac # case $arg_mode - - # Aesthetically quote the previous argument. - lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` - - case $lastarg in - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, and some SunOS ksh mistreat backslash-escaping - # in scan sets (worked around with variable expansion), - # and furthermore cannot handle '|' '&' '(' ')' in scan sets - # at all, so we specify them separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - lastarg="\"$lastarg\"" - ;; - esac - - base_compile="$base_compile $lastarg" - done # for arg - - case $arg_mode in - arg) - $echo "$modename: you must specify an argument for -Xcompile" - exit $EXIT_FAILURE - ;; - target) - $echo "$modename: you must specify a target with \`-o'" 1>&2 - exit $EXIT_FAILURE - ;; - *) - # Get the name of the library object. - [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` - ;; - esac - - # Recognize several different file suffixes. - # If the user specifies -o file.o, it is replaced with file.lo - xform='[cCFSifmso]' - case $libobj in - *.ada) xform=ada ;; - *.adb) xform=adb ;; - *.ads) xform=ads ;; - *.asm) xform=asm ;; - *.c++) xform=c++ ;; - *.cc) xform=cc ;; - *.ii) xform=ii ;; - *.class) xform=class ;; - *.cpp) xform=cpp ;; - *.cxx) xform=cxx ;; - *.[fF][09]?) xform=[fF][09]. ;; - *.for) xform=for ;; - *.java) xform=java ;; - *.obj) xform=obj ;; - esac - - libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` - - case $libobj in - *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; - *) - $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - func_infer_tag $base_compile - - for arg in $later; do - case $arg in - -static) - build_old_libs=yes - continue - ;; - - -prefer-pic) - pic_mode=yes - continue - ;; - - -prefer-non-pic) - pic_mode=no - continue - ;; - esac - done - - qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` - case $qlibobj in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - qlibobj="\"$qlibobj\"" ;; - esac - test "X$libobj" != "X$qlibobj" \ - && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' &()|`$[]' \ - && $echo "$modename: libobj name \`$libobj' may not contain shell special characters." - objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` - xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$obj"; then - xdir= - else - xdir=$xdir/ - fi - lobj=${xdir}$objdir/$objname - - if test -z "$base_compile"; then - $echo "$modename: you must specify a compilation command" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Delete any leftover library objects. - if test "$build_old_libs" = yes; then - removelist="$obj $lobj $libobj ${libobj}T" - else - removelist="$lobj $libobj ${libobj}T" - fi - - $run $rm $removelist - trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 - - # On Cygwin there's no "real" PIC flag so we must build both object types - case $host_os in - cygwin* | mingw* | pw32* | os2*) - pic_mode=default - ;; - esac - if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then - # non-PIC code in shared libraries is not supported - pic_mode=default - fi - - # Calculate the filename of the output object if compiler does - # not support -o with -c - if test "$compiler_c_o" = no; then - output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} - lockfile="$output_obj.lock" - removelist="$removelist $output_obj $lockfile" - trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 - else - output_obj= - need_locks=no - lockfile= - fi - - # Lock this critical section if it is needed - # We use this script file to make the link, it avoids creating a new file - if test "$need_locks" = yes; then - until $run ln "$progpath" "$lockfile" 2>/dev/null; do - $show "Waiting for $lockfile to be removed" - sleep 2 - done - elif test "$need_locks" = warn; then - if test -f "$lockfile"; then - $echo "\ -*** ERROR, $lockfile exists and contains: -`cat $lockfile 2>/dev/null` - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit $EXIT_FAILURE - fi - $echo "$srcfile" > "$lockfile" - fi - - if test -n "$fix_srcfile_path"; then - eval srcfile=\"$fix_srcfile_path\" - fi - qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` - case $qsrcfile in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - qsrcfile="\"$qsrcfile\"" ;; - esac - - $run $rm "$libobj" "${libobj}T" - - # Create a libtool object file (analogous to a ".la" file), - # but don't create it if we're doing a dry run. - test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then - $echo "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed, then go on to compile the next one - if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then - $show "$mv $output_obj $lobj" - if $run $mv $output_obj $lobj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # Append the name of the PIC object to the libtool object file. - test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != "X$srcfile"; then - $echo "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed - if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then - $show "$mv $output_obj $obj" - if $run $mv $output_obj $obj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # Append the name of the non-PIC object the libtool object file. - # Only append if the libtool object file exists. - test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 - fi - if test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=yes - ;; - -static) - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=built - ;; - -static-libtool-libs) - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=yes - ;; - esac - build_libtool_libs=no - build_old_libs=yes - break - ;; - esac - done - - # See if our shared archives depend on static archives. - test -n "$old_archive_from_new_cmds" && build_old_libs=yes - - # Go through the arguments, transforming them on the way. - while test "$#" -gt 0; do - arg="$1" - shift - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test - ;; - *) qarg=$arg ;; - esac - libtool_args="$libtool_args $qarg" - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - output) - compile_command="$compile_command @OUTPUT@" - finalize_command="$finalize_command @OUTPUT@" - ;; - esac - - case $prev in - dlfiles|dlprefiles) - if test "$preload" = no; then - # Add the symbol object into the linking commands. - compile_command="$compile_command @SYMFILE@" - finalize_command="$finalize_command @SYMFILE@" - preload=yes - fi - case $arg in - *.la | *.lo) ;; # We handle these cases below. - force) - if test "$dlself" = no; then - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - self) - if test "$prev" = dlprefiles; then - dlself=yes - elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then - dlself=yes - else - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - *) - if test "$prev" = dlfiles; then - dlfiles="$dlfiles $arg" - else - dlprefiles="$dlprefiles $arg" - fi - prev= - continue - ;; - esac - ;; - expsyms) - export_symbols="$arg" - if test ! -f "$arg"; then - $echo "$modename: symbol file \`$arg' does not exist" - exit $EXIT_FAILURE - fi - prev= - continue - ;; - expsyms_regex) - export_symbols_regex="$arg" - prev= - continue - ;; - inst_prefix) - inst_prefix_dir="$arg" - prev= - continue - ;; - precious_regex) - precious_files_regex="$arg" - prev= - continue - ;; - release) - release="-$arg" - prev= - continue - ;; - objectlist) - if test -f "$arg"; then - save_arg=$arg - moreargs= - for fil in `cat $save_arg` - do -# moreargs="$moreargs $fil" - arg=$fil - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - pic_object= - non_pic_object= - - # Read the .lo file - # If there is no directory component, then add one. - case $arg in - */* | *\\*) . $arg ;; - *) . ./$arg ;; - esac - - if test -z "$pic_object" || \ - test -z "$non_pic_object" || - test "$pic_object" = none && \ - test "$non_pic_object" = none; then - $echo "$modename: cannot find name of object for \`$arg'" 1>&2 - exit $EXIT_FAILURE - fi - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - dlfiles="$dlfiles $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - dlprefiles="$dlprefiles $pic_object" - prev= - fi - - # A PIC object. - libobjs="$libobjs $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - non_pic_objects="$non_pic_objects $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - else - # If the PIC object exists, use it instead. - # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" - non_pic_objects="$non_pic_objects $non_pic_object" - fi - else - # Only an error if not doing a dry-run. - if test -z "$run"; then - $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 - exit $EXIT_FAILURE - else - # Dry-run case. - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` - non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` - libobjs="$libobjs $pic_object" - non_pic_objects="$non_pic_objects $non_pic_object" - fi - fi - done - else - $echo "$modename: link input file \`$save_arg' does not exist" - exit $EXIT_FAILURE - fi - arg=$save_arg - prev= - continue - ;; - rpath | xrpath) - # We need an absolute path. - case $arg in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - $echo "$modename: only absolute run-paths are allowed" 1>&2 - exit $EXIT_FAILURE - ;; - esac - if test "$prev" = rpath; then - case "$rpath " in - *" $arg "*) ;; - *) rpath="$rpath $arg" ;; - esac - else - case "$xrpath " in - *" $arg "*) ;; - *) xrpath="$xrpath $arg" ;; - esac - fi - prev= - continue - ;; - xcompiler) - compiler_flags="$compiler_flags $qarg" - prev= - compile_command="$compile_command $qarg" - finalize_command="$finalize_command $qarg" - continue - ;; - xlinker) - linker_flags="$linker_flags $qarg" - compiler_flags="$compiler_flags $wl$qarg" - prev= - compile_command="$compile_command $wl$qarg" - finalize_command="$finalize_command $wl$qarg" - continue - ;; - xcclinker) - linker_flags="$linker_flags $qarg" - compiler_flags="$compiler_flags $qarg" - prev= - compile_command="$compile_command $qarg" - finalize_command="$finalize_command $qarg" - continue - ;; - shrext) - shrext_cmds="$arg" - prev= - continue - ;; - darwin_framework|darwin_framework_skip) - test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - prev= - continue - ;; - *) - eval "$prev=\"\$arg\"" - prev= - continue - ;; - esac - fi # test -n "$prev" - - prevarg="$arg" - - case $arg in - -all-static) - if test -n "$link_static_flag"; then - compile_command="$compile_command $link_static_flag" - finalize_command="$finalize_command $link_static_flag" - fi - continue - ;; - - -allow-undefined) - # FIXME: remove this flag sometime in the future. - $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 - continue - ;; - - -avoid-version) - avoid_version=yes - continue - ;; - - -dlopen) - prev=dlfiles - continue - ;; - - -dlpreopen) - prev=dlprefiles - continue - ;; - - -export-dynamic) - export_dynamic=yes - continue - ;; - - -export-symbols | -export-symbols-regex) - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: more than one -exported-symbols argument is not allowed" - exit $EXIT_FAILURE - fi - if test "X$arg" = "X-export-symbols"; then - prev=expsyms - else - prev=expsyms_regex - fi - continue - ;; - - -framework|-arch|-isysroot) - case " $CC " in - *" ${arg} ${1} "* | *" ${arg} ${1} "*) - prev=darwin_framework_skip ;; - *) compiler_flags="$compiler_flags $arg" - prev=darwin_framework ;; - esac - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - continue - ;; - - -inst-prefix-dir) - prev=inst_prefix - continue - ;; - - # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* - # so, if we see these flags be careful not to treat them like -L - -L[A-Z][A-Z]*:*) - case $with_gcc/$host in - no/*-*-irix* | /*-*-irix*) - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - ;; - esac - continue - ;; - - -L*) - dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 - absdir="$dir" - notinst_path="$notinst_path $dir" - fi - dir="$absdir" - ;; - esac - case "$deplibs " in - *" -L$dir "*) ;; - *) - deplibs="$deplibs -L$dir" - lib_search_path="$lib_search_path $dir" - ;; - esac - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'` - case :$dllsearchpath: in - *":$dir:"*) ;; - *) dllsearchpath="$dllsearchpath:$dir";; - esac - case :$dllsearchpath: in - *":$testbindir:"*) ;; - *) dllsearchpath="$dllsearchpath:$testbindir";; - esac - ;; - esac - continue - ;; - - -l*) - if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*) - # These systems don't actually have a C or math library (as such) - continue - ;; - *-*-os2*) - # These systems don't actually have a C library (as such) - test "X$arg" = "X-lc" && continue - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C and math libraries are in the System framework - deplibs="$deplibs -framework System" - continue - ;; - *-*-sco3.2v5* | *-*-sco5v6*) - # Causes problems with __ctype - test "X$arg" = "X-lc" && continue - ;; - *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) - # Compiler inserts libc in the correct place for threads to work - test "X$arg" = "X-lc" && continue - ;; - esac - elif test "X$arg" = "X-lc_r"; then - case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc_r directly, use -pthread flag. - continue - ;; - esac - fi - deplibs="$deplibs $arg" - continue - ;; - - # Tru64 UNIX uses -model [arg] to determine the layout of C++ - # classes, name mangling, and exception handling. - -model) - compile_command="$compile_command $arg" - compiler_flags="$compiler_flags $arg" - finalize_command="$finalize_command $arg" - prev=xcompiler - continue - ;; - - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) - compiler_flags="$compiler_flags $arg" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - continue - ;; - - -module) - module=yes - continue - ;; - - # -64, -mips[0-9] enable 64-bit mode on the SGI compiler - # -r[0-9][0-9]* specifies the processor on the SGI compiler - # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler - # +DA*, +DD* enable 64-bit mode on the HP compiler - # -q* pass through compiler args for the IBM compiler - # -m* pass through architecture-specific compiler args for GCC - # -m*, -t[45]*, -txscale* pass through architecture-specific - # compiler args for GCC - # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC - # -F/path gives path to uninstalled frameworks, gcc on darwin - # @file GCC response files - -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ - -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*) - - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - compiler_flags="$compiler_flags $arg" - continue - ;; - - -shrext) - prev=shrext - continue - ;; - - -no-fast-install) - fast_install=no - continue - ;; - - -no-install) - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin*) - # The PATH hackery in wrapper scripts is required on Windows - # and Darwin in order for the loader to find any dlls it needs. - $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 - $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 - fast_install=no - ;; - *) no_install=yes ;; - esac - continue - ;; - - -no-undefined) - allow_undefined=no - continue - ;; - - -objectlist) - prev=objectlist - continue - ;; - - -o) prev=output ;; - - -precious-files-regex) - prev=precious_regex - continue - ;; - - -release) - prev=release - continue - ;; - - -rpath) - prev=rpath - continue - ;; - - -R) - prev=xrpath - continue - ;; - - -R*) - dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - $echo "$modename: only absolute run-paths are allowed" 1>&2 - exit $EXIT_FAILURE - ;; - esac - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - continue - ;; - - -static | -static-libtool-libs) - # The effects of -static are defined in a previous loop. - # We used to do the same as -all-static on platforms that - # didn't have a PIC flag, but the assumption that the effects - # would be equivalent was wrong. It would break on at least - # Digital Unix and AIX. - continue - ;; - - -thread-safe) - thread_safe=yes - continue - ;; - - -version-info) - prev=vinfo - continue - ;; - -version-number) - prev=vinfo - vinfo_number=yes - continue - ;; - - -Wc,*) - args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - case $flag in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - flag="\"$flag\"" - ;; - esac - arg="$arg $wl$flag" - compiler_flags="$compiler_flags $flag" - done - IFS="$save_ifs" - arg=`$echo "X$arg" | $Xsed -e "s/^ //"` - ;; - - -Wl,*) - args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - case $flag in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - flag="\"$flag\"" - ;; - esac - arg="$arg $wl$flag" - compiler_flags="$compiler_flags $wl$flag" - linker_flags="$linker_flags $flag" - done - IFS="$save_ifs" - arg=`$echo "X$arg" | $Xsed -e "s/^ //"` - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Xlinker) - prev=xlinker - continue - ;; - - -XCClinker) - prev=xcclinker - continue - ;; - - # Some other compiler flag. - -* | +*) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - ;; - - *.$objext) - # A standard object. - objs="$objs $arg" - ;; - - *.lo) - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - pic_object= - non_pic_object= - - # Read the .lo file - # If there is no directory component, then add one. - case $arg in - */* | *\\*) . $arg ;; - *) . ./$arg ;; - esac - - if test -z "$pic_object" || \ - test -z "$non_pic_object" || - test "$pic_object" = none && \ - test "$non_pic_object" = none; then - $echo "$modename: cannot find name of object for \`$arg'" 1>&2 - exit $EXIT_FAILURE - fi - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - dlfiles="$dlfiles $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - dlprefiles="$dlprefiles $pic_object" - prev= - fi - - # A PIC object. - libobjs="$libobjs $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - non_pic_objects="$non_pic_objects $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - else - # If the PIC object exists, use it instead. - # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" - non_pic_objects="$non_pic_objects $non_pic_object" - fi - else - # Only an error if not doing a dry-run. - if test -z "$run"; then - $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 - exit $EXIT_FAILURE - else - # Dry-run case. - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` - non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` - libobjs="$libobjs $pic_object" - non_pic_objects="$non_pic_objects $non_pic_object" - fi - fi - ;; - - *.$libext) - # An archive. - deplibs="$deplibs $arg" - old_deplibs="$old_deplibs $arg" - continue - ;; - - *.la) - # A libtool-controlled library. - - if test "$prev" = dlfiles; then - # This library was specified with -dlopen. - dlfiles="$dlfiles $arg" - prev= - elif test "$prev" = dlprefiles; then - # The library was specified with -dlpreopen. - dlprefiles="$dlprefiles $arg" - prev= - else - deplibs="$deplibs $arg" - fi - continue - ;; - - # Some other compiler argument. - *) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - ;; - esac # arg - - # Now actually substitute the argument into the commands. - if test -n "$arg"; then - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - fi - done # argument parsing loop - - if test -n "$prev"; then - $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then - eval arg=\"$export_dynamic_flag_spec\" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - fi - - oldlibs= - # calculate the name of the file, without its directory - outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` - libobjs_save="$libobjs" - - if test -n "$shlibpath_var"; then - # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` - else - shlib_search_path= - fi - eval sys_lib_search_path=\"$sys_lib_search_path_spec\" - eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" - - output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` - if test "X$output_objdir" = "X$output"; then - output_objdir="$objdir" - else - output_objdir="$output_objdir/$objdir" - fi - # Create the object directory. - if test ! -d "$output_objdir"; then - $show "$mkdir $output_objdir" - $run $mkdir $output_objdir - exit_status=$? - if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then - exit $exit_status - fi - fi - - # Determine the type of output - case $output in - "") - $echo "$modename: you must specify an output file" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; - *.$libext) linkmode=oldlib ;; - *.lo | *.$objext) linkmode=obj ;; - *.la) linkmode=lib ;; - *) linkmode=prog ;; # Anything else should be a program. - esac - - case $host in - *cygwin* | *mingw* | *pw32*) - # don't eliminate duplications in $postdeps and $predeps - duplicate_compiler_generated_deps=yes - ;; - *) - duplicate_compiler_generated_deps=$duplicate_deps - ;; - esac - specialdeplibs= - - libs= - # Find all interdependent deplibs by searching for libraries - # that are linked more than once (e.g. -la -lb -la) - for deplib in $deplibs; do - if test "X$duplicate_deps" = "Xyes" ; then - case "$libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - libs="$libs $deplib" - done - - if test "$linkmode" = lib; then - libs="$predeps $libs $compiler_lib_search_path $postdeps" - - # Compute libraries that are listed more than once in $predeps - # $postdeps and mark them as special (i.e., whose duplicates are - # not to be eliminated). - pre_post_deps= - if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then - for pre_post_dep in $predeps $postdeps; do - case "$pre_post_deps " in - *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; - esac - pre_post_deps="$pre_post_deps $pre_post_dep" - done - fi - pre_post_deps= - fi - - deplibs= - newdependency_libs= - newlib_search_path= - need_relink=no # whether we're linking any uninstalled libtool libraries - notinst_deplibs= # not-installed libtool libraries - case $linkmode in - lib) - passes="conv link" - for file in $dlfiles $dlprefiles; do - case $file in - *.la) ;; - *) - $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 - exit $EXIT_FAILURE - ;; - esac - done - ;; - prog) - compile_deplibs= - finalize_deplibs= - alldeplibs=no - newdlfiles= - newdlprefiles= - passes="conv scan dlopen dlpreopen link" - ;; - *) passes="conv" - ;; - esac - for pass in $passes; do - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan"; then - libs="$deplibs" - deplibs= - fi - if test "$linkmode" = prog; then - case $pass in - dlopen) libs="$dlfiles" ;; - dlpreopen) libs="$dlprefiles" ;; - link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; - esac - fi - if test "$pass" = dlopen; then - # Collect dlpreopened libraries - save_deplibs="$deplibs" - deplibs= - fi - for deplib in $libs; do - lib= - found=no - case $deplib in - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - compiler_flags="$compiler_flags $deplib" - fi - continue - ;; - -l*) - if test "$linkmode" != lib && test "$linkmode" != prog; then - $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 - continue - fi - name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` - for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do - for search_ext in .la $std_shrext .so .a; do - # Search the libtool library - lib="$searchdir/lib${name}${search_ext}" - if test -f "$lib"; then - if test "$search_ext" = ".la"; then - found=yes - else - found=no - fi - break 2 - fi - done - done - if test "$found" != yes; then - # deplib doesn't seem to be a libtool library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - else # deplib is a libtool library - # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, - # We need to do some special things here, and not later. - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $deplib "*) - if (${SED} -e '2q' $lib | - grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - library_names= - old_library= - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - for l in $old_library $library_names; do - ll="$l" - done - if test "X$ll" = "X$old_library" ; then # only static version available - found=no - ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` - test "X$ladir" = "X$lib" && ladir="." - lib=$ladir/$old_library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - fi - fi - ;; - *) ;; - esac - fi - fi - ;; # -l - -L*) - case $linkmode in - lib) - deplibs="$deplib $deplibs" - test "$pass" = conv && continue - newdependency_libs="$deplib $newdependency_libs" - newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` - ;; - prog) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - if test "$pass" = scan; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` - ;; - *) - $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 - ;; - esac # linkmode - continue - ;; # -L - -R*) - if test "$pass" = link; then - dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` - # Make sure the xrpath contains only unique directories. - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - fi - deplibs="$deplib $deplibs" - continue - ;; - *.la) lib="$deplib" ;; - *.$libext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - case $linkmode in - lib) - valid_a_lib=no - case $deplibs_check_method in - match_pattern*) - set dummy $deplibs_check_method - match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` - if eval $echo \"$deplib\" 2>/dev/null \ - | $SED 10q \ - | $EGREP "$match_pattern_regex" > /dev/null; then - valid_a_lib=yes - fi - ;; - pass_all) - valid_a_lib=yes - ;; - esac - if test "$valid_a_lib" != yes; then - $echo - $echo "*** Warning: Trying to link with static lib archive $deplib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have" - $echo "*** because the file extensions .$libext of this argument makes me believe" - $echo "*** that it is just a static archive that I should not used here." - else - $echo - $echo "*** Warning: Linking the shared library $output against the" - $echo "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" - fi - continue - ;; - prog) - if test "$pass" != link; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - continue - ;; - esac # linkmode - ;; # *.$libext - *.lo | *.$objext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - elif test "$linkmode" = prog; then - if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlopen support or we're linking statically, - # we need to preload. - newdlprefiles="$newdlprefiles $deplib" - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - newdlfiles="$newdlfiles $deplib" - fi - fi - continue - ;; - %DEPLIBS%) - alldeplibs=yes - continue - ;; - esac # case $deplib - if test "$found" = yes || test -f "$lib"; then : - else - $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2 - exit $EXIT_FAILURE - fi - - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - - ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` - test "X$ladir" = "X$lib" && ladir="." - - dlname= - dlopen= - dlpreopen= - libdir= - library_names= - old_library= - # If the library was installed with an old release of libtool, - # it will not redefine variables installed, or shouldnotlink - installed=yes - shouldnotlink=no - avoidtemprpath= - - - # Read the .la file - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan" || - { test "$linkmode" != prog && test "$linkmode" != lib; }; then - test -n "$dlopen" && dlfiles="$dlfiles $dlopen" - test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" - fi - - if test "$pass" = conv; then - # Only check for convenience libraries - deplibs="$lib $deplibs" - if test -z "$libdir"; then - if test -z "$old_library"; then - $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 - exit $EXIT_FAILURE - fi - # It is a libtool convenience library, so add in its objects. - convenience="$convenience $ladir/$objdir/$old_library" - old_convenience="$old_convenience $ladir/$objdir/$old_library" - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done - elif test "$linkmode" != prog && test "$linkmode" != lib; then - $echo "$modename: \`$lib' is not a convenience library" 1>&2 - exit $EXIT_FAILURE - fi - continue - fi # $pass = conv - - - # Get the name of the library we link against. - linklib= - for l in $old_library $library_names; do - linklib="$l" - done - if test -z "$linklib"; then - $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 - exit $EXIT_FAILURE - fi - - # This library was specified with -dlopen. - if test "$pass" = dlopen; then - if test -z "$libdir"; then - $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 - exit $EXIT_FAILURE - fi - if test -z "$dlname" || - test "$dlopen_support" != yes || - test "$build_libtool_libs" = no; then - # If there is no dlname, no dlopen support or we're linking - # statically, we need to preload. We also need to preload any - # dependent libraries so libltdl's deplib preloader doesn't - # bomb out in the load deplibs phase. - dlprefiles="$dlprefiles $lib $dependency_libs" - else - newdlfiles="$newdlfiles $lib" - fi - continue - fi # $pass = dlopen - - # We need an absolute path. - case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; - *) - abs_ladir=`cd "$ladir" && pwd` - if test -z "$abs_ladir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 - $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 - abs_ladir="$ladir" - fi - ;; - esac - laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - - # Find the relevant object directory and library name. - if test "X$installed" = Xyes; then - if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - $echo "$modename: warning: library \`$lib' was moved." 1>&2 - dir="$ladir" - absdir="$abs_ladir" - libdir="$abs_ladir" - else - dir="$libdir" - absdir="$libdir" - fi - test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes - else - if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then - dir="$ladir" - absdir="$abs_ladir" - # Remove this search path later - notinst_path="$notinst_path $abs_ladir" - else - dir="$ladir/$objdir" - absdir="$abs_ladir/$objdir" - # Remove this search path later - notinst_path="$notinst_path $abs_ladir" - fi - fi # $installed = yes - name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` - - # This library was specified with -dlpreopen. - if test "$pass" = dlpreopen; then - if test -z "$libdir"; then - $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 - exit $EXIT_FAILURE - fi - # Prefer using a static library (so that no silly _DYNAMIC symbols - # are required to link). - if test -n "$old_library"; then - newdlprefiles="$newdlprefiles $dir/$old_library" - # Otherwise, use the dlname, so that lt_dlopen finds it. - elif test -n "$dlname"; then - newdlprefiles="$newdlprefiles $dir/$dlname" - else - newdlprefiles="$newdlprefiles $dir/$linklib" - fi - fi # $pass = dlpreopen - - if test -z "$libdir"; then - # Link the convenience library - if test "$linkmode" = lib; then - deplibs="$dir/$old_library $deplibs" - elif test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$dir/$old_library $compile_deplibs" - finalize_deplibs="$dir/$old_library $finalize_deplibs" - else - deplibs="$lib $deplibs" # used for prog,scan pass - fi - continue - fi - - - if test "$linkmode" = prog && test "$pass" != link; then - newlib_search_path="$newlib_search_path $ladir" - deplibs="$lib $deplibs" - - linkalldeplibs=no - if test "$link_all_deplibs" != no || test -z "$library_names" || - test "$build_libtool_libs" = no; then - linkalldeplibs=yes - fi - - tmp_libs= - for deplib in $dependency_libs; do - case $deplib in - -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test - esac - # Need to link against all dependency_libs? - if test "$linkalldeplibs" = yes; then - deplibs="$deplib $deplibs" - else - # Need to hardcode shared library paths - # or/and link against static libraries - newdependency_libs="$deplib $newdependency_libs" - fi - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done # for deplib - continue - fi # $linkmode = prog... - - if test "$linkmode,$pass" = "prog,link"; then - if test -n "$library_names" && - { { test "$prefer_static_libs" = no || - test "$prefer_static_libs,$installed" = "built,yes"; } || - test -z "$old_library"; }; then - # We need to hardcode the library path - if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then - # Make sure the rpath contains only unique directories. - case "$temp_rpath " in - *" $dir "*) ;; - *" $absdir "*) ;; - *) temp_rpath="$temp_rpath $absdir" ;; - esac - fi - - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) compile_rpath="$compile_rpath $absdir" - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" - esac - ;; - esac - fi # $linkmode,$pass = prog,link... - - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - fi - - link_static=no # Whether the deplib will be linked statically - use_static_libs=$prefer_static_libs - if test "$use_static_libs" = built && test "$installed" = yes ; then - use_static_libs=no - fi - if test -n "$library_names" && - { test "$use_static_libs" = no || test -z "$old_library"; }; then - if test "$installed" = no; then - notinst_deplibs="$notinst_deplibs $lib" - need_relink=yes - fi - # This is a shared library - - # Warn about portability, can't link against -module's on - # some systems (darwin) - if test "$shouldnotlink" = yes && test "$pass" = link ; then - $echo - if test "$linkmode" = prog; then - $echo "*** Warning: Linking the executable $output against the loadable module" - else - $echo "*** Warning: Linking the shared library $output against the loadable module" - fi - $echo "*** $linklib is not portable!" - fi - if test "$linkmode" = lib && - test "$hardcode_into_libs" = yes; then - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) compile_rpath="$compile_rpath $absdir" - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" - esac - ;; - esac - fi - - if test -n "$old_archive_from_expsyms_cmds"; then - # figure out the soname - set dummy $library_names - realname="$2" - shift; shift - libname=`eval \\$echo \"$libname_spec\"` - # use dlname if we got it. it's perfectly good, no? - if test -n "$dlname"; then - soname="$dlname" - elif test -n "$soname_spec"; then - # bleh windows - case $host in - *cygwin* | mingw*) - major=`expr $current - $age` - versuffix="-$major" - ;; - esac - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - - # Make a new name for the extract_expsyms_cmds to use - soroot="$soname" - soname=`$echo $soroot | ${SED} -e 's/^.*\///'` - newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" - - # If the library has no export list, then create one now - if test -f "$output_objdir/$soname-def"; then : - else - $show "extracting exported symbol list from \`$soname'" - save_ifs="$IFS"; IFS='~' - cmds=$extract_expsyms_cmds - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - # Create $newlib - if test -f "$output_objdir/$newlib"; then :; else - $show "generating import library for \`$soname'" - save_ifs="$IFS"; IFS='~' - cmds=$old_archive_from_expsyms_cmds - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - # make sure the library variables are pointing to the new library - dir=$output_objdir - linklib=$newlib - fi # test -n "$old_archive_from_expsyms_cmds" - - if test "$linkmode" = prog || test "$mode" != relink; then - add_shlibpath= - add_dir= - add= - lib_linked=yes - case $hardcode_action in - immediate | unsupported) - if test "$hardcode_direct" = no; then - add="$dir/$linklib" - case $host in - *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; - *-*-sysv4*uw2*) add_dir="-L$dir" ;; - *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ - *-*-unixware7*) add_dir="-L$dir" ;; - *-*-darwin* ) - # if the lib is a module then we can not link against - # it, someone is ignoring the new warnings I added - if /usr/bin/file -L $add 2> /dev/null | - $EGREP ": [^:]* bundle" >/dev/null ; then - $echo "** Warning, lib $linklib is a module, not a shared library" - if test -z "$old_library" ; then - $echo - $echo "** And there doesn't seem to be a static archive available" - $echo "** The link will probably fail, sorry" - else - add="$dir/$old_library" - fi - fi - esac - elif test "$hardcode_minus_L" = no; then - case $host in - *-*-sunos*) add_shlibpath="$dir" ;; - esac - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = no; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - relink) - if test "$hardcode_direct" = yes; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$dir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - add_dir="$add_dir -L$inst_prefix_dir$libdir" - ;; - esac - fi - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - *) lib_linked=no ;; - esac - - if test "$lib_linked" != yes; then - $echo "$modename: configuration error: unsupported hardcode properties" - exit $EXIT_FAILURE - fi - - if test -n "$add_shlibpath"; then - case :$compile_shlibpath: in - *":$add_shlibpath:"*) ;; - *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; - esac - fi - if test "$linkmode" = prog; then - test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" - test -n "$add" && compile_deplibs="$add $compile_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - if test "$hardcode_direct" != yes && \ - test "$hardcode_minus_L" != yes && \ - test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - fi - fi - fi - - if test "$linkmode" = prog || test "$mode" = relink; then - add_shlibpath= - add_dir= - add= - # Finalize command for both is simple: just hardcode it. - if test "$hardcode_direct" = yes; then - add="$libdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$libdir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - add="-l$name" - elif test "$hardcode_automatic" = yes; then - if test -n "$inst_prefix_dir" && - test -f "$inst_prefix_dir$libdir/$linklib" ; then - add="$inst_prefix_dir$libdir/$linklib" - else - add="$libdir/$linklib" - fi - else - # We cannot seem to hardcode it, guess we'll fake it. - add_dir="-L$libdir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - add_dir="$add_dir -L$inst_prefix_dir$libdir" - ;; - esac - fi - add="-l$name" - fi - - if test "$linkmode" = prog; then - test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" - test -n "$add" && finalize_deplibs="$add $finalize_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - fi - fi - elif test "$linkmode" = prog; then - # Here we assume that one of hardcode_direct or hardcode_minus_L - # is not unsupported. This is valid on all known static and - # shared platforms. - if test "$hardcode_direct" != unsupported; then - test -n "$old_library" && linklib="$old_library" - compile_deplibs="$dir/$linklib $compile_deplibs" - finalize_deplibs="$dir/$linklib $finalize_deplibs" - else - compile_deplibs="-l$name -L$dir $compile_deplibs" - finalize_deplibs="-l$name -L$dir $finalize_deplibs" - fi - elif test "$build_libtool_libs" = yes; then - # Not a shared library - if test "$deplibs_check_method" != pass_all; then - # We're trying link a shared library against a static one - # but the system doesn't support it. - - # Just print a warning and add the library to dependency_libs so - # that the program can be linked against the static library. - $echo - $echo "*** Warning: This system can not link to static lib archive $lib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have." - if test "$module" = yes; then - $echo "*** But as you try to build a module library, libtool will still create " - $echo "*** a static module, that should work as long as the dlopening application" - $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." - if test -z "$global_symbol_pipe"; then - $echo - $echo "*** However, this would only work if libtool was able to extract symbol" - $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - $echo "*** not find such a program. So, this module is probably useless." - $echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - else - deplibs="$dir/$old_library $deplibs" - link_static=yes - fi - fi # link shared/static library? - - if test "$linkmode" = lib; then - if test -n "$dependency_libs" && - { test "$hardcode_into_libs" != yes || - test "$build_old_libs" = yes || - test "$link_static" = yes; }; then - # Extract -R from dependency_libs - temp_deplibs= - for libdir in $dependency_libs; do - case $libdir in - -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` - case " $xrpath " in - *" $temp_xrpath "*) ;; - *) xrpath="$xrpath $temp_xrpath";; - esac;; - *) temp_deplibs="$temp_deplibs $libdir";; - esac - done - dependency_libs="$temp_deplibs" - fi - - newlib_search_path="$newlib_search_path $absdir" - # Link against this library - test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" - # ... and its dependency_libs - tmp_libs= - for deplib in $dependency_libs; do - newdependency_libs="$deplib $newdependency_libs" - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done - - if test "$link_all_deplibs" != no; then - # Add the search paths of all dependency libraries - for deplib in $dependency_libs; do - case $deplib in - -L*) path="$deplib" ;; - *.la) - dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$deplib" && dir="." - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 - absdir="$dir" - fi - ;; - esac - if grep "^installed=no" $deplib > /dev/null; then - path="$absdir/$objdir" - else - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - if test -z "$libdir"; then - $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - if test "$absdir" != "$libdir"; then - $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 - fi - path="$absdir" - fi - depdepl= - case $host in - *-*-darwin*) - # we do not want to link against static libs, - # but need to link against shared - eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` - if test -n "$deplibrary_names" ; then - for tmp in $deplibrary_names ; do - depdepl=$tmp - done - if test -f "$path/$depdepl" ; then - depdepl="$path/$depdepl" - fi - # do not add paths which are already there - case " $newlib_search_path " in - *" $path "*) ;; - *) newlib_search_path="$newlib_search_path $path";; - esac - fi - path="" - ;; - *) - path="-L$path" - ;; - esac - ;; - -l*) - case $host in - *-*-darwin*) - # Again, we only want to link against shared libraries - eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` - for tmp in $newlib_search_path ; do - if test -f "$tmp/lib$tmp_libs.dylib" ; then - eval depdepl="$tmp/lib$tmp_libs.dylib" - break - fi - done - path="" - ;; - *) continue ;; - esac - ;; - *) continue ;; - esac - case " $deplibs " in - *" $path "*) ;; - *) deplibs="$path $deplibs" ;; - esac - case " $deplibs " in - *" $depdepl "*) ;; - *) deplibs="$depdepl $deplibs" ;; - esac - done - fi # link_all_deplibs != no - fi # linkmode = lib - done # for deplib in $libs - dependency_libs="$newdependency_libs" - if test "$pass" = dlpreopen; then - # Link the dlpreopened libraries before other libraries - for deplib in $save_deplibs; do - deplibs="$deplib $deplibs" - done - fi - if test "$pass" != dlopen; then - if test "$pass" != conv; then - # Make sure lib_search_path contains only unique directories. - lib_search_path= - for dir in $newlib_search_path; do - case "$lib_search_path " in - *" $dir "*) ;; - *) lib_search_path="$lib_search_path $dir" ;; - esac - done - newlib_search_path= - fi - - if test "$linkmode,$pass" != "prog,link"; then - vars="deplibs" - else - vars="compile_deplibs finalize_deplibs" - fi - for var in $vars dependency_libs; do - # Add libraries to $var in reverse order - eval tmp_libs=\"\$$var\" - new_libs= - for deplib in $tmp_libs; do - # FIXME: Pedantically, this is the right thing to do, so - # that some nasty dependency loop isn't accidentally - # broken: - #new_libs="$deplib $new_libs" - # Pragmatically, this seems to cause very few problems in - # practice: - case $deplib in - -L*) new_libs="$deplib $new_libs" ;; - -R*) ;; - *) - # And here is the reason: when a library appears more - # than once as an explicit dependence of a library, or - # is implicitly linked in more than once by the - # compiler, it is considered special, and multiple - # occurrences thereof are not removed. Compare this - # with having the same library being listed as a - # dependency of multiple other libraries: in this case, - # we know (pedantically, we assume) the library does not - # need to be listed more than once, so we keep only the - # last copy. This is not always right, but it is rare - # enough that we require users that really mean to play - # such unportable linking tricks to link the library - # using -Wl,-lname, so that libtool does not consider it - # for duplicate removal. - case " $specialdeplibs " in - *" $deplib "*) new_libs="$deplib $new_libs" ;; - *) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$deplib $new_libs" ;; - esac - ;; - esac - ;; - esac - done - tmp_libs= - for deplib in $new_libs; do - case $deplib in - -L*) - case " $tmp_libs " in - *" $deplib "*) ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - done - eval $var=\"$tmp_libs\" - done # for var - fi - # Last step: remove runtime libs from dependency_libs - # (they stay in deplibs) - tmp_libs= - for i in $dependency_libs ; do - case " $predeps $postdeps $compiler_lib_search_path " in - *" $i "*) - i="" - ;; - esac - if test -n "$i" ; then - tmp_libs="$tmp_libs $i" - fi - done - dependency_libs=$tmp_libs - done # for pass - if test "$linkmode" = prog; then - dlfiles="$newdlfiles" - dlprefiles="$newdlprefiles" - fi - - case $linkmode in - oldlib) - if test -n "$deplibs"; then - $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 - fi - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 - fi - - if test -n "$rpath"; then - $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 - fi - - if test -n "$xrpath"; then - $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 - fi - - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 - fi - - # Now set the variables for building old libraries. - build_libtool_libs=no - oldlibs="$output" - objs="$objs$old_deplibs" - ;; - - lib) - # Make sure we only generate libraries of the form `libNAME.la'. - case $outputname in - lib*) - name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - ;; - *) - if test "$module" = no; then - $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - if test "$need_lib_prefix" != no; then - # Add the "lib" prefix for modules if required - name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - else - libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` - fi - ;; - esac - - if test -n "$objs"; then - if test "$deplibs_check_method" != pass_all; then - $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 - exit $EXIT_FAILURE - else - $echo - $echo "*** Warning: Linking the shared library $output against the non-libtool" - $echo "*** objects $objs is not portable!" - libobjs="$libobjs $objs" - fi - fi - - if test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 - fi - - set dummy $rpath - if test "$#" -gt 2; then - $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 - fi - install_libdir="$2" - - oldlibs= - if test -z "$rpath"; then - if test "$build_libtool_libs" = yes; then - # Building a libtool convenience library. - # Some compilers have problems with a `.al' extension so - # convenience libraries should have the same extension an - # archive normally would. - oldlibs="$output_objdir/$libname.$libext $oldlibs" - build_libtool_libs=convenience - build_old_libs=yes - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 - fi - else - - # Parse the version information argument. - save_ifs="$IFS"; IFS=':' - set dummy $vinfo 0 0 0 - IFS="$save_ifs" - - if test -n "$8"; then - $echo "$modename: too many parameters to \`-version-info'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # convert absolute version numbers to libtool ages - # this retains compatibility with .la files and attempts - # to make the code below a bit more comprehensible - - case $vinfo_number in - yes) - number_major="$2" - number_minor="$3" - number_revision="$4" - # - # There are really only two kinds -- those that - # use the current revision as the major version - # and those that subtract age and use age as - # a minor version. But, then there is irix - # which has an extra 1 added just for fun - # - case $version_type in - darwin|linux|osf|windows|none) - current=`expr $number_major + $number_minor` - age="$number_minor" - revision="$number_revision" - ;; - freebsd-aout|freebsd-elf|sunos) - current="$number_major" - revision="$number_minor" - age="0" - ;; - irix|nonstopux) - current=`expr $number_major + $number_minor` - age="$number_minor" - revision="$number_minor" - lt_irix_increment=no - ;; - esac - ;; - no) - current="$2" - revision="$3" - age="$4" - ;; - esac - - # Check that each of the things are valid numbers. - case $current in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - case $revision in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - case $age in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - if test "$age" -gt "$current"; then - $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit $EXIT_FAILURE - fi - - # Calculate the version variables. - major= - versuffix= - verstring= - case $version_type in - none) ;; - - darwin) - # Like Linux, but with the current version available in - # verstring for coding it into the library header - major=.`expr $current - $age` - versuffix="$major.$age.$revision" - # Darwin ld doesn't like 0 for these options... - minor_current=`expr $current + 1` - xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" - verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" - ;; - - freebsd-aout) - major=".$current" - versuffix=".$current.$revision"; - ;; - - freebsd-elf) - major=".$current" - versuffix=".$current"; - ;; - - irix | nonstopux) - if test "X$lt_irix_increment" = "Xno"; then - major=`expr $current - $age` - else - major=`expr $current - $age + 1` - fi - case $version_type in - nonstopux) verstring_prefix=nonstopux ;; - *) verstring_prefix=sgi ;; - esac - verstring="$verstring_prefix$major.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$revision - while test "$loop" -ne 0; do - iface=`expr $revision - $loop` - loop=`expr $loop - 1` - verstring="$verstring_prefix$major.$iface:$verstring" - done - - # Before this point, $major must not contain `.'. - major=.$major - versuffix="$major.$revision" - ;; - - linux) - major=.`expr $current - $age` - versuffix="$major.$age.$revision" - ;; - - osf) - major=.`expr $current - $age` - versuffix=".$current.$age.$revision" - verstring="$current.$age.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$age - while test "$loop" -ne 0; do - iface=`expr $current - $loop` - loop=`expr $loop - 1` - verstring="$verstring:${iface}.0" - done - - # Make executables depend on our current version. - verstring="$verstring:${current}.0" - ;; - - sunos) - major=".$current" - versuffix=".$current.$revision" - ;; - - windows) - # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 filesystems. - major=`expr $current - $age` - versuffix="-$major" - ;; - - *) - $echo "$modename: unknown library version type \`$version_type'" 1>&2 - $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit $EXIT_FAILURE - ;; - esac - - # Clear the version info if we defaulted, and they specified a release. - if test -z "$vinfo" && test -n "$release"; then - major= - case $version_type in - darwin) - # we can't check for "0.0" in archive_cmds due to quoting - # problems, so we reset it completely - verstring= - ;; - *) - verstring="0.0" - ;; - esac - if test "$need_version" = no; then - versuffix= - else - versuffix=".0.0" - fi - fi - - # Remove version info from name if versioning should be avoided - if test "$avoid_version" = yes && test "$need_version" = no; then - major= - versuffix= - verstring="" - fi - - # Check to see if the archive will have undefined symbols. - if test "$allow_undefined" = yes; then - if test "$allow_undefined_flag" = unsupported; then - $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 - build_libtool_libs=no - build_old_libs=yes - fi - else - # Don't allow undefined symbols. - allow_undefined_flag="$no_undefined_flag" - fi - fi - - if test "$mode" != relink; then - # Remove our outputs, but don't remove object files since they - # may have been created when compiling PIC objects. - removelist= - tempremovelist=`$echo "$output_objdir/*"` - for p in $tempremovelist; do - case $p in - *.$objext) - ;; - $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) - if test "X$precious_files_regex" != "X"; then - if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 - then - continue - fi - fi - removelist="$removelist $p" - ;; - *) ;; - esac - done - if test -n "$removelist"; then - $show "${rm}r $removelist" - $run ${rm}r $removelist - fi - fi - - # Now set the variables for building old libraries. - if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then - oldlibs="$oldlibs $output_objdir/$libname.$libext" - - # Transform .lo files to .o files. - oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` - fi - - # Eliminate all temporary directories. - #for path in $notinst_path; do - # lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"` - # deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"` - # dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"` - #done - - if test -n "$xrpath"; then - # If the user specified any rpath flags, then add them. - temp_xrpath= - for libdir in $xrpath; do - temp_xrpath="$temp_xrpath -R$libdir" - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then - dependency_libs="$temp_xrpath $dependency_libs" - fi - fi - - # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles="$dlfiles" - dlfiles= - for lib in $old_dlfiles; do - case " $dlprefiles $dlfiles " in - *" $lib "*) ;; - *) dlfiles="$dlfiles $lib" ;; - esac - done - - # Make sure dlprefiles contains only unique files - old_dlprefiles="$dlprefiles" - dlprefiles= - for lib in $old_dlprefiles; do - case "$dlprefiles " in - *" $lib "*) ;; - *) dlprefiles="$dlprefiles $lib" ;; - esac - done - - if test "$build_libtool_libs" = yes; then - if test -n "$rpath"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) - # these systems don't actually have a c library (as such)! - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C library is in the System framework - deplibs="$deplibs -framework System" - ;; - *-*-netbsd*) - # Don't link with libc until the a.out ld.so is fixed. - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - ;; - *-*-sco3.2v5* | *-*-sco5v6*) - # Causes problems with __ctype - ;; - *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) - # Compiler inserts libc in the correct place for threads to work - ;; - *) - # Add libc to deplibs on all other systems if necessary. - if test "$build_libtool_need_lc" = "yes"; then - deplibs="$deplibs -lc" - fi - ;; - esac - fi - - # Transform deplibs into only deplibs that can be linked in shared. - name_save=$name - libname_save=$libname - release_save=$release - versuffix_save=$versuffix - major_save=$major - # I'm not sure if I'm treating the release correctly. I think - # release should show up in the -l (ie -lgmp5) so we don't want to - # add it in twice. Is that correct? - release="" - versuffix="" - major="" - newdeplibs= - droppeddeps=no - case $deplibs_check_method in - pass_all) - # Don't check for shared/static. Everything works. - # This might be a little naive. We might want to check - # whether the library exists or not. But this is on - # osf3 & osf4 and I'm not really sure... Just - # implementing what was already the behavior. - newdeplibs=$deplibs - ;; - test_compile) - # This code stresses the "libraries are programs" paradigm to its - # limits. Maybe even breaks it. We compile a program, linking it - # against the deplibs as a proxy for the library. Then we can check - # whether they linked in statically or dynamically with ldd. - $rm conftest.c - cat > conftest.c </dev/null` - for potent_lib in $potential_libs; do - # Follow soft links. - if ls -lLd "$potent_lib" 2>/dev/null \ - | grep " -> " >/dev/null; then - continue - fi - # The statement above tries to avoid entering an - # endless loop below, in case of cyclic links. - # We might still enter an endless loop, since a link - # loop can be closed while we follow links, - # but so what? - potlib="$potent_lib" - while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` - case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; - *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; - esac - done - if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ - | ${SED} 10q \ - | $EGREP "$file_magic_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - $echo - $echo "*** Warning: linker path does not have real file for library $a_deplib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have" - $echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $echo "*** with $libname but no candidates were found. (...for file magic test)" - else - $echo "*** with $libname and none of the candidates passed a file format test" - $echo "*** using a file magic. Last file checked: $potlib" - fi - fi - else - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - fi - done # Gone through all deplibs. - ;; - match_pattern*) - set dummy $deplibs_check_method - match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` - for a_deplib in $deplibs; do - name=`expr $a_deplib : '-l\(.*\)'` - # If $name is empty we are operating on a -L argument. - if test -n "$name" && test "$name" != "0"; then - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $a_deplib "*) - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - ;; - esac - fi - if test -n "$a_deplib" ; then - libname=`eval \\$echo \"$libname_spec\"` - for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - potential_libs=`ls $i/$libname[.-]* 2>/dev/null` - for potent_lib in $potential_libs; do - potlib="$potent_lib" # see symlink-check above in file_magic test - if eval $echo \"$potent_lib\" 2>/dev/null \ - | ${SED} 10q \ - | $EGREP "$match_pattern_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - $echo - $echo "*** Warning: linker path does not have real file for library $a_deplib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have" - $echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $echo "*** with $libname but no candidates were found. (...for regex pattern test)" - else - $echo "*** with $libname and none of the candidates passed a file format test" - $echo "*** using a regex pattern. Last file checked: $potlib" - fi - fi - else - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - fi - done # Gone through all deplibs. - ;; - none | unknown | *) - newdeplibs="" - tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ - -e 's/ -[LR][^ ]*//g'` - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - for i in $predeps $postdeps ; do - # can't use Xsed below, because $i might contain '/' - tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` - done - fi - if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ - | grep . >/dev/null; then - $echo - if test "X$deplibs_check_method" = "Xnone"; then - $echo "*** Warning: inter-library dependencies are not supported in this platform." - else - $echo "*** Warning: inter-library dependencies are not known to be supported." - fi - $echo "*** All declared inter-library dependencies are being dropped." - droppeddeps=yes - fi - ;; - esac - versuffix=$versuffix_save - major=$major_save - release=$release_save - libname=$libname_save - name=$name_save - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` - ;; - esac - - if test "$droppeddeps" = yes; then - if test "$module" = yes; then - $echo - $echo "*** Warning: libtool could not satisfy all declared inter-library" - $echo "*** dependencies of module $libname. Therefore, libtool will create" - $echo "*** a static module, that should work as long as the dlopening" - $echo "*** application is linked with the -dlopen flag." - if test -z "$global_symbol_pipe"; then - $echo - $echo "*** However, this would only work if libtool was able to extract symbol" - $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - $echo "*** not find such a program. So, this module is probably useless." - $echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - else - $echo "*** The inter-library dependencies that have been dropped here will be" - $echo "*** automatically added whenever a program is linked with this library" - $echo "*** or is declared to -dlopen it." - - if test "$allow_undefined" = no; then - $echo - $echo "*** Since this library must not contain undefined symbols," - $echo "*** because either the platform does not support them or" - $echo "*** it was explicitly requested with -no-undefined," - $echo "*** libtool will only create a static version of it." - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - fi - fi - # Done checking deplibs! - deplibs=$newdeplibs - fi - - - # move library search paths that coincide with paths to not yet - # installed libraries to the beginning of the library search list - new_libs= - for path in $notinst_path; do - case " $new_libs " in - *" -L$path/$objdir "*) ;; - *) - case " $deplibs " in - *" -L$path/$objdir "*) - new_libs="$new_libs -L$path/$objdir" ;; - esac - ;; - esac - done - for deplib in $deplibs; do - case $deplib in - -L*) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$new_libs $deplib" ;; - esac - ;; - *) new_libs="$new_libs $deplib" ;; - esac - done - deplibs="$new_libs" - - - # All the library-specific variables (install_libdir is set above). - library_names= - old_library= - dlname= - - # Test again, we may have decided not to build it any more - if test "$build_libtool_libs" = yes; then - if test "$hardcode_into_libs" = yes; then - # Hardcode the library paths - hardcode_libdirs= - dep_rpath= - rpath="$finalize_rpath" - test "$mode" != relink && rpath="$compile_rpath$rpath" - for libdir in $rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - dep_rpath="$dep_rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - if test -n "$hardcode_libdir_flag_spec_ld"; then - case $archive_cmds in - *\$LD*) eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" ;; - *) eval dep_rpath=\"$hardcode_libdir_flag_spec\" ;; - esac - else - eval dep_rpath=\"$hardcode_libdir_flag_spec\" - fi - fi - if test -n "$runpath_var" && test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" - fi - test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" - fi - - shlibpath="$finalize_shlibpath" - test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" - if test -n "$shlibpath"; then - eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" - fi - - # Get the real and link names of the library. - eval shared_ext=\"$shrext_cmds\" - eval library_names=\"$library_names_spec\" - set dummy $library_names - realname="$2" - shift; shift - - if test -n "$soname_spec"; then - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - if test -z "$dlname"; then - dlname=$soname - fi - - lib="$output_objdir/$realname" - linknames= - for link - do - linknames="$linknames $link" - done - - # Use standard objects if they are pic - test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then - $show "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $run $rm $export_symbols - cmds=$export_symbols_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - if len=`expr "X$cmd" : ".*"` && - test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then - $show "$cmd" - $run eval "$cmd" || exit $? - skipped_export=false - else - # The command line is too long to execute in one step. - $show "using reloadable object file for export list..." - skipped_export=: - # Break out early, otherwise skipped_export may be - # set to false by a later but shorter cmd. - break - fi - done - IFS="$save_ifs" - if test -n "$export_symbols_regex"; then - $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" - $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - $show "$mv \"${export_symbols}T\" \"$export_symbols\"" - $run eval '$mv "${export_symbols}T" "$export_symbols"' - fi - fi - fi - - if test -n "$export_symbols" && test -n "$include_expsyms"; then - $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' - fi - - tmp_deplibs= - for test_deplib in $deplibs; do - case " $convenience " in - *" $test_deplib "*) ;; - *) - tmp_deplibs="$tmp_deplibs $test_deplib" - ;; - esac - done - deplibs="$tmp_deplibs" - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - else - gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" - - func_extract_archives $gentop $convenience - libobjs="$libobjs $func_extract_archives_result" - fi - fi - - if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then - eval flag=\"$thread_safe_flag_spec\" - linker_flags="$linker_flags $flag" - fi - - # Make a backup of the uninstalled library when relinking - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? - fi - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - eval test_cmds=\"$module_expsym_cmds\" - cmds=$module_expsym_cmds - else - eval test_cmds=\"$module_cmds\" - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - eval test_cmds=\"$archive_expsym_cmds\" - cmds=$archive_expsym_cmds - else - eval test_cmds=\"$archive_cmds\" - cmds=$archive_cmds - fi - fi - - if test "X$skipped_export" != "X:" && - len=`expr "X$test_cmds" : ".*" 2>/dev/null` && - test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then - : - else - # The command line is too long to link in one step, link piecewise. - $echo "creating reloadable object files..." - - # Save the value of $output and $libobjs because we want to - # use them later. If we have whole_archive_flag_spec, we - # want to use save_libobjs as it was before - # whole_archive_flag_spec was expanded, because we can't - # assume the linker understands whole_archive_flag_spec. - # This may have to be revisited, in case too many - # convenience libraries get linked in and end up exceeding - # the spec. - if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - fi - save_output=$output - output_la=`$echo "X$output" | $Xsed -e "$basename"` - - # Clear the reloadable object creation command queue and - # initialize k to one. - test_cmds= - concat_cmds= - objlist= - delfiles= - last_robj= - k=1 - output=$output_objdir/$output_la-${k}.$objext - # Loop over the list of objects to be linked. - for obj in $save_libobjs - do - eval test_cmds=\"$reload_cmds $objlist $last_robj\" - if test "X$objlist" = X || - { len=`expr "X$test_cmds" : ".*" 2>/dev/null` && - test "$len" -le "$max_cmd_len"; }; then - objlist="$objlist $obj" - else - # The command $test_cmds is almost too long, add a - # command to the queue. - if test "$k" -eq 1 ; then - # The first file doesn't have a previous command to add. - eval concat_cmds=\"$reload_cmds $objlist $last_robj\" - else - # All subsequent reloadable object files will link in - # the last one created. - eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" - fi - last_robj=$output_objdir/$output_la-${k}.$objext - k=`expr $k + 1` - output=$output_objdir/$output_la-${k}.$objext - objlist=$obj - len=1 - fi - done - # Handle the remaining objects by creating one last - # reloadable object file. All subsequent reloadable object - # files will link in the last one created. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" - - if ${skipped_export-false}; then - $show "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $run $rm $export_symbols - libobjs=$output - # Append the command to create the export file. - eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" - fi - - # Set up a command to remove the reloadable object files - # after they are used. - i=0 - while test "$i" -lt "$k" - do - i=`expr $i + 1` - delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" - done - - $echo "creating a temporary reloadable object file: $output" - - # Loop through the commands generated above and execute them. - save_ifs="$IFS"; IFS='~' - for cmd in $concat_cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - libobjs=$output - # Restore the value of output. - output=$save_output - - if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - fi - # Expand the library linking commands again to reset the - # value of $libobjs for piecewise linking. - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - cmds=$module_expsym_cmds - else - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - cmds=$archive_expsym_cmds - else - cmds=$archive_cmds - fi - fi - - # Append the command to remove the reloadable object files - # to the just-reset $cmds. - eval cmds=\"\$cmds~\$rm $delfiles\" - fi - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' - fi - - exit $lt_exit - } - done - IFS="$save_ifs" - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? - - if test -n "$convenience"; then - if test -z "$whole_archive_flag_spec"; then - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - fi - fi - - exit $EXIT_SUCCESS - fi - - # Create links to the real library. - for linkname in $linknames; do - if test "$realname" != "$linkname"; then - $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" - $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? - fi - done - - # If -module or -export-dynamic was specified, set the dlname. - if test "$module" = yes || test "$export_dynamic" = yes; then - # On all known operating systems, these are identical. - dlname="$soname" - fi - fi - ;; - - obj) - if test -n "$deplibs"; then - $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 - fi - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 - fi - - if test -n "$rpath"; then - $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 - fi - - if test -n "$xrpath"; then - $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 - fi - - case $output in - *.lo) - if test -n "$objs$old_deplibs"; then - $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 - exit $EXIT_FAILURE - fi - libobj="$output" - obj=`$echo "X$output" | $Xsed -e "$lo2o"` - ;; - *) - libobj= - obj="$output" - ;; - esac - - # Delete the old objects. - $run $rm $obj $libobj - - # Objects from convenience libraries. This assumes - # single-version convenience libraries. Whenever we create - # different ones for PIC/non-PIC, this we'll have to duplicate - # the extraction. - reload_conv_objs= - gentop= - # reload_cmds runs $LD directly, so let us get rid of - # -Wl from whole_archive_flag_spec and hope we can get by with - # turning comma into space.. - wl= - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" - reload_conv_objs=$reload_objs\ `$echo "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` - else - gentop="$output_objdir/${obj}x" - generated="$generated $gentop" - - func_extract_archives $gentop $convenience - reload_conv_objs="$reload_objs $func_extract_archives_result" - fi - fi - - # Create the old-style object. - reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test - - output="$obj" - cmds=$reload_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - # Exit if we aren't doing a library object file. - if test -z "$libobj"; then - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - exit $EXIT_SUCCESS - fi - - if test "$build_libtool_libs" != yes; then - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - # Create an invalid libtool object if no PIC, so that we don't - # accidentally link it into a program. - # $show "echo timestamp > $libobj" - # $run eval "echo timestamp > $libobj" || exit $? - exit $EXIT_SUCCESS - fi - - if test -n "$pic_flag" || test "$pic_mode" != default; then - # Only do commands if we really have different PIC objects. - reload_objs="$libobjs $reload_conv_objs" - output="$libobj" - cmds=$reload_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - exit $EXIT_SUCCESS - ;; - - prog) - case $host in - *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; - esac - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 - fi - - if test "$preload" = yes; then - if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && - test "$dlopen_self_static" = unknown; then - $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." - fi - fi - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` - finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` - ;; - esac - - case $host in - *darwin*) - # Don't allow lazy linking, it breaks C++ global constructors - if test "$tagname" = CXX ; then - compile_command="$compile_command ${wl}-bind_at_load" - finalize_command="$finalize_command ${wl}-bind_at_load" - fi - ;; - esac - - - # move library search paths that coincide with paths to not yet - # installed libraries to the beginning of the library search list - new_libs= - for path in $notinst_path; do - case " $new_libs " in - *" -L$path/$objdir "*) ;; - *) - case " $compile_deplibs " in - *" -L$path/$objdir "*) - new_libs="$new_libs -L$path/$objdir" ;; - esac - ;; - esac - done - for deplib in $compile_deplibs; do - case $deplib in - -L*) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$new_libs $deplib" ;; - esac - ;; - *) new_libs="$new_libs $deplib" ;; - esac - done - compile_deplibs="$new_libs" - - - compile_command="$compile_command $compile_deplibs" - finalize_command="$finalize_command $finalize_deplibs" - - if test -n "$rpath$xrpath"; then - # If the user specified any rpath flags, then add them. - for libdir in $rpath $xrpath; do - # This is the magic to use -rpath. - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - fi - - # Now hardcode the library paths - rpath= - hardcode_libdirs= - for libdir in $compile_rpath $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'` - case :$dllsearchpath: in - *":$libdir:"*) ;; - *) dllsearchpath="$dllsearchpath:$libdir";; - esac - case :$dllsearchpath: in - *":$testbindir:"*) ;; - *) dllsearchpath="$dllsearchpath:$testbindir";; - esac - ;; - esac - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - compile_rpath="$rpath" - - rpath= - hardcode_libdirs= - for libdir in $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$finalize_perm_rpath " in - *" $libdir "*) ;; - *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - finalize_rpath="$rpath" - - if test -n "$libobjs" && test "$build_old_libs" = yes; then - # Transform all the library objects into standard objects. - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - fi - - dlsyms= - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - if test -n "$NM" && test -n "$global_symbol_pipe"; then - dlsyms="${outputname}S.c" - else - $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 - fi - fi - - if test -n "$dlsyms"; then - case $dlsyms in - "") ;; - *.c) - # Discover the nlist of each of the dlfiles. - nlist="$output_objdir/${outputname}.nm" - - $show "$rm $nlist ${nlist}S ${nlist}T" - $run $rm "$nlist" "${nlist}S" "${nlist}T" - - # Parse the name list into a source file. - $show "creating $output_objdir/$dlsyms" - - test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ -/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ -/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ - -#ifdef __cplusplus -extern \"C\" { -#endif - -/* Prevent the only kind of declaration conflicts we can make. */ -#define lt_preloaded_symbols some_other_symbol - -/* External symbol declarations for the compiler. */\ -" - - if test "$dlself" = yes; then - $show "generating symbol list for \`$output'" - - test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" - - # Add our own program objects to the symbol list. - progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - for arg in $progfiles; do - $show "extracting global C symbols from \`$arg'" - $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" - done - - if test -n "$exclude_expsyms"; then - $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' - $run eval '$mv "$nlist"T "$nlist"' - fi - - if test -n "$export_symbols_regex"; then - $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' - $run eval '$mv "$nlist"T "$nlist"' - fi - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - export_symbols="$output_objdir/$outputname.exp" - $run $rm $export_symbols - $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' - case $host in - *cygwin* | *mingw* ) - $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' - $run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' - ;; - esac - else - $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' - $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' - $run eval 'mv "$nlist"T "$nlist"' - case $host in - *cygwin* | *mingw* ) - $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' - $run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' - ;; - esac - fi - fi - - for arg in $dlprefiles; do - $show "extracting global C symbols from \`$arg'" - name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` - $run eval '$echo ": $name " >> "$nlist"' - $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" - done - - if test -z "$run"; then - # Make sure we have at least an empty file. - test -f "$nlist" || : > "$nlist" - - if test -n "$exclude_expsyms"; then - $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T - $mv "$nlist"T "$nlist" - fi - - # Try sorting and uniquifying the output. - if grep -v "^: " < "$nlist" | - if sort -k 3 /dev/null 2>&1; then - sort -k 3 - else - sort +2 - fi | - uniq > "$nlist"S; then - : - else - grep -v "^: " < "$nlist" > "$nlist"S - fi - - if test -f "$nlist"S; then - eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' - else - $echo '/* NONE */' >> "$output_objdir/$dlsyms" - fi - - $echo >> "$output_objdir/$dlsyms" "\ - -#undef lt_preloaded_symbols - -#if defined (__STDC__) && __STDC__ -# define lt_ptr void * -#else -# define lt_ptr char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -" - - case $host in - *cygwin* | *mingw* ) - $echo >> "$output_objdir/$dlsyms" "\ -/* DATA imports from DLLs on WIN32 can't be const, because - runtime relocations are performed -- see ld's documentation - on pseudo-relocs */ -struct { -" - ;; - * ) - $echo >> "$output_objdir/$dlsyms" "\ -const struct { -" - ;; - esac - - - $echo >> "$output_objdir/$dlsyms" "\ - const char *name; - lt_ptr address; -} -lt_preloaded_symbols[] = -{\ -" - - eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" - - $echo >> "$output_objdir/$dlsyms" "\ - {0, (lt_ptr) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif\ -" - fi - - pic_flag_for_symtable= - case $host in - # compiling the symbol table file with pic_flag works around - # a FreeBSD bug that causes programs to crash when -lm is - # linked before any other PIC object. But we must not use - # pic_flag when linking with -static. The problem exists in - # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. - *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; - esac;; - *-*-hpux*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag";; - esac - esac - - # Now compile the dynamic symbol file. - $show "(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" - $run eval '(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? - - # Clean up the generated files. - $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" - $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" - - # Transform the symbol file into the correct name. - case $host in - *cygwin* | *mingw* ) - if test -f "$output_objdir/${outputname}.def" ; then - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` - finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP` - else - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` - finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` - fi - ;; - * ) - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` - finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP` - ;; - esac - ;; - *) - $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 - exit $EXIT_FAILURE - ;; - esac - else - # We keep going just in case the user didn't refer to - # lt_preloaded_symbols. The linker will fail if global_symbol_pipe - # really was required. - - # Nullify the symbol file. - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` - finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP` - fi - - if test "$need_relink" = no || test "$build_libtool_libs" != yes; then - # Replace the output file specification. - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$output"'%g' | $NL2SP` - link_command="$compile_command$compile_rpath" - - # We have no uninstalled library dependencies, so finalize right now. - $show "$link_command" - $run eval "$link_command" - exit_status=$? - - # Delete the generated files. - if test -n "$dlsyms"; then - $show "$rm $output_objdir/${outputname}S.${objext}" - $run $rm "$output_objdir/${outputname}S.${objext}" - fi - - exit $exit_status - fi - - if test -n "$shlibpath_var"; then - # We should set the shlibpath_var - rpath= - for dir in $temp_rpath; do - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) - # Absolute path. - rpath="$rpath$dir:" - ;; - *) - # Relative path: add a thisdir entry. - rpath="$rpath\$thisdir/$dir:" - ;; - esac - done - temp_rpath="$rpath" - fi - - if test -n "$compile_shlibpath$finalize_shlibpath"; then - compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" - fi - if test -n "$finalize_shlibpath"; then - finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" - fi - - compile_var= - finalize_var= - if test -n "$runpath_var"; then - if test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - compile_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - if test -n "$finalize_perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $finalize_perm_rpath; do - rpath="$rpath$dir:" - done - finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - fi - - if test "$no_install" = yes; then - # We don't need to create a wrapper script. - link_command="$compile_var$compile_command$compile_rpath" - # Replace the output file specification. - link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` - # Delete the old output file. - $run $rm $output - # Link the executable and exit - $show "$link_command" - $run eval "$link_command" || exit $? - exit $EXIT_SUCCESS - fi - - if test "$hardcode_action" = relink; then - # Fast installation is not supported - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - - $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 - $echo "$modename: \`$output' will be relinked during installation" 1>&2 - else - if test "$fast_install" != no; then - link_command="$finalize_var$compile_command$finalize_rpath" - if test "$fast_install" = yes; then - relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $SP2NL | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g' | $NL2SP` - else - # fast_install is set to needless - relink_command= - fi - else - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - fi - fi - - # Replace the output file specification. - link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` - - # Delete the old output files. - $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname - - $show "$link_command" - $run eval "$link_command" || exit $? - - # Now create the wrapper script. - $show "creating $output" - - # Quote the relink command for shipping. - if test -n "$relink_command"; then - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` - relink_command="$var=\"$var_value\"; export $var; $relink_command" - fi - done - relink_command="(cd `pwd`; $relink_command)" - relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` - fi - - # Quote $echo for shipping. - if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then - case $progpath in - [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; - *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; - esac - qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` - else - qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` - fi - - # Only actually do things if our run command is non-null. - if test -z "$run"; then - # win32 will think the script is a binary if it has - # a .exe suffix, so we strip it off here. - case $output in - *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; - esac - # test for cygwin because mv fails w/o .exe extensions - case $host in - *cygwin*) - exeext=.exe - outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; - *) exeext= ;; - esac - case $host in - *cygwin* | *mingw* ) - output_name=`basename $output` - output_path=`dirname $output` - cwrappersource="$output_path/$objdir/lt-$output_name.c" - cwrapper="$output_path/$output_name.exe" - $rm $cwrappersource $cwrapper - trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 - - cat > $cwrappersource <> $cwrappersource<<"EOF" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(PATH_MAX) -# define LT_PATHMAX PATH_MAX -#elif defined(MAXPATHLEN) -# define LT_PATHMAX MAXPATHLEN -#else -# define LT_PATHMAX 1024 -#endif - -#ifndef DIR_SEPARATOR -# define DIR_SEPARATOR '/' -# define PATH_SEPARATOR ':' -#endif - -#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ - defined (__OS2__) -# define HAVE_DOS_BASED_FILE_SYSTEM -# ifndef DIR_SEPARATOR_2 -# define DIR_SEPARATOR_2 '\\' -# endif -# ifndef PATH_SEPARATOR_2 -# define PATH_SEPARATOR_2 ';' -# endif -#endif - -#ifndef DIR_SEPARATOR_2 -# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) -#else /* DIR_SEPARATOR_2 */ -# define IS_DIR_SEPARATOR(ch) \ - (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) -#endif /* DIR_SEPARATOR_2 */ - -#ifndef PATH_SEPARATOR_2 -# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) -#else /* PATH_SEPARATOR_2 */ -# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) -#endif /* PATH_SEPARATOR_2 */ - -#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) -#define XFREE(stale) do { \ - if (stale) { free ((void *) stale); stale = 0; } \ -} while (0) - -/* -DDEBUG is fairly common in CFLAGS. */ -#undef DEBUG -#if defined DEBUGWRAPPER -# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__) -#else -# define DEBUG(format, ...) -#endif - -const char *program_name = NULL; - -void * xmalloc (size_t num); -char * xstrdup (const char *string); -const char * base_name (const char *name); -char * find_executable(const char *wrapper); -int check_executable(const char *path); -char * strendzap(char *str, const char *pat); -void lt_fatal (const char *message, ...); - -int -main (int argc, char *argv[]) -{ - char **newargz; - int i; - - program_name = (char *) xstrdup (base_name (argv[0])); - DEBUG("(main) argv[0] : %s\n",argv[0]); - DEBUG("(main) program_name : %s\n",program_name); - newargz = XMALLOC(char *, argc+2); -EOF - - cat >> $cwrappersource <> $cwrappersource <<"EOF" - newargz[1] = find_executable(argv[0]); - if (newargz[1] == NULL) - lt_fatal("Couldn't find %s", argv[0]); - DEBUG("(main) found exe at : %s\n",newargz[1]); - /* we know the script has the same name, without the .exe */ - /* so make sure newargz[1] doesn't end in .exe */ - strendzap(newargz[1],".exe"); - for (i = 1; i < argc; i++) - newargz[i+1] = xstrdup(argv[i]); - newargz[argc+1] = NULL; - - for (i=0; i> $cwrappersource <> $cwrappersource <> $cwrappersource <<"EOF" - return 127; -} - -void * -xmalloc (size_t num) -{ - void * p = (void *) malloc (num); - if (!p) - lt_fatal ("Memory exhausted"); - - return p; -} - -char * -xstrdup (const char *string) -{ - return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL -; -} - -const char * -base_name (const char *name) -{ - const char *base; - -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - /* Skip over the disk name in MSDOS pathnames. */ - if (isalpha ((unsigned char)name[0]) && name[1] == ':') - name += 2; -#endif - - for (base = name; *name; name++) - if (IS_DIR_SEPARATOR (*name)) - base = name + 1; - return base; -} - -int -check_executable(const char * path) -{ - struct stat st; - - DEBUG("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!"); - if ((!path) || (!*path)) - return 0; - - if ((stat (path, &st) >= 0) && - ( - /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */ -#if defined (S_IXOTH) - ((st.st_mode & S_IXOTH) == S_IXOTH) || -#endif -#if defined (S_IXGRP) - ((st.st_mode & S_IXGRP) == S_IXGRP) || -#endif - ((st.st_mode & S_IXUSR) == S_IXUSR)) - ) - return 1; - else - return 0; -} - -/* Searches for the full path of the wrapper. Returns - newly allocated full path name if found, NULL otherwise */ -char * -find_executable (const char* wrapper) -{ - int has_slash = 0; - const char* p; - const char* p_next; - /* static buffer for getcwd */ - char tmp[LT_PATHMAX + 1]; - int tmp_len; - char* concat_name; - - DEBUG("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"); - - if ((wrapper == NULL) || (*wrapper == '\0')) - return NULL; - - /* Absolute path? */ -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':') - { - concat_name = xstrdup (wrapper); - if (check_executable(concat_name)) - return concat_name; - XFREE(concat_name); - } - else - { -#endif - if (IS_DIR_SEPARATOR (wrapper[0])) - { - concat_name = xstrdup (wrapper); - if (check_executable(concat_name)) - return concat_name; - XFREE(concat_name); - } -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - } -#endif - - for (p = wrapper; *p; p++) - if (*p == '/') - { - has_slash = 1; - break; - } - if (!has_slash) - { - /* no slashes; search PATH */ - const char* path = getenv ("PATH"); - if (path != NULL) - { - for (p = path; *p; p = p_next) - { - const char* q; - size_t p_len; - for (q = p; *q; q++) - if (IS_PATH_SEPARATOR(*q)) - break; - p_len = q - p; - p_next = (*q == '\0' ? q : q + 1); - if (p_len == 0) - { - /* empty path: current directory */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal ("getcwd failed"); - tmp_len = strlen(tmp); - concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); - memcpy (concat_name, tmp, tmp_len); - concat_name[tmp_len] = '/'; - strcpy (concat_name + tmp_len + 1, wrapper); - } - else - { - concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1); - memcpy (concat_name, p, p_len); - concat_name[p_len] = '/'; - strcpy (concat_name + p_len + 1, wrapper); - } - if (check_executable(concat_name)) - return concat_name; - XFREE(concat_name); - } - } - /* not found in PATH; assume curdir */ - } - /* Relative path | not found in path: prepend cwd */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal ("getcwd failed"); - tmp_len = strlen(tmp); - concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1); - memcpy (concat_name, tmp, tmp_len); - concat_name[tmp_len] = '/'; - strcpy (concat_name + tmp_len + 1, wrapper); - - if (check_executable(concat_name)) - return concat_name; - XFREE(concat_name); - return NULL; -} - -char * -strendzap(char *str, const char *pat) -{ - size_t len, patlen; - - assert(str != NULL); - assert(pat != NULL); - - len = strlen(str); - patlen = strlen(pat); - - if (patlen <= len) - { - str += len - patlen; - if (strcmp(str, pat) == 0) - *str = '\0'; - } - return str; -} - -static void -lt_error_core (int exit_status, const char * mode, - const char * message, va_list ap) -{ - fprintf (stderr, "%s: %s: ", program_name, mode); - vfprintf (stderr, message, ap); - fprintf (stderr, ".\n"); - - if (exit_status >= 0) - exit (exit_status); -} - -void -lt_fatal (const char *message, ...) -{ - va_list ap; - va_start (ap, message); - lt_error_core (EXIT_FAILURE, "FATAL", message, ap); - va_end (ap); -} -EOF - # we should really use a build-platform specific compiler - # here, but OTOH, the wrappers (shell script and this C one) - # are only useful if you want to execute the "real" binary. - # Since the "real" binary is built for $host, then this - # wrapper might as well be built for $host, too. - $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource - ;; - esac - $rm $output - trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 - - $echo > $output "\ -#! $SHELL - -# $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# The $output program cannot be directly executed until all the libtool -# libraries that it depends on are installed. -# -# This wrapper script should never be moved out of the build directory. -# If it is, it will not operate correctly. - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='${SED} -e 1s/^X//' -sed_quote_subst='$sed_quote_subst' - -# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). -if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -relink_command=\"$relink_command\" - -# This environment variable determines our operation mode. -if test \"\$libtool_install_magic\" = \"$magic\"; then - # install mode needs the following variable: - notinst_deplibs='$notinst_deplibs' -else - # When we are sourced in execute mode, \$file and \$echo are already set. - if test \"\$libtool_execute_magic\" != \"$magic\"; then - echo=\"$qecho\" - file=\"\$0\" - # Make sure echo works. - if test \"X\$1\" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift - elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then - # Yippee, \$echo works! - : - else - # Restart under the correct shell, and then maybe \$echo will work. - exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} - fi - fi\ -" - $echo >> $output "\ - - # Find the directory that this script lives in. - thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` - test \"x\$thisdir\" = \"x\$file\" && thisdir=. - - # Follow symbolic links until we get to the real thisdir. - file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` - while test -n \"\$file\"; do - destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` - - # If there was a directory component, then change thisdir. - if test \"x\$destdir\" != \"x\$file\"; then - case \"\$destdir\" in - [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; - *) thisdir=\"\$thisdir/\$destdir\" ;; - esac - fi - - file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` - file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` - done - - # Try to get the absolute directory name. - absdir=\`cd \"\$thisdir\" && pwd\` - test -n \"\$absdir\" && thisdir=\"\$absdir\" -" - - if test "$fast_install" = yes; then - $echo >> $output "\ - program=lt-'$outputname'$exeext - progdir=\"\$thisdir/$objdir\" - - if test ! -f \"\$progdir/\$program\" || \\ - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ - test \"X\$file\" != \"X\$progdir/\$program\"; }; then - - file=\"\$\$-\$program\" - - if test ! -d \"\$progdir\"; then - $mkdir \"\$progdir\" - else - $rm \"\$progdir/\$file\" - fi" - - $echo >> $output "\ - - # relink executable if necessary - if test -n \"\$relink_command\"; then - if relink_command_output=\`eval \$relink_command 2>&1\`; then : - else - $echo \"\$relink_command_output\" >&2 - $rm \"\$progdir/\$file\" - exit $EXIT_FAILURE - fi - fi - - $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || - { $rm \"\$progdir/\$program\"; - $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } - $rm \"\$progdir/\$file\" - fi" - else - $echo >> $output "\ - program='$outputname' - progdir=\"\$thisdir/$objdir\" -" - fi - - $echo >> $output "\ - - if test -f \"\$progdir/\$program\"; then" - - # Export our shlibpath_var if we have one. - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then - $echo >> $output "\ - # Add our own library path to $shlibpath_var - $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" - - # Some systems cannot cope with colon-terminated $shlibpath_var - # The second colon is a workaround for a bug in BeOS R4 sed - $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` - - export $shlibpath_var -" - fi - - # fixup the dll searchpath if we need to. - if test -n "$dllsearchpath"; then - $echo >> $output "\ - # Add the dll search path components to the executable PATH - PATH=$dllsearchpath:\$PATH -" - fi - - $echo >> $output "\ - if test \"\$libtool_execute_magic\" != \"$magic\"; then - # Run the actual program with our arguments. -" - case $host in - # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2*) - $echo >> $output "\ - exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} -" - ;; - - *) - $echo >> $output "\ - exec \"\$progdir/\$program\" \${1+\"\$@\"} -" - ;; - esac - $echo >> $output "\ - \$echo \"\$0: cannot exec \$program \$*\" - exit $EXIT_FAILURE - fi - else - # The program doesn't exist. - \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 - \$echo \"This script is just a wrapper for \$program.\" 1>&2 - $echo \"See the $PACKAGE documentation for more information.\" 1>&2 - exit $EXIT_FAILURE - fi -fi\ -" - chmod +x $output - fi - exit $EXIT_SUCCESS - ;; - esac - - # See if we need to build an old-fashioned archive. - for oldlib in $oldlibs; do - - if test "$build_libtool_libs" = convenience; then - oldobjs="$libobjs_save" - addlibs="$convenience" - build_libtool_libs=no - else - if test "$build_libtool_libs" = module; then - oldobjs="$libobjs_save" - build_libtool_libs=no - else - oldobjs="$old_deplibs $non_pic_objects" - fi - addlibs="$old_convenience" - fi - - if test -n "$addlibs"; then - gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" - - func_extract_archives $gentop $addlibs - oldobjs="$oldobjs $func_extract_archives_result" - fi - - # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then - cmds=$old_archive_from_new_cmds - else - # POSIX demands no paths to be encoded in archives. We have - # to avoid creating archives with duplicate basenames if we - # might have to extract them afterwards, e.g., when creating a - # static archive out of a convenience library, or when linking - # the entirety of a libtool archive into another (currently - # not supported by libtool). - if (for obj in $oldobjs - do - $echo "X$obj" | $Xsed -e 's%^.*/%%' - done | sort | sort -uc >/dev/null 2>&1); then - : - else - $echo "copying selected object files to avoid basename conflicts..." - - if test -z "$gentop"; then - gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" - - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "$mkdir $gentop" - $run $mkdir "$gentop" - exit_status=$? - if test "$exit_status" -ne 0 && test ! -d "$gentop"; then - exit $exit_status - fi - fi - - save_oldobjs=$oldobjs - oldobjs= - counter=1 - for obj in $save_oldobjs - do - objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` - case " $oldobjs " in - " ") oldobjs=$obj ;; - *[\ /]"$objbase "*) - while :; do - # Make sure we don't pick an alternate name that also - # overlaps. - newobj=lt$counter-$objbase - counter=`expr $counter + 1` - case " $oldobjs " in - *[\ /]"$newobj "*) ;; - *) if test ! -f "$gentop/$newobj"; then break; fi ;; - esac - done - $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" - $run ln "$obj" "$gentop/$newobj" || - $run cp "$obj" "$gentop/$newobj" - oldobjs="$oldobjs $gentop/$newobj" - ;; - *) oldobjs="$oldobjs $obj" ;; - esac - done - fi - - eval cmds=\"$old_archive_cmds\" - - if len=`expr "X$cmds" : ".*"` && - test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then - cmds=$old_archive_cmds - else - # the command line is too long to link in one step, link in parts - $echo "using piecewise archive linking..." - save_RANLIB=$RANLIB - RANLIB=: - objlist= - concat_cmds= - save_oldobjs=$oldobjs - - # Is there a better way of finding the last object in the list? - for obj in $save_oldobjs - do - last_oldobj=$obj - done - for obj in $save_oldobjs - do - oldobjs="$objlist $obj" - objlist="$objlist $obj" - eval test_cmds=\"$old_archive_cmds\" - if len=`expr "X$test_cmds" : ".*" 2>/dev/null` && - test "$len" -le "$max_cmd_len"; then - : - else - # the above command should be used before it gets too long - oldobjs=$objlist - if test "$obj" = "$last_oldobj" ; then - RANLIB=$save_RANLIB - fi - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" - objlist= - fi - done - RANLIB=$save_RANLIB - oldobjs=$objlist - if test "X$oldobjs" = "X" ; then - eval cmds=\"\$concat_cmds\" - else - eval cmds=\"\$concat_cmds~\$old_archive_cmds\" - fi - fi - fi - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - eval cmd=\"$cmd\" - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - done - - if test -n "$generated"; then - $show "${rm}r$generated" - $run ${rm}r$generated - fi - - # Now create the libtool archive. - case $output in - *.la) - old_library= - test "$build_old_libs" = yes && old_library="$libname.$libext" - $show "creating $output" - - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` - relink_command="$var=\"$var_value\"; export $var; $relink_command" - fi - done - # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" - relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP` - if test "$hardcode_automatic" = yes ; then - relink_command= - fi - - - # Only create the output if not a dry run. - if test -z "$run"; then - for installed in no yes; do - if test "$installed" = yes; then - if test -z "$install_libdir"; then - break - fi - output="$output_objdir/$outputname"i - # Replace all uninstalled libtool libraries with the installed ones - newdependency_libs= - for deplib in $dependency_libs; do - case $deplib in - *.la) - name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - if test -z "$libdir"; then - $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - newdependency_libs="$newdependency_libs $libdir/$name" - ;; - *) newdependency_libs="$newdependency_libs $deplib" ;; - esac - done - dependency_libs="$newdependency_libs" - newdlfiles= - for lib in $dlfiles; do - name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - if test -z "$libdir"; then - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - newdlfiles="$newdlfiles $libdir/$name" - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - if test -z "$libdir"; then - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - newdlprefiles="$newdlprefiles $libdir/$name" - done - dlprefiles="$newdlprefiles" - else - newdlfiles= - for lib in $dlfiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; - *) abs=`pwd`"/$lib" ;; - esac - newdlfiles="$newdlfiles $abs" - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; - *) abs=`pwd`"/$lib" ;; - esac - newdlprefiles="$newdlprefiles $abs" - done - dlprefiles="$newdlprefiles" - fi - $rm $output - # place dlname in correct position for cygwin - tdlname=$dlname - case $host,$output,$installed,$module,$dlname in - *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; - esac - $echo > $output "\ -# $outputname - a libtool library file -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='$tdlname' - -# Names of this library. -library_names='$library_names' - -# The name of the static archive. -old_library='$old_library' - -# Libraries that this one depends upon. -dependency_libs='$dependency_libs' - -# Version information for $libname. -current=$current -age=$age -revision=$revision - -# Is this an already installed library? -installed=$installed - -# Should we warn about portability when linking against -modules? -shouldnotlink=$module - -# Files to dlopen/dlpreopen -dlopen='$dlfiles' -dlpreopen='$dlprefiles' - -# Directory that this library needs to be installed in: -libdir='$install_libdir'" - if test "$installed" = no && test "$need_relink" = yes; then - $echo >> $output "\ -relink_command=\"$relink_command\"" - fi - done - fi - - # Do a symbolic link so that the libtool archive can be found in - # LD_LIBRARY_PATH before the program is installed. - $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" - $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? - ;; - esac - exit $EXIT_SUCCESS - ;; - - # libtool install mode - install) - modename="$modename: install" - - # There may be an optional sh(1) argument at the beginning of - # install_prog (especially on Windows NT). - if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || - # Allow the use of GNU shtool's install command. - $echo "X$nonopt" | grep shtool > /dev/null; then - # Aesthetically quote it. - arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - install_prog="$arg " - arg="$1" - shift - else - install_prog= - arg=$nonopt - fi - - # The real first argument should be the name of the installation program. - # Aesthetically quote it. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - install_prog="$install_prog$arg" - - # We need to accept at least all the BSD install flags. - dest= - files= - opts= - prev= - install_type= - isdir=no - stripme= - for arg - do - if test -n "$dest"; then - files="$files $dest" - dest=$arg - continue - fi - - case $arg in - -d) isdir=yes ;; - -f) - case " $install_prog " in - *[\\\ /]cp\ *) ;; - *) prev=$arg ;; - esac - ;; - -g | -m | -o) prev=$arg ;; - -s) - stripme=" -s" - continue - ;; - -*) - ;; - *) - # If the previous option needed an argument, then skip it. - if test -n "$prev"; then - prev= - else - dest=$arg - continue - fi - ;; - esac - - # Aesthetically quote the argument. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - install_prog="$install_prog $arg" - done - - if test -z "$install_prog"; then - $echo "$modename: you must specify an install program" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - if test -n "$prev"; then - $echo "$modename: the \`$prev' option requires an argument" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - if test -z "$files"; then - if test -z "$dest"; then - $echo "$modename: no file or destination specified" 1>&2 - else - $echo "$modename: you must specify a destination" 1>&2 - fi - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Strip any trailing slash from the destination. - dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` - - # Check to see that the destination is a directory. - test -d "$dest" && isdir=yes - if test "$isdir" = yes; then - destdir="$dest" - destname= - else - destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` - test "X$destdir" = "X$dest" && destdir=. - destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` - - # Not a directory, so check to see that there is only one file specified. - set dummy $files - if test "$#" -gt 2; then - $echo "$modename: \`$dest' is not a directory" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - fi - case $destdir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - for file in $files; do - case $file in - *.lo) ;; - *) - $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; - esac - done - ;; - esac - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - staticlibs= - future_libdirs= - current_libdirs= - for file in $files; do - - # Do each installation. - case $file in - *.$libext) - # Do the static libraries later. - staticlibs="$staticlibs $file" - ;; - - *.la) - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - library_names= - old_library= - relink_command= - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Add the libdir to current_libdirs if it is the destination. - if test "X$destdir" = "X$libdir"; then - case "$current_libdirs " in - *" $libdir "*) ;; - *) current_libdirs="$current_libdirs $libdir" ;; - esac - else - # Note the libdir as a future libdir. - case "$future_libdirs " in - *" $libdir "*) ;; - *) future_libdirs="$future_libdirs $libdir" ;; - esac - fi - - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ - test "X$dir" = "X$file/" && dir= - dir="$dir$objdir" - - if test -n "$relink_command"; then - # Determine the prefix the user has applied to our future dir. - inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` - - # Don't allow the user to place us outside of our expected - # location b/c this prevents finding dependent libraries that - # are installed to the same prefix. - # At present, this check doesn't affect windows .dll's that - # are installed into $libdir/../bin (currently, that works fine) - # but it's something to keep an eye on. - if test "$inst_prefix_dir" = "$destdir"; then - $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 - exit $EXIT_FAILURE - fi - - if test -n "$inst_prefix_dir"; then - # Stick the inst_prefix_dir data into the link command. - relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%" | $NL2SP` - else - relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%%" | $NL2SP` - fi - - $echo "$modename: warning: relinking \`$file'" 1>&2 - $show "$relink_command" - if $run eval "$relink_command"; then : - else - $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 - exit $EXIT_FAILURE - fi - fi - - # See the names of the shared library. - set dummy $library_names - if test -n "$2"; then - realname="$2" - shift - shift - - srcname="$realname" - test -n "$relink_command" && srcname="$realname"T - - # Install the shared library and build the symlinks. - $show "$install_prog $dir/$srcname $destdir/$realname" - $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? - if test -n "$stripme" && test -n "$striplib"; then - $show "$striplib $destdir/$realname" - $run eval "$striplib $destdir/$realname" || exit $? - fi - - if test "$#" -gt 0; then - # Delete the old symlinks, and create new ones. - # Try `ln -sf' first, because the `ln' binary might depend on - # the symlink we replace! Solaris /bin/ln does not understand -f, - # so we also need to try rm && ln -s. - for linkname - do - if test "$linkname" != "$realname"; then - $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" - $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" - fi - done - fi - - # Do each command in the postinstall commands. - lib="$destdir/$realname" - cmds=$postinstall_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' - fi - - exit $lt_exit - } - done - IFS="$save_ifs" - fi - - # Install the pseudo-library for information purposes. - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - instname="$dir/$name"i - $show "$install_prog $instname $destdir/$name" - $run eval "$install_prog $instname $destdir/$name" || exit $? - - # Maybe install the static library, too. - test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" - ;; - - *.lo) - # Install (i.e. copy) a libtool object. - - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - destfile="$destdir/$destfile" - fi - - # Deduce the name of the destination old-style object file. - case $destfile in - *.lo) - staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` - ;; - *.$objext) - staticdest="$destfile" - destfile= - ;; - *) - $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - # Install the libtool object if requested. - if test -n "$destfile"; then - $show "$install_prog $file $destfile" - $run eval "$install_prog $file $destfile" || exit $? - fi - - # Install the old object if enabled. - if test "$build_old_libs" = yes; then - # Deduce the name of the old-style object file. - staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` - - $show "$install_prog $staticobj $staticdest" - $run eval "$install_prog \$staticobj \$staticdest" || exit $? - fi - exit $EXIT_SUCCESS - ;; - - *) - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - destfile="$destdir/$destfile" - fi - - # If the file is missing, and there is a .exe on the end, strip it - # because it is most likely a libtool script we actually want to - # install - stripped_ext="" - case $file in - *.exe) - if test ! -f "$file"; then - file=`$echo $file|${SED} 's,.exe$,,'` - stripped_ext=".exe" - fi - ;; - esac - - # Do a test to see if this is really a libtool program. - case $host in - *cygwin*|*mingw*) - wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` - ;; - *) - wrapper=$file - ;; - esac - if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then - notinst_deplibs= - relink_command= - - # Note that it is not necessary on cygwin/mingw to append a dot to - # foo even if both foo and FILE.exe exist: automatic-append-.exe - # behavior happens only for exec(3), not for open(2)! Also, sourcing - # `FILE.' does not work on cygwin managed mounts. - # - # If there is no directory component, then add one. - case $wrapper in - */* | *\\*) . ${wrapper} ;; - *) . ./${wrapper} ;; - esac - - # Check the variables that should have been set. - if test -z "$notinst_deplibs"; then - $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 - exit $EXIT_FAILURE - fi - - finalize=yes - for lib in $notinst_deplibs; do - # Check to see that each library is installed. - libdir= - if test -f "$lib"; then - # If there is no directory component, then add one. - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - fi - libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test - if test -n "$libdir" && test ! -f "$libfile"; then - $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 - finalize=no - fi - done - - relink_command= - # Note that it is not necessary on cygwin/mingw to append a dot to - # foo even if both foo and FILE.exe exist: automatic-append-.exe - # behavior happens only for exec(3), not for open(2)! Also, sourcing - # `FILE.' does not work on cygwin managed mounts. - # - # If there is no directory component, then add one. - case $wrapper in - */* | *\\*) . ${wrapper} ;; - *) . ./${wrapper} ;; - esac - - outputname= - if test "$fast_install" = no && test -n "$relink_command"; then - if test "$finalize" = yes && test -z "$run"; then - tmpdir=`func_mktempdir` - file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` - outputname="$tmpdir/$file" - # Replace the output file specification. - relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g' | $NL2SP` - - $show "$relink_command" - if $run eval "$relink_command"; then : - else - $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 - ${rm}r "$tmpdir" - continue - fi - file="$outputname" - else - $echo "$modename: warning: cannot relink \`$file'" 1>&2 - fi - else - # Install the binary that we compiled earlier. - file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` - fi - fi - - # remove .exe since cygwin /usr/bin/install will append another - # one anyway - case $install_prog,$host in - */usr/bin/install*,*cygwin*) - case $file:$destfile in - *.exe:*.exe) - # this is ok - ;; - *.exe:*) - destfile=$destfile.exe - ;; - *:*.exe) - destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` - ;; - esac - ;; - esac - $show "$install_prog$stripme $file $destfile" - $run eval "$install_prog\$stripme \$file \$destfile" || exit $? - test -n "$outputname" && ${rm}r "$tmpdir" - ;; - esac - done - - for file in $staticlibs; do - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - - # Set up the ranlib parameters. - oldlib="$destdir/$name" - - $show "$install_prog $file $oldlib" - $run eval "$install_prog \$file \$oldlib" || exit $? - - if test -n "$stripme" && test -n "$old_striplib"; then - $show "$old_striplib $oldlib" - $run eval "$old_striplib $oldlib" || exit $? - fi - - # Do each command in the postinstall commands. - cmds=$old_postinstall_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - done - - if test -n "$future_libdirs"; then - $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 - fi - - if test -n "$current_libdirs"; then - # Maybe just do a dry run. - test -n "$run" && current_libdirs=" -n$current_libdirs" - exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' - else - exit $EXIT_SUCCESS - fi - ;; - - # libtool finish mode - finish) - modename="$modename: finish" - libdirs="$nonopt" - admincmds= - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - for dir - do - libdirs="$libdirs $dir" - done - - for libdir in $libdirs; do - if test -n "$finish_cmds"; then - # Do each command in the finish commands. - cmds=$finish_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || admincmds="$admincmds - $cmd" - done - IFS="$save_ifs" - fi - if test -n "$finish_eval"; then - # Do the single finish_eval. - eval cmds=\"$finish_eval\" - $run eval "$cmds" || admincmds="$admincmds - $cmds" - fi - done - fi - - # Exit here if they wanted silent mode. - test "$show" = : && exit $EXIT_SUCCESS - - $echo "X----------------------------------------------------------------------" | $Xsed - $echo "Libraries have been installed in:" - for libdir in $libdirs; do - $echo " $libdir" - done - $echo - $echo "If you ever happen to want to link against installed libraries" - $echo "in a given directory, LIBDIR, you must either use libtool, and" - $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" - $echo "flag during linking and do at least one of the following:" - if test -n "$shlibpath_var"; then - $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" - $echo " during execution" - fi - if test -n "$runpath_var"; then - $echo " - add LIBDIR to the \`$runpath_var' environment variable" - $echo " during linking" - fi - if test -n "$hardcode_libdir_flag_spec"; then - libdir=LIBDIR - eval flag=\"$hardcode_libdir_flag_spec\" - - $echo " - use the \`$flag' linker flag" - fi - if test -n "$admincmds"; then - $echo " - have your system administrator run these commands:$admincmds" - fi - if test -f /etc/ld.so.conf; then - $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" - fi - $echo - $echo "See any operating system documentation about shared libraries for" - $echo "more information, such as the ld(1) and ld.so(8) manual pages." - $echo "X----------------------------------------------------------------------" | $Xsed - exit $EXIT_SUCCESS - ;; - - # libtool execute mode - execute) - modename="$modename: execute" - - # The first argument is the command name. - cmd="$nonopt" - if test -z "$cmd"; then - $echo "$modename: you must specify a COMMAND" 1>&2 - $echo "$help" - exit $EXIT_FAILURE - fi - - # Handle -dlopen flags immediately. - for file in $execute_dlfiles; do - if test ! -f "$file"; then - $echo "$modename: \`$file' is not a file" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - dir= - case $file in - *.la) - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Read the libtool library. - dlname= - library_names= - - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Skip this library if it cannot be dlopened. - if test -z "$dlname"; then - # Warn if it was a shared library. - test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" - continue - fi - - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. - - if test -f "$dir/$objdir/$dlname"; then - dir="$dir/$objdir" - else - if test ! -f "$dir/$dlname"; then - $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 - exit $EXIT_FAILURE - fi - fi - ;; - - *.lo) - # Just add the directory containing the .lo file. - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. - ;; - - *) - $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 - continue - ;; - esac - - # Get the absolute pathname. - absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir="$absdir" - - # Now add the directory to shlibpath_var. - if eval "test -z \"\$$shlibpath_var\""; then - eval "$shlibpath_var=\"\$dir\"" - else - eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" - fi - done - - # This variable tells wrapper scripts just to set shlibpath_var - # rather than running their programs. - libtool_execute_magic="$magic" - - # Check if any of the arguments is a wrapper script. - args= - for file - do - case $file in - -*) ;; - *) - # Do a test to see if this is really a libtool program. - if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Transform arg to wrapped name. - file="$progdir/$program" - fi - ;; - esac - # Quote arguments (to preserve shell metacharacters). - file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` - args="$args \"$file\"" - done - - if test -z "$run"; then - if test -n "$shlibpath_var"; then - # Export the shlibpath_var. - eval "export $shlibpath_var" - fi - - # Restore saved environment variables - for lt_var in LANG LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES - do - eval "if test \"\${save_$lt_var+set}\" = set; then - $lt_var=\$save_$lt_var; export $lt_var - fi" - done - - # Now prepare to actually exec the command. - exec_cmd="\$cmd$args" - else - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" - $echo "export $shlibpath_var" - fi - $echo "$cmd$args" - exit $EXIT_SUCCESS - fi - ;; - - # libtool clean and uninstall mode - clean | uninstall) - modename="$modename: $mode" - rm="$nonopt" - files= - rmforce= - exit_status=0 - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - for arg - do - case $arg in - -f) rm="$rm $arg"; rmforce=yes ;; - -*) rm="$rm $arg" ;; - *) files="$files $arg" ;; - esac - done - - if test -z "$rm"; then - $echo "$modename: you must specify an RM program" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - rmdirs= - - origobjdir="$objdir" - for file in $files; do - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - if test "X$dir" = "X$file"; then - dir=. - objdir="$origobjdir" - else - objdir="$dir/$origobjdir" - fi - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - test "$mode" = uninstall && objdir="$dir" - - # Remember objdir for removal later, being careful to avoid duplicates - if test "$mode" = clean; then - case " $rmdirs " in - *" $objdir "*) ;; - *) rmdirs="$rmdirs $objdir" ;; - esac - fi - - # Don't error if the file doesn't exist and rm -f was used. - if (test -L "$file") >/dev/null 2>&1 \ - || (test -h "$file") >/dev/null 2>&1 \ - || test -f "$file"; then - : - elif test -d "$file"; then - exit_status=1 - continue - elif test "$rmforce" = yes; then - continue - fi - - rmfiles="$file" - - case $name in - *.la) - # Possibly a libtool archive, so verify it. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - . $dir/$name - - # Delete the libtool libraries and symlinks. - for n in $library_names; do - rmfiles="$rmfiles $objdir/$n" - done - test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" - - case "$mode" in - clean) - case " $library_names " in - # " " in the beginning catches empty $dlname - *" $dlname "*) ;; - *) rmfiles="$rmfiles $objdir/$dlname" ;; - esac - test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" - ;; - uninstall) - if test -n "$library_names"; then - # Do each command in the postuninstall commands. - cmds=$postuninstall_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" - if test "$?" -ne 0 && test "$rmforce" != yes; then - exit_status=1 - fi - done - IFS="$save_ifs" - fi - - if test -n "$old_library"; then - # Do each command in the old_postuninstall commands. - cmds=$old_postuninstall_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" - if test "$?" -ne 0 && test "$rmforce" != yes; then - exit_status=1 - fi - done - IFS="$save_ifs" - fi - # FIXME: should reinstall the best remaining shared library. - ;; - esac - fi - ;; - - *.lo) - # Possibly a libtool object, so verify it. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - - # Read the .lo file - . $dir/$name - - # Add PIC object to the list of files to remove. - if test -n "$pic_object" \ - && test "$pic_object" != none; then - rmfiles="$rmfiles $dir/$pic_object" - fi - - # Add non-PIC object to the list of files to remove. - if test -n "$non_pic_object" \ - && test "$non_pic_object" != none; then - rmfiles="$rmfiles $dir/$non_pic_object" - fi - fi - ;; - - *) - if test "$mode" = clean ; then - noexename=$name - case $file in - *.exe) - file=`$echo $file|${SED} 's,.exe$,,'` - noexename=`$echo $name|${SED} 's,.exe$,,'` - # $file with .exe has already been added to rmfiles, - # add $file without .exe - rmfiles="$rmfiles $file" - ;; - esac - # Do a test to see if this is a libtool program. - if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - relink_command= - . $dir/$noexename - - # note $name still contains .exe if it was in $file originally - # as does the version of $file that was added into $rmfiles - rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" - if test "$fast_install" = yes && test -n "$relink_command"; then - rmfiles="$rmfiles $objdir/lt-$name" - fi - if test "X$noexename" != "X$name" ; then - rmfiles="$rmfiles $objdir/lt-${noexename}.c" - fi - fi - fi - ;; - esac - $show "$rm $rmfiles" - $run $rm $rmfiles || exit_status=1 - done - objdir="$origobjdir" - - # Try to remove the ${objdir}s in the directories where we deleted files - for dir in $rmdirs; do - if test -d "$dir"; then - $show "rmdir $dir" - $run rmdir $dir >/dev/null 2>&1 - fi - done - - exit $exit_status - ;; - - "") - $echo "$modename: you must specify a MODE" 1>&2 - $echo "$generic_help" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - if test -z "$exec_cmd"; then - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$generic_help" 1>&2 - exit $EXIT_FAILURE - fi -fi # test -z "$show_help" - -if test -n "$exec_cmd"; then - eval exec $exec_cmd - exit $EXIT_FAILURE -fi - -# We need to display help for each of the modes. -case $mode in -"") $echo \ -"Usage: $modename [OPTION]... [MODE-ARG]... - -Provide generalized library-building support services. - - --config show all configuration variables - --debug enable verbose shell tracing --n, --dry-run display commands without modifying any files - --features display basic configuration information and exit - --finish same as \`--mode=finish' - --help display this help message and exit - --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] - --quiet same as \`--silent' - --silent don't print informational messages - --tag=TAG use configuration variables from tag TAG - --version print version information - -MODE must be one of the following: - - clean remove files from the build directory - compile compile a source file into a libtool object - execute automatically set library path, then run a program - finish complete the installation of libtool libraries - install install libraries or executables - link create a library or an executable - uninstall remove libraries from an installed directory - -MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for -a more detailed description of MODE. - -Report bugs to ." - exit $EXIT_SUCCESS - ;; - -clean) - $echo \ -"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... - -Remove files from the build directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, object or program, all the files associated -with it are deleted. Otherwise, only FILE itself is deleted using RM." - ;; - -compile) - $echo \ -"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE - -Compile a source file into a libtool library object. - -This mode accepts the following additional options: - - -o OUTPUT-FILE set the output file name to OUTPUT-FILE - -prefer-pic try to building PIC objects only - -prefer-non-pic try to building non-PIC objects only - -static always build a \`.o' file suitable for static linking - -COMPILE-COMMAND is a command to be used in creating a \`standard' object file -from the given SOURCEFILE. - -The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix \`.c' with the -library object suffix, \`.lo'." - ;; - -execute) - $echo \ -"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... - -Automatically set library path, then run a program. - -This mode accepts the following additional options: - - -dlopen FILE add the directory containing FILE to the library path - -This mode sets the library path environment variable according to \`-dlopen' -flags. - -If any of the ARGS are libtool executable wrappers, then they are translated -into their corresponding uninstalled binary, and any of their required library -directories are added to the library path. - -Then, COMMAND is executed, with ARGS as arguments." - ;; - -finish) - $echo \ -"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... - -Complete the installation of libtool libraries. - -Each LIBDIR is a directory that contains libtool libraries. - -The commands that this mode executes may require superuser privileges. Use -the \`--dry-run' option if you just want to see what would be executed." - ;; - -install) - $echo \ -"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... - -Install executables or libraries. - -INSTALL-COMMAND is the installation command. The first component should be -either the \`install' or \`cp' program. - -The rest of the components are interpreted as arguments to that command (only -BSD-compatible install options are recognized)." - ;; - -link) - $echo \ -"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... - -Link object files or libraries together to form another library, or to -create an executable program. - -LINK-COMMAND is a command using the C compiler that you would use to create -a program from several object files. - -The following components of LINK-COMMAND are treated specially: - - -all-static do not do any dynamic linking at all - -avoid-version do not add a version suffix if possible - -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime - -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols - -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) - -export-symbols SYMFILE - try to export only the symbols listed in SYMFILE - -export-symbols-regex REGEX - try to export only the symbols matching REGEX - -LLIBDIR search LIBDIR for required installed libraries - -lNAME OUTPUT-FILE requires the installed library libNAME - -module build a library that can dlopened - -no-fast-install disable the fast-install mode - -no-install link a not-installable executable - -no-undefined declare that a library does not refer to external symbols - -o OUTPUT-FILE create OUTPUT-FILE from the specified objects - -objectlist FILE Use a list of object files found in FILE to specify objects - -precious-files-regex REGEX - don't remove output files matching REGEX - -release RELEASE specify package release information - -rpath LIBDIR the created library will eventually be installed in LIBDIR - -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries - -static do not do any dynamic linking of uninstalled libtool libraries - -static-libtool-libs - do not do any dynamic linking of libtool libraries - -version-info CURRENT[:REVISION[:AGE]] - specify library version info [each variable defaults to 0] - -All other options (arguments beginning with \`-') are ignored. - -Every other argument is treated as a filename. Files ending in \`.la' are -treated as uninstalled libtool libraries, other files are standard or library -object files. - -If the OUTPUT-FILE ends in \`.la', then a libtool library is created, -only library objects (\`.lo' files) may be specified, and \`-rpath' is -required, except when creating a convenience library. - -If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created -using \`ar' and \`ranlib', or on Windows using \`lib'. - -If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file -is created, otherwise an executable program is created." - ;; - -uninstall) - $echo \ -"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... - -Remove libraries from an installation directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, all the files associated with it are deleted. -Otherwise, only FILE itself is deleted using RM." - ;; - -*) - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; -esac - -$echo -$echo "Try \`$modename --help' for more information about other modes." - -exit $? - -# The TAGs below are defined such that we never get into a situation -# in which we disable both kinds of libraries. Given conflicting -# choices, we go for a static library, that is the most portable, -# since we can't tell whether shared libraries were disabled because -# the user asked for that or because the platform doesn't support -# them. This is particularly important on AIX, because we don't -# support having both static and shared libraries enabled at the same -# time on that platform, so we default to a shared-only configuration. -# If a disable-shared tag is given, we'll fallback to a static-only -# configuration. But we'll never go from static-only to shared-only. - -# ### BEGIN LIBTOOL TAG CONFIG: disable-shared -disable_libs=shared -# ### END LIBTOOL TAG CONFIG: disable-shared - -# ### BEGIN LIBTOOL TAG CONFIG: disable-static -disable_libs=static -# ### END LIBTOOL TAG CONFIG: disable-static - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: -# ### BEGIN LIBTOOL TAG CONFIG: CXX - -# Libtool was configured on host lambda: - -# Shell to use when invoking shell scripts. -SHELL="/bin/sh" - -# Whether or not to build shared libraries. -build_libtool_libs=yes - -# Whether or not to build static libraries. -build_old_libs=yes - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=no - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=no - -# Whether or not to optimize for fast installation. -fast_install=yes - -# The host system. -host_alias= -host=i686-pc-linux-gnu -host_os=linux-gnu - -# The build system. -build_alias= -build=i686-pc-linux-gnu -build_os=linux-gnu - -# An echo program that does not interpret backslashes. -echo="echo" - -# The archiver. -AR="ar" -AR_FLAGS="cru" - -# A C compiler. -LTCC="gcc" - -# LTCC compiler flags. -LTCFLAGS="-g -O2" - -# A language-specific compiler. -CC="g++" - -# Is the compiler the GNU C compiler? -with_gcc=yes - -# An ERE matcher. -EGREP="/bin/grep -E" - -# The linker used to build libraries. -LD="/usr/bin/ld" - -# Whether we need hard or soft links. -LN_S="ln -s" - -# A BSD-compatible nm program. -NM="/usr/bin/nm -B" - -# A symbol stripping program -STRIP="strip" - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=file - -# Used on cygwin: DLL creation program. -DLLTOOL="dlltool" - -# Used on cygwin: object dumper. -OBJDUMP="objdump" - -# Used on cygwin: assembler. -AS="as" - -# The name of the directory that contains temporary libtool files. -objdir=.libs - -# How to create reloadable object files. -reload_flag=" -r" -reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" - -# How to pass a linker flag through the compiler. -wl="-Wl," - -# Object file suffix (normally "o"). -objext="o" - -# Old archive suffix (normally "a"). -libext="a" - -# Shared library suffix (normally ".so"). -shrext_cmds='.so' - -# Executable file suffix (normally ""). -exeext="" - -# Additional compiler flags for building library objects. -pic_flag=" -fPIC -DPIC" -pic_mode=default - -# What is the maximum length of a command? -max_cmd_len=98304 - -# Does compiler simultaneously support -c and -o options? -compiler_c_o="yes" - -# Must we lock files when doing compilation? -need_locks="no" - -# Do we need the lib prefix for modules? -need_lib_prefix=no - -# Do we need a version for libraries? -need_version=no - -# Whether dlopen is supported. -dlopen_support=unknown - -# Whether dlopen of programs is supported. -dlopen_self=unknown - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=unknown - -# Compiler flag to prevent dynamic linking. -link_static_flag="-static" - -# Compiler flag to turn off builtin functions. -no_builtin_flag=" -fno-builtin" - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec="\${wl}--export-dynamic" - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec="" - -# Library versioning type. -version_type=linux - -# Format of library name prefix. -libname_spec="lib\$name" - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" - -# The coded name of the library, if different from the real name. -soname_spec="\${libname}\${release}\${shared_ext}\$major" - -# Commands used to build and install an old-style archive. -RANLIB="ranlib" -old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs~\$RANLIB \$oldlib" -old_postinstall_cmds="chmod 644 \$oldlib~\$RANLIB \$oldlib" -old_postuninstall_cmds="" - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds="" - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds="" - -# Commands used to build and install a shared archive. -archive_cmds="\$CC -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" -archive_expsym_cmds="\$CC -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-retain-symbols-file \$wl\$export_symbols -o \$lib" -postinstall_cmds="" -postuninstall_cmds="" - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds="" -module_expsym_cmds="" - -# Commands to strip libraries. -old_striplib="strip --strip-debug" -striplib="strip --strip-unneeded" - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects="/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crti.o /usr/lib/gcc/i386-redhat-linux/4.1.2/crtbeginS.o" - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects="/usr/lib/gcc/i386-redhat-linux/4.1.2/crtendS.o /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crtn.o" - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps="" - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps="-lstdc++ -lm -lgcc_s -lc -lgcc_s" - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path="-L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2/../../.." - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method="pass_all" - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd="\$MAGIC_CMD" - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag="" - -# Flag that forces no undefined symbols. -no_undefined_flag="" - -# Commands used to finish a libtool library installation in a directory. -finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval="" - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2 \\2/p'" - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'" - -# This is the shared library runtime path variable. -runpath_var=LD_RUN_PATH - -# This is the shared library path variable. -shlibpath_var=LD_LIBRARY_PATH - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=no - -# How to hardcode a shared library path into an executable. -hardcode_action=immediate - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=yes - -# Flag to hardcode $libdir into a binary during linking. -# This must work even if $libdir does not exist. -hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" - -# If ld is used when linking, flag to hardcode $libdir into -# a binary during linking. This must work even if $libdir does -# not exist. -hardcode_libdir_flag_spec_ld="" - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator="" - -# Set to yes if using DIR/libNAME during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=no - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=no - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=unsupported - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=no - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=unknown - -# Compile-time system search path for libraries -sys_lib_search_path_spec="/usr/lib /lib /usr/local/lib" - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec="/usr/lib /lib /usr/lib/qt-3.3/lib " - -# Fix the shell variable $srcfile for the compiler. -fix_srcfile_path="" - -# Set to yes if exported symbols are required. -always_export_symbols=no - -# The commands to list exported symbols. -export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds="" - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms="" - -# Symbols that must always be exported. -include_expsyms="" - -# ### END LIBTOOL TAG CONFIG: CXX - -# ### BEGIN LIBTOOL TAG CONFIG: F77 - -# Libtool was configured on host lambda: - -# Shell to use when invoking shell scripts. -SHELL="/bin/sh" - -# Whether or not to build shared libraries. -build_libtool_libs=yes - -# Whether or not to build static libraries. -build_old_libs=yes - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=no - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=no - -# Whether or not to optimize for fast installation. -fast_install=yes - -# The host system. -host_alias= -host=i686-pc-linux-gnu -host_os=linux-gnu - -# The build system. -build_alias= -build=i686-pc-linux-gnu -build_os=linux-gnu - -# An echo program that does not interpret backslashes. -echo="echo" - -# The archiver. -AR="ar" -AR_FLAGS="cru" - -# A C compiler. -LTCC="gcc" - -# LTCC compiler flags. -LTCFLAGS="-g -O2" - -# A language-specific compiler. -CC="gfortran" - -# Is the compiler the GNU C compiler? -with_gcc=yes - -# An ERE matcher. -EGREP="/bin/grep -E" - -# The linker used to build libraries. -LD="/usr/bin/ld" - -# Whether we need hard or soft links. -LN_S="ln -s" - -# A BSD-compatible nm program. -NM="/usr/bin/nm -B" - -# A symbol stripping program -STRIP="strip" - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=file - -# Used on cygwin: DLL creation program. -DLLTOOL="dlltool" - -# Used on cygwin: object dumper. -OBJDUMP="objdump" - -# Used on cygwin: assembler. -AS="as" - -# The name of the directory that contains temporary libtool files. -objdir=.libs - -# How to create reloadable object files. -reload_flag=" -r" -reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" - -# How to pass a linker flag through the compiler. -wl="-Wl," - -# Object file suffix (normally "o"). -objext="o" - -# Old archive suffix (normally "a"). -libext="a" - -# Shared library suffix (normally ".so"). -shrext_cmds='.so' - -# Executable file suffix (normally ""). -exeext="" - -# Additional compiler flags for building library objects. -pic_flag=" -fPIC" -pic_mode=default - -# What is the maximum length of a command? -max_cmd_len=98304 - -# Does compiler simultaneously support -c and -o options? -compiler_c_o="yes" - -# Must we lock files when doing compilation? -need_locks="no" - -# Do we need the lib prefix for modules? -need_lib_prefix=no - -# Do we need a version for libraries? -need_version=no - -# Whether dlopen is supported. -dlopen_support=unknown - -# Whether dlopen of programs is supported. -dlopen_self=unknown - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=unknown - -# Compiler flag to prevent dynamic linking. -link_static_flag="-static" - -# Compiler flag to turn off builtin functions. -no_builtin_flag="" - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec="\${wl}--export-dynamic" - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec="" - -# Library versioning type. -version_type=linux - -# Format of library name prefix. -libname_spec="lib\$name" - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec="\${libname}\${release}\${shared_ext}\$versuffix \${libname}\${release}\${shared_ext}\$major \$libname\${shared_ext}" - -# The coded name of the library, if different from the real name. -soname_spec="\${libname}\${release}\${shared_ext}\$major" - -# Commands used to build and install an old-style archive. -RANLIB="ranlib" -old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs~\$RANLIB \$oldlib" -old_postinstall_cmds="chmod 644 \$oldlib~\$RANLIB \$oldlib" -old_postuninstall_cmds="" - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds="" - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds="" - -# Commands used to build and install a shared archive. -archive_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname -o \$lib" -archive_expsym_cmds="\$echo \\\"{ global:\\\" > \$output_objdir/\$libname.ver~ - cat \$export_symbols | sed -e \\\"s/\\\\(.*\\\\)/\\\\1;/\\\" >> \$output_objdir/\$libname.ver~ - \$echo \\\"local: *; };\\\" >> \$output_objdir/\$libname.ver~ - \$CC -shared \$libobjs \$deplibs \$compiler_flags \${wl}-soname \$wl\$soname \${wl}-version-script \${wl}\$output_objdir/\$libname.ver -o \$lib" -postinstall_cmds="" -postuninstall_cmds="" - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds="" -module_expsym_cmds="" - -# Commands to strip libraries. -old_striplib="strip --strip-debug" -striplib="strip --strip-unneeded" - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects="" - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects="" - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps="" - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps="" - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path="" - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method="pass_all" - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd="\$MAGIC_CMD" - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag="" - -# Flag that forces no undefined symbols. -no_undefined_flag="" - -# Commands used to finish a libtool library installation in a directory. -finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval="" - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[ ][ ]*\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2 \\2/p'" - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'" - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/ {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/ {\"\\2\", (lt_ptr) \\&\\2},/p'" - -# This is the shared library runtime path variable. -runpath_var=LD_RUN_PATH - -# This is the shared library path variable. -shlibpath_var=LD_LIBRARY_PATH - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=no - -# How to hardcode a shared library path into an executable. -hardcode_action=immediate - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=yes - -# Flag to hardcode $libdir into a binary during linking. -# This must work even if $libdir does not exist. -hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" - -# If ld is used when linking, flag to hardcode $libdir into -# a binary during linking. This must work even if $libdir does -# not exist. -hardcode_libdir_flag_spec_ld="" - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator="" - -# Set to yes if using DIR/libNAME during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=no - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=no - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=unsupported - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=no - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="PATH LD_LIBRARY_PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=unknown - -# Compile-time system search path for libraries -sys_lib_search_path_spec="/usr/lib /lib /usr/local/lib" - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec="/usr/lib /lib /usr/lib/qt-3.3/lib " - -# Fix the shell variable $srcfile for the compiler. -fix_srcfile_path="" - -# Set to yes if exported symbols are required. -always_export_symbols=no - -# The commands to list exported symbols. -export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED 's/.* //' | sort | uniq > \$export_symbols" - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds="" - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms="_GLOBAL_OFFSET_TABLE_" - -# Symbols that must always be exported. -include_expsyms="" - -# ### END LIBTOOL TAG CONFIG: F77 - diff --git a/src/Makefile.am b/src/Makefile.am index a10fe732..aa5160a4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -667,6 +667,7 @@ libpulsecore_la_SOURCES += \ pulsecore/fdsem.c pulsecore/fdsem.h \ pulsecore/object.c pulsecore/object.h \ pulsecore/msgobject.c pulsecore/msgobject.h \ + pulsecore/macro.h \ $(PA_THREAD_OBJS) if OS_IS_WIN32 -- cgit From 3cbcb982e2d3d789bb28f0e92cc5ce4750b06147 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 12 Aug 2007 21:14:25 +0000 Subject: build fix for newer glibc git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1654 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/utils/padsp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/padsp.c b/src/utils/padsp.c index 041115ec..078b2e52 100644 --- a/src/utils/padsp.c +++ b/src/utils/padsp.c @@ -1436,6 +1436,7 @@ fail: return -1; } +#undef open int open(const char *filename, int flags, ...) { va_list args; mode_t mode = 0; -- cgit From 5e96d5da78c0ec989ac589a85f8184090b5a3c8c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 12 Aug 2007 21:20:08 +0000 Subject: yet another new glibc build fix git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1655 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/utils/padsp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utils/padsp.c b/src/utils/padsp.c index 078b2e52..556ac2b7 100644 --- a/src/utils/padsp.c +++ b/src/utils/padsp.c @@ -2491,6 +2491,7 @@ int stat64(const char *pathname, struct stat64 *buf) { return 0; } +#undef open64 int open64(const char *filename, int flags, ...) { va_list args; mode_t mode = 0; -- cgit From e381dd9e4d6e4f518af49e244ad03ed093200938 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 12 Aug 2007 23:24:05 +0000 Subject: 64 bit fixes and minor gcc shut ups git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1656 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/asyncmsgq.c | 2 +- src/pulsecore/asyncmsgq.h | 2 +- src/pulsecore/asyncq.h | 2 +- src/pulsecore/authkey.c | 2 +- src/pulsecore/core-scache.c | 5 ++--- src/pulsecore/core-util.c | 2 +- src/pulsecore/memblock.c | 2 +- src/pulsecore/sink.c | 4 ++-- 8 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/pulsecore/asyncmsgq.c b/src/pulsecore/asyncmsgq.c index 1bef8bda..cc57d3a6 100644 --- a/src/pulsecore/asyncmsgq.c +++ b/src/pulsecore/asyncmsgq.c @@ -191,7 +191,7 @@ int pa_asyncmsgq_get(pa_asyncmsgq *a, pa_msgobject **object, int *code, void **u if (chunk) *chunk = a->current->memchunk; - pa_log_debug("Get q=%p object=%p (%s) code=%i data=%p chunk.length=%u", (void*) a, (void*) a->current->object, a->current->object ? a->current->object->parent.type_name : NULL, a->current->code, (void*) a->current->userdata, a->current->memchunk.length); + pa_log_debug("Get q=%p object=%p (%s) code=%i data=%p chunk.length=%lu", (void*) a, (void*) a->current->object, a->current->object ? a->current->object->parent.type_name : NULL, a->current->code, (void*) a->current->userdata, (unsigned long) a->current->memchunk.length); return 0; } diff --git a/src/pulsecore/asyncmsgq.h b/src/pulsecore/asyncmsgq.h index 2f188376..55812c6f 100644 --- a/src/pulsecore/asyncmsgq.h +++ b/src/pulsecore/asyncmsgq.h @@ -54,7 +54,7 @@ enum { typedef struct pa_asyncmsgq pa_asyncmsgq; -pa_asyncmsgq* pa_asyncmsgq_new(size_t size); +pa_asyncmsgq* pa_asyncmsgq_new(unsigned size); pa_asyncmsgq* pa_asyncmsgq_ref(pa_asyncmsgq *q); void pa_asyncmsgq_unref(pa_asyncmsgq* q); diff --git a/src/pulsecore/asyncq.h b/src/pulsecore/asyncq.h index 729ec466..53d45866 100644 --- a/src/pulsecore/asyncq.h +++ b/src/pulsecore/asyncq.h @@ -43,7 +43,7 @@ typedef struct pa_asyncq pa_asyncq; -pa_asyncq* pa_asyncq_new(size_t size); +pa_asyncq* pa_asyncq_new(unsigned size); void pa_asyncq_free(pa_asyncq* q, pa_free_cb_t free_cb); void* pa_asyncq_pop(pa_asyncq *q, int wait); diff --git a/src/pulsecore/authkey.c b/src/pulsecore/authkey.c index 1476482d..d8056247 100644 --- a/src/pulsecore/authkey.c +++ b/src/pulsecore/authkey.c @@ -57,7 +57,7 @@ static int generate(int fd, void *ret_data, size_t length) { pa_random(ret_data, length); lseek(fd, 0, SEEK_SET); - ftruncate(fd, 0); + (void) ftruncate(fd, 0); if ((r = pa_loop_write(fd, ret_data, length, NULL)) < 0 || (size_t) r != length) { pa_log("Failed to write cookie file: %s", pa_cstrerror(errno)); diff --git a/src/pulsecore/core-scache.c b/src/pulsecore/core-scache.c index 8a7ba13d..6176dcbd 100644 --- a/src/pulsecore/core-scache.c +++ b/src/pulsecore/core-scache.c @@ -164,8 +164,8 @@ int pa_scache_add_item(pa_core *c, const char *name, const pa_sample_spec *ss, c if (idx) *idx = e->index; - pa_log_debug("created sample \"%s\" (#%d), %d bytes with sample spec %s", - name, e->index, e->memchunk.length, + pa_log_debug("created sample \"%s\" (#%d), %lu bytes with sample spec %s", + name, e->index, (unsigned long) e->memchunk.length, pa_sample_spec_snprint(st, sizeof(st), &e->sample_spec)); return 0; @@ -316,7 +316,6 @@ int pa_scache_play_item_by_name(pa_core *c, const char *name, const char*sink_na return pa_scache_play_item(c, name, sink, volume); } - const char * pa_scache_get_name_by_id(pa_core *c, uint32_t id) { pa_scache_entry *e; assert(c && id != PA_IDXSET_INVALID); diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index e61be704..165fcf3d 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -169,7 +169,7 @@ int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) { uid = getuid(); if (gid == (gid_t)-1) gid = getgid(); - chown(dir, uid, gid); + (void) chown(dir, uid, gid); #endif #ifdef HAVE_CHMOD diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index f0e2b4c9..da996093 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -311,7 +311,7 @@ pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) { pa_atomic_ptr_store(&b->data, mempool_slot_data(slot)); } else { - pa_log_debug("Memory block too large for pool: %u > %u", length, p->block_size - sizeof(struct mempool_slot)); + pa_log_debug("Memory block too large for pool: %lu > %lu", (unsigned long) length, (unsigned long) (p->block_size - sizeof(struct mempool_slot))); pa_atomic_inc(&p->stat.n_too_large_for_pool); return NULL; } diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index df08ff6e..ced80381 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -738,7 +738,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse volume_is_norm = pa_cvolume_is_norm(&info->sink_input->thread_info.volume); - pa_log_debug("Buffering %u bytes ...", info->buffer_bytes); + pa_log_debug("Buffering l%u bytes ...", (unsigned long) info->buffer_bytes); while (info->buffer_bytes > 0) { pa_memchunk memchunk; @@ -772,7 +772,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse pa_memblockq_sink_input_set_queue(info->ghost_sink_input, info->buffer); - pa_log_debug("Buffered %u bytes ...", pa_memblockq_get_length(info->buffer)); + pa_log_debug("Buffered %lu bytes ...", (unsigned long) pa_memblockq_get_length(info->buffer)); } /* Let's remove the sink input ...*/ -- cgit From 1d5e9f0205330207c37203d21ff642946f043bf7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 12 Aug 2007 23:29:12 +0000 Subject: deactivate module-x11-xsmp by default, due to a deadlock when pa is being started from gnome-session git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1657 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/default.pa.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in index 583b26cb..c472c09b 100755 --- a/src/daemon/default.pa.in +++ b/src/daemon/default.pa.in @@ -77,7 +77,8 @@ load-module module-x11-bell sample=x11-bell load-module module-x11-publish ### Register ourselves in the X11 session manager -load-module module-x11-xsmp +# Deactivated by default, to avoid deadlock when PA is started from gnome-session +# load-module module-x11-xsmp ### Load additional modules from GConf settings. This can be configured with the paprefs tool. ### Please keep in mind that the modules configured by paprefs might conflict with manually -- cgit From 8a663d4cda21c22849c7185690f2e47ff7d0219a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 13 Aug 2007 00:15:55 +0000 Subject: a couple of build fixes git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1658 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/oss-util.c | 2 +- src/pulsecore/protocol-native.c | 20 ++++++++++---------- src/pulsecore/sink.c | 2 +- src/tests/asyncq-test.c | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/modules/oss-util.c b/src/modules/oss-util.c index 155d42e4..5a939cf8 100644 --- a/src/modules/oss-util.c +++ b/src/modules/oss-util.c @@ -268,7 +268,7 @@ static int pa_oss_get_volume(int fd, int mixer, const pa_sample_spec *ss, pa_cvo return 0; } -static int pa_oss_set_volume(int fd, int mixer, const pa_sample_spec *ss, const pa_cvolume *volume) { +static int pa_oss_set_volume(int fd, long mixer, const pa_sample_spec *ss, const pa_cvolume *volume) { char cv[PA_CVOLUME_SNPRINT_MAX]; unsigned vol; pa_volume_t l, r; diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 1a112a8d..6b49efec 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -590,14 +590,14 @@ static playback_stream* playback_stream_new( const pa_sample_spec *ss, const pa_channel_map *map, const char *name, - size_t *maxlength, - size_t *tlength, - size_t *prebuf, - size_t *minreq, + uint32_t *maxlength, + uint32_t *tlength, + uint32_t *prebuf, + uint32_t *minreq, pa_cvolume *volume, uint32_t syncid, int corked, - size_t *missing) { + uint32_t *missing) { playback_stream *s, *ssync; pa_sink_input *sink_input; @@ -674,11 +674,11 @@ static playback_stream* playback_stream_new( pa_memblock_unref(silence); - *maxlength = pa_memblockq_get_maxlength(s->memblockq); - *tlength = pa_memblockq_get_tlength(s->memblockq); - *prebuf = pa_memblockq_get_prebuf(s->memblockq); - *minreq = pa_memblockq_get_minreq(s->memblockq); - *missing = pa_memblockq_missing(s->memblockq); + *maxlength = (uint32_t) pa_memblockq_get_maxlength(s->memblockq); + *tlength = (uint32_t) pa_memblockq_get_tlength(s->memblockq); + *prebuf = (uint32_t) pa_memblockq_get_prebuf(s->memblockq); + *minreq = (uint32_t) pa_memblockq_get_minreq(s->memblockq); + *missing = (uint32_t) pa_memblockq_missing(s->memblockq); pa_atomic_store(&s->missing, 0); s->last_missing = *missing; diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index ced80381..cfead9be 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -738,7 +738,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse volume_is_norm = pa_cvolume_is_norm(&info->sink_input->thread_info.volume); - pa_log_debug("Buffering l%u bytes ...", (unsigned long) info->buffer_bytes); + pa_log_debug("Buffering %lu bytes ...", (unsigned long) info->buffer_bytes); while (info->buffer_bytes > 0) { pa_memchunk memchunk; diff --git a/src/tests/asyncq-test.c b/src/tests/asyncq-test.c index 2e4b66cc..09b20047 100644 --- a/src/tests/asyncq-test.c +++ b/src/tests/asyncq-test.c @@ -41,10 +41,10 @@ static void producer(void *_q) { for (i = 0; i < 1000; i++) { printf("pushing %i\n", i); - pa_asyncq_push(q, (void*) (i+1), 1); + pa_asyncq_push(q, PA_UINT_TO_PTR(i+1), 1); } - pa_asyncq_push(q, (void*) -1, 1); + pa_asyncq_push(q, PA_UINT_TO_PTR(-1), 1); printf("pushed end\n"); } @@ -58,10 +58,10 @@ static void consumer(void *_q) { for (i = 0;; i++) { p = pa_asyncq_pop(q, 1); - if (p == (void*) -1) + if (p == PA_UINT_TO_PTR(-1)) break; - pa_assert(p == (void *) (i+1)); + pa_assert(p == PA_UINT_TO_PTR(i+1)); printf("popped %i\n", i); } -- cgit From 80f5abf6d967a26ac8e40ee3276c8258f6e0af59 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 13 Aug 2007 23:34:46 +0000 Subject: add load-module and unload-module commands to pactl git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1659 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/utils/pactl.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 8 deletions(-) diff --git a/src/utils/pactl.c b/src/utils/pactl.c index b95cbfee..cfc3f55d 100644 --- a/src/utils/pactl.c +++ b/src/utils/pactl.c @@ -48,8 +48,9 @@ static pa_context *context = NULL; static pa_mainloop_api *mainloop_api = NULL; -static char *device = NULL, *sample_name = NULL, *sink_name = NULL, *source_name = NULL; +static char *device = NULL, *sample_name = NULL, *sink_name = NULL, *source_name = NULL, *module_name = NULL, *module_args = NULL; static uint32_t sink_input_idx = PA_INVALID_INDEX, source_output_idx = PA_INVALID_INDEX; +static uint32_t module_index; static SNDFILE *sndfile = NULL; static pa_stream *sample_stream = NULL; @@ -69,7 +70,9 @@ static enum { REMOVE_SAMPLE, LIST, MOVE_SINK_INPUT, - MOVE_SOURCE_OUTPUT + MOVE_SOURCE_OUTPUT, + LOAD_MODULE, + UNLOAD_MODULE, } action = NONE; static void quit(int ret) { @@ -492,6 +495,18 @@ static void simple_callback(pa_context *c, int success, void *userdata) { complete_action(); } +static void index_callback(pa_context *c, uint32_t idx, void *userdata) { + if (idx == PA_INVALID_INDEX) { + fprintf(stderr, "Failure: %s\n", pa_strerror(pa_context_errno(c))); + quit(1); + return; + } + + printf("%u\n", idx); + + complete_action(); +} + static void stream_state_callback(pa_stream *s, void *userdata) { assert(s); @@ -594,6 +609,14 @@ static void context_state_callback(pa_context *c, void *userdata) { pa_operation_unref(pa_context_move_source_output_by_name(c, source_output_idx, source_name, simple_callback, NULL)); break; + case LOAD_MODULE: + pa_operation_unref(pa_context_load_module(c, module_name, module_args, index_callback, NULL)); + break; + + case UNLOAD_MODULE: + pa_operation_unref(pa_context_unload_module(c, module_index, simple_callback, NULL)); + break; + default: assert(0); } @@ -624,12 +647,14 @@ static void help(const char *argv0) { "%s [options] play-sample NAME [SINK]\n" "%s [options] move-sink-input ID SINK\n" "%s [options] move-source-output ID SOURCE\n" - "%s [options] remove-sample NAME\n\n" + "%s [options] remove-sample NAME\n" + "%s [options] load-module NAME [ARGS ...]\n" + "%s [options] unload-module ID\n\n" " -h, --help Show this help\n" " --version Show version\n\n" " -s, --server=SERVER The name of the server to connect to\n" " -n, --client-name=NAME How to call this client on the server\n", - argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0); + argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0); } enum { ARG_VERSION = 256 }; @@ -728,7 +753,7 @@ int main(int argc, char *argv[]) { sample_length = sfinfo.frames*pa_frame_size(&sample_spec); } else if (!strcmp(argv[optind], "play-sample")) { action = PLAY_SAMPLE; - if (optind+1 >= argc) { + if (argc != optind+2 && argc != optind+3) { fprintf(stderr, "You have to specify a sample name to play\n"); goto quit; } @@ -740,7 +765,7 @@ int main(int argc, char *argv[]) { } else if (!strcmp(argv[optind], "remove-sample")) { action = REMOVE_SAMPLE; - if (optind+1 >= argc) { + if (argc != optind+2) { fprintf(stderr, "You have to specify a sample name to remove\n"); goto quit; } @@ -748,7 +773,7 @@ int main(int argc, char *argv[]) { sample_name = pa_xstrdup(argv[optind+1]); } else if (!strcmp(argv[optind], "move-sink-input")) { action = MOVE_SINK_INPUT; - if (optind+2 >= argc) { + if (argc != optind+3) { fprintf(stderr, "You have to specify a sink input index and a sink\n"); goto quit; } @@ -757,14 +782,48 @@ int main(int argc, char *argv[]) { sink_name = pa_xstrdup(argv[optind+2]); } else if (!strcmp(argv[optind], "move-source-output")) { action = MOVE_SOURCE_OUTPUT; - if (optind+2 >= argc) { + if (argc != optind+3) { fprintf(stderr, "You have to specify a source output index and a source\n"); goto quit; } source_output_idx = atoi(argv[optind+1]); source_name = pa_xstrdup(argv[optind+2]); + } else if (!strcmp(argv[optind], "load-module")) { + int i; + size_t n = 0; + char *p; + + action = LOAD_MODULE; + + if (argc <= optind+1) { + fprintf(stderr, "You have to specify a module name and arguments.\n"); + goto quit; + } + + module_name = argv[optind+1]; + + for (i = optind+2; i < argc; i++) + n += strlen(argv[i])+1; + + if (n > 0) { + p = module_args = pa_xnew0(char, n); + + for (i = optind+2; i < argc; i++) + p += sprintf(p, "%s%s", p == module_args ? "" : " ", argv[i]); + } + + } else if (!strcmp(argv[optind], "unload-module")) { + action = UNLOAD_MODULE; + + if (argc != optind+2) { + fprintf(stderr, "You have to specify a source output index and a source\n"); + goto quit; + } + + module_index = atoi(argv[optind+1]); } + } if (action == NONE) { @@ -819,6 +878,7 @@ quit: pa_xfree(sample_name); pa_xfree(sink_name); pa_xfree(source_name); + pa_xfree(module_args); return ret; } -- cgit From 44f91cfafa0c615f773095a822ab7c0c5bdcb585 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 13 Aug 2007 23:49:26 +0000 Subject: load module-x11-xsmp from a /etc/xdg/autostart file, to make sure it is loaded when we have XSMP git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1660 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 9 ++++++++- src/daemon/default.pa.in | 3 ++- src/daemon/pulseaudio-module-xsmp.desktop | 10 ++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 src/daemon/pulseaudio-module-xsmp.desktop diff --git a/src/Makefile.am b/src/Makefile.am index aa5160a4..a962826a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,6 +30,7 @@ pulseincludedir=$(includedir)/pulse pulsecoreincludedir=$(includedir)/pulsecore pulseconfdir=$(sysconfdir)/pulse pulselibexecdir=$(libexecdir)/pulse +xdgautostartdir=$(sysconfdir)/xdg/autostart ################################### # Defines # @@ -103,13 +104,19 @@ EXTRA_DIST = \ depmod.py \ daemon/esdcompat.in \ utils/padsp \ - modules/module-defs.h.m4 + modules/module-defs.h.m4 \ + daemon/pulseaudio-module-xsmp.desktop pulseconf_DATA = \ default.pa \ daemon.conf \ client.conf +if HAVE_X11 +xdgautostart_DATA = \ + daemon/pulseaudio-module-xsmp.desktop +endif + BUILT_SOURCES = \ pulse/version.h diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in index c472c09b..6ece607d 100755 --- a/src/daemon/default.pa.in +++ b/src/daemon/default.pa.in @@ -77,7 +77,8 @@ load-module module-x11-bell sample=x11-bell load-module module-x11-publish ### Register ourselves in the X11 session manager -# Deactivated by default, to avoid deadlock when PA is started from gnome-session +# Deactivated by default, to avoid deadlock when PA is started as esd from gnome-session +# Instead we load this via /etc/xdg/autostart/ and "pactl load-module" now # load-module module-x11-xsmp ### Load additional modules from GConf settings. This can be configured with the paprefs tool. diff --git a/src/daemon/pulseaudio-module-xsmp.desktop b/src/daemon/pulseaudio-module-xsmp.desktop new file mode 100644 index 00000000..fa719a73 --- /dev/null +++ b/src/daemon/pulseaudio-module-xsmp.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Version=1.0 +Encoding=UTF-8 +Name=PulseAudio Session Management +Comment=Load module-x11-xsmp into PulseAudio +Exec=pactl load-module module-x11-xsmp +Terminal=false +Type=Application +Categories= +GenericName= -- cgit From 6f714d988750336df036d8036cea9c01dfe6cf39 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 Aug 2007 19:25:42 +0000 Subject: actually mute sinks when asked for i, add new function pa_sink_suspend_all git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1661 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink.c | 14 ++++++++++++++ src/pulsecore/sink.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index cfead9be..2c7c661c 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -587,6 +587,7 @@ void pa_sink_set_mute(pa_sink *s, int mute) { pa_sink_assert_ref(s); changed = s->muted != mute; + s->muted = mute; if (s->set_mute && s->set_mute(s) < 0) s->set_mute = NULL; @@ -819,3 +820,16 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse return -1; } + +int pa_sink_suspend_all(pa_core *c, int suspend) { + pa_sink *sink; + uint32_t idx; + int ret = 0; + + pa_core_assert_ref(c); + + for (sink = PA_SINK(pa_idxset_first(c->sinks, &idx)); sink; sink = PA_SINK(pa_idxset_next(c->sinks, &idx))) + ret -= pa_sink_suspend(sink, suspend) < 0; + + return ret; +} diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index 8a6fa236..fadc76eb 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -163,4 +163,6 @@ static inline int PA_SINK_OPENED(pa_sink_state_t x) { return x == PA_SINK_RUNNING || x == PA_SINK_IDLE; } +int pa_sink_suspend_all(pa_core *c, int suspend); + #endif -- cgit From 3d9299029c89d1bdc23c5e39bf627b0f4d7f2f3c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 Aug 2007 19:25:56 +0000 Subject: actually mute sinks when asked for i, add new function pa_sink_suspend_all git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1662 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/source.c | 14 ++++++++++++++ src/pulsecore/source.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 0e448f60..30a45cb6 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -320,6 +320,7 @@ void pa_source_set_mute(pa_source *s, int mute) { pa_source_assert_ref(s); changed = s->muted != mute; + s->muted = mute; if (s->set_mute && s->set_mute(s) < 0) s->set_mute = NULL; @@ -438,3 +439,16 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_ return -1; } + +int pa_source_suspend_all(pa_core *c, int suspend) { + uint32_t idx; + pa_source *source; + int ret = 0; + + pa_core_assert_ref(c); + + for (source = PA_SOURCE(pa_idxset_first(c->sources, &idx)); source; source = PA_SOURCE(pa_idxset_next(c->sources, &idx))) + ret -= pa_source_suspend(source, suspend) < 0; + + return ret; +} diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index fe59e584..ffe51079 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -152,4 +152,6 @@ static inline int PA_SOURCE_OPENED(pa_source_state_t x) { return x == PA_SOURCE_RUNNING || x == PA_SOURCE_IDLE; } +int pa_source_suspend_all(pa_core *c, int suspend); + #endif -- cgit From a74e804973eff2c6d9dff34fe415df9a0bb40683 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 Aug 2007 19:26:38 +0000 Subject: fix muting for sink inputs git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1663 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink-input.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 5fd1da47..8bec5d5d 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -398,7 +398,11 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) /* It might be necessary to adjust the volume here */ if (do_volume_adj_here && !volume_is_norm) { pa_memchunk_make_writable(&tchunk, 0); - pa_volume_memchunk(&tchunk, &i->thread_info.sample_spec, &i->thread_info.volume); + + if (i->thread_info.muted) + pa_silence_memchunk(&tchunk, &i->thread_info.sample_spec); + else + pa_volume_memchunk(&tchunk, &i->thread_info.sample_spec, &i->thread_info.volume); } pa_resampler_run(i->thread_info.resampler, &tchunk, &i->thread_info.resampled_chunk); @@ -430,8 +434,10 @@ finish: if (do_volume_adj_here) /* We had different channel maps, so we already did the adjustment */ pa_cvolume_reset(volume, i->sink->sample_spec.channels); - else + else if (i->thread_info.muted) /* We've both the same channel map, so let's have the sink do the adjustment for us*/ + pa_cvolume_mute(volume, i->sink->sample_spec.channels); + else *volume = i->thread_info.volume; } -- cgit From b20d204a30f3f5e1fa79ba236ce18a9025b0877b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 Aug 2007 19:27:12 +0000 Subject: use pa_source_suspend_all/pa_sink_suspend_all for suspending all sinks/sources git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1664 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/cli-command.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c index fac8d0e0..7440e744 100644 --- a/src/pulsecore/cli-command.c +++ b/src/pulsecore/cli-command.c @@ -965,10 +965,8 @@ static int pa_cli_command_suspend_source(pa_core *c, pa_tokenizer *t, pa_strbuf static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *m; - pa_sink *sink; - pa_source *source; int suspend; - uint32_t idx; + int ret; if (!(m = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a suspend switch setting (0/1).\n"); @@ -980,11 +978,12 @@ static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, i return -1; } - for (sink = pa_idxset_first(c->sinks, &idx); sink; sink = pa_idxset_next(c->sinks, &idx)) - pa_sink_suspend(sink, suspend); + ret = - (pa_sink_suspend_all(c, suspend) < 0); + if (pa_source_suspend_all(c, suspend) < 0) + ret = -1; - for (source = pa_idxset_first(c->sources, &idx); source; source = pa_idxset_next(c->sources, &idx)) - pa_source_suspend(source, suspend); + if (ret < 0) + pa_strbuf_puts(buf, "Failed to resume/suspend all sinks/sources.\n"); return 0; } -- cgit From 0640615c4ab87422379c043d67fc137c1bea6c1f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 Aug 2007 19:27:52 +0000 Subject: bump protocol revision and soname of libpulse git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1665 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 1bde5cc7..b037b898 100644 --- a/configure.ac +++ b/configure.ac @@ -37,9 +37,9 @@ AC_SUBST(PA_MAJORMINOR, "PA_MAJOR.PA_MINOR") AC_SUBST(PACKAGE_URL, [http://0pointer.de/lennart/projects/pulseaudio/]) AC_SUBST(PA_API_VERSION, 10) -AC_SUBST(PA_PROTOCOL_VERSION, 10) +AC_SUBST(PA_PROTOCOL_VERSION, 11) -AC_SUBST(LIBPULSE_VERSION_INFO, [2:1:2]) +AC_SUBST(LIBPULSE_VERSION_INFO, [3:0:3]) AC_SUBST(LIBPULSECORE_VERSION_INFO, [4:0:0]) AC_SUBST(LIBPULSE_SIMPLE_VERSION_INFO, [0:0:0]) AC_SUBST(LIBPULSE_BROWSE_VERSION_INFO, [1:0:1]) -- cgit From d2d0978454458f3604cea8c20bef0940fbff32d5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 Aug 2007 19:30:04 +0000 Subject: add protocol support for muting sink inputs and suspending sinks/sources git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1666 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/introspect.c | 143 ++++++++++++++++++++++++++++++++++++++-- src/pulse/introspect.h | 18 ++++- src/pulsecore/native-common.h | 3 + src/pulsecore/protocol-native.c | 88 ++++++++++++++++++++++++- 4 files changed, 242 insertions(+), 10 deletions(-) diff --git a/src/pulse/introspect.c b/src/pulse/introspect.c index 7f6406cf..568749d7 100644 --- a/src/pulse/introspect.c +++ b/src/pulse/introspect.c @@ -47,6 +47,8 @@ static void context_stat_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNU assert(o); assert(o->ref >= 1); + memset(&i, 0, sizeof(i)); + if (!o->context) goto finish; @@ -59,8 +61,7 @@ static void context_stat_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNU pa_tagstruct_getu32(t, &i.memblock_total_size) < 0 || pa_tagstruct_getu32(t, &i.memblock_allocated) < 0 || pa_tagstruct_getu32(t, &i.memblock_allocated_size) < 0 || - pa_tagstruct_getu32(t, &i.scache_size) < 0 || - !pa_tagstruct_eof(t)) { + pa_tagstruct_getu32(t, &i.scache_size) < 0) { pa_context_fail(o->context, PA_ERR_PROTOCOL); goto finish; } @@ -89,6 +90,8 @@ static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command, assert(o); assert(o->ref >= 1); + memset(&i, 0, sizeof(i)); + if (!o->context) goto finish; @@ -104,8 +107,7 @@ static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command, pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 || pa_tagstruct_gets(t, &i.default_sink_name) < 0 || pa_tagstruct_gets(t, &i.default_source_name) < 0 || - pa_tagstruct_getu32(t, &i.cookie) < 0 || - !pa_tagstruct_eof(t)) { + pa_tagstruct_getu32(t, &i.cookie) < 0) { pa_context_fail(o->context, PA_ERR_PROTOCOL); goto finish; @@ -148,6 +150,7 @@ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, P while (!pa_tagstruct_eof(t)) { pa_sink_info i; + memset(&i, 0, sizeof(i)); if (pa_tagstruct_getu32(t, &i.index) < 0 || pa_tagstruct_gets(t, &i.name) < 0 || @@ -258,6 +261,7 @@ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, while (!pa_tagstruct_eof(t)) { pa_source_info i; uint32_t flags; + memset(&i, 0, sizeof(i)); if (pa_tagstruct_getu32(t, &i.index) < 0 || pa_tagstruct_gets(t, &i.name) < 0 || @@ -367,6 +371,7 @@ static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, while (!pa_tagstruct_eof(t)) { pa_client_info i; + memset(&i, 0, sizeof(i)); if (pa_tagstruct_getu32(t, &i.index) < 0 || pa_tagstruct_gets(t, &i.name) < 0 || @@ -441,6 +446,7 @@ static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, while (!pa_tagstruct_eof(t)) { pa_module_info i; + memset(&i, 0, sizeof(i)); if (pa_tagstruct_getu32(t, &i.index) < 0 || pa_tagstruct_gets(t, &i.name) < 0 || @@ -516,7 +522,8 @@ static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t comm while (!pa_tagstruct_eof(t)) { pa_sink_input_info i; - + memset(&i, 0, sizeof(i)); + if (pa_tagstruct_getu32(t, &i.index) < 0 || pa_tagstruct_gets(t, &i.name) < 0 || pa_tagstruct_getu32(t, &i.owner_module) < 0 || @@ -528,7 +535,8 @@ static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t comm pa_tagstruct_get_usec(t, &i.buffer_usec) < 0 || pa_tagstruct_get_usec(t, &i.sink_usec) < 0 || pa_tagstruct_gets(t, &i.resample_method) < 0 || - pa_tagstruct_gets(t, &i.driver) < 0) { + pa_tagstruct_gets(t, &i.driver) < 0 || + (o->context->version >= 11 && pa_tagstruct_get_boolean(t, &i.mute) < 0)) { pa_context_fail(o->context, PA_ERR_PROTOCOL); goto finish; @@ -600,6 +608,8 @@ static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t c while (!pa_tagstruct_eof(t)) { pa_source_output_info i; + memset(&i, 0, sizeof(i)); + if (pa_tagstruct_getu32(t, &i.index) < 0 || pa_tagstruct_gets(t, &i.name) < 0 || pa_tagstruct_getu32(t, &i.owner_module) < 0 || @@ -781,6 +791,29 @@ pa_operation* pa_context_set_sink_input_volume(pa_context *c, uint32_t idx, cons return o; } +pa_operation* pa_context_set_sink_input_mute(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata) { + pa_operation *o; + pa_tagstruct *t; + uint32_t tag; + + assert(c); + assert(c->ref >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); + + t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_INPUT_MUTE, &tag); + pa_tagstruct_putu32(t, idx); + pa_tagstruct_put_boolean(t, mute); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); + + return o; +} + pa_operation* pa_context_set_source_volume_by_index(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata) { pa_operation *o; pa_tagstruct *t; @@ -900,6 +933,8 @@ static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, while (!pa_tagstruct_eof(t)) { pa_sample_info i; + memset(&i, 0, sizeof(i)); + if (pa_tagstruct_getu32(t, &i.index) < 0 || pa_tagstruct_gets(t, &i.name) < 0 || pa_tagstruct_get_cvolume(t, &i.volume) < 0 || @@ -1096,6 +1131,8 @@ static void context_get_autoload_info_callback(pa_pdispatch *pd, uint32_t comman while (!pa_tagstruct_eof(t)) { pa_autoload_info i; + memset(&i, 0, sizeof(i)); + if (pa_tagstruct_getu32(t, &i.index) < 0 || pa_tagstruct_gets(t, &i.name) < 0 || pa_tagstruct_getu32(t, &i.type) < 0 || @@ -1341,3 +1378,97 @@ pa_operation* pa_context_move_source_output_by_index(pa_context *c, uint32_t idx return o; } + +pa_operation* pa_context_suspend_sink_by_name(pa_context *c, char *sink_name, int suspend, pa_context_success_cb_t cb, void* userdata) { + pa_operation *o; + pa_tagstruct *t; + uint32_t tag; + + assert(c); + assert(c->ref >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED); + PA_CHECK_VALIDITY_RETURN_NULL(c, !sink_name || *sink_name, PA_ERR_INVALID); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); + + t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SINK, &tag); + pa_tagstruct_putu32(t, PA_INVALID_INDEX); + pa_tagstruct_puts(t, sink_name); + pa_tagstruct_put_boolean(t, suspend); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); + + return o; +} + +pa_operation* pa_context_suspend_sink_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata) { + pa_operation *o; + pa_tagstruct *t; + uint32_t tag; + + assert(c); + assert(c->ref >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); + + t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SINK, &tag); + pa_tagstruct_putu32(t, idx); + pa_tagstruct_puts(t, idx == PA_INVALID_INDEX ? "" : NULL); + pa_tagstruct_put_boolean(t, suspend); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); + + return o; +} + +pa_operation* pa_context_suspend_source_by_name(pa_context *c, char *source_name, int suspend, pa_context_success_cb_t cb, void* userdata) { + pa_operation *o; + pa_tagstruct *t; + uint32_t tag; + + assert(c); + assert(c->ref >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED); + PA_CHECK_VALIDITY_RETURN_NULL(c, !source_name || *source_name, PA_ERR_INVALID); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); + + t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SOURCE, &tag); + pa_tagstruct_putu32(t, PA_INVALID_INDEX); + pa_tagstruct_puts(t, source_name); + pa_tagstruct_put_boolean(t, suspend); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); + + return o; +} + +pa_operation* pa_context_suspend_source_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata) { + pa_operation *o; + pa_tagstruct *t; + uint32_t tag; + + assert(c); + assert(c->ref >= 1); + + PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED); + + o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata); + + t = pa_tagstruct_command(c, PA_COMMAND_SUSPEND_SOURCE, &tag); + pa_tagstruct_putu32(t, idx); + pa_tagstruct_puts(t, idx == PA_INVALID_INDEX ? "" : NULL); + pa_tagstruct_put_boolean(t, suspend); + pa_pstream_send_tagstruct(c->pstream, t); + pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref); + + return o; +} diff --git a/src/pulse/introspect.h b/src/pulse/introspect.h index 43e430b2..e700e39b 100644 --- a/src/pulse/introspect.h +++ b/src/pulse/introspect.h @@ -249,7 +249,7 @@ typedef struct pa_source_info { const char *monitor_of_sink_name; /**< Name of the owning sink, or PA_INVALID_INDEX */ pa_usec_t latency; /**< Length of filled record buffer of this source. \since 0.5 */ const char *driver; /**< Driver name \since 0.8 */ - pa_source_flags_t flags; /**< Flags \since 0.8 */ + pa_source_flags_t flags; /**< Flags \since 0.8 */ } pa_source_info; /** Callback prototype for pa_context_get_source_info_by_name() and friends */ @@ -331,6 +331,7 @@ typedef struct pa_sink_input_info { pa_usec_t sink_usec; /**< Latency of the sink device, see pa_latency_info for details */ const char *resample_method; /**< Thre resampling method used by this sink input. \since 0.7 */ const char *driver; /**< Driver name \since 0.8 */ + int mute; /**< Stream muted \since 0.9.7 */ } pa_sink_input_info; /** Callback prototype for pa_context_get_sink_input_info() and firends*/ @@ -381,6 +382,9 @@ pa_operation* pa_context_set_sink_mute_by_name(pa_context *c, const char *name, /** Set the volume of a sink input stream */ pa_operation* pa_context_set_sink_input_volume(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); +/** Set the mute switch of a sink input stream \since 0.9.7 */ +pa_operation* pa_context_set_sink_input_mute(pa_context *c, uint32_t idx, int mute, pa_context_success_cb_t cb, void *userdata); + /** Set the volume of a source device specified by its index \since 0.8 */ pa_operation* pa_context_set_source_volume_by_index(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); @@ -499,6 +503,18 @@ pa_operation* pa_context_move_source_output_by_name(pa_context *c, uint32_t idx, /** Move the specified source output to a different source. \since 0.9.5 */ pa_operation* pa_context_move_source_output_by_index(pa_context *c, uint32_t idx, uint32_t source_idx, pa_context_success_cb_t cb, void* userdata); +/** Suspend/Resume a sink. \since 0.9.7 */ +pa_operation* pa_context_suspend_sink_by_name(pa_context *c, char *sink_name, int suspend, pa_context_success_cb_t cb, void* userdata); + +/** Suspend/Resume a sink. If idx is PA_INVALID_INDEX all sinks will be suspended. \since 0.9.7 */ +pa_operation* pa_context_suspend_sink_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata); + +/** Suspend/Resume a source. \since 0.9.7 */ +pa_operation* pa_context_suspend_source_by_name(pa_context *c, char *source_name, int suspend, pa_context_success_cb_t cb, void* userdata); + +/** Suspend/Resume a source. If idx is PA_INVALID_INDEX all sources will be suspended. \since 0.9.7 */ +pa_operation* pa_context_suspend_source_by_index(pa_context *c, uint32_t idx, int suspend, pa_context_success_cb_t cb, void* userdata); + PA_C_DECL_END #endif diff --git a/src/pulsecore/native-common.h b/src/pulsecore/native-common.h index d22c8d12..9defc4a5 100644 --- a/src/pulsecore/native-common.h +++ b/src/pulsecore/native-common.h @@ -117,6 +117,9 @@ enum { PA_COMMAND_SET_SINK_INPUT_MUTE, + PA_COMMAND_SUSPEND_SINK, + PA_COMMAND_SUSPEND_SOURCE, + PA_COMMAND_MAX }; diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 6b49efec..fe73865a 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -247,6 +247,7 @@ static void command_get_autoload_info_list(pa_pdispatch *pd, uint32_t command, u static void command_cork_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); static void command_flush_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); +static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = { [PA_COMMAND_ERROR] = NULL, @@ -296,6 +297,9 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = { [PA_COMMAND_SET_SINK_INPUT_MUTE] = command_set_mute, [PA_COMMAND_SET_SOURCE_MUTE] = command_set_mute, + [PA_COMMAND_SUSPEND_SINK] = command_suspend, + [PA_COMMAND_SUSPEND_SOURCE] = command_suspend, + [PA_COMMAND_CORK_PLAYBACK_STREAM] = command_cork_playback_stream, [PA_COMMAND_FLUSH_PLAYBACK_STREAM] = command_trigger_or_flush_or_prebuf_playback_stream, [PA_COMMAND_TRIGGER_PLAYBACK_STREAM] = command_trigger_or_flush_or_prebuf_playback_stream, @@ -1770,7 +1774,7 @@ static void module_fill_tagstruct(pa_tagstruct *t, pa_module *module) { pa_tagstruct_put_boolean(t, module->auto_unload); } -static void sink_input_fill_tagstruct(pa_tagstruct *t, pa_sink_input *s) { +static void sink_input_fill_tagstruct(connection *c, pa_tagstruct *t, pa_sink_input *s) { pa_assert(t); pa_sink_input_assert_ref(s); @@ -1786,6 +1790,8 @@ static void sink_input_fill_tagstruct(pa_tagstruct *t, pa_sink_input *s) { pa_tagstruct_put_usec(t, pa_sink_get_latency(s->sink)); pa_tagstruct_puts(t, pa_resample_method_to_string(pa_sink_input_get_resample_method(s))); pa_tagstruct_puts(t, s->driver); + if (c->version >= 11) + pa_tagstruct_put_boolean(t, pa_sink_input_get_mute(s)); } static void source_output_fill_tagstruct(pa_tagstruct *t, pa_source_output *s) { @@ -1891,7 +1897,7 @@ static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, u else if (module) module_fill_tagstruct(reply, module); else if (si) - sink_input_fill_tagstruct(reply, si); + sink_input_fill_tagstruct(c, reply, si); else if (so) source_output_fill_tagstruct(reply, so); else @@ -1946,7 +1952,7 @@ static void command_get_info_list(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t comma else if (command == PA_COMMAND_GET_MODULE_INFO_LIST) module_fill_tagstruct(reply, p); else if (command == PA_COMMAND_GET_SINK_INPUT_INFO_LIST) - sink_input_fill_tagstruct(reply, p); + sink_input_fill_tagstruct(c, reply, p); else if (command == PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST) source_output_fill_tagstruct(reply, p); else { @@ -2620,6 +2626,8 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag pa_source_output *so = NULL; pa_source *source; + pa_assert(command == PA_COMMAND_MOVE_SOURCE_OUTPUT); + so = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx); if (idx_device != PA_INVALID_INDEX) @@ -2638,6 +2646,80 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag pa_pstream_send_simple_ack(c->pstream, tag); } +static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { + connection *c = CONNECTION(userdata); + uint32_t idx = PA_INVALID_INDEX; + const char *name = NULL; + int b; + + connection_assert_ref(c); + pa_assert(t); + + if (pa_tagstruct_getu32(t, &idx) < 0 || + pa_tagstruct_gets(t, &name) < 0 || + pa_tagstruct_get_boolean(t, &b) < 0 || + !pa_tagstruct_eof(t)) { + protocol_error(c); + return; + } + + CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); + CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || !*name || pa_utf8_valid(name), tag, PA_ERR_INVALID); + + if (command == PA_COMMAND_SUSPEND_SINK) { + + if (idx == PA_INVALID_INDEX && name && !*name) { + + if (pa_sink_suspend_all(c->protocol->core, b) < 0) { + pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID); + return; + } + } else { + pa_sink *sink = NULL; + + if (idx != PA_INVALID_INDEX) + sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx); + else + sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK, 1); + + CHECK_VALIDITY(c->pstream, sink, tag, PA_ERR_NOENTITY); + + if (pa_sink_suspend(sink, b) < 0) { + pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID); + return; + } + } + } else { + + pa_assert(command == PA_COMMAND_SUSPEND_SOURCE); + + if (idx == PA_INVALID_INDEX && name && !*name) { + + if (pa_source_suspend_all(c->protocol->core, b) < 0) { + pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID); + return; + } + + } else { + pa_source *source; + + if (idx != PA_INVALID_INDEX) + source = pa_idxset_get_by_index(c->protocol->core->sources, idx); + else + source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1); + + CHECK_VALIDITY(c->pstream, source, tag, PA_ERR_NOENTITY); + + if (pa_source_suspend(source, b) < 0) { + pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID); + return; + } + } + } + + pa_pstream_send_simple_ack(c->pstream, tag); +} + /*** pstream callbacks ***/ static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata) { -- cgit From 5679de5cfc4b4bbb7998e0d9eb5804e55c5786be Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 Aug 2007 19:57:12 +0000 Subject: add new commands suspend-source, suspend-sink git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1667 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/utils/pactl.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/src/utils/pactl.c b/src/utils/pactl.c index cfc3f55d..7c49007c 100644 --- a/src/utils/pactl.c +++ b/src/utils/pactl.c @@ -51,6 +51,7 @@ static pa_mainloop_api *mainloop_api = NULL; static char *device = NULL, *sample_name = NULL, *sink_name = NULL, *source_name = NULL, *module_name = NULL, *module_args = NULL; static uint32_t sink_input_idx = PA_INVALID_INDEX, source_output_idx = PA_INVALID_INDEX; static uint32_t module_index; +static int suspend; static SNDFILE *sndfile = NULL; static pa_stream *sample_stream = NULL; @@ -73,6 +74,8 @@ static enum { MOVE_SOURCE_OUTPUT, LOAD_MODULE, UNLOAD_MODULE, + SUSPEND_SINK, + SUSPEND_SOURCE, } action = NONE; static void quit(int ret) { @@ -357,7 +360,7 @@ static void get_sink_input_info_callback(pa_context *c, const pa_sink_input_info i->sink, pa_sample_spec_snprint(s, sizeof(s), &i->sample_spec), pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map), - pa_cvolume_snprint(cv, sizeof(cv), &i->volume), + i->mute ? "muted" : pa_cvolume_snprint(cv, sizeof(cv), &i->volume), (double) i->buffer_usec, (double) i->sink_usec, i->resample_method ? i->resample_method : "n/a"); @@ -616,6 +619,20 @@ static void context_state_callback(pa_context *c, void *userdata) { case UNLOAD_MODULE: pa_operation_unref(pa_context_unload_module(c, module_index, simple_callback, NULL)); break; + + case SUSPEND_SINK: + if (sink_name) + pa_operation_unref(pa_context_suspend_sink_by_name(c, sink_name, suspend, simple_callback, NULL)); + else + pa_operation_unref(pa_context_suspend_sink_by_index(c, PA_INVALID_INDEX, suspend, simple_callback, NULL)); + break; + + case SUSPEND_SOURCE: + if (source_name) + pa_operation_unref(pa_context_suspend_source_by_name(c, source_name, suspend, simple_callback, NULL)); + else + pa_operation_unref(pa_context_suspend_source_by_index(c, PA_INVALID_INDEX, suspend, simple_callback, NULL)); + break; default: assert(0); @@ -649,12 +666,14 @@ static void help(const char *argv0) { "%s [options] move-source-output ID SOURCE\n" "%s [options] remove-sample NAME\n" "%s [options] load-module NAME [ARGS ...]\n" - "%s [options] unload-module ID\n\n" + "%s [options] unload-module ID\n" + "%s [options] suspend-sink [SINK] 1|0\n" + "%s [options] suspend-source [SOURCE] 1|0\n\n" " -h, --help Show this help\n" " --version Show version\n\n" " -s, --server=SERVER The name of the server to connect to\n" " -n, --client-name=NAME How to call this client on the server\n", - argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0); + argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0, argv0); } enum { ARG_VERSION = 256 }; @@ -817,13 +836,38 @@ int main(int argc, char *argv[]) { action = UNLOAD_MODULE; if (argc != optind+2) { - fprintf(stderr, "You have to specify a source output index and a source\n"); + fprintf(stderr, "You have to specify a module index\n"); goto quit; } module_index = atoi(argv[optind+1]); - } + } else if (!strcmp(argv[optind], "suspend-sink")) { + action = SUSPEND_SINK; + + if (argc > optind+3 || optind+1 >= argc) { + fprintf(stderr, "You may not specify more than one sink. You have to specify at least one boolean value.\n"); + goto quit; + } + + suspend = !!atoi(argv[argc-1]); + + if (argc > optind+2) + sink_name = pa_xstrdup(argv[optind+1]); + + } else if (!strcmp(argv[optind], "suspend-source")) { + action = SUSPEND_SOURCE; + + if (argc > optind+3 || optind+1 >= argc) { + fprintf(stderr, "You may not specify more than one source. You have to specify at least one boolean value.\n"); + goto quit; + } + + suspend = !!atoi(argv[argc-1]); + + if (argc > optind+2) + source_name = pa_xstrdup(argv[optind+1]); + } } if (action == NONE) { @@ -879,6 +923,7 @@ quit: pa_xfree(sink_name); pa_xfree(source_name); pa_xfree(module_args); + pa_xfree(client_name); return ret; } -- cgit From 33c6f9dd52fe3f0617dc1c29c4eb2e145432afc7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 Aug 2007 20:47:53 +0000 Subject: set CLOEXEC on more fds git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1668 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/mainloop.c | 2 ++ src/pulsecore/fdsem.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index 0563507d..0dd0e119 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -460,6 +460,8 @@ pa_mainloop *pa_mainloop_new(void) { pa_make_nonblock_fd(m->wakeup_pipe[0]); pa_make_nonblock_fd(m->wakeup_pipe[1]); + pa_fd_set_cloexec(m->wakeup_pipe[0], 1); + pa_fd_set_cloexec(m->wakeup_pipe[1], 1); m->wakeup_requested = 0; PA_LLIST_HEAD_INIT(pa_io_event, m->io_events); diff --git a/src/pulsecore/fdsem.c b/src/pulsecore/fdsem.c index c51ebba6..20d262eb 100644 --- a/src/pulsecore/fdsem.c +++ b/src/pulsecore/fdsem.c @@ -54,6 +54,9 @@ pa_fdsem *pa_fdsem_new(void) { return NULL; } + pa_fd_set_cloexec(f->fds[0], 1); + pa_fd_set_cloexec(f->fds[1], 1); + pa_atomic_store(&f->waiting, 0); pa_atomic_store(&f->signalled, 0); pa_atomic_store(&f->in_pipe, 0); -- cgit From a96c5f813706f5c9ccf91a2d40b20362eb6c446c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 Aug 2007 20:50:15 +0000 Subject: add new tool pasuspender which temporarily suspends all sinks and resumes them later again git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1669 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 8 +- src/utils/pasuspender.c | 286 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 293 insertions(+), 1 deletion(-) create mode 100644 src/utils/pasuspender.c diff --git a/src/Makefile.am b/src/Makefile.am index a962826a..a711de29 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -161,7 +161,8 @@ endif bin_PROGRAMS += \ pacat \ pactl \ - paplay + paplay \ + pasuspender if HAVE_AF_UNIX bin_PROGRAMS += pacmd @@ -192,6 +193,11 @@ pactl_LDADD = $(AM_LDADD) libpulse.la $(LIBSNDFILE_LIBS) pactl_CFLAGS = $(AM_CFLAGS) $(LIBSNDFILE_CFLAGS) pactl_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) +pasuspender_SOURCES = utils/pasuspender.c +pasuspender_LDADD = $(AM_LDADD) libpulse.la $(LIBSNDFILE_LIBS) +pasuspender_CFLAGS = $(AM_CFLAGS) $(LIBSNDFILE_CFLAGS) +pasuspender_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + pacmd_SOURCES = utils/pacmd.c pulsecore/pid.c pulsecore/pid.h pacmd_CFLAGS = $(AM_CFLAGS) pacmd_LDADD = $(AM_LDADD) libpulse.la diff --git a/src/utils/pasuspender.c b/src/utils/pasuspender.c new file mode 100644 index 00000000..2172ccf5 --- /dev/null +++ b/src/utils/pasuspender.c @@ -0,0 +1,286 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#if PA_API_VERSION < 10 +#error Invalid PulseAudio API version +#endif + +#define BUFSIZE 1024 + +static pa_context *context = NULL; +static pa_mainloop_api *mainloop_api = NULL; +static char **child_argv = NULL; +static int child_argc = 0; +static pid_t child_pid = (pid_t) -1; +static int child_ret = 0; +static int dead = 1; + +static void quit(int ret) { + pa_assert(mainloop_api); + mainloop_api->quit(mainloop_api, ret); +} + + +static void context_drain_complete(pa_context *c, void *userdata) { + pa_context_disconnect(c); +} + +static void drain(void) { + pa_operation *o; + + if (!(o = pa_context_drain(context, context_drain_complete, NULL))) + pa_context_disconnect(context); + else + pa_operation_unref(o); +} + +static void suspend_complete(pa_context *c, int success, void *userdata) { + static int n = 0; + + n++; + + if (!success) { + fprintf(stderr, "Failure to suspend: %s\n", pa_strerror(pa_context_errno(c))); + quit(1); + } + + if (n >= 2) { + + if ((child_pid = fork()) < 0) { + + fprintf(stderr, "fork(): %s\n", strerror(errno)); + quit(1); + + } else if (child_pid == 0) { + /* Child */ + +#ifdef __linux__ + prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0); +#endif + + if (execvp(child_argv[0], child_argv) < 0) + fprintf(stderr, "execvp(): %s\n", strerror(errno)); + + _exit(1); + + } else { + + /* parent */ + dead = 0; + } + } +} + +static void resume_complete(pa_context *c, int success, void *userdata) { + static int n = 0; + + n++; + + if (!success) { + fprintf(stderr, "Failure to resume: %s\n", pa_strerror(pa_context_errno(c))); + quit(1); + return; + } + + if (n >= 2) + drain(); /* drain and quit */ +} + +static void context_state_callback(pa_context *c, void *userdata) { + pa_assert(c); + + switch (pa_context_get_state(c)) { + case PA_CONTEXT_CONNECTING: + case PA_CONTEXT_AUTHORIZING: + case PA_CONTEXT_SETTING_NAME: + break; + + case PA_CONTEXT_READY: + pa_operation_unref(pa_context_suspend_sink_by_index(c, PA_INVALID_INDEX, 1, suspend_complete, NULL)); + pa_operation_unref(pa_context_suspend_source_by_index(c, PA_INVALID_INDEX, 1, suspend_complete, NULL)); + break; + + case PA_CONTEXT_TERMINATED: + quit(0); + break; + + case PA_CONTEXT_FAILED: + default: + fprintf(stderr, "Connection failure: %s\n", pa_strerror(pa_context_errno(c))); + quit(1); + } +} + +static void sigint_callback(pa_mainloop_api *m, pa_signal_event *e, int sig, void *userdata) { + fprintf(stderr, "Got SIGINT, exiting.\n"); + quit(0); +} + +static void sigchld_callback(pa_mainloop_api *m, pa_signal_event *e, int sig, void *userdata) { + int status = 0; + pid_t p; + + p = waitpid(-1, &status, WNOHANG); + + if (p != child_pid) + return; + + dead = 1; + + if (WIFEXITED(status)) + child_ret = WEXITSTATUS(status); + else if (WIFSIGNALED(status)) { + fprintf(stderr, "WARNING: Child process terminated by signal %u\n", WTERMSIG(status)); + child_ret = 1; + } + + pa_operation_unref(pa_context_suspend_sink_by_index(context, PA_INVALID_INDEX, 0, resume_complete, NULL)); + pa_operation_unref(pa_context_suspend_source_by_index(context, PA_INVALID_INDEX, 0, resume_complete, NULL)); +} + +static void help(const char *argv0) { + + printf("%s [options] ... \n\n" + " -h, --help Show this help\n" + " --version Show version\n" + " -s, --server=SERVER The name of the server to connect to\n\n", + argv0); +} + +enum { + ARG_VERSION = 256 +}; + +int main(int argc, char *argv[]) { + pa_mainloop* m = NULL; + int c, ret = 1; + char *server = NULL, *bn; + + static const struct option long_options[] = { + {"server", 1, NULL, 's'}, + {"version", 0, NULL, ARG_VERSION}, + {"help", 0, NULL, 'h'}, + {NULL, 0, NULL, 0} + }; + + if (!(bn = strrchr(argv[0], '/'))) + bn = argv[0]; + else + bn++; + + while ((c = getopt_long(argc, argv, "s:h", long_options, NULL)) != -1) { + switch (c) { + case 'h' : + help(bn); + ret = 0; + goto quit; + + case ARG_VERSION: + printf("pasuspender "PACKAGE_VERSION"\nCompiled with libpulse %s\nLinked with libpulse %s\n", pa_get_headers_version(), pa_get_library_version()); + ret = 0; + goto quit; + + case 's': + pa_xfree(server); + server = pa_xstrdup(optarg); + break; + + default: + goto quit; + } + } + + child_argv = argv + optind; + child_argc = argc - optind; + + if (child_argc <= 0) { + help(bn); + ret = 0; + goto quit; + } + + if (!(m = pa_mainloop_new())) { + fprintf(stderr, "pa_mainloop_new() failed.\n"); + goto quit; + } + + pa_assert_se(mainloop_api = pa_mainloop_get_api(m)); + pa_assert_se(pa_signal_init(mainloop_api) == 0); + pa_signal_new(SIGINT, sigint_callback, NULL); + pa_signal_new(SIGCHLD, sigchld_callback, NULL); +#ifdef SIGPIPE + signal(SIGPIPE, SIG_IGN); +#endif + + if (!(context = pa_context_new(mainloop_api, bn))) { + fprintf(stderr, "pa_context_new() failed.\n"); + goto quit; + } + + pa_context_set_state_callback(context, context_state_callback, NULL); + pa_context_connect(context, server, 0, NULL); + + if (pa_mainloop_run(m, &ret) < 0) { + fprintf(stderr, "pa_mainloop_run() failed.\n"); + goto quit; + } + +quit: + if (context) + pa_context_unref(context); + + if (m) { + pa_signal_done(); + pa_mainloop_free(m); + } + + pa_xfree(server); + + if (!dead) + kill(child_pid, SIGTERM); + + return ret == 0 ? child_ret : ret; +} -- cgit From 1ff47862c4e9432225b5f95d5727eb00ad0a4234 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 Aug 2007 21:03:53 +0000 Subject: don't fail if no pa is srunning git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1670 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/utils/pasuspender.c | 78 +++++++++++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/src/utils/pasuspender.c b/src/utils/pasuspender.c index 2172ccf5..9ffd6d63 100644 --- a/src/utils/pasuspender.c +++ b/src/utils/pasuspender.c @@ -77,6 +77,32 @@ static void drain(void) { pa_operation_unref(o); } +static void start_child(void) { + + if ((child_pid = fork()) < 0) { + + fprintf(stderr, "fork(): %s\n", strerror(errno)); + quit(1); + + } else if (child_pid == 0) { + /* Child */ + +#ifdef __linux__ + prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0); +#endif + + if (execvp(child_argv[0], child_argv) < 0) + fprintf(stderr, "execvp(): %s\n", strerror(errno)); + + _exit(1); + + } else { + + /* parent */ + dead = 0; + } +} + static void suspend_complete(pa_context *c, int success, void *userdata) { static int n = 0; @@ -85,33 +111,11 @@ static void suspend_complete(pa_context *c, int success, void *userdata) { if (!success) { fprintf(stderr, "Failure to suspend: %s\n", pa_strerror(pa_context_errno(c))); quit(1); + return; } - if (n >= 2) { - - if ((child_pid = fork()) < 0) { - - fprintf(stderr, "fork(): %s\n", strerror(errno)); - quit(1); - - } else if (child_pid == 0) { - /* Child */ - -#ifdef __linux__ - prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0); -#endif - - if (execvp(child_argv[0], child_argv) < 0) - fprintf(stderr, "execvp(): %s\n", strerror(errno)); - - _exit(1); - - } else { - - /* parent */ - dead = 0; - } - } + if (n >= 2) + start_child(); } static void resume_complete(pa_context *c, int success, void *userdata) { @@ -150,7 +154,18 @@ static void context_state_callback(pa_context *c, void *userdata) { case PA_CONTEXT_FAILED: default: fprintf(stderr, "Connection failure: %s\n", pa_strerror(pa_context_errno(c))); - quit(1); + + pa_context_unref(context); + context = NULL; + + if (child_pid == (pid_t) -1) + /* not started yet, then we do it now */ + start_child(); + else if (dead) + /* already started, and dead, so let's quit */ + quit(1); + + break; } } @@ -177,8 +192,13 @@ static void sigchld_callback(pa_mainloop_api *m, pa_signal_event *e, int sig, vo child_ret = 1; } - pa_operation_unref(pa_context_suspend_sink_by_index(context, PA_INVALID_INDEX, 0, resume_complete, NULL)); - pa_operation_unref(pa_context_suspend_source_by_index(context, PA_INVALID_INDEX, 0, resume_complete, NULL)); + if (context) { + /* A context is around, so let's resume */ + pa_operation_unref(pa_context_suspend_sink_by_index(context, PA_INVALID_INDEX, 0, resume_complete, NULL)); + pa_operation_unref(pa_context_suspend_source_by_index(context, PA_INVALID_INDEX, 0, resume_complete, NULL)); + } else + /* Hmm, no context here, so let's terminate right away */ + quit(0); } static void help(const char *argv0) { @@ -261,7 +281,7 @@ int main(int argc, char *argv[]) { } pa_context_set_state_callback(context, context_state_callback, NULL); - pa_context_connect(context, server, 0, NULL); + pa_context_connect(context, server, PA_CONTEXT_NOAUTOSPAWN, NULL); if (pa_mainloop_run(m, &ret) < 0) { fprintf(stderr, "pa_mainloop_run() failed.\n"); -- cgit From c0d668431b252587021586bf4f52d99f8934035d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 Aug 2007 22:47:59 +0000 Subject: fix an awful race condition when handling data requests git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1671 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-native.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index fe73865a..a0b70669 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -537,13 +537,23 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata, switch (code) { case PLAYBACK_STREAM_MESSAGE_REQUEST_DATA: { pa_tagstruct *t; - int32_t l; + int32_t l = 0; - if ((l = pa_atomic_load(&s->missing)) <= 0) + for (;;) { + int32_t k; + + if ((k = pa_atomic_load(&s->missing)) <= 0) + break; + + l += k; + + if (pa_atomic_sub(&s->missing, k) <= k) + break; + } + + if (l <= 0) break; - pa_assert_se(pa_atomic_sub(&s->missing, l) >= l); - t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_REQUEST); pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ @@ -551,7 +561,7 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata, pa_tagstruct_putu32(t, l); pa_pstream_send_tagstruct(s->connection->pstream, t); -/* pa_log("Requesting %u bytes", l); */ +/* pa_log("Requesting %u bytes", l); */ break; } @@ -770,24 +780,22 @@ static void connection_free(pa_object *o) { /* Called from thread context */ static void request_bytes(playback_stream *s) { size_t new_missing, delta, previous_missing; + size_t minreq; -/* pa_log("request_bytes()"); */ playback_stream_assert_ref(s); new_missing = pa_memblockq_missing(s->memblockq); - - if (new_missing <= s->last_missing) { - s->last_missing = new_missing; - return; - } - - delta = new_missing - s->last_missing; + delta = new_missing > s->last_missing ? new_missing - s->last_missing : 0; s->last_missing = new_missing; + if (delta <= 0) + return; + /* pa_log("request_bytes(%u)", delta); */ + minreq = pa_memblockq_get_minreq(s->memblockq); previous_missing = pa_atomic_add(&s->missing, delta); - if (previous_missing < pa_memblockq_get_minreq(s->memblockq) && previous_missing+delta >= pa_memblockq_get_minreq(s->memblockq)) + if (previous_missing < minreq && previous_missing+delta >= minreq) pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); } -- cgit From 81cdb3798c146a577f5b362367137cc93610cba4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 Aug 2007 23:13:53 +0000 Subject: add fedora-snapshot target git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1672 fefdeb5f-60dc-0310-8127-8f9354f1896f --- Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile.am b/Makefile.am index 0fd4ccc0..288c24ef 100644 --- a/Makefile.am +++ b/Makefile.am @@ -51,4 +51,7 @@ eolspace: untabify: find \( -name '*.c' -o -name '*.h' \) -exec perl -i -pe 's/\t/ /g;' \{\} \; +fedora-snapshot: dist + cp $(distdir).tar.gz $$HOME/cvs.fedora/pulseaudio/devel/$(distdir).svn`date +%Y%m%d`.tar.gz + .PHONY: homepage distcleancheck doxygen -- cgit From 03b0b1db7b9d20d3b0b563becda07c3ef93b85de Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 16 Aug 2007 13:46:32 +0000 Subject: add pa_truncate_utf8() function for truncating a string and guaranteeing it stays valid UTF8 afterwards git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1673 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core-util.c | 18 ++++++++++++++++++ src/pulsecore/core-util.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 165fcf3d..9d846c6d 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -78,6 +78,7 @@ #include #include +#include #include #include @@ -1223,3 +1224,20 @@ int pa_snprintf(char *str, size_t size, const char *format, ...) { return ret; } + +/* Truncate the specified string, but guarantee that the string + * returned still validates as UTF8 */ +char *pa_truncate_utf8(char *c, size_t l) { + pa_assert(c); + pa_assert(pa_utf8_valid(c)); + + if (strlen(c) <= l) + return c; + + c[l] = 0; + + while (l > 0 && !pa_utf8_valid(c)) + c[--l] = 0; + + return c; +} diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index a593317d..88ed23fd 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -94,4 +94,6 @@ int pa_atou(const char *s, uint32_t *ret_u); int pa_snprintf(char *str, size_t size, const char *format, ...); +char *pa_truncate_utf8(char *c, size_t l); + #endif -- cgit From 39d1e653387e9c139cfaa69820b2925234356b2a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 16 Aug 2007 13:47:18 +0000 Subject: truncate service names if necessary, include user name in service string git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1674 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-zeroconf-publish.c | 71 +++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 23 deletions(-) diff --git a/src/modules/module-zeroconf-publish.c b/src/modules/module-zeroconf-publish.c index 34565395..1cdde84c 100644 --- a/src/modules/module-zeroconf-publish.c +++ b/src/modules/module-zeroconf-publish.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -102,25 +103,31 @@ struct userdata { }; static void get_service_data(struct userdata *u, struct service *s, pa_sample_spec *ret_ss, char **ret_description) { - pa_assert(u && s && s->loaded.valid && ret_ss && ret_description); + pa_assert(u); + pa_assert(s); + pa_assert(s->loaded.valid); + pa_assert(ret_ss); + pa_assert(ret_description); if (s->loaded.type == PA_NAMEREG_SINK) { - pa_sink *sink = pa_idxset_get_by_index(u->core->sinks, s->loaded.index); - pa_assert(sink); + pa_sink *sink = PA_SINK(pa_idxset_get_by_index(u->core->sinks, s->loaded.index)); + pa_sink_assert_ref(sink); *ret_ss = sink->sample_spec; *ret_description = sink->description; + } else if (s->loaded.type == PA_NAMEREG_SOURCE) { - pa_source *source = pa_idxset_get_by_index(u->core->sources, s->loaded.index); - pa_assert(source); + pa_source *source = PA_SOURCE(pa_idxset_get_by_index(u->core->sources, s->loaded.index)); + pa_source_assert_ref(source); *ret_ss = source->sample_spec; *ret_description = source->description; } else - pa_assert(0); + pa_assert_not_reached(); } static AvahiStringList* txt_record_server_data(pa_core *c, AvahiStringList *l) { char s[128]; - pa_assert(c); + + pa_core_assert_ref(c); l = avahi_string_list_add_pair(l, "server-version", PACKAGE_NAME" "PACKAGE_VERSION); l = avahi_string_list_add_pair(l, "user-name", pa_get_user_name(s, sizeof(s))); @@ -135,6 +142,8 @@ static int publish_service(struct userdata *u, struct service *s); static void service_entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) { struct service *s = userdata; + pa_assert(s); + if (state == AVAHI_ENTRY_GROUP_COLLISION) { char *t; @@ -244,7 +253,7 @@ finish: static struct service *get_service(struct userdata *u, const char *name, const char *description) { struct service *s; - char hn[64]; + char hn[64], un[64]; if ((s = pa_hashmap_get(u->services, name))) return s; @@ -255,7 +264,7 @@ static struct service *get_service(struct userdata *u, const char *name, const c s->published = UNPUBLISHED; s->name = pa_xstrdup(name); s->loaded.valid = s->autoload.valid = 0; - s->service_name = pa_sprintf_malloc("%s on %s", description ? description : s->name, pa_get_host_name(hn, sizeof(hn))); + s->service_name = pa_truncate_utf8(pa_sprintf_malloc("%s@%s: %s", pa_get_user_name(un, sizeof(un)), pa_get_host_name(hn, sizeof(hn)), description ? description : s->name), AVAHI_LABEL_MAX-1); pa_hashmap_put(u->services, s->name, s); @@ -265,7 +274,9 @@ static struct service *get_service(struct userdata *u, const char *name, const c static int publish_sink(struct userdata *u, pa_sink *s) { struct service *svc; int ret; - pa_assert(u && s); + + pa_assert(u); + pa_sink_assert_ref(s); svc = get_service(u, s->name, s->description); if (svc->loaded.valid) @@ -286,7 +297,8 @@ static int publish_source(struct userdata *u, pa_source *s) { struct service *svc; int ret; - pa_assert(u && s); + pa_assert(u); + pa_source_assert_ref(s); svc = get_service(u, s->name, s->description); if (svc->loaded.valid) @@ -309,7 +321,8 @@ static int publish_autoload(struct userdata *u, pa_autoload_entry *s) { struct service *svc; int ret; - pa_assert(u && s); + pa_assert(u); + pa_assert(s); svc = get_service(u, s->name, NULL); if (svc->autoload.valid) @@ -328,7 +341,9 @@ static int publish_autoload(struct userdata *u, pa_autoload_entry *s) { static int remove_sink(struct userdata *u, uint32_t idx) { struct service *svc; - pa_assert(u && idx != PA_INVALID_INDEX); + + pa_assert(u); + pa_assert(idx != PA_INVALID_INDEX); if (!(svc = pa_dynarray_get(u->sink_dynarray, idx))) return 0; @@ -344,7 +359,9 @@ static int remove_sink(struct userdata *u, uint32_t idx) { static int remove_source(struct userdata *u, uint32_t idx) { struct service *svc; - pa_assert(u && idx != PA_INVALID_INDEX); + + pa_assert(u); + pa_assert(idx != PA_INVALID_INDEX); if (!(svc = pa_dynarray_get(u->source_dynarray, idx))) return 0; @@ -360,7 +377,9 @@ static int remove_source(struct userdata *u, uint32_t idx) { static int remove_autoload(struct userdata *u, uint32_t idx) { struct service *svc; - pa_assert(u && idx != PA_INVALID_INDEX); + + pa_assert(u); + pa_assert(idx != PA_INVALID_INDEX); if (!(svc = pa_dynarray_get(u->autoload_dynarray, idx))) return 0; @@ -376,14 +395,17 @@ static int remove_autoload(struct userdata *u, uint32_t idx) { static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { struct userdata *u = userdata; - pa_assert(u && c); + + pa_assert(u); + pa_core_assert_ref(c); switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) + case PA_SUBSCRIPTION_EVENT_SINK: { if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { pa_sink *sink; - if ((sink = pa_idxset_get_by_index(c->sinks, idx))) { + if ((sink = PA_SINK(pa_idxset_get_by_index(c->sinks, idx)))) { if (publish_sink(u, sink) < 0) goto fail; } @@ -399,7 +421,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3 if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { pa_source *source; - if ((source = pa_idxset_get_by_index(c->sources, idx))) { + if ((source = PA_SOURCE(pa_idxset_get_by_index(c->sources, idx)))) { if (publish_source(u, source) < 0) goto fail; } @@ -456,6 +478,8 @@ static int publish_main_service(struct userdata *u) { AvahiStringList *txt = NULL; int r = -1; + pa_assert(u); + if (!u->main_entry_group) { if (!(u->main_entry_group = avahi_entry_group_new(u->client, main_entry_group_callback, u))) { pa_log("avahi_entry_group_new() failed: %s", avahi_strerror(avahi_client_errno(u->client))); @@ -505,11 +529,11 @@ static int publish_all_services(struct userdata *u) { pa_log_debug("Publishing services in Zeroconf"); - for (sink = pa_idxset_first(u->core->sinks, &idx); sink; sink = pa_idxset_next(u->core->sinks, &idx)) + for (sink = PA_SINK(pa_idxset_first(u->core->sinks, &idx)); sink; sink = PA_SINK(pa_idxset_next(u->core->sinks, &idx))) if (publish_sink(u, sink) < 0) goto fail; - for (source = pa_idxset_first(u->core->sources, &idx); source; source = pa_idxset_next(u->core->sources, &idx)) + for (source = PA_SOURCE(pa_idxset_first(u->core->sources, &idx)); source; source = PA_SOURCE(pa_idxset_next(u->core->sources, &idx))) if (publish_source(u, source) < 0) goto fail; @@ -558,7 +582,9 @@ static void unpublish_all_services(struct userdata *u, int rem) { static void client_callback(AvahiClient *c, AvahiClientState state, void *userdata) { struct userdata *u = userdata; + pa_assert(c); + pa_assert(u); u->client = c; @@ -592,7 +618,7 @@ int pa__init(pa_module*m) { struct userdata *u; uint32_t port = PA_NATIVE_DEFAULT_PORT; pa_modargs *ma = NULL; - char hn[256]; + char hn[256], un[256]; int error; if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { @@ -623,7 +649,7 @@ int pa__init(pa_module*m) { u->main_entry_group = NULL; - u->service_name = pa_xstrdup(pa_get_host_name(hn, sizeof(hn))); + u->service_name = pa_truncate_utf8(pa_sprintf_malloc("%s@%s", pa_get_user_name(un, sizeof(un)), pa_get_host_name(hn, sizeof(hn))), AVAHI_LABEL_MAX); if (!(u->client = avahi_client_new(u->avahi_poll, AVAHI_CLIENT_NO_FAIL, client_callback, u, &error))) { pa_log("pa_avahi_client_new() failed: %s", avahi_strerror(error)); @@ -678,7 +704,6 @@ void pa__done(pa_module*m) { if (u->autoload_dynarray) pa_dynarray_free(u->autoload_dynarray, NULL, NULL); - if (u->main_entry_group) avahi_entry_group_free(u->main_entry_group); -- cgit From 843dcceb1d9884fd677846f0a556671e9417235c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 16 Aug 2007 18:26:35 +0000 Subject: only suspend device when server is local git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1675 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/utils/pasuspender.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/utils/pasuspender.c b/src/utils/pasuspender.c index 9ffd6d63..a546f9a4 100644 --- a/src/utils/pasuspender.c +++ b/src/utils/pasuspender.c @@ -143,8 +143,12 @@ static void context_state_callback(pa_context *c, void *userdata) { break; case PA_CONTEXT_READY: - pa_operation_unref(pa_context_suspend_sink_by_index(c, PA_INVALID_INDEX, 1, suspend_complete, NULL)); - pa_operation_unref(pa_context_suspend_source_by_index(c, PA_INVALID_INDEX, 1, suspend_complete, NULL)); + if (pa_context_is_local(c)) { + pa_operation_unref(pa_context_suspend_sink_by_index(c, PA_INVALID_INDEX, 1, suspend_complete, NULL)); + pa_operation_unref(pa_context_suspend_source_by_index(c, PA_INVALID_INDEX, 1, suspend_complete, NULL)); + } else + start_child(); + break; case PA_CONTEXT_TERMINATED: @@ -193,9 +197,12 @@ static void sigchld_callback(pa_mainloop_api *m, pa_signal_event *e, int sig, vo } if (context) { - /* A context is around, so let's resume */ - pa_operation_unref(pa_context_suspend_sink_by_index(context, PA_INVALID_INDEX, 0, resume_complete, NULL)); - pa_operation_unref(pa_context_suspend_source_by_index(context, PA_INVALID_INDEX, 0, resume_complete, NULL)); + if (pa_context_is_local(context)) { + /* A context is around, so let's resume */ + pa_operation_unref(pa_context_suspend_sink_by_index(context, PA_INVALID_INDEX, 0, resume_complete, NULL)); + pa_operation_unref(pa_context_suspend_source_by_index(context, PA_INVALID_INDEX, 0, resume_complete, NULL)); + } else + drain(); } else /* Hmm, no context here, so let's terminate right away */ quit(0); -- cgit From d5cbf4fed9f695cceebfbe17b35313622540befe Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 16 Aug 2007 19:44:51 +0000 Subject: Keep CAP_SYS_NICE not only in PERMITTED but also in EFFECTIVE capset git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1676 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/caps.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/daemon/caps.c b/src/daemon/caps.c index f92db743..5b4008a5 100644 --- a/src/daemon/caps.c +++ b/src/daemon/caps.c @@ -26,11 +26,11 @@ #include #endif -#include #include #include #include #include +#include #ifdef HAVE_SYS_CAPABILITY_H #include @@ -60,7 +60,7 @@ void pa_drop_root(void) { if (uid == 0 || geteuid() != 0) return; - pa_log_info("dropping root rights."); + pa_log_info("Dropping root priviliges."); #if defined(HAVE_SETRESUID) setresuid(uid, uid, uid); @@ -88,8 +88,9 @@ int pa_limit_caps(void) { cap_value_t nice_cap = CAP_SYS_NICE; caps = cap_init(); - assert(caps); + pa_assert(caps); cap_clear(caps); + cap_set_flag(caps, CAP_EFFECTIVE, 1, &nice_cap, CAP_SET); cap_set_flag(caps, CAP_PERMITTED, 1, &nice_cap, CAP_SET); if (cap_set_proc(caps) < 0) @@ -98,7 +99,7 @@ int pa_limit_caps(void) { if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) goto fail; - pa_log_info("dropped capabilities successfully."); + pa_log_info("Dropped capabilities successfully."); r = 1; @@ -114,14 +115,14 @@ int pa_drop_caps(void) { int r = -1; caps = cap_init(); - assert(caps); + pa_assert(caps); cap_clear(caps); prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0); if (cap_set_proc(caps) < 0) { - pa_log("failed to drop capabilities: %s", pa_cstrerror(errno)); + pa_log("Failed to drop capabilities: %s", pa_cstrerror(errno)); goto fail; } -- cgit From 5e93816e1b96463865b2951abad68b235f149a4e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 16 Aug 2007 19:46:11 +0000 Subject: seperately get high nice level and acquire realtime sched git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1677 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core-util.c | 95 ++++++++++++++++------------------------------- src/pulsecore/core-util.h | 1 + 2 files changed, 32 insertions(+), 64 deletions(-) diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 9d846c6d..2c5a32e9 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -355,8 +355,7 @@ ssize_t pa_loop_write(int fd, const void*data, size_t size, int *type) { /** Platform independent read function. Necessary since not all * systems treat all file descriptors equal. */ -int pa_close(int fd) -{ +int pa_close(int fd) { #ifdef OS_IS_WIN32 int ret; @@ -483,28 +482,37 @@ char *pa_strlcpy(char *b, const char *s, size_t l) { return b; } -#define NICE_LEVEL (-15) +/* Make the current thread a realtime thread*/ +void pa_make_realtime(void) { -/* Raise the priority of the current process as much as possible and -sensible: set the nice level to -15 and enable realtime scheduling if -supported.*/ -void pa_raise_priority(void) { -#if defined(HAVE_SYS_CAPABILITY_H) - cap_t caps; - - /* Temporarily acquire CAP_SYS_NICE in the effective set */ - if ((caps = cap_get_proc())) { - cap_t caps_new; - cap_value_t nice_cap = CAP_SYS_NICE; - - if ((caps_new = cap_dup(caps))) { - cap_set_flag(caps_new, CAP_EFFECTIVE, 1, &nice_cap, CAP_SET); - cap_set_flag(caps_new, CAP_PERMITTED, 1, &nice_cap, CAP_SET); - cap_set_proc(caps_new); - cap_free(caps_new); - } +#ifdef _POSIX_PRIORITY_SCHEDULING + struct sched_param sp; + int r, policy; + + memset(&sp, 0, sizeof(sp)); + policy = 0; + + if ((r = pthread_getschedparam(pthread_self(), &policy, &sp)) != 0) { + pa_log("pthread_getschedgetparam(): %s", pa_cstrerror(r)); + return; + } + + sp.sched_priority = 1; + if ((r = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp)) != 0) { + pa_log_warn("pthread_setschedparam(): %s", pa_cstrerror(r)); + return; } + + pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread."); #endif + +} + +#define NICE_LEVEL (-11) + +/* Raise the priority of the current process as much as possible and +sensible: set the nice level to -15.*/ +void pa_raise_priority(void) { #ifdef HAVE_SYS_RESOURCE_H if (setpriority(PRIO_PROCESS, 0, NICE_LEVEL) < 0) @@ -513,62 +521,21 @@ void pa_raise_priority(void) { pa_log_info("Successfully gained nice level %i.", NICE_LEVEL); #endif -#ifdef _POSIX_PRIORITY_SCHEDULING - { - struct sched_param sp; - - if (sched_getparam(0, &sp) < 0) { - pa_log("sched_getparam(): %s", pa_cstrerror(errno)); - goto fail; - } - - sp.sched_priority = 1; - if (sched_setscheduler(0, SCHED_FIFO, &sp) < 0) { - pa_log_warn("sched_setscheduler(): %s", pa_cstrerror(errno)); - goto fail; - } - - pa_log_info("Successfully enabled SCHED_FIFO scheduling."); - } -#endif - #ifdef OS_IS_WIN32 if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError()); else pa_log_info("Successfully gained high priority class."); #endif - -fail: - -#if defined(HAVE_SYS_CAPABILITY_H) - if (caps) { - /* Restore original caps */ - cap_set_proc(caps); - cap_free(caps); - } -#endif - - ; /* We put this here to get the code to compile when - * HAVE_SYS_CAPABILITY_H is not defined. Don't remove unless you - * know what you do */ } -/* Reset the priority to normal, inverting the changes made by pa_raise_priority() */ +/* Reset the priority to normal, inverting the changes made by + * pa_raise_priority() */ void pa_reset_priority(void) { #ifdef OS_IS_WIN32 SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); #endif -#ifdef _POSIX_PRIORITY_SCHEDULING - { - struct sched_param sp; - sched_getparam(0, &sp); - sp.sched_priority = 0; - sched_setscheduler(0, SCHED_OTHER, &sp); - } -#endif - #ifdef HAVE_SYS_RESOURCE_H setpriority(PRIO_PROCESS, 0, 0); #endif diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index 88ed23fd..cb78d32d 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -55,6 +55,7 @@ char *pa_strlcpy(char *b, const char *s, size_t l); char *pa_parent_dir(const char *fn); +void pa_make_realtime(void); void pa_raise_priority(void); void pa_reset_priority(void); -- cgit From 876e682ad8ef324e80c6ef1ec296715dc086fa04 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 16 Aug 2007 19:48:49 +0000 Subject: never stay root after startup, even if we don't have capabilites git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1678 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/main.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/daemon/main.c b/src/daemon/main.c index eac470bf..cf2e628b 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -336,10 +336,19 @@ int main(int argc, char *argv[]) { #endif if (suid_root) { - if (pa_limit_caps() > 0) - /* We managed to drop capabilities except the needed - * ones. Hence we can drop the uid. */ - pa_drop_root(); + /* Drop all capabilities except CAP_SYS_NICE */ + pa_limit_caps(); + + /* Drop priviliges, but keep CAP_SYS_NICE */ + pa_drop_root(); + + /* After dropping root, the effective set is reset, hence, + * let's raise it again */ + pa_limit_caps(); + + /* When capabilities are not supported we will not be able to + * aquire RT sched anymore. But yes, that's the way it is. It + * is just too risky tun let PA run as root all the time. */ } setlocale(LC_ALL, ""); @@ -386,7 +395,7 @@ int main(int argc, char *argv[]) { if (conf->high_priority && conf->cmd == PA_CMD_DAEMON) pa_raise_priority(); - if (suid_root) { + if (suid_root && conf->cmd != PA_CMD_DAEMON) { pa_drop_caps(); pa_drop_root(); } -- cgit From 2d292befabf5b0a87bc1d6493ef471725de88d41 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 16 Aug 2007 19:50:11 +0000 Subject: use realtime scheduling for ALSA and OSS driver threads git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1679 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 2 ++ src/modules/module-alsa-source.c | 2 ++ src/modules/module-oss.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index cf999a92..f1031b68 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -527,6 +527,8 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); + pa_make_realtime(); + pa_thread_mq_install(&u->thread_mq); if (build_pollfd(u) < 0) diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 8ff074d6..a1de2f2e 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -516,6 +516,8 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); + pa_make_realtime(); + pa_thread_mq_install(&u->thread_mq); if (build_pollfd(u) < 0) diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index d9b5b963..346ccbd5 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -791,6 +791,8 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); + pa_make_realtime(); + pa_thread_mq_install(&u->thread_mq); trigger(u, 0); -- cgit From fa7fc315bd62deb8375194d48e688c808e2919fb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 00:18:04 +0000 Subject: modernizations git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1681 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/timeval.c | 43 +++++++++++++++++++++++-------------------- src/pulse/timeval.h | 4 ++++ 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/pulse/timeval.c b/src/pulse/timeval.c index 78ece061..ba1128c4 100644 --- a/src/pulse/timeval.c +++ b/src/pulse/timeval.c @@ -26,7 +26,6 @@ #include #endif -#include #include #include @@ -34,15 +33,17 @@ #include #endif -#include "../pulsecore/winsock.h" +#include +#include #include "timeval.h" struct timeval *pa_gettimeofday(struct timeval *tv) { #ifdef HAVE_GETTIMEOFDAY - assert(tv); + pa_assert(tv); - return gettimeofday(tv, NULL) < 0 ? NULL : tv; + pa_assert_se(gettimeofday(tv, NULL) == 0); + return tv; #elif defined(OS_IS_WIN32) /* * Copied from implementation by Steven Edwards (LGPL). @@ -54,12 +55,12 @@ struct timeval *pa_gettimeofday(struct timeval *tv) { #else #define EPOCHFILETIME (116444736000000000LL) #endif - + FILETIME ft; LARGE_INTEGER li; __int64 t; - assert(tv); + pa_assert(tv); GetSystemTimeAsFileTime(&ft); li.LowPart = ft.dwLowDateTime; @@ -67,8 +68,8 @@ struct timeval *pa_gettimeofday(struct timeval *tv) { t = li.QuadPart; /* In 100-nanosecond intervals */ t -= EPOCHFILETIME; /* Offset to the Epoch time */ t /= 10; /* In microseconds */ - tv->tv_sec = (long)(t / 1000000); - tv->tv_usec = (long)(t % 1000000); + tv->tv_sec = (time_t) (t / PA_USEC_PER_SEC); + tv->tv_usec = (suseconds_t) (t % PA_USEC_PER_SEC); return tv; #else @@ -78,9 +79,10 @@ struct timeval *pa_gettimeofday(struct timeval *tv) { pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) { pa_usec_t r; - assert(a && b); + pa_assert(a); + pa_assert(b); - /* Check which whan is the earlier time and swap the two arguments if reuqired. */ + /* Check which whan is the earlier time and swap the two arguments if required. */ if (pa_timeval_cmp(a, b) < 0) { const struct timeval *c; c = a; @@ -89,7 +91,7 @@ pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) { } /* Calculate the second difference*/ - r = ((pa_usec_t) a->tv_sec - b->tv_sec)* 1000000; + r = ((pa_usec_t) a->tv_sec - b->tv_sec) * PA_USEC_PER_SEC; /* Calculate the microsecond difference */ if (a->tv_usec > b->tv_usec) @@ -101,7 +103,8 @@ pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) { } int pa_timeval_cmp(const struct timeval *a, const struct timeval *b) { - assert(a && b); + pa_assert(a); + pa_assert(b); if (a->tv_sec < b->tv_sec) return -1; @@ -120,25 +123,25 @@ int pa_timeval_cmp(const struct timeval *a, const struct timeval *b) { pa_usec_t pa_timeval_age(const struct timeval *tv) { struct timeval now; - assert(tv); + pa_assert(tv); return pa_timeval_diff(pa_gettimeofday(&now), tv); } struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v) { unsigned long secs; - assert(tv); + pa_assert(tv); - secs = (v/1000000); - tv->tv_sec += (unsigned long) secs; - v -= secs*1000000; + secs = (unsigned long) (v/PA_USEC_PER_SEC); + tv->tv_sec += secs; + v -= ((pa_usec_t) secs) * PA_USEC_PER_SEC; - tv->tv_usec += v; + tv->tv_usec += (suseconds_t) v; /* Normalize */ - while (tv->tv_usec >= 1000000) { + while (tv->tv_usec >= PA_USEC_PER_SEC) { tv->tv_sec++; - tv->tv_usec -= 1000000; + tv->tv_usec -= PA_USEC_PER_SEC; } return tv; diff --git a/src/pulse/timeval.h b/src/pulse/timeval.h index 1e5627e3..dbf4319c 100644 --- a/src/pulse/timeval.h +++ b/src/pulse/timeval.h @@ -33,6 +33,10 @@ PA_C_DECL_BEGIN +#define PA_MSEC_PER_SEC 1000 +#define PA_USEC_PER_SEC 1000000 +#define PA_NSEC_PER_SEC 1000000000 + struct timeval; /** Return the current timestamp, just like UNIX gettimeofday() */ -- cgit From b0b06b0002fc9eb14f2a151796d547543bec6b9b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 00:18:58 +0000 Subject: add more PA_PTR_TO_XXX macros git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1682 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/macro.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/macro.h b/src/pulsecore/macro.h index fe944ae8..efd0f5ed 100644 --- a/src/pulsecore/macro.h +++ b/src/pulsecore/macro.h @@ -76,7 +76,14 @@ static inline size_t pa_align(size_t l) { #define PA_PTR_TO_UINT(p) ((unsigned int) (unsigned long) (p)) #define PA_UINT_TO_PTR(u) ((void*) (unsigned long) (u)) + #define PA_PTR_TO_UINT32(p) ((uint32_t) PA_PTR_TO_UINT(p)) -#define PA_UINT32_TO_PTR(u) PA_UINT_TO_PTR(u) +#define PA_UINT32_TO_PTR(u) PA_UINT_TO_PTR((uint32_t) u) + +#define PA_PTR_TO_INT(p) ((int) PA_PTR_TO_UINT(p)) +#define PA_INT_TO_PTR(u) PA_UINT_TO_PTR((int) u) + +#define PA_PTR_TO_INT32(p) ((int32_t) PA_PTR_TO_UINT(p)) +#define PA_INT32_TO_PTR(u) PA_UINT_TO_PTR((int32_t) u) #endif -- cgit From a0ad42a35f73a9bdc0751cbb902f01da2c3c4b05 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 00:19:33 +0000 Subject: add macro for creating static TLS objects git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1683 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/pulsecore/thread.h b/src/pulsecore/thread.h index ca1fe4da..44b80a06 100644 --- a/src/pulsecore/thread.h +++ b/src/pulsecore/thread.h @@ -48,4 +48,30 @@ void pa_tls_free(pa_tls *t); void * pa_tls_get(pa_tls *t); void *pa_tls_set(pa_tls *t, void *userdata); +/* To make use of the static TLS stuff you have to include once.h, as well */ + +#define PA_STATIC_TLS_DECLARE(name, free_cb) \ + static struct { \ + pa_once once; \ + pa_tls *tls; \ + } name##_tls = { \ + .once = PA_ONCE_INIT, \ + .tls = NULL \ + }; \ + static void name##_tls_init(void) { \ + name##_tls.tls = pa_tls_new(free_cb); \ + } \ + static inline pa_tls* name##_tls_get(void) { \ + pa_run_once(&name##_tls.once, name##_tls_init); \ + return name##_tls.tls; \ + } \ + static void name##_tls_destructor(void) PA_GCC_DESTRUCTOR; \ + static void name##_tls_destructor(void) { \ + if (name##_tls.tls) \ + pa_tls_free(name##_tls.tls); \ + } \ + struct __stupid_useless_struct_to_allow_trailing_semicolon + +#define PA_STATIC_TLS_GET(name) (name##_tls_get()) + #endif -- cgit From b7b119ae00090074ec0bc48da7a0c4b689efa55c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 00:20:13 +0000 Subject: add pa_is_power_of_two() and pa_make_power_of_two() functions git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1684 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core-util.c | 18 ++++++++++++++++++ src/pulsecore/core-util.h | 3 +++ 2 files changed, 21 insertions(+) diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 2c5a32e9..0005e220 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -1208,3 +1208,21 @@ char *pa_truncate_utf8(char *c, size_t l) { return c; } + +int pa_is_power_of_two(unsigned n) { + return !(n & (n - 1)); +} + +unsigned pa_make_power_of_two(unsigned n) { + unsigned j = n; + + if (pa_is_power_of_two(n)) + return n; + + while (j) { + j = j >> 1; + n = n | j; + } + + return n + 1; +} diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index cb78d32d..29dc2fb1 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -97,4 +97,7 @@ int pa_snprintf(char *str, size_t size, const char *format, ...); char *pa_truncate_utf8(char *c, size_t l); +int pa_is_power_of_two(unsigned n); +unsigned pa_make_power_of_two(unsigned n); + #endif -- cgit From 531cc3cfaffaeac5f46fc808e20711001b8fc1db Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 00:21:00 +0000 Subject: make use of new public function pa_is_power_of_two() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1685 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/flist.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/pulsecore/flist.c b/src/pulsecore/flist.c index 022010b3..b0f3228f 100644 --- a/src/pulsecore/flist.c +++ b/src/pulsecore/flist.c @@ -104,17 +104,13 @@ struct pa_flist { #define PA_FLIST_CELLS(x) ((struct cell*) ((uint8_t*) (x) + PA_ALIGN(sizeof(struct pa_flist)))) -static int is_power_of_two(unsigned size) { - return !(size & (size - 1)); -} - pa_flist *pa_flist_new(unsigned size) { pa_flist *l; if (!size) size = FLIST_SIZE; - assert(is_power_of_two(size)); + assert(pa_is_power_of_two(size)); l = pa_xmalloc0(PA_ALIGN(sizeof(pa_flist)) + (sizeof(struct cell) * size)); -- cgit From 6bfeef18187ff56b92875e2dd926bf32c3a6c720 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 00:21:28 +0000 Subject: rename a few things in a macro to make name collisions less likely git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1686 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/flist.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/pulsecore/flist.h b/src/pulsecore/flist.h index 69b9c741..daf0fec4 100644 --- a/src/pulsecore/flist.h +++ b/src/pulsecore/flist.h @@ -44,25 +44,25 @@ void* pa_flist_pop(pa_flist*l); /* Please not that the destructor stuff is not really necesary, we do * this just to make valgrind output more useful. */ -#define PA_STATIC_FLIST_DECLARE(name, size, destroy_cb) \ +#define PA_STATIC_FLIST_DECLARE(name, size, free_cb) \ static struct { \ pa_flist *flist; \ pa_once once; \ - } name##_static_flist = { NULL, PA_ONCE_INIT }; \ - static void name##_init(void) { \ - name##_static_flist.flist = pa_flist_new(size); \ + } name##_flist = { NULL, PA_ONCE_INIT }; \ + static void name##_flist_init(void) { \ + name##_flist.flist = pa_flist_new(size); \ } \ - static inline pa_flist* name##_get(void) { \ - pa_run_once(&name##_static_flist.once, name##_init); \ - return name##_static_flist.flist; \ + static inline pa_flist* name##_flist_get(void) { \ + pa_run_once(&name##_flist.once, name##_flist_init); \ + return name##_flist.flist; \ } \ - static void name##_destructor(void) PA_GCC_DESTRUCTOR; \ - static void name##_destructor(void) { \ - if (name##_static_flist.flist) \ - pa_flist_free(name##_static_flist.flist, destroy_cb); \ + static void name##_flist_destructor(void) PA_GCC_DESTRUCTOR; \ + static void name##_flist_destructor(void) { \ + if (name##_flist.flist) \ + pa_flist_free(name##_flist.flist, (free_cb)); \ } \ struct __stupid_useless_struct_to_allow_trailing_semicolon -#define PA_STATIC_FLIST_GET(name) (name##_get()) +#define PA_STATIC_FLIST_GET(name) (name##_flist_get()) #endif -- cgit From ef2bc41b875332e7a0bf641b5ecdbe9906ae378c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 00:22:51 +0000 Subject: add monotonic clock abstraction pa_rtclock git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1687 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/rtclock.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++ src/pulsecore/rtclock.h | 48 +++++++++++++++ 2 files changed, 201 insertions(+) create mode 100644 src/pulsecore/rtclock.c create mode 100644 src/pulsecore/rtclock.h diff --git a/src/pulsecore/rtclock.c b/src/pulsecore/rtclock.c new file mode 100644 index 00000000..507b8999 --- /dev/null +++ b/src/pulsecore/rtclock.c @@ -0,0 +1,153 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include + +#include "rtclock.h" + +struct timespec *pa_timespec_store(struct timespec *a, pa_usec_t u) { + pa_assert(a); + + a->tv_sec = u / PA_USEC_PER_SEC; + + u -= (pa_usec_t) a->tv_sec * PA_USEC_PER_SEC; + + a->tv_nsec = u * 1000; + + return a; +} + +pa_usec_t pa_timespec_load(struct timespec *ts) { + pa_assert(ts); + + return (pa_usec_t) ts->tv_sec * PA_USEC_PER_SEC + (pa_usec_t) (ts->tv_nsec / 1000); +} + +pa_usec_t pa_timespec_diff(const struct timespec *a, const struct timespec *b) { + pa_usec_t r; + + pa_assert(a); + pa_assert(b); + + /* Check which whan is the earlier time and swap the two arguments if required. */ + if (pa_timespec_cmp(a, b) < 0) { + const struct timespec *c; + c = a; + a = b; + b = c; + } + + /* Calculate the second difference*/ + r = ((pa_usec_t) a->tv_sec - b->tv_sec) * PA_USEC_PER_SEC; + + /* Calculate the microsecond difference */ + if (a->tv_nsec > b->tv_nsec) + r += (pa_usec_t) ((a->tv_nsec - b->tv_nsec) / 1000); + else if (a->tv_nsec < b->tv_nsec) + r -= (pa_usec_t) ((b->tv_nsec - a->tv_nsec) / 1000); + + return r; +} + +int pa_timespec_cmp(const struct timespec *a, const struct timespec *b) { + pa_assert(a); + pa_assert(b); + + if (a->tv_sec < b->tv_sec) + return -1; + + if (a->tv_sec > b->tv_sec) + return 1; + + if (a->tv_nsec < b->tv_nsec) + return -1; + + if (a->tv_nsec > b->tv_nsec) + return 1; + + return 0; +} + +struct timespec* pa_timespec_add(struct timespec *ts, pa_usec_t v) { + unsigned long secs; + pa_assert(ts); + + secs = (unsigned long) (v/PA_USEC_PER_SEC); + ts->tv_sec += secs; + v -= ((pa_usec_t) secs) * PA_USEC_PER_SEC; + + ts->tv_nsec += (long) (v*1000); + + /* Normalize */ + while (ts->tv_nsec >= PA_NSEC_PER_SEC) { + ts->tv_sec++; + ts->tv_nsec -= PA_NSEC_PER_SEC; + } + + return ts; +} + +pa_usec_t pa_rtclock_age(const struct timespec *ts) { + struct timespec now; + pa_assert(ts); + + return pa_timespec_diff(pa_rtclock_get(&now), ts); +} + +struct timespec *pa_rtclock_get(struct timespec *ts) { + static int no_monotonic = 0; + + /* No locking or atomic ops for no_monotonic here */ + + pa_assert(ts); + + if (!no_monotonic) { + if (clock_gettime(CLOCK_MONOTONIC, ts) >= 0) + return ts; + + no_monotonic = 1; + } + + pa_assert_se(clock_gettime(CLOCK_REALTIME, ts) == 0); + return ts; +} + +int pa_rtclock_hrtimer(void) { + struct timespec ts; + + if (clock_getres(CLOCK_MONOTONIC, &ts) >= 0) + return ts.tv_sec == 0 && ts.tv_nsec <= PA_HRTIMER_THRESHOLD_USEC*1000; + + pa_assert_se(clock_getres(CLOCK_REALTIME, &ts) == 0); + return ts.tv_sec == 0 && ts.tv_nsec <= PA_HRTIMER_THRESHOLD_USEC*1000; +} + diff --git a/src/pulsecore/rtclock.h b/src/pulsecore/rtclock.h new file mode 100644 index 00000000..145533cd --- /dev/null +++ b/src/pulsecore/rtclock.h @@ -0,0 +1,48 @@ +#ifndef foopulsertclockhfoo +#define foopulsertclockhfoo + +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include +#include + +#include + +/* Something like pulse/timeval.h but based on CLOCK_MONOTONIC and + * timespec instead of timeval */ + +struct timespec *pa_rtclock_get(struct timespec *ts); +pa_usec_t pa_rtclock_age(const struct timespec *tv); +int pa_rtclock_hrtimer(void); + +struct timespec *pa_timespec_store(struct timespec *a, pa_usec_t u); +pa_usec_t pa_timespec_load(struct timespec *tv); +struct timespec *pa_timespec_add(struct timespec *tv, pa_usec_t t); +pa_usec_t pa_timespec_diff(const struct timespec *a, const struct timespec *b); +int pa_timespec_cmp(const struct timespec *a, const struct timespec *b); + +/* timer with a resolution better than this are considered high-resolution */ +#define PA_HRTIMER_THRESHOLD_USEC 10 + +#endif -- cgit From 8972d06bc78ec61792a4c423f19df18f8f8a5838 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 00:23:33 +0000 Subject: add facility for managing realtime signals git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1688 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/rtsig.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/pulsecore/rtsig.h | 44 ++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 src/pulsecore/rtsig.c create mode 100644 src/pulsecore/rtsig.h diff --git a/src/pulsecore/rtsig.c b/src/pulsecore/rtsig.c new file mode 100644 index 00000000..1b8cdaa3 --- /dev/null +++ b/src/pulsecore/rtsig.c @@ -0,0 +1,111 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include +#include +#include + +#include "rtsig.h" + +static void _free_rtsig(void *p) { + pa_rtsig_put(PA_PTR_TO_INT(p)); +} + +PA_STATIC_FLIST_DECLARE(rtsig_flist, pa_make_power_of_two(SIGRTMAX-SIGRTMIN+1), NULL); +PA_STATIC_TLS_DECLARE(rtsig_tls, _free_rtsig); + +static pa_atomic_t rtsig_current = PA_ATOMIC_INIT(-1); + +static int rtsig_start = -1, rtsig_end = -1; + +int pa_rtsig_get(void) { + void *p; + int sig; + + if ((p = pa_flist_pop(PA_STATIC_FLIST_GET(rtsig_flist)))) + return PA_PTR_TO_INT(p); + + sig = pa_atomic_inc(&rtsig_current); + + pa_assert(sig >= SIGRTMIN); + pa_assert(sig >= rtsig_start); + + if (sig > rtsig_end) { + pa_atomic_dec(&rtsig_current); + return -1; + } + + return sig; +} + +int pa_rtsig_get_for_thread(void) { + int sig; + void *p; + + if ((p = pa_tls_get(PA_STATIC_TLS_GET(rtsig_tls)))) + return PA_PTR_TO_INT(p); + + if ((sig = pa_rtsig_get()) < 0) + return -1; + + pa_tls_set(PA_STATIC_TLS_GET(rtsig_tls), PA_INT_TO_PTR(sig)); + return sig; +} + +void pa_rtsig_put(int sig) { + pa_assert(sig >= rtsig_start); + pa_assert(sig <= rtsig_end); + + pa_assert_se(pa_flist_push(PA_STATIC_FLIST_GET(rtsig_flist), PA_INT_TO_PTR(sig)) >= 0); +} + +void pa_rtsig_configure(int start, int end) { + int s; + sigset_t ss; + + pa_assert(pa_atomic_load(&rtsig_current) == -1); + + pa_assert(SIGRTMIN <= start); + pa_assert(start <= end); + pa_assert(end <= SIGRTMAX); + + rtsig_start = start; + rtsig_end = end; + + sigemptyset(&ss); + + for (s = rtsig_start; s <= rtsig_end; s++) + pa_assert_se(sigaddset(&ss, s) == 0); + + pa_assert(pthread_sigmask(SIG_BLOCK, &ss, NULL) == 0); + + pa_atomic_store(&rtsig_current, rtsig_start); +} diff --git a/src/pulsecore/rtsig.h b/src/pulsecore/rtsig.h new file mode 100644 index 00000000..48f5f050 --- /dev/null +++ b/src/pulsecore/rtsig.h @@ -0,0 +1,44 @@ +#ifndef foopulsertsighfoo +#define foopulsertsighfoo + +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include +#include + +/* Return the next unused POSIX Realtime signals */ +int pa_rtsig_get(void); + +/* If not called before in the current thread, return the next unused + * rtsig, and install it in a TLS region and give it up automatically + * when the thread shuts down */ +int pa_rtsig_get_for_thread(void); + +/* Give an rtsig back. */ +void pa_rtsig_put(int sig); + +/* Block all RT signals */ +void pa_rtsig_configure(int start, int end); + +#endif -- cgit From 78c362c5d92cf56c3e7d87f4fdc2dca84af2f224 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 00:24:12 +0000 Subject: add new realtime event loop abstraction which precise time keeping by using hrtimers on Linux, if they are available git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1689 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/rtpoll.c | 454 +++++++++++++++++++++++++++++++++++++++++++++++++ src/pulsecore/rtpoll.h | 71 ++++++++ 2 files changed, 525 insertions(+) create mode 100644 src/pulsecore/rtpoll.c create mode 100644 src/pulsecore/rtpoll.h diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c new file mode 100644 index 00000000..36549b5e --- /dev/null +++ b/src/pulsecore/rtpoll.c @@ -0,0 +1,454 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "rtpoll.h" + +struct pa_rtpoll { + + struct pollfd *pollfd, *pollfd2; + unsigned n_pollfd_alloc, n_pollfd_used; + + pa_usec_t interval; + + int scan_for_dead; + int running, installed, rebuild_needed; + +#ifdef HAVE_PPOLL + int rtsig; + sigset_t sigset_unblocked; + struct timespec interval_timespec; + timer_t timer; +#ifdef __linux__ + int dont_use_ppoll; +#endif +#endif + + PA_LLIST_HEAD(pa_rtpoll_item, items); +}; + +struct pa_rtpoll_item { + pa_rtpoll *rtpoll; + int dead; + + struct pollfd *pollfd; + unsigned n_pollfd; + + int (*before_cb)(pa_rtpoll_item *i); + void (*after_cb)(pa_rtpoll_item *i); + void *userdata; + + PA_LLIST_FIELDS(pa_rtpoll_item); +}; + +PA_STATIC_FLIST_DECLARE(items, 0, pa_xfree); + +static void signal_handler_noop(int s) { } + +pa_rtpoll *pa_rtpoll_new(void) { + pa_rtpoll *p; + + p = pa_xnew(pa_rtpoll, 1); + +#ifdef HAVE_PPOLL + +#ifdef __linux__ + /* ppoll is broken on Linux < 2.6.16 */ + + p->dont_use_ppoll = 0; + + { + struct utsname u; + unsigned major, minor, micro; + + pa_assert_se(uname(&u) == 0); + + if (sscanf(u.release, "%u.%u.%u", &major, &minor, µ) != 3 || + (major < 2) || + (major == 2 && minor < 6) || + (major == 2 && minor == 6 && micro < 16)) + + p->dont_use_ppoll = 1; + } + +#endif + + p->rtsig = -1; + sigemptyset(&p->sigset_unblocked); + memset(&p->interval_timespec, 0, sizeof(p->interval_timespec)); + p->timer = (timer_t) -1; + +#endif + + p->n_pollfd_alloc = 32; + p->pollfd = pa_xnew(struct pollfd, p->n_pollfd_alloc); + p->pollfd2 = pa_xnew(struct pollfd, p->n_pollfd_alloc); + p->n_pollfd_used = 0; + + p->interval = 0; + + p->running = 0; + p->installed = 0; + p->scan_for_dead = 0; + p->rebuild_needed = 0; + + PA_LLIST_HEAD_INIT(pa_rtpoll_item, p->items); + + return p; +} + +void pa_rtpoll_install(pa_rtpoll *p) { + pa_assert(p); + pa_assert(!p->installed); + + p->installed = 1; + +#ifdef HAVE_PPOLL + if (p->dont_use_ppoll) + return; + + if ((p->rtsig = pa_rtsig_get_for_thread()) < 0) { + pa_log_warn("Failed to reserve POSIX realtime signal."); + return; + } + + pa_log_debug("Acquired POSIX realtime signal SIGRTMIN+%i", p->rtsig - SIGRTMIN); + + { + sigset_t ss; + struct sigaction sa; + + pa_assert_se(sigemptyset(&ss) == 0); + pa_assert_se(sigaddset(&ss, p->rtsig) == 0); + pa_assert_se(pthread_sigmask(SIG_BLOCK, &ss, &p->sigset_unblocked) == 0); + pa_assert_se(sigdelset(&p->sigset_unblocked, p->rtsig) == 0); + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = signal_handler_noop; + pa_assert_se(sigemptyset(&sa.sa_mask) == 0); + + pa_assert_se(sigaction(p->rtsig, &sa, NULL) == 0); + + /* We never reset the signal handler. Why should we? */ + } + +#endif +} + +static void rtpoll_rebuild(pa_rtpoll *p) { + + struct pollfd *e, *t; + pa_rtpoll_item *i; + int ra = 0; + + pa_assert(p); + + p->rebuild_needed = 0; + + if (p->n_pollfd_used > p->n_pollfd_alloc) { + /* Hmm, we have to allocate some more space */ + p->n_pollfd_alloc = p->n_pollfd_used * 2; + p->pollfd2 = pa_xrealloc(p->pollfd2, p->n_pollfd_alloc * sizeof(struct pollfd)); + ra = 1; + } + + e = p->pollfd2; + + for (i = p->items; i; i = i->next) { + + if (i->n_pollfd > 0) { + size_t l = i->n_pollfd * sizeof(struct pollfd); + + if (i->pollfd) + memcpy(e, i->pollfd, l); + else + memset(e, 0, l); + + i->pollfd = e; + } else + i->pollfd = NULL; + + e += i->n_pollfd; + } + + pa_assert((unsigned) (e - p->pollfd2) == p->n_pollfd_used); + t = p->pollfd; + p->pollfd = p->pollfd2; + p->pollfd2 = t; + + if (ra) + p->pollfd2 = pa_xrealloc(p->pollfd2, p->n_pollfd_alloc * sizeof(struct pollfd)); + +} + +static void rtpoll_item_destroy(pa_rtpoll_item *i) { + pa_rtpoll *p; + + pa_assert(i); + + p = i->rtpoll; + + PA_LLIST_REMOVE(pa_rtpoll_item, p->items, i); + + p->n_pollfd_used -= i->n_pollfd; + + if (pa_flist_push(PA_STATIC_FLIST_GET(items), i) < 0) + pa_xfree(i); + + p->rebuild_needed = 1; +} + +void pa_rtpoll_free(pa_rtpoll *p) { + pa_assert(p); + + pa_assert(!p->items); + pa_xfree(p->pollfd); + pa_xfree(p->pollfd2); + +#ifdef HAVE_PPOLL + if (p->timer != (timer_t) -1) + timer_delete(p->timer); +#endif + + pa_xfree(p); +} + +int pa_rtpoll_run(pa_rtpoll *p) { + pa_rtpoll_item *i; + int r = 0; + + pa_assert(p); + pa_assert(!p->running); + pa_assert(p->installed); + + p->running = 1; + + for (i = p->items; i; i = i->next) { + + if (i->dead) + continue; + + if (!i->before_cb) + continue; + + if (i->before_cb(i) < 0) { + + /* Hmm, this one doesn't let us enter the poll, so rewind everything */ + + for (i = i->prev; i; i = i->prev) { + + if (i->dead) + continue; + + if (!i->after_cb) + continue; + + i->after_cb(i); + } + + goto finish; + } + } + + if (p->rebuild_needed) + rtpoll_rebuild(p); + + /* OK, now let's sleep */ +#ifdef HAVE_PPOLL + +#ifdef __linux__ + if (!p->dont_use_ppoll) +#endif + r = ppoll(p->pollfd, p->n_pollfd_used, p->interval > 0 ? &p->interval_timespec : NULL, p->rtsig < 0 ? NULL : &p->sigset_unblocked); +#ifdef __linux__ + else +#endif + +#else + r = poll(p->pollfd, p->n_pollfd_used, p->interval > 0 ? p->interval / 1000 : -1); +#endif + + if (r < 0 && (errno == EAGAIN || errno == EINTR)) + r = 0; + + for (i = p->items; i; i = i->next) { + + if (i->dead) + continue; + + if (!i->after_cb) + continue; + + i->after_cb(i); + } + +finish: + + p->running = 0; + + if (p->scan_for_dead) { + pa_rtpoll_item *n; + + p->scan_for_dead = 0; + + for (i = p->items; i; i = n) { + n = i->next; + + if (i->dead) + rtpoll_item_destroy(i); + } + } + + return r; +} + +void pa_rtpoll_set_itimer(pa_rtpoll *p, pa_usec_t usec) { + pa_assert(p); + + p->interval = usec; + +#ifdef HAVE_PPOLL + pa_timespec_store(&p->interval_timespec, usec); + +#ifdef __linux__ + if (!p->dont_use_ppoll) { +#endif + + if (p->timer == (timer_t) -1) { + struct sigevent se; + + memset(&se, 0, sizeof(se)); + se.sigev_notify = SIGEV_SIGNAL; + se.sigev_signo = p->rtsig; + + if (timer_create(CLOCK_MONOTONIC, &se, &p->timer) < 0) + if (timer_create(CLOCK_REALTIME, &se, &p->timer) < 0) { + pa_log_warn("Failed to allocate POSIX timer: %s", pa_cstrerror(errno)); + p->timer = (timer_t) -1; + } + } + + if (p->timer != (timer_t) -1) { + struct itimerspec its; + + memset(&its, 0, sizeof(its)); + pa_timespec_store(&its.it_value, usec); + pa_timespec_store(&its.it_interval, usec); + + assert(timer_settime(p->timer, 0, &its, NULL) == 0); + } + +#ifdef __linux__ + } +#endif + +#endif +} + +pa_rtpoll_item *pa_rtpoll_item_new(pa_rtpoll *p, unsigned n_fds) { + pa_rtpoll_item *i; + + pa_assert(p); + pa_assert(n_fds > 0); + + if (!(i = pa_flist_pop(PA_STATIC_FLIST_GET(items)))) + i = pa_xnew(pa_rtpoll_item, 1); + + i->rtpoll = p; + i->dead = 0; + i->n_pollfd = n_fds; + i->pollfd = NULL; + + i->userdata = NULL; + i->before_cb = NULL; + i->after_cb = NULL; + + PA_LLIST_PREPEND(pa_rtpoll_item, p->items, i); + + p->rebuild_needed = 1; + p->n_pollfd_used += n_fds; + + return i; +} + +void pa_rtpoll_item_free(pa_rtpoll_item *i) { + pa_assert(i); + + if (i->rtpoll->running) { + i->dead = 1; + i->rtpoll->scan_for_dead = 1; + return; + } + + rtpoll_item_destroy(i); +} + +struct pollfd *pa_rtpoll_item_get_pollfd(pa_rtpoll_item *i, unsigned *n_fds) { + pa_assert(i); + + if (i->rtpoll->rebuild_needed) + rtpoll_rebuild(i->rtpoll); + + if (n_fds) + *n_fds = i->n_pollfd; + + return i->pollfd; +} + +void pa_rtpoll_item_set_before_callback(pa_rtpoll_item *i, int (*before_cb)(pa_rtpoll_item *i)) { + pa_assert(i); + + i->before_cb = before_cb; +} + +void pa_rtpoll_item_set_after_callback(pa_rtpoll_item *i, void (*after_cb)(pa_rtpoll_item *i)) { + pa_assert(i); + + i->after_cb = after_cb; +} + +void pa_rtpoll_item_set_userdata(pa_rtpoll_item *i, void *userdata) { + pa_assert(i); + + i->userdata = userdata; +} diff --git a/src/pulsecore/rtpoll.h b/src/pulsecore/rtpoll.h new file mode 100644 index 00000000..5e508e1b --- /dev/null +++ b/src/pulsecore/rtpoll.h @@ -0,0 +1,71 @@ +#ifndef foopulsertpollhfoo +#define foopulsertpollhfoo + +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include +#include + +#include + +/* An implementation of a "real-time" poll loop. Basically, this is + * yet another wrapper around poll(). However it has certain + * advantages over pa_mainloop and suchlike: + * + * 1) It uses timer_create() and POSIX real time signals to guarantee + * optimal high-resolution timing. Starting with Linux 2.6.21 hrtimers + * are available, and since right now only nanosleep() and the POSIX + * clock and timer interfaces have been ported to hrtimers (and not + * ppoll/pselect!) we have to combine ppoll() with timer_create(). The + * fact that POSIX timers and POSIX rt signals are used internally is + * completely hidden. + * + * 2) It allows raw access to the pollfd data to users + * + * 3) It allows arbitrary functions to be run before entering the + * actual poll() and after it. + * + * Only a single interval timer is supported..*/ + +typedef struct pa_rtpoll pa_rtpoll; +typedef struct pa_rtpoll_item pa_rtpoll_item; + +pa_rtpoll *pa_rtpoll_new(void); +void pa_rtpoll_free(pa_rtpoll *p); + +void pa_rtpoll_install(pa_rtpoll *p); + +int pa_rtpoll_run(pa_rtpoll *f); +void pa_rtpoll_set_itimer(pa_rtpoll *p, pa_usec_t usec); + +pa_rtpoll_item *pa_rtpoll_item_new(pa_rtpoll *p, unsigned n_fds); +void pa_rtpoll_item_free(pa_rtpoll_item *i); + +struct pollfd *pa_rtpoll_item_get_pollfd(pa_rtpoll_item *i, unsigned *n_fds); + +void pa_rtpoll_item_set_before_callback(pa_rtpoll_item *i, int (*before_cb)(pa_rtpoll_item *i)); +void pa_rtpoll_item_set_after_callback(pa_rtpoll_item *i, void (*after_cb)(pa_rtpoll_item *i)); +void pa_rtpoll_item_set_userdata(pa_rtpoll_item *i, void *userdata); + +#endif -- cgit From dc9d80326e29d20d42fbfc6055963c66c378b596 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 00:24:31 +0000 Subject: add test program for pa_rtpoll git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1690 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/tests/rtpoll-test.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/tests/rtpoll-test.c diff --git a/src/tests/rtpoll-test.c b/src/tests/rtpoll-test.c new file mode 100644 index 00000000..29f2e923 --- /dev/null +++ b/src/tests/rtpoll-test.c @@ -0,0 +1,80 @@ +/* $Id: thread-test.c 1621 2007-08-10 22:00:22Z lennart $ */ + +/*** + This file is part of PulseAudio. + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include +#include + +static int before(pa_rtpoll_item *i) { + pa_log("before"); + return 0; +} + +static void after(pa_rtpoll_item *i) { + pa_log("after"); +} + +int main(int argc, char *argv[]) { + pa_rtpoll *p; + pa_rtpoll_item *i; + struct pollfd *pollfd; + + pa_rtsig_configure(SIGRTMIN+10, SIGRTMAX); + + p = pa_rtpoll_new(); + + i = pa_rtpoll_item_new(p, 1); + pa_rtpoll_item_set_before_callback(i, before); + pa_rtpoll_item_set_after_callback(i, after); + + pollfd = pa_rtpoll_item_get_pollfd(i, NULL); + pollfd->fd = 0; + pollfd->events = POLLIN; + + pa_rtpoll_install(p); + pa_rtpoll_set_itimer(p, 10000000); /* 10 s */ + + pa_rtpoll_run(p); + + pa_rtpoll_item_free(i); + + i = pa_rtpoll_item_new(p, 1); + pa_rtpoll_item_set_before_callback(i, before); + pa_rtpoll_item_set_after_callback(i, after); + + pollfd = pa_rtpoll_item_get_pollfd(i, NULL); + pollfd->fd = 0; + pollfd->events = POLLIN; + + pa_rtpoll_run(p); + + pa_rtpoll_item_free(i); + + pa_rtpoll_free(p); + + return 0; +} -- cgit From 8568f7038cc855b98d0959c60efe7acb912b4e77 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 00:25:03 +0000 Subject: add rtpoll, rtclock, rtsig to Makefile git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1691 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index a711de29..9b843a4a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -238,7 +238,8 @@ noinst_PROGRAMS = \ flist-test \ asyncq-test \ asyncmsgq-test \ - queue-test + queue-test \ + rtpoll-test if HAVE_SIGXCPU noinst_PROGRAMS += \ @@ -313,6 +314,11 @@ queue_test_CFLAGS = $(AM_CFLAGS) queue_test_LDADD = $(AM_LDADD) libpulsecore.la queue_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) +rtpoll_test_SOURCES = tests/rtpoll-test.c +rtpoll_test_CFLAGS = $(AM_CFLAGS) +rtpoll_test_LDADD = $(AM_LDADD) libpulsecore.la +rtpoll_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + mcalign_test_SOURCES = tests/mcalign-test.c mcalign_test_CFLAGS = $(AM_CFLAGS) mcalign_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecore.la @@ -680,6 +686,9 @@ libpulsecore_la_SOURCES += \ pulsecore/fdsem.c pulsecore/fdsem.h \ pulsecore/object.c pulsecore/object.h \ pulsecore/msgobject.c pulsecore/msgobject.h \ + pulsecore/rtsig.c pulsecore/rtsog.h \ + pulsecore/rtpoll.c pulsecore/rtpoll.h \ + pulsecore/rtclock.c pulsecore/rtclock.h \ pulsecore/macro.h \ $(PA_THREAD_OBJS) -- cgit From 35461981c68ce656b194faf30d892fa35a9ed9b7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 00:25:29 +0000 Subject: add check for ppoll() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1692 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index b037b898..d9983309 100644 --- a/configure.ac +++ b/configure.ac @@ -255,7 +255,7 @@ AC_CHECK_FUNCS([lstat]) # Non-standard -AC_CHECK_FUNCS([setresuid setresgid setreuid setregid seteuid setegid]) +AC_CHECK_FUNCS([setresuid setresgid setreuid setregid seteuid setegid ppoll]) #### POSIX threads #### -- cgit From b3029464a4cc0348649beeeea76e459b384addd5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 00:26:43 +0000 Subject: add new option to pa_core stating whether we are running as high prio process git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1693 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core.c | 5 +++-- src/pulsecore/core.h | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c index 2e9d96b1..7ca2e753 100644 --- a/src/pulsecore/core.c +++ b/src/pulsecore/core.c @@ -127,8 +127,6 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { c->mempool = pool; - c->disallow_module_loading = 0; - c->quit_event = NULL; c->exit_idle_time = -1; @@ -138,6 +136,9 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { c->resample_method = PA_RESAMPLER_SRC_SINC_FASTEST; c->is_system_instance = 0; + c->disallow_module_loading = 0; + c->high_priority = 0; + for (j = 0; j < PA_CORE_HOOK_MAX; j++) pa_hook_init(&c->hooks[j], c); diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index 4d92960d..61cb47d5 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -101,16 +101,16 @@ struct pa_core { pa_mempool *mempool; - int disallow_module_loading, running_as_daemon; int exit_idle_time, module_idle_time, scache_idle_time; pa_time_event *quit_event; pa_time_event *scache_auto_unload_event; + int disallow_module_loading, running_as_daemon; pa_resample_method_t resample_method; - int is_system_instance; + int high_priority; /* hooks */ pa_hook hooks[PA_CORE_HOOK_MAX]; -- cgit From 7fca89034f9822c51c2ccea2fb3df126dbd12aea Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 00:27:25 +0000 Subject: check pa_core::high_priority before becoming rt thread git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1694 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 3 ++- src/modules/module-alsa-source.c | 3 ++- src/modules/module-oss.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index f1031b68..5546657b 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -527,7 +527,8 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); - pa_make_realtime(); + if (u->core->high_priority) + pa_make_realtime(); pa_thread_mq_install(&u->thread_mq); diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index a1de2f2e..58e7cb4a 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -516,7 +516,8 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); - pa_make_realtime(); + if (u->core->high_priority) + pa_make_realtime(); pa_thread_mq_install(&u->thread_mq); diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 346ccbd5..f4454813 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -791,7 +791,8 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); - pa_make_realtime(); + if (u->core->high_priority) + pa_make_realtime(); pa_thread_mq_install(&u->thread_mq); -- cgit -- cgit From 0da65cf3df16b6e9249be40beb0e2ac94cd7f00c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 00:29:15 +0000 Subject: add message about hrtimers, and initialize pa_core::high_priority git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1696 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/main.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/daemon/main.c b/src/daemon/main.c index cf2e628b..76adb104 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -78,6 +78,7 @@ #include #include #include +#include #include "cmdline.h" #include "cpulimit.h" @@ -395,7 +396,7 @@ int main(int argc, char *argv[]) { if (conf->high_priority && conf->cmd == PA_CMD_DAEMON) pa_raise_priority(); - if (suid_root && conf->cmd != PA_CMD_DAEMON) { + if (suid_root && (conf->cmd != PA_CMD_DAEMON || !conf->high_priority)) { pa_drop_caps(); pa_drop_root(); } @@ -543,7 +544,7 @@ int main(int argc, char *argv[]) { #endif } - chdir("/"); + pa_assert(chdir("/") == 0); umask(0022); if (conf->system_instance) { @@ -573,21 +574,28 @@ int main(int argc, char *argv[]) { signal(SIGPIPE, SIG_IGN); #endif + if (!pa_rtclock_hrtimer()) + pa_log_debug("Fresh high-resolution timers available! Bon appetit!"); + else + pa_log_info("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"); + + pa_rtsig_configure(SIGRTMIN+10, SIGRTMAX); + mainloop = pa_mainloop_new(); assert(mainloop); if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm))) { - pa_log("pa_core_new() failed."); + pa_log("pa_core_new() failed."); goto finish; } c->is_system_instance = !!conf->system_instance; + c->high_priority = !!conf->high_priority; c->default_sample_spec = conf->default_sample_spec; c->default_n_fragments = conf->default_n_fragments; c->default_fragment_size_msec = conf->default_fragment_size_msec; - r = pa_signal_init(pa_mainloop_get_api(mainloop)); - assert(r == 0); + pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0); pa_signal_new(SIGINT, signal_callback, c); pa_signal_new(SIGTERM, signal_callback, c); -- cgit From 190648a3ed1267896083a24dbb27d7552104ca00 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 17:05:07 +0000 Subject: add missing #include git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1697 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/flist.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pulsecore/flist.c b/src/pulsecore/flist.c index b0f3228f..ada0d571 100644 --- a/src/pulsecore/flist.c +++ b/src/pulsecore/flist.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "flist.h" -- cgit From 044996685258c69e120de7198b3cfbb96faa50ba Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 17:05:41 +0000 Subject: make pa_make_power_of_two() and pa_is_power_of_two() inline functions git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1698 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core-util.c | 18 ------------------ src/pulsecore/core-util.h | 19 +++++++++++++++++-- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 0005e220..2c5a32e9 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -1208,21 +1208,3 @@ char *pa_truncate_utf8(char *c, size_t l) { return c; } - -int pa_is_power_of_two(unsigned n) { - return !(n & (n - 1)); -} - -unsigned pa_make_power_of_two(unsigned n) { - unsigned j = n; - - if (pa_is_power_of_two(n)) - return n; - - while (j) { - j = j >> 1; - n = n | j; - } - - return n + 1; -} diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index 29dc2fb1..ea571e70 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -97,7 +97,22 @@ int pa_snprintf(char *str, size_t size, const char *format, ...); char *pa_truncate_utf8(char *c, size_t l); -int pa_is_power_of_two(unsigned n); -unsigned pa_make_power_of_two(unsigned n); +static inline int pa_is_power_of_two(unsigned n) { + return !(n & (n - 1)); +} + +static inline unsigned pa_make_power_of_two(unsigned n) { + unsigned j = n; + + if (pa_is_power_of_two(n)) + return n; + + while (j) { + j = j >> 1; + n = n | j; + } + + return n + 1; +} #endif -- cgit From 7490977a84bf9b451bfee406b1e3f7925b669afa Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 17:06:04 +0000 Subject: add missing include git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1699 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/rtsig.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pulsecore/rtsig.c b/src/pulsecore/rtsig.c index 1b8cdaa3..a3226a0e 100644 --- a/src/pulsecore/rtsig.c +++ b/src/pulsecore/rtsig.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "rtsig.h" -- cgit From b937009bcd4f4bb6e6f012c90d27ac667592588a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 17:11:26 +0000 Subject: add convenience functions to hook up pa_fdsem and pa_asyncmsgq to an pa_rtpoll; add pa_rtpoll_item_get_userdata(), on EINTR/EAGAIN, reset revents; automatically destory left over items git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1700 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/rtpoll.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/pulsecore/rtpoll.h | 7 ++++ 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c index 36549b5e..4f39c68c 100644 --- a/src/pulsecore/rtpoll.c +++ b/src/pulsecore/rtpoll.c @@ -241,7 +241,9 @@ static void rtpoll_item_destroy(pa_rtpoll_item *i) { void pa_rtpoll_free(pa_rtpoll *p) { pa_assert(p); - pa_assert(!p->items); + while (p->items) + rtpoll_item_destroy(p->items); + pa_xfree(p->pollfd); pa_xfree(p->pollfd2); @@ -256,6 +258,8 @@ void pa_rtpoll_free(pa_rtpoll *p) { int pa_rtpoll_run(pa_rtpoll *p) { pa_rtpoll_item *i; int r = 0; + int no_events = 0; + int saved_errno; pa_assert(p); pa_assert(!p->running); @@ -308,8 +312,12 @@ int pa_rtpoll_run(pa_rtpoll *p) { r = poll(p->pollfd, p->n_pollfd_used, p->interval > 0 ? p->interval / 1000 : -1); #endif - if (r < 0 && (errno == EAGAIN || errno == EINTR)) + saved_errno = errno; + + if (r < 0 && (errno == EAGAIN || errno == EINTR)) { r = 0; + no_events = 1; + } for (i = p->items; i; i = i->next) { @@ -319,6 +327,13 @@ int pa_rtpoll_run(pa_rtpoll *p) { if (!i->after_cb) continue; + if (no_events) { + unsigned j; + + for (j = 0; j < i->n_pollfd; j++) + i->pollfd[j].revents = 0; + } + i->after_cb(i); } @@ -339,6 +354,8 @@ finish: } } + errno = saved_errno; + return r; } @@ -452,3 +469,68 @@ void pa_rtpoll_item_set_userdata(pa_rtpoll_item *i, void *userdata) { i->userdata = userdata; } + +void* pa_rtpoll_item_get_userdata(pa_rtpoll_item *i) { + pa_assert(i); + + return i->userdata; +} + +static int fdsem_before(pa_rtpoll_item *i) { + return pa_fdsem_before_poll(i->userdata); +} + +static void fdsem_after(pa_rtpoll_item *i) { + pa_assert((i->pollfd[0].revents & ~POLLIN) == 0); + pa_fdsem_after_poll(i->userdata); +} + +pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_fdsem *f) { + pa_rtpoll_item *i; + struct pollfd *pollfd; + + pa_assert(p); + pa_assert(f); + + i = pa_rtpoll_item_new(p, 1); + + pollfd = pa_rtpoll_item_get_pollfd(i, NULL); + + pollfd->fd = pa_fdsem_get(f); + pollfd->events = POLLIN; + + i->before_cb = fdsem_before; + i->after_cb = fdsem_after; + i->userdata = f; + + return i; +} + +static int asyncmsgq_before(pa_rtpoll_item *i) { + return pa_asyncmsgq_before_poll(i->userdata); +} + +static void asyncmsgq_after(pa_rtpoll_item *i) { + pa_assert((i->pollfd[0].revents & ~POLLIN) == 0); + pa_asyncmsgq_after_poll(i->userdata); +} + +pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq(pa_rtpoll *p, pa_asyncmsgq *q) { + pa_rtpoll_item *i; + struct pollfd *pollfd; + + pa_assert(p); + pa_assert(q); + + i = pa_rtpoll_item_new(p, 1); + + pollfd = pa_rtpoll_item_get_pollfd(i, NULL); + pollfd->fd = pa_asyncmsgq_get_fd(q); + pollfd->events = POLLIN; + + i->before_cb = asyncmsgq_before; + i->after_cb = asyncmsgq_after; + i->userdata = q; + + return i; +} diff --git a/src/pulsecore/rtpoll.h b/src/pulsecore/rtpoll.h index 5e508e1b..bed3ae3c 100644 --- a/src/pulsecore/rtpoll.h +++ b/src/pulsecore/rtpoll.h @@ -28,6 +28,8 @@ #include #include +#include +#include /* An implementation of a "real-time" poll loop. Basically, this is * yet another wrapper around poll(). However it has certain @@ -67,5 +69,10 @@ struct pollfd *pa_rtpoll_item_get_pollfd(pa_rtpoll_item *i, unsigned *n_fds); void pa_rtpoll_item_set_before_callback(pa_rtpoll_item *i, int (*before_cb)(pa_rtpoll_item *i)); void pa_rtpoll_item_set_after_callback(pa_rtpoll_item *i, void (*after_cb)(pa_rtpoll_item *i)); void pa_rtpoll_item_set_userdata(pa_rtpoll_item *i, void *userdata); +void* pa_rtpoll_item_get_userdata(pa_rtpoll_item *i); + +pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_fdsem *s); +pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq(pa_rtpoll *p, pa_asyncmsgq *q); + #endif -- cgit From 79d3dddecdb979e8275dc15b015075a8f6037095 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 17:11:54 +0000 Subject: reverse hrtimer check, add missing #include git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1701 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/daemon/main.c b/src/daemon/main.c index 76adb104..15d35925 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -79,6 +79,7 @@ #include #include #include +#include #include "cmdline.h" #include "cpulimit.h" @@ -574,7 +575,7 @@ int main(int argc, char *argv[]) { signal(SIGPIPE, SIG_IGN); #endif - if (!pa_rtclock_hrtimer()) + if (pa_rtclock_hrtimer()) pa_log_debug("Fresh high-resolution timers available! Bon appetit!"); else pa_log_info("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"); -- cgit From 53b872c07067a606515d5946b709d02657337086 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 17:13:07 +0000 Subject: port alsa driver to make use of new pa_rtpoll object git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1702 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 282 +++++++++++++++++++++-------------------- 1 file changed, 142 insertions(+), 140 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 5546657b..3e521482 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -51,6 +51,7 @@ #include #include #include +#include #include "alsa-util.h" #include "module-alsa-sink-symdef.h" @@ -75,8 +76,10 @@ struct userdata { pa_core *core; pa_module *module; pa_sink *sink; + pa_thread *thread; pa_thread_mq thread_mq; + pa_rtpoll *rtpoll; snd_pcm_t *pcm_handle; @@ -95,13 +98,7 @@ struct userdata { int first; - struct pollfd *pollfd; - int n_alsa_fds; -}; - -enum { - POLLFD_ASYNCQ, - POLLFD_ALSA_BASE + pa_rtpoll_item *alsa_rtpoll_item; }; static const char* const valid_modargs[] = { @@ -118,18 +115,18 @@ static const char* const valid_modargs[] = { }; static int mmap_write(struct userdata *u) { - snd_pcm_sframes_t n; - int err; - const snd_pcm_channel_area_t *areas; - snd_pcm_uframes_t offset, frames; int work_done = 0; pa_assert(u); - pa_assert(u->sink); + pa_sink_assert_ref(u->sink); for (;;) { pa_memchunk chunk; void *p; + snd_pcm_sframes_t n; + int err; + const snd_pcm_channel_area_t *areas; + snd_pcm_uframes_t offset, frames; if ((n = snd_pcm_avail_update(u->pcm_handle)) < 0) { @@ -211,10 +208,85 @@ static int mmap_write(struct userdata *u) { work_done = 1; + if (frames >= (snd_pcm_uframes_t) n) + return work_done; + /* pa_log("wrote %i samples", (int) frames); */ } } +static int unix_write(struct userdata *u) { + snd_pcm_status_t *status; + int work_done = 0; + + snd_pcm_status_alloca(&status); + + pa_assert(u); + pa_sink_assert_ref(u->sink); + + for (;;) { + void *p; + snd_pcm_sframes_t t; + ssize_t l; + int err; + + if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) { + pa_log("Failed to query DSP status data: %s", snd_strerror(t)); + return -1; + } + + if (snd_pcm_status_get_avail_max(status)*u->frame_size >= u->hwbuf_size) + pa_log_debug("Buffer underrun!"); + + l = snd_pcm_status_get_avail(status) * u->frame_size; + +/* pa_log("%u bytes to write", l); */ + + if (l <= 0) + return work_done; + + if (u->memchunk.length <= 0) + pa_sink_render(u->sink, l, &u->memchunk); + + pa_assert(u->memchunk.length > 0); + + p = pa_memblock_acquire(u->memchunk.memblock); + t = snd_pcm_writei(u->pcm_handle, (const uint8_t*) p + u->memchunk.index, u->memchunk.length / u->frame_size); + pa_memblock_release(u->memchunk.memblock); + +/* pa_log("wrote %i bytes of %u (%u)", t*u->frame_size, u->memchunk.length, l); */ + + pa_assert(t != 0); + + if (t < 0) { + + if ((t = snd_pcm_recover(u->pcm_handle, t, 1)) == 0) + continue; + + if (t == -EAGAIN) { + pa_log_debug("EAGAIN"); + return work_done; + } else { + pa_log("Failed to write data to DSP: %s", snd_strerror(t)); + return -1; + } + } + + u->memchunk.index += t * u->frame_size; + u->memchunk.length -= t * u->frame_size; + + if (u->memchunk.length <= 0) { + pa_memblock_unref(u->memchunk.memblock); + pa_memchunk_reset(&u->memchunk); + } + + work_done = 1; + + if (t * u->frame_size >= (unsigned) l) + return work_done; + } +} + static pa_usec_t sink_get_latency(struct userdata *u) { pa_usec_t r = 0; snd_pcm_status_t *status; @@ -224,6 +296,7 @@ static pa_usec_t sink_get_latency(struct userdata *u) { snd_pcm_status_alloca(&status); pa_assert(u); + pa_assert(u->pcm_handle); if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) pa_log("Failed to get delay: %s", snd_strerror(err)); @@ -241,22 +314,24 @@ static pa_usec_t sink_get_latency(struct userdata *u) { static int build_pollfd(struct userdata *u) { int err; + struct pollfd *pollfd; + int n; pa_assert(u); pa_assert(u->pcm_handle); - if ((u->n_alsa_fds = snd_pcm_poll_descriptors_count(u->pcm_handle)) < 0) { - pa_log("snd_pcm_poll_descriptors_count() failed: %s", snd_strerror(u->n_alsa_fds)); + if ((n = snd_pcm_poll_descriptors_count(u->pcm_handle)) < 0) { + pa_log("snd_pcm_poll_descriptors_count() failed: %s", snd_strerror(n)); return -1; } - pa_xfree(u->pollfd); - u->pollfd = pa_xnew0(struct pollfd, POLLFD_ALSA_BASE + u->n_alsa_fds); + if (u->alsa_rtpoll_item) + pa_rtpoll_item_free(u->alsa_rtpoll_item); - u->pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->thread_mq.inq); - u->pollfd[POLLFD_ASYNCQ].events = POLLIN; + u->alsa_rtpoll_item = pa_rtpoll_item_new(u->rtpoll, n); + pollfd = pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, NULL); - if ((err = snd_pcm_poll_descriptors(u->pcm_handle, u->pollfd+POLLFD_ALSA_BASE, u->n_alsa_fds)) < 0) { + if ((err = snd_pcm_poll_descriptors(u->pcm_handle, pollfd, n)) < 0) { pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err)); return -1; } @@ -272,6 +347,11 @@ static int suspend(struct userdata *u) { snd_pcm_close(u->pcm_handle); u->pcm_handle = NULL; + if (u->alsa_rtpoll_item) { + pa_rtpoll_item_free(u->alsa_rtpoll_item); + u->alsa_rtpoll_item = NULL; + } + pa_log_debug("Device suspended..."); return 0; @@ -516,14 +596,9 @@ static int sink_set_mute_cb(pa_sink *s) { } static void thread_func(void *userdata) { - struct userdata *u = userdata; - unsigned short revents = 0; - snd_pcm_status_t *status; - int err; pa_assert(u); - snd_pcm_status_alloca(&status); pa_log_debug("Thread starting up"); @@ -531,6 +606,7 @@ static void thread_func(void *userdata) { pa_make_realtime(); pa_thread_mq_install(&u->thread_mq); + pa_rtpoll_install(u->rtpoll); if (build_pollfd(u) < 0) goto fail; @@ -541,142 +617,64 @@ static void thread_func(void *userdata) { void *data; pa_memchunk chunk; int64_t offset; - int r; /* pa_log("loop"); */ - /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { - int ret; - -/* pa_log("processing msg"); */ - - if (!object && code == PA_MESSAGE_SHUTDOWN) { - pa_asyncmsgq_done(u->thread_mq.inq, 0); - goto finish; - } - - ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); - pa_asyncmsgq_done(u->thread_mq.inq, ret); - continue; - } - -/* pa_log("loop2"); */ - /* Render some data and write it to the dsp */ - - if (PA_SINK_OPENED(u->sink->thread_info.state) && ((revents & POLLOUT) || u->first == 1)) { + if (PA_SINK_OPENED(u->sink->thread_info.state)) { int work_done = 0; + pa_assert(u->pcm_handle); if (u->use_mmap) { - if ((work_done = mmap_write(u)) < 0) goto fail; - } else { - - for (;;) { - void *p; - snd_pcm_sframes_t t; - ssize_t l; - - if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) { - pa_log("Failed to query DSP status data: %s", snd_strerror(t)); - goto fail; - } - - if (snd_pcm_status_get_avail_max(status)*u->frame_size >= u->hwbuf_size) - pa_log_debug("Buffer underrun!"); - - l = snd_pcm_status_get_avail(status) * u->frame_size; - -/* pa_log("%u bytes to write", l); */ - - if (l <= 0) - break; - - if (u->memchunk.length <= 0) - pa_sink_render(u->sink, l, &u->memchunk); - - pa_assert(u->memchunk.length > 0); - - p = pa_memblock_acquire(u->memchunk.memblock); - t = snd_pcm_writei(u->pcm_handle, (const uint8_t*) p + u->memchunk.index, u->memchunk.length / u->frame_size); - pa_memblock_release(u->memchunk.memblock); - -/* pa_log("wrote %i bytes of %u (%u)", t*u->frame_size, u->memchunk.length, l); */ - - pa_assert(t != 0); - - if (t < 0) { - - if ((t = snd_pcm_recover(u->pcm_handle, t, 1)) == 0) - continue; - - if (t == -EAGAIN) { - pa_log_debug("EAGAIN"); - break; - } else { - pa_log("Failed to write data to DSP: %s", snd_strerror(t)); - goto fail; - } - } - - u->memchunk.index += t * u->frame_size; - u->memchunk.length -= t * u->frame_size; - - if (u->memchunk.length <= 0) { - pa_memblock_unref(u->memchunk.memblock); - pa_memchunk_reset(&u->memchunk); - } - - work_done = 1; - - if (t * u->frame_size >= (unsigned) l) - break; - } + if ((work_done = unix_write(u)) < 0) + goto fail; } - revents &= ~POLLOUT; - - if (work_done) { - - if (u->first) { - pa_log_info("Starting playback."); - snd_pcm_start(u->pcm_handle); - u->first = 0; - } - + if (work_done && u->first) { + pa_log_info("Starting playback."); + snd_pcm_start(u->pcm_handle); + u->first = 0; continue; } } - /* Hmm, nothing to do. Let's sleep */ - if (pa_asyncmsgq_before_poll(u->thread_mq.inq) < 0) - continue; +/* pa_log("loop2"); */ -/* pa_log("polling for %i", POLLFD_ALSA_BASE + (PA_SINK_OPENED(u->sink->thread_info.state) ? u->n_alsa_fds : 0)); */ - r = poll(u->pollfd, POLLFD_ALSA_BASE + (PA_SINK_OPENED(u->sink->thread_info.state) ? u->n_alsa_fds : 0), -1); -/* pa_log("poll end"); */ + /* Check whether there is a message for us to process */ + if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { + int ret; - pa_asyncmsgq_after_poll(u->thread_mq.inq); +/* pa_log("processing msg"); */ - if (r < 0) { - if (errno == EINTR) { - u->pollfd[POLLFD_ASYNCQ].revents = 0; - revents = 0; - continue; + if (!object && code == PA_MESSAGE_SHUTDOWN) { + pa_asyncmsgq_done(u->thread_mq.inq, 0); + goto finish; } + ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); + pa_asyncmsgq_done(u->thread_mq.inq, ret); + continue; + } + + /* Hmm, nothing to do. Let's sleep */ + if (pa_rtpoll_run(u->rtpoll) < 0) { pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; } - pa_assert(r > 0); - if (PA_SINK_OPENED(u->sink->thread_info.state)) { - if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, u->pollfd + POLLFD_ALSA_BASE, u->n_alsa_fds, &revents)) < 0) { + struct pollfd *pollfd; + unsigned short revents = 0; + int err; + unsigned n; + + pollfd = pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, &n); + + if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, pollfd, n, &revents)) < 0) { pa_log("snd_pcm_poll_descriptors_revents() failed: %s", snd_strerror(err)); goto fail; } @@ -692,10 +690,8 @@ static void thread_func(void *userdata) { goto fail; } /* pa_log("got alsa event"); */ - } else - revents = 0; + } - pa_assert((u->pollfd[POLLFD_ASYNCQ].revents & ~POLLIN) == 0); } fail: @@ -764,9 +760,10 @@ int pa__init(pa_module*m) { m->userdata = u; u->use_mmap = use_mmap; u->first = 1; - u->n_alsa_fds = 0; - u->pollfd = NULL; pa_thread_mq_init(&u->thread_mq, m->core->mainloop); + u->rtpoll = pa_rtpoll_new(); + u->alsa_rtpoll_item = NULL; + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, u->thread_mq.inq); snd_config_update_free_global(); if ((err = snd_pcm_open(&u->pcm_handle, dev = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { @@ -943,13 +940,19 @@ void pa__done(pa_module*m) { } pa_thread_mq_done(&u->thread_mq); - + if (u->sink) pa_sink_unref(u->sink); if (u->memchunk.memblock) pa_memblock_unref(u->memchunk.memblock); + if (u->alsa_rtpoll_item) + pa_rtpoll_item_free(u->alsa_rtpoll_item); + + if (u->rtpoll) + pa_rtpoll_free(u->rtpoll); + if (u->mixer_fdl) pa_alsa_fdlist_free(u->mixer_fdl); @@ -961,7 +964,6 @@ void pa__done(pa_module*m) { snd_pcm_close(u->pcm_handle); } - pa_xfree(u->pollfd); pa_xfree(u->device_name); pa_xfree(u); -- cgit From 0ff2afd8a65517c6f0458dc936108bd64ad9afa1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 22:26:30 +0000 Subject: support absolute, relative and periodic timers in pa_rtpoll git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1703 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/rtpoll.c | 108 +++++++++++++++++++++++++++++++++++++++++------- src/pulsecore/rtpoll.h | 10 ++++- src/tests/rtpoll-test.c | 2 +- 3 files changed, 102 insertions(+), 18 deletions(-) diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c index 4f39c68c..0f09c7d0 100644 --- a/src/pulsecore/rtpoll.c +++ b/src/pulsecore/rtpoll.c @@ -49,7 +49,9 @@ struct pa_rtpoll { struct pollfd *pollfd, *pollfd2; unsigned n_pollfd_alloc, n_pollfd_used; - pa_usec_t interval; + int timer_enabled; + struct timespec next_elapse; + pa_usec_t period; int scan_for_dead; int running, installed, rebuild_needed; @@ -57,7 +59,6 @@ struct pa_rtpoll { #ifdef HAVE_PPOLL int rtsig; sigset_t sigset_unblocked; - struct timespec interval_timespec; timer_t timer; #ifdef __linux__ int dont_use_ppoll; @@ -115,7 +116,6 @@ pa_rtpoll *pa_rtpoll_new(void) { p->rtsig = -1; sigemptyset(&p->sigset_unblocked); - memset(&p->interval_timespec, 0, sizeof(p->interval_timespec)); p->timer = (timer_t) -1; #endif @@ -125,7 +125,9 @@ pa_rtpoll *pa_rtpoll_new(void) { p->pollfd2 = pa_xnew(struct pollfd, p->n_pollfd_alloc); p->n_pollfd_used = 0; - p->interval = 0; + p->period = 0; + memset(&p->next_elapse, 0, sizeof(p->next_elapse)); + p->timer_enabled = 0; p->running = 0; p->installed = 0; @@ -260,6 +262,7 @@ int pa_rtpoll_run(pa_rtpoll *p) { int r = 0; int no_events = 0; int saved_errno; + struct timespec timeout; pa_assert(p); pa_assert(!p->running); @@ -296,6 +299,17 @@ int pa_rtpoll_run(pa_rtpoll *p) { if (p->rebuild_needed) rtpoll_rebuild(p); + + /* Calculate timeout */ + if (p->timer_enabled) { + struct timespec now; + pa_rtclock_get(&now); + + if (pa_timespec_cmp(&p->next_elapse, &now) <= 0) + memset(&timeout, 0, sizeof(timeout)); + else + pa_timespec_store(&timeout, pa_timespec_diff(&p->next_elapse, &now)); + } /* OK, now let's sleep */ #ifdef HAVE_PPOLL @@ -303,18 +317,33 @@ int pa_rtpoll_run(pa_rtpoll *p) { #ifdef __linux__ if (!p->dont_use_ppoll) #endif - r = ppoll(p->pollfd, p->n_pollfd_used, p->interval > 0 ? &p->interval_timespec : NULL, p->rtsig < 0 ? NULL : &p->sigset_unblocked); + r = ppoll(p->pollfd, p->n_pollfd_used, p->timer_enabled > 0 ? &timeout : NULL, p->rtsig < 0 ? NULL : &p->sigset_unblocked); #ifdef __linux__ else #endif #else - r = poll(p->pollfd, p->n_pollfd_used, p->interval > 0 ? p->interval / 1000 : -1); + r = poll(p->pollfd, p->n_pollfd_used, p->timer_enabled > 0 ? (timeout.tv_sec*1000) + (timeout.tv_nsec / 1000000) : -1); #endif saved_errno = errno; + + if (p->timer_enabled) { + if (p->period > 0) { + struct timespec now; + pa_rtclock_get(&now); + + pa_timespec_add(&p->next_elapse, p->period); + + /* Guarantee that the next timeout will happen in the future */ + if (pa_timespec_cmp(&p->next_elapse, &now) < 0) + pa_timespec_add(&p->next_elapse, (pa_timespec_diff(&now, &p->next_elapse) / p->period + 1) * p->period); + + } else + p->timer_enabled = 0; + } - if (r < 0 && (errno == EAGAIN || errno == EINTR)) { + if (r == 0 || (r < 0 && (errno == EAGAIN || errno == EINTR))) { r = 0; no_events = 1; } @@ -359,13 +388,10 @@ finish: return r; } -void pa_rtpoll_set_itimer(pa_rtpoll *p, pa_usec_t usec) { +static void update_timer(pa_rtpoll *p) { pa_assert(p); - p->interval = usec; - #ifdef HAVE_PPOLL - pa_timespec_store(&p->interval_timespec, usec); #ifdef __linux__ if (!p->dont_use_ppoll) { @@ -387,12 +413,21 @@ void pa_rtpoll_set_itimer(pa_rtpoll *p, pa_usec_t usec) { if (p->timer != (timer_t) -1) { struct itimerspec its; - memset(&its, 0, sizeof(its)); - pa_timespec_store(&its.it_value, usec); - pa_timespec_store(&its.it_interval, usec); - assert(timer_settime(p->timer, 0, &its, NULL) == 0); + if (p->timer_enabled) { + its.it_value = p->next_elapse; + + /* Make sure that 0,0 is not understood as + * "disarming" */ + if (its.it_value.tv_sec == 0) + its.it_value.tv_nsec = 1; + + if (p->period > 0) + pa_timespec_store(&its.it_interval, p->period); + } + + pa_assert_se(timer_settime(p->timer, TIMER_ABSTIME, &its, NULL) == 0); } #ifdef __linux__ @@ -402,6 +437,49 @@ void pa_rtpoll_set_itimer(pa_rtpoll *p, pa_usec_t usec) { #endif } +void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timespec *ts) { + pa_assert(p); + pa_assert(ts); + + p->next_elapse = *ts; + p->period = 0; + p->timer_enabled = 1; + + update_timer(p); +} + +void pa_rtpoll_set_timer_periodic(pa_rtpoll *p, pa_usec_t usec) { + pa_assert(p); + + p->period = usec; + pa_rtclock_get(&p->next_elapse); + pa_timespec_add(&p->next_elapse, usec); + p->timer_enabled = 1; + + update_timer(p); +} + +void pa_rtpoll_set_timer_relative(pa_rtpoll *p, pa_usec_t usec) { + pa_assert(p); + + p->period = 0; + pa_rtclock_get(&p->next_elapse); + pa_timespec_add(&p->next_elapse, usec); + p->timer_enabled = 1; + + update_timer(p); +} + +void pa_rtpoll_set_timer_disabled(pa_rtpoll *p) { + pa_assert(p); + + p->period = 0; + memset(&p->next_elapse, 0, sizeof(p->next_elapse)); + p->timer_enabled = 0; + + update_timer(p); +} + pa_rtpoll_item *pa_rtpoll_item_new(pa_rtpoll *p, unsigned n_fds) { pa_rtpoll_item *i; diff --git a/src/pulsecore/rtpoll.h b/src/pulsecore/rtpoll.h index bed3ae3c..7fe5cb37 100644 --- a/src/pulsecore/rtpoll.h +++ b/src/pulsecore/rtpoll.h @@ -59,11 +59,18 @@ void pa_rtpoll_free(pa_rtpoll *p); void pa_rtpoll_install(pa_rtpoll *p); int pa_rtpoll_run(pa_rtpoll *f); -void pa_rtpoll_set_itimer(pa_rtpoll *p, pa_usec_t usec); + +void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timespec *ts); +void pa_rtpoll_set_timer_periodic(pa_rtpoll *p, pa_usec_t usec); +void pa_rtpoll_set_timer_relative(pa_rtpoll *p, pa_usec_t usec); +void pa_rtpoll_set_timer_disabled(pa_rtpoll *p); pa_rtpoll_item *pa_rtpoll_item_new(pa_rtpoll *p, unsigned n_fds); void pa_rtpoll_item_free(pa_rtpoll_item *i); +/* Please note that this pointer might change on every call and when + * pa_rtpoll_run() is called. Hence: call this immediately before + * using the pointer and don't save the result anywhere */ struct pollfd *pa_rtpoll_item_get_pollfd(pa_rtpoll_item *i, unsigned *n_fds); void pa_rtpoll_item_set_before_callback(pa_rtpoll_item *i, int (*before_cb)(pa_rtpoll_item *i)); @@ -74,5 +81,4 @@ void* pa_rtpoll_item_get_userdata(pa_rtpoll_item *i); pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_fdsem *s); pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq(pa_rtpoll *p, pa_asyncmsgq *q); - #endif diff --git a/src/tests/rtpoll-test.c b/src/tests/rtpoll-test.c index 29f2e923..2a90684e 100644 --- a/src/tests/rtpoll-test.c +++ b/src/tests/rtpoll-test.c @@ -56,7 +56,7 @@ int main(int argc, char *argv[]) { pollfd->events = POLLIN; pa_rtpoll_install(p); - pa_rtpoll_set_itimer(p, 10000000); /* 10 s */ + pa_rtpoll_set_timer_periodic(p, 10000000); /* 10 s */ pa_rtpoll_run(p); -- cgit From 1bfa1802d48149cbd699e36cf80989b9c062341b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 22:27:07 +0000 Subject: minor cleanups git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1704 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 43 ++++++++++++++---------------------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 3e521482..a805845c 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -28,12 +28,6 @@ #include -#ifdef HAVE_SYS_POLL_H -#include -#else -#include "poll.h" -#endif - #include #include @@ -343,7 +337,8 @@ static int suspend(struct userdata *u) { pa_assert(u); pa_assert(u->pcm_handle); - snd_pcm_drain(u->pcm_handle); /* Let's suspend */ + /* Let's suspend */ + snd_pcm_drain(u->pcm_handle); snd_pcm_close(u->pcm_handle); u->pcm_handle = NULL; @@ -624,8 +619,6 @@ static void thread_func(void *userdata) { if (PA_SINK_OPENED(u->sink->thread_info.state)) { int work_done = 0; - pa_assert(u->pcm_handle); - if (u->use_mmap) { if ((work_done = mmap_write(u)) < 0) goto fail; @@ -648,8 +641,6 @@ static void thread_func(void *userdata) { if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; -/* pa_log("processing msg"); */ - if (!object && code == PA_MESSAGE_SHUTDOWN) { pa_asyncmsgq_done(u->thread_mq.inq, 0); goto finish; @@ -707,7 +698,6 @@ finish: int pa__init(pa_module*m) { pa_modargs *ma = NULL; - int ret = -1; struct userdata *u = NULL; const char *dev; pa_sample_spec ss; @@ -723,6 +713,8 @@ int pa__init(pa_module*m) { int namereg_fail; int use_mmap = 1, b; + snd_pcm_info_alloca(&pcm_info); + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { @@ -773,8 +765,7 @@ int pa__init(pa_module*m) { u->device_name = pa_xstrdup(dev); - if ((err = snd_pcm_info_malloc(&pcm_info)) < 0 || - (err = snd_pcm_info(u->pcm_handle, pcm_info)) < 0) { + if ((err = snd_pcm_info(u->pcm_handle, pcm_info)) < 0) { pa_log("Error fetching PCM info: %s", snd_strerror(err)); goto fail; } @@ -903,24 +894,18 @@ int pa__init(pa_module*m) { if (u->sink->get_mute) u->sink->get_mute(u->sink); - ret = 0; - -finish: - - if (ma) - pa_modargs_free(ma); - - if (pcm_info) - snd_pcm_info_free(pcm_info); - - return ret; - + pa_modargs_free(ma); + + return 0; + fail: - if (u) - pa__done(m); + if (ma) + pa_modargs_free(ma); + + pa__done(m); - goto finish; + return -1; } void pa__done(pa_module*m) { -- cgit From 9d381599be89f5cb99da60f83e086e476f50a72f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 22:27:53 +0000 Subject: port remaining sinks to pa_rtpoll git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1705 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-source.c | 295 +++++++++++++++++++-------------------- src/modules/module-null-sink.c | 88 +++++------- src/modules/module-oss.c | 170 +++++++++++----------- src/modules/module-pipe-sink.c | 93 ++++++------ 4 files changed, 306 insertions(+), 340 deletions(-) diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 58e7cb4a..6ea99ec7 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -29,15 +29,10 @@ #include #include -#ifdef HAVE_SYS_POLL_H -#include -#else -#include "poll.h" -#endif - #include #include +#include #include #include @@ -52,6 +47,7 @@ #include #include #include +#include #include "alsa-util.h" #include "module-alsa-source-symdef.h" @@ -76,8 +72,10 @@ struct userdata { pa_core *core; pa_module *module; pa_source *source; + pa_thread *thread; pa_thread_mq thread_mq; + pa_rtpoll *rtpoll; snd_pcm_t *pcm_handle; @@ -93,13 +91,7 @@ struct userdata { int use_mmap; - struct pollfd *pollfd; - int n_alsa_fds; -}; - -enum { - POLLFD_ASYNCQ, - POLLFD_ALSA_BASE + pa_rtpoll_item *alsa_rtpoll_item; }; static const char* const valid_modargs[] = { @@ -116,16 +108,16 @@ static const char* const valid_modargs[] = { }; static int mmap_read(struct userdata *u) { - snd_pcm_sframes_t n; - int err; - const snd_pcm_channel_area_t *areas; - snd_pcm_uframes_t offset, frames; int work_done = 0; pa_assert(u); - pa_assert(u->source); + pa_source_assert_ref(u->source); for (;;) { + snd_pcm_sframes_t n; + int err; + const snd_pcm_channel_area_t *areas; + snd_pcm_uframes_t offset, frames; pa_memchunk chunk; void *p; @@ -207,6 +199,73 @@ static int mmap_read(struct userdata *u) { } } +static int unix_read(struct userdata *u) { + snd_pcm_status_t *status; + int work_done = 0; + + snd_pcm_status_alloca(&status); + + pa_assert(u); + pa_source_assert_ref(u->source); + + for (;;) { + void *p; + snd_pcm_sframes_t t; + ssize_t l; + int err; + pa_memchunk chunk; + + if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) { + pa_log("Failed to query DSP status data: %s", snd_strerror(t)); + return -1; + } + + if (snd_pcm_status_get_avail_max(status)*u->frame_size >= u->hwbuf_size) + pa_log_debug("Buffer overrun!"); + + l = snd_pcm_status_get_avail(status) * u->frame_size; + + if (l <= 0) + return work_done; + + chunk.memblock = pa_memblock_new(u->core->mempool, l); + + p = pa_memblock_acquire(chunk.memblock); + t = snd_pcm_readi(u->pcm_handle, (uint8_t*) p, l / u->frame_size); + pa_memblock_release(chunk.memblock); + +/* pa_log("wrote %i bytes of %u (%u)", t*u->frame_size, u->memchunk.length, l); */ + + pa_assert(t != 0); + + if (t < 0) { + pa_memblock_unref(chunk.memblock); + + if ((t = snd_pcm_recover(u->pcm_handle, t, 1)) == 0) + continue; + + if (t == -EAGAIN) { + pa_log_debug("EAGAIN"); + return work_done; + } else { + pa_log("Failed to read data from DSP: %s", snd_strerror(t)); + return -1; + } + } + + chunk.index = 0; + chunk.length = t * u->frame_size; + + pa_source_post(u->source, &chunk); + pa_memblock_unref(chunk.memblock); + + work_done = 1; + + if (t * u->frame_size >= (unsigned) l) + return work_done; + } +} + static pa_usec_t source_get_latency(struct userdata *u) { pa_usec_t r = 0; snd_pcm_status_t *status; @@ -216,6 +275,7 @@ static pa_usec_t source_get_latency(struct userdata *u) { snd_pcm_status_alloca(&status); pa_assert(u); + pa_assert(u->pcm_handle); if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) pa_log("Failed to get delay: %s", snd_strerror(err)); @@ -230,22 +290,24 @@ static pa_usec_t source_get_latency(struct userdata *u) { static int build_pollfd(struct userdata *u) { int err; + struct pollfd *pollfd; + int n; pa_assert(u); pa_assert(u->pcm_handle); - if ((u->n_alsa_fds = snd_pcm_poll_descriptors_count(u->pcm_handle)) < 0) { - pa_log("snd_pcm_poll_descriptors_count() failed: %s", snd_strerror(u->n_alsa_fds)); + if ((n = snd_pcm_poll_descriptors_count(u->pcm_handle)) < 0) { + pa_log("snd_pcm_poll_descriptors_count() failed: %s", snd_strerror(n)); return -1; } - pa_xfree(u->pollfd); - u->pollfd = pa_xnew0(struct pollfd, POLLFD_ALSA_BASE + u->n_alsa_fds); - - u->pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->thread_mq.inq); - u->pollfd[POLLFD_ASYNCQ].events = POLLIN; + if (u->alsa_rtpoll_item) + pa_rtpoll_item_free(u->alsa_rtpoll_item); - if ((err = snd_pcm_poll_descriptors(u->pcm_handle, u->pollfd+POLLFD_ALSA_BASE, u->n_alsa_fds)) < 0) { + u->alsa_rtpoll_item = pa_rtpoll_item_new(u->rtpoll, n); + pollfd = pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, NULL); + + if ((err = snd_pcm_poll_descriptors(u->pcm_handle, pollfd, n)) < 0) { pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err)); return -1; } @@ -261,6 +323,11 @@ static int suspend(struct userdata *u) { snd_pcm_close(u->pcm_handle); u->pcm_handle = NULL; + if (u->alsa_rtpoll_item) { + pa_rtpoll_item_free(u->alsa_rtpoll_item); + u->alsa_rtpoll_item = NULL; + } + pa_log_debug("Device suspended..."); return 0; @@ -505,14 +572,9 @@ static int source_set_mute_cb(pa_source *s) { } static void thread_func(void *userdata) { - struct userdata *u = userdata; - int err; - unsigned short revents = 0; - snd_pcm_status_t *status; pa_assert(u); - snd_pcm_status_alloca(&status); pa_log_debug("Thread starting up"); @@ -520,20 +582,37 @@ static void thread_func(void *userdata) { pa_make_realtime(); pa_thread_mq_install(&u->thread_mq); + pa_rtpoll_install(u->rtpoll); if (build_pollfd(u) < 0) goto fail; + snd_pcm_start(u->pcm_handle); + for (;;) { pa_msgobject *object; int code; void *data; - int r; int64_t offset; pa_memchunk chunk; /* pa_log("loop"); */ + /* Render some data and write it to the dsp */ + if (PA_SOURCE_OPENED(u->source->thread_info.state)) { + + if (u->use_mmap) { + if (mmap_read(u) < 0) + goto fail; + + } else { + if (unix_read(u) < 0) + goto fail; + } + } + +/* pa_log("loop2"); */ + /* Check whether there is a message for us to process */ if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; @@ -550,109 +629,20 @@ static void thread_func(void *userdata) { continue; } -/* pa_log("loop2"); */ - - /* Render some data and write it to the dsp */ - - if (PA_SOURCE_OPENED(u->source->thread_info.state) && (revents & POLLIN)) { - int work_done = 0; - pa_assert(u->pcm_handle); - - if (u->use_mmap) { - - if ((work_done = mmap_read(u)) < 0) - goto fail; - - } else { - - for (;;) { - void *p; - snd_pcm_sframes_t t; - ssize_t l; - - if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) { - pa_log("Failed to query DSP status data: %s", snd_strerror(t)); - goto fail; - } - - if (snd_pcm_status_get_avail_max(status)*u->frame_size >= u->hwbuf_size) - pa_log_debug("Buffer overrun!"); - - l = snd_pcm_status_get_avail(status) * u->frame_size; - - if (l <= 0) - break; - - chunk.memblock = pa_memblock_new(u->core->mempool, l); - - p = pa_memblock_acquire(chunk.memblock); - t = snd_pcm_readi(u->pcm_handle, (uint8_t*) p, l / u->frame_size); - pa_memblock_release(chunk.memblock); - -/* pa_log("wrote %i bytes of %u (%u)", t*u->frame_size, u->memchunk.length, l); */ - - pa_assert(t != 0); - - if (t < 0) { - pa_memblock_unref(chunk.memblock); - - if ((t = snd_pcm_recover(u->pcm_handle, t, 1)) == 0) - continue; - - if (t == -EAGAIN) { - pa_log_debug("EAGAIN"); - break; - } else { - pa_log("Failed to read data from DSP: %s", snd_strerror(t)); - goto fail; - } - - } - - chunk.index = 0; - chunk.length = t * u->frame_size; - - pa_source_post(u->source, &chunk); - pa_memblock_unref(chunk.memblock); - - work_done = 1; - - if (t * u->frame_size >= (unsigned) l) - break; - } - } - - revents &= ~POLLIN; - - if (work_done) - continue; - } - - /* Hmm, nothing to do. Let's sleep */ - if (pa_asyncmsgq_before_poll(u->thread_mq.inq) < 0) - continue; - -/* pa_log("polling for %i", POLLFD_ALSA_BASE + (PA_SOURCE_OPENED(u->source->thread_info.state) ? n_alsa_fds : 0)); */ - r = poll(u->pollfd, POLLFD_ALSA_BASE + (PA_SOURCE_OPENED(u->source->thread_info.state) ? u->n_alsa_fds : 0), -1); -/* pa_log("poll end"); */ - - pa_asyncmsgq_after_poll(u->thread_mq.inq); - - if (r < 0) { - if (errno == EINTR) { - u->pollfd[POLLFD_ASYNCQ].revents = 0; - revents = 0; - continue; - } - + if (pa_rtpoll_run(u->rtpoll) < 0) { pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; } - pa_assert(r > 0); - if (PA_SOURCE_OPENED(u->source->thread_info.state)) { - if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, u->pollfd + POLLFD_ALSA_BASE, u->n_alsa_fds, &revents)) < 0) { + struct pollfd *pollfd; + unsigned short revents = 0; + int err; + unsigned n; + + pollfd = pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, &n); + + if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, pollfd, n, &revents)) < 0) { pa_log("snd_pcm_poll_descriptors_revents() failed: %s", snd_strerror(err)); goto fail; } @@ -668,10 +658,7 @@ static void thread_func(void *userdata) { goto fail; } /* pa_log("got alsa event"); */ - } else - revents = 0; - - pa_assert((u->pollfd[POLLFD_ASYNCQ].revents & ~POLLIN) == 0); + } } fail: @@ -687,7 +674,6 @@ finish: int pa__init(pa_module*m) { pa_modargs *ma = NULL; - int ret = -1; struct userdata *u = NULL; const char *dev; pa_sample_spec ss; @@ -703,6 +689,8 @@ int pa__init(pa_module*m) { int namereg_fail; int use_mmap = 1, b; + snd_pcm_info_alloca(&pcm_info); + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { @@ -739,9 +727,10 @@ int pa__init(pa_module*m) { u->module = m; m->userdata = u; u->use_mmap = use_mmap; - u->n_alsa_fds = 0; - u->pollfd = NULL; pa_thread_mq_init(&u->thread_mq, m->core->mainloop); + u->rtpoll = pa_rtpoll_new(); + u->alsa_rtpoll_item = NULL; + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, u->thread_mq.inq); snd_config_update_free_global(); if ((err = snd_pcm_open(&u->pcm_handle, dev = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) { @@ -751,8 +740,7 @@ int pa__init(pa_module*m) { u->device_name = pa_xstrdup(dev); - if ((err = snd_pcm_info_malloc(&pcm_info)) < 0 || - (err = snd_pcm_info(u->pcm_handle, pcm_info)) < 0) { + if ((err = snd_pcm_info(u->pcm_handle, pcm_info)) < 0) { pa_log("Error fetching PCM info: %s", snd_strerror(err)); goto fail; } @@ -875,26 +863,18 @@ int pa__init(pa_module*m) { if (u->source->get_mute) u->source->get_mute(u->source); - snd_pcm_start(u->pcm_handle); + pa_modargs_free(ma); - ret = 0; - -finish: - - if (ma) - pa_modargs_free(ma); + return 0; - if (pcm_info) - snd_pcm_info_free(pcm_info); - - return ret; - fail: - if (u) - pa__done(m); + if (ma) + pa_modargs_free(ma); - goto finish; + pa__done(m); + + return -1; } void pa__done(pa_module*m) { @@ -918,6 +898,12 @@ void pa__done(pa_module*m) { if (u->source) pa_source_unref(u->source); + if (u->alsa_rtpoll_item) + pa_rtpoll_item_free(u->alsa_rtpoll_item); + + if (u->rtpoll) + pa_rtpoll_free(u->rtpoll); + if (u->mixer_fdl) pa_alsa_fdlist_free(u->mixer_fdl); @@ -929,7 +915,6 @@ void pa__done(pa_module*m) { snd_pcm_close(u->pcm_handle); } - pa_xfree(u->pollfd); pa_xfree(u->device_name); pa_xfree(u); diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index 8b17b59e..3b512371 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -47,6 +46,8 @@ #include #include #include +#include +#include #include "module-null-sink-symdef.h" @@ -67,11 +68,14 @@ struct userdata { pa_core *core; pa_module *module; pa_sink *sink; + pa_thread *thread; pa_thread_mq thread_mq; + pa_rtpoll *rtpoll; + size_t block_size; - struct timeval timestamp; + struct timespec timestamp; }; static const char* const valid_modargs[] = { @@ -91,19 +95,19 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse case PA_SINK_MESSAGE_SET_STATE: if (PA_PTR_TO_UINT(data) == PA_SINK_RUNNING) - pa_gettimeofday(&u->timestamp); + pa_rtclock_get(&u->timestamp); break; case PA_SINK_MESSAGE_GET_LATENCY: { - struct timeval now; + struct timespec now; - pa_gettimeofday(&now); + pa_rtclock_get(&now); - if (pa_timeval_cmp(&u->timestamp, &now) > 0) + if (pa_timespec_cmp(&u->timestamp, &now) > 0) *((pa_usec_t*) data) = 0; else - *((pa_usec_t*) data) = pa_timeval_diff(&u->timestamp, &now); + *((pa_usec_t*) data) = pa_timespec_diff(&u->timestamp, &now); break; } } @@ -113,29 +117,41 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse static void thread_func(void *userdata) { struct userdata *u = userdata; - struct pollfd pollfd; pa_assert(u); pa_log_debug("Thread starting up"); pa_thread_mq_install(&u->thread_mq); + pa_rtpoll_install(u->rtpoll); - pa_gettimeofday(&u->timestamp); - - memset(&pollfd, 0, sizeof(pollfd)); - pollfd.fd = pa_asyncmsgq_get_fd(u->thread_mq.inq); - pollfd.events = POLLIN; + pa_rtclock_get(&u->timestamp); for (;;) { pa_msgobject *object; int code; void *data; pa_memchunk chunk; - int r, timeout; - struct timeval now; int64_t offset; + /* Render some data and drop it immediately */ + if (u->sink->thread_info.state == PA_SINK_RUNNING) { + struct timespec now; + + pa_rtclock_get(&now); + + if (pa_timespec_cmp(&u->timestamp, &now) <= 0) { + + pa_sink_render(u->sink, u->block_size, &chunk); + pa_memblock_unref(chunk.memblock); + + pa_timespec_add(&u->timestamp, pa_bytes_to_usec(chunk.length, &u->sink->sample_spec)); + } + + pa_rtpoll_set_timer_absolute(u->rtpoll, &u->timestamp); + } else + pa_rtpoll_set_timer_disabled(u->rtpoll); + /* Check whether there is a message for us to process */ if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; @@ -150,45 +166,11 @@ static void thread_func(void *userdata) { continue; } - /* Render some data and drop it immediately */ - if (u->sink->thread_info.state == PA_SINK_RUNNING) { - pa_gettimeofday(&now); - - if (pa_timeval_cmp(&u->timestamp, &now) <= 0) { - - pa_sink_render(u->sink, u->block_size, &chunk); - pa_memblock_unref(chunk.memblock); - - pa_timeval_add(&u->timestamp, pa_bytes_to_usec(chunk.length, &u->sink->sample_spec)); - continue; - } - - timeout = pa_timeval_diff(&u->timestamp, &now)/1000; - - if (timeout < 1) - timeout = 1; - } else - timeout = -1; - /* Hmm, nothing to do. Let's sleep */ - - if (pa_asyncmsgq_before_poll(u->thread_mq.inq) < 0) - continue; - - r = poll(&pollfd, 1, timeout); - pa_asyncmsgq_after_poll(u->thread_mq.inq); - - if (r < 0) { - if (errno == EINTR) { - pollfd.revents = 0; - continue; - } - + if (pa_rtpoll_run(u->rtpoll) < 0) { pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; } - - pa_assert(r == 0 || pollfd.revents == POLLIN); } fail: @@ -224,8 +206,9 @@ int pa__init(pa_module*m) { u->core = m->core; u->module = m; m->userdata = u; - pa_thread_mq_init(&u->thread_mq, m->core->mainloop); + u->rtpoll = pa_rtpoll_new(); + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, u->thread_mq.inq); if (!(u->sink = pa_sink_new(m->core, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map))) { pa_log("Failed to create sink."); @@ -282,5 +265,8 @@ void pa__done(pa_module*m) { if (u->sink) pa_sink_unref(u->sink); + if (u->rtpoll) + pa_rtpoll_free(u->rtpoll); + pa_xfree(u); } diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index f4454813..85fdd9c8 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -32,9 +32,7 @@ * the device. If none is avilable from the inputs, we write silence * instead. * - * If power should be saved on IDLE this should be implemented in a - * special suspend-on-idle module that will put us into SUSPEND mode - * as soon and we're idle for too long. + * If power should be saved on IDLE module-suspend-on-idle should be used. * */ @@ -48,12 +46,6 @@ #include #endif -#ifdef HAVE_SYS_POLL_H -#include -#else -#include "poll.h" -#endif - #include #include #include @@ -80,6 +72,7 @@ #include #include #include +#include #include "oss-util.h" #include "module-oss-symdef.h" @@ -108,8 +101,10 @@ struct userdata { pa_module *module; pa_sink *sink; pa_source *source; + pa_thread *thread; pa_thread_mq thread_mq; + pa_rtpoll *rtpoll; char *device_name; @@ -135,6 +130,8 @@ struct userdata { pa_memblock **in_mmap_memblocks, **out_mmap_memblocks; int in_mmap_saved_nfrags, out_mmap_saved_nfrags; + + pa_rtpoll_item *rtpoll_item; }; static const char* const valid_modargs[] = { @@ -156,10 +153,12 @@ static const char* const valid_modargs[] = { static void trigger(struct userdata *u, int quick) { int enable_bits = 0, zero = 0; + pa_assert(u); + if (u->fd < 0) return; - pa_log_debug("trigger"); +/* pa_log_debug("trigger"); */ if (u->source && PA_SOURCE_OPENED(u->source->thread_info.state)) enable_bits |= PCM_ENABLE_INPUT; @@ -479,6 +478,11 @@ static int suspend(struct userdata *u) { close(u->fd); u->fd = -1; + if (u->rtpoll_item) { + pa_rtpoll_item_free(u->rtpoll_item); + u->rtpoll_item = NULL; + } + pa_log_debug("Device suspended..."); return 0; @@ -490,6 +494,7 @@ static int unsuspend(struct userdata *u) { int frag_size, in_frag_size, out_frag_size; int in_nfrags, out_nfrags; struct audio_buf_info info; + struct pollfd *pollfd; pa_assert(u); pa_assert(u->fd < 0); @@ -568,7 +573,15 @@ static int unsuspend(struct userdata *u) { u->out_mmap_current = u->in_mmap_current = 0; u->out_mmap_saved_nfrags = u->in_mmap_saved_nfrags = 0; + + pa_assert(!u->rtpoll_item); + u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, 1); + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + pollfd->fd = u->fd; + pollfd->events = 0; + pollfd->revents = 0; + pa_log_debug("Resumed successfully..."); return 0; @@ -777,15 +790,9 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off } static void thread_func(void *userdata) { - enum { - POLLFD_ASYNCQ, - POLLFD_DSP, - POLLFD_MAX, - }; - struct userdata *u = userdata; - struct pollfd pollfd[POLLFD_MAX]; int write_type = 0, read_type = 0; + unsigned short revents = 0; pa_assert(u); @@ -795,46 +802,22 @@ static void thread_func(void *userdata) { pa_make_realtime(); pa_thread_mq_install(&u->thread_mq); + pa_rtpoll_install(u->rtpoll); trigger(u, 0); - memset(&pollfd, 0, sizeof(pollfd)); - - pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->thread_mq.inq); - pollfd[POLLFD_ASYNCQ].events = POLLIN; - pollfd[POLLFD_DSP].fd = u->fd; - for (;;) { pa_msgobject *object; int code; void *data; pa_memchunk chunk; - int r; int64_t offset; /* pa_log("loop"); */ - /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { - int ret; - -/* pa_log("processing msg"); */ - - if (!object && code == PA_MESSAGE_SHUTDOWN) { - pa_asyncmsgq_done(u->thread_mq.inq, 0); - goto finish; - } - - ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); - pa_asyncmsgq_done(u->thread_mq.inq, ret); - continue; - } - -/* pa_log("loop2"); */ - /* Render some data and write it to the dsp */ - if (u->sink && u->sink->thread_info.state != PA_SINK_DISCONNECTED && u->fd >= 0 && (pollfd[POLLFD_DSP].revents & POLLOUT)) { + if (u->sink && u->sink->thread_info.state != PA_SINK_DISCONNECTED && u->fd >= 0 && (revents & POLLOUT)) { if (u->use_mmap) { int ret; @@ -842,7 +825,7 @@ static void thread_func(void *userdata) { if ((ret = mmap_write(u)) < 0) goto fail; - pollfd[POLLFD_DSP].revents &= ~POLLOUT; + revents &= ~POLLOUT; if (ret > 0) continue; @@ -894,7 +877,7 @@ static void thread_func(void *userdata) { else if (errno == EAGAIN) { pa_log_debug("EAGAIN"); - pollfd[POLLFD_DSP].revents &= ~POLLOUT; + revents &= ~POLLOUT; break; } else { @@ -914,7 +897,7 @@ static void thread_func(void *userdata) { l -= t; - pollfd[POLLFD_DSP].revents &= ~POLLOUT; + revents &= ~POLLOUT; } } while (loop && l > 0); @@ -925,7 +908,7 @@ static void thread_func(void *userdata) { /* Try to read some data and pass it on to the source driver */ - if (u->source && u->source->thread_info.state != PA_SOURCE_DISCONNECTED && u->fd >= 0 && ((pollfd[POLLFD_DSP].revents & POLLIN))) { + if (u->source && u->source->thread_info.state != PA_SOURCE_DISCONNECTED && u->fd >= 0 && ((revents & POLLIN))) { if (u->use_mmap) { int ret; @@ -933,7 +916,7 @@ static void thread_func(void *userdata) { if ((ret = mmap_read(u)) < 0) goto fail; - pollfd[POLLFD_DSP].revents &= ~POLLIN; + revents &= ~POLLIN; if (ret > 0) continue; @@ -985,7 +968,7 @@ static void thread_func(void *userdata) { else if (errno == EAGAIN) { pa_log_debug("EAGAIN"); - pollfd[POLLFD_DSP].revents &= ~POLLIN; + revents &= ~POLLIN; break; } else { @@ -1002,7 +985,7 @@ static void thread_func(void *userdata) { l -= t; - pollfd[POLLFD_DSP].revents &= ~POLLIN; + revents &= ~POLLIN; } } while (loop && l > 0); @@ -1010,46 +993,53 @@ static void thread_func(void *userdata) { } } - if (u->fd >= 0) { - pollfd[POLLFD_DSP].fd = u->fd; - pollfd[POLLFD_DSP].events = - ((u->source && PA_SOURCE_OPENED(u->source->thread_info.state)) ? POLLIN : 0) | - ((u->sink && PA_SINK_OPENED(u->sink->thread_info.state)) ? POLLOUT : 0); - } - - /* Hmm, nothing to do. Let's sleep */ +/* pa_log("loop2"); */ - if (pa_asyncmsgq_before_poll(u->thread_mq.inq) < 0) + /* Check whether there is a message for us to process */ + if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { + int ret; + +/* pa_log("processing msg"); */ + + if (!object && code == PA_MESSAGE_SHUTDOWN) { + pa_asyncmsgq_done(u->thread_mq.inq, 0); + goto finish; + } + + ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); + pa_asyncmsgq_done(u->thread_mq.inq, ret); continue; + } -/* pa_log("polling for %i (legend: %i=POLLIN, %i=POLLOUT)", u->fd >= 0 ? pollfd[POLLFD_DSP].events : -1, POLLIN, POLLOUT); */ - r = poll(pollfd, u->fd >= 0 ? POLLFD_MAX : POLLFD_DSP, -1); -/* pa_log("polling got dsp=%i amq=%i (%i)", r > 0 ? pollfd[POLLFD_DSP].revents : 0, r > 0 ? pollfd[POLLFD_ASYNCQ].revents : 0, r); */ + if (u->fd >= 0) { + struct pollfd *pollfd; - pa_asyncmsgq_after_poll(u->thread_mq.inq); + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + pollfd->events = + ((u->source && PA_SOURCE_OPENED(u->source->thread_info.state)) ? POLLIN : 0) | + ((u->sink && PA_SINK_OPENED(u->sink->thread_info.state)) ? POLLOUT : 0); + } - if (u->fd < 0) - pollfd[POLLFD_DSP].revents = 0; - if (r < 0) { - if (errno == EINTR) { - pollfd[POLLFD_ASYNCQ].revents = 0; - pollfd[POLLFD_DSP].revents = 0; - continue; - } - + /* Hmm, nothing to do. Let's sleep */ + if (pa_rtpoll_run(u->rtpoll) < 0) { pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; } - pa_assert(r > 0); - - if (pollfd[POLLFD_DSP].revents & ~(POLLOUT|POLLIN)) { - pa_log("DSP shutdown."); - goto fail; - } + if (u->fd >= 0) { + struct pollfd *pollfd; + + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + + if (pollfd->revents & ~(POLLOUT|POLLIN)) { + pa_log("DSP shutdown."); + goto fail; + } - pa_assert((pollfd[POLLFD_ASYNCQ].revents & ~POLLIN) == 0); + revents = pollfd->revents; + } else + revents = 0; } fail: @@ -1077,6 +1067,7 @@ int pa__init(pa_module*m) { char hwdesc[64], *t; const char *name; int namereg_fail; + struct pollfd *pollfd; pa_assert(m); @@ -1165,7 +1156,14 @@ int pa__init(pa_module*m) { u->out_fragment_size = u->in_fragment_size = u->frag_size = frag_size; u->use_mmap = use_mmap; pa_thread_mq_init(&u->thread_mq, m->core->mainloop); - + u->rtpoll = pa_rtpoll_new(); + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, u->thread_mq.inq); + u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, 1); + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + pollfd->fd = fd; + pollfd->events = 0; + pollfd->revents = 0; + if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) >= 0) { pa_log_info("Input -- %u fragments of size %u.", info.fragstotal, info.fragsize); u->in_fragment_size = info.fragsize; @@ -1294,14 +1292,14 @@ go_on: goto fail; } - pa_modargs_free(ma); - /* Read mixer settings */ if (u->source) pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->source), PA_SOURCE_MESSAGE_GET_VOLUME, &u->source->volume, 0, NULL, NULL); if (u->sink) pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_GET_VOLUME, &u->sink->volume, 0, NULL, NULL); + pa_modargs_free(ma); + return 0; fail: @@ -1343,10 +1341,16 @@ void pa__done(pa_module*m) { if (u->source) pa_source_unref(u->source); - + if (u->memchunk.memblock) pa_memblock_unref(u->memchunk.memblock); + if (u->rtpoll_item) + pa_rtpoll_item_free(u->rtpoll_item); + + if (u->rtpoll) + pa_rtpoll_free(u->rtpoll); + if (u->out_mmap_memblocks) { unsigned i; for (i = 0; i < u->out_nfrags; i++) diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index 2f82cae8..a1101ab8 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -34,7 +34,6 @@ #include #include #include -#include #include @@ -46,6 +45,7 @@ #include #include #include +#include #include "module-pipe-sink-symdef.h" @@ -67,12 +67,17 @@ struct userdata { pa_core *core; pa_module *module; pa_sink *sink; + pa_thread *thread; pa_thread_mq thread_mq; + pa_rtpoll *rtpoll; + char *filename; int fd; pa_memchunk memchunk; + + pa_rtpoll_item *rtpoll_item; }; static const char* const valid_modargs[] = { @@ -108,14 +113,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse } static void thread_func(void *userdata) { - enum { - POLLFD_ASYNCQ, - POLLFD_FIFO, - POLLFD_MAX, - }; - struct userdata *u = userdata; - struct pollfd pollfd[POLLFD_MAX]; int write_type = 0; pa_assert(u); @@ -123,38 +121,21 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); pa_thread_mq_install(&u->thread_mq); - - memset(&pollfd, 0, sizeof(pollfd)); - - pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->thread_mq.inq); - pollfd[POLLFD_ASYNCQ].events = POLLIN; - pollfd[POLLFD_FIFO].fd = u->fd; + pa_rtpoll_install(u->rtpoll); for (;;) { pa_msgobject *object; int code; void *data; pa_memchunk chunk; - int r; int64_t offset; - - /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { - int ret; - - if (!object && code == PA_MESSAGE_SHUTDOWN) { - pa_asyncmsgq_done(u->thread_mq.inq, 0); - goto finish; - } - - ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); - pa_asyncmsgq_done(u->thread_mq.inq, ret); - continue; - } + struct pollfd *pollfd; /* Render some data and write it to the fifo */ - if (u->sink->thread_info.state == PA_SINK_RUNNING && pollfd[POLLFD_FIFO].revents) { + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + + if (u->sink->thread_info.state == PA_SINK_RUNNING && pollfd->revents) { ssize_t l; void *p; @@ -188,41 +169,37 @@ static void thread_func(void *userdata) { pa_memchunk_reset(&u->memchunk); } - pollfd[POLLFD_FIFO].revents = 0; - continue; + pollfd->revents = 0; } } - pollfd[POLLFD_FIFO].events = u->sink->thread_info.state == PA_SINK_RUNNING ? POLLOUT : 0; + /* Check whether there is a message for us to process */ + if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { + int ret; - /* Hmm, nothing to do. Let's sleep */ + if (!object && code == PA_MESSAGE_SHUTDOWN) { + pa_asyncmsgq_done(u->thread_mq.inq, 0); + goto finish; + } - if (pa_asyncmsgq_before_poll(u->thread_mq.inq) < 0) + ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); + pa_asyncmsgq_done(u->thread_mq.inq, ret); continue; + } + + /* Hmm, nothing to do. Let's sleep */ + pollfd->events = u->sink->thread_info.state == PA_SINK_RUNNING ? POLLOUT : 0; -/* pa_log("polling for %u", pollfd[POLLFD_FIFO].events); */ - r = poll(pollfd, POLLFD_MAX, -1); -/* pa_log("polling got %u", r > 0 ? pollfd[POLLFD_FIFO].revents : 0); */ - - pa_asyncmsgq_after_poll(u->thread_mq.inq); - - if (r < 0) { - if (errno == EINTR) { - pollfd[POLLFD_ASYNCQ].revents = 0; - pollfd[POLLFD_FIFO].revents = 0; - continue; - } - + if (pa_rtpoll_run(u->rtpoll) < 0) { pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; } - if (pollfd[POLLFD_FIFO].revents & ~POLLOUT) { + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + if (pollfd->revents & ~POLLOUT) { pa_log("FIFO shutdown."); goto fail; } - - pa_assert((pollfd[POLLFD_ASYNCQ].revents & ~POLLIN) == 0); } fail: @@ -242,6 +219,7 @@ int pa__init(pa_module*m) { pa_channel_map map; pa_modargs *ma; char *t; + struct pollfd *pollfd; pa_assert(m); @@ -262,6 +240,8 @@ int pa__init(pa_module*m) { m->userdata = u; pa_memchunk_reset(&u->memchunk); pa_thread_mq_init(&u->thread_mq, m->core->mainloop); + u->rtpoll = pa_rtpoll_new(); + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, u->thread_mq.inq); u->filename = pa_xstrdup(pa_modargs_get_value(ma, "file", DEFAULT_FILE_NAME)); @@ -297,6 +277,11 @@ int pa__init(pa_module*m) { pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Unix FIFO sink '%s'", u->filename)); pa_xfree(t); + u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, 1); + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + pollfd->fd = u->fd; + pollfd->events = pollfd->revents = 0; + if (!(u->thread = pa_thread_new(thread_func, u))) { pa_log("Failed to create thread."); goto fail; @@ -339,6 +324,12 @@ void pa__done(pa_module*m) { if (u->memchunk.memblock) pa_memblock_unref(u->memchunk.memblock); + if (u->rtpoll_item) + pa_rtpoll_item_free(u->rtpoll_item); + + if (u->rtpoll) + pa_rtpoll_free(u->rtpoll); + if (u->filename) { unlink(u->filename); pa_xfree(u->filename); -- cgit From b3b382d8ef6393eff49da97e3822a721468a6bed Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Aug 2007 22:36:39 +0000 Subject: fix minor typo git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1706 fefdeb5f-60dc-0310-8127-8f9354f1896f --- libltdl/config.h | 2 +- src/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libltdl/config.h b/libltdl/config.h index 0fe3124c..195d2143 100644 --- a/libltdl/config.h +++ b/libltdl/config.h @@ -160,7 +160,7 @@ #define LTDL_SHLIB_EXT ".so" /* Define to the system default library search path. */ -#define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/lib/qt-3.3/lib" +#define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/local/lib:/usr/lib/qt-3.3/lib" /* Define if dlsym() requires a leading underscore in symbol names. */ /* #undef NEED_USCORE */ diff --git a/src/Makefile.am b/src/Makefile.am index 9b843a4a..04e57662 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -686,7 +686,7 @@ libpulsecore_la_SOURCES += \ pulsecore/fdsem.c pulsecore/fdsem.h \ pulsecore/object.c pulsecore/object.h \ pulsecore/msgobject.c pulsecore/msgobject.h \ - pulsecore/rtsig.c pulsecore/rtsog.h \ + pulsecore/rtsig.c pulsecore/rtsig.h \ pulsecore/rtpoll.c pulsecore/rtpoll.h \ pulsecore/rtclock.c pulsecore/rtclock.h \ pulsecore/macro.h \ -- cgit From 5ff891c15652849399c7bd832fa56b7674620395 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 23 Aug 2007 22:31:01 +0000 Subject: add a copy of the speex resampler to our sources git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1707 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/speex/arch.h | 197 ++++++ src/pulsecore/speex/fixed_generic.h | 106 ++++ src/pulsecore/speex/resample.c | 1114 +++++++++++++++++++++++++++++++++ src/pulsecore/speex/speex_resampler.h | 328 ++++++++++ 4 files changed, 1745 insertions(+) create mode 100644 src/pulsecore/speex/arch.h create mode 100644 src/pulsecore/speex/fixed_generic.h create mode 100644 src/pulsecore/speex/resample.c create mode 100644 src/pulsecore/speex/speex_resampler.h diff --git a/src/pulsecore/speex/arch.h b/src/pulsecore/speex/arch.h new file mode 100644 index 00000000..e2d731ac --- /dev/null +++ b/src/pulsecore/speex/arch.h @@ -0,0 +1,197 @@ +/* Copyright (C) 2003 Jean-Marc Valin */ +/** + @file arch.h + @brief Various architecture definitions Speex +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef ARCH_H +#define ARCH_H + +#ifndef OUTSIDE_SPEEX +#include "speex/speex_types.h" +#endif + +#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */ +#define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit value. */ +#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 16-bit value. */ +#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */ +#define ABS32(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 32-bit value. */ +#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Maximum 32-bit value. */ +#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */ + +#ifdef FIXED_POINT + +typedef spx_int16_t spx_word16_t; +typedef spx_int32_t spx_word32_t; +typedef spx_word32_t spx_mem_t; +typedef spx_word16_t spx_coef_t; +typedef spx_word16_t spx_lsp_t; +typedef spx_word32_t spx_sig_t; + +#define Q15ONE 32767 + +#define LPC_SCALING 8192 +#define SIG_SCALING 16384 +#define LSP_SCALING 8192. +#define GAMMA_SCALING 32768. +#define GAIN_SCALING 64 +#define GAIN_SCALING_1 0.015625 + +#define LPC_SHIFT 13 +#define LSP_SHIFT 13 +#define SIG_SHIFT 14 + +#define VERY_SMALL 0 +#define VERY_LARGE32 ((spx_word32_t)2147483647) +#define VERY_LARGE16 ((spx_word16_t)32767) +#define Q15_ONE ((spx_word16_t)32767) + + +#ifdef FIXED_DEBUG +#include "fixed_debug.h" +#else + +#include "fixed_generic.h" + +#ifdef ARM5E_ASM +#include "fixed_arm5e.h" +#elif defined (ARM4_ASM) +#include "fixed_arm4.h" +#elif defined (ARM5E_ASM) +#include "fixed_arm5e.h" +#elif defined (BFIN_ASM) +#include "fixed_bfin.h" +#endif + +#endif + + +#else + +typedef float spx_mem_t; +typedef float spx_coef_t; +typedef float spx_lsp_t; +typedef float spx_sig_t; +typedef float spx_word16_t; +typedef float spx_word32_t; + +#define Q15ONE 1.0f +#define LPC_SCALING 1.f +#define SIG_SCALING 1.f +#define LSP_SCALING 1.f +#define GAMMA_SCALING 1.f +#define GAIN_SCALING 1.f +#define GAIN_SCALING_1 1.f + +#define LPC_SHIFT 0 +#define LSP_SHIFT 0 +#define SIG_SHIFT 0 + +#define VERY_SMALL 1e-15f +#define VERY_LARGE32 1e15f +#define VERY_LARGE16 1e15f +#define Q15_ONE ((spx_word16_t)1.f) + +#define QCONST16(x,bits) (x) +#define QCONST32(x,bits) (x) + +#define NEG16(x) (-(x)) +#define NEG32(x) (-(x)) +#define EXTRACT16(x) (x) +#define EXTEND32(x) (x) +#define SHR16(a,shift) (a) +#define SHL16(a,shift) (a) +#define SHR32(a,shift) (a) +#define SHL32(a,shift) (a) +#define PSHR16(a,shift) (a) +#define PSHR32(a,shift) (a) +#define VSHR32(a,shift) (a) +#define SATURATE16(x,a) (x) +#define SATURATE32(x,a) (x) + +#define PSHR(a,shift) (a) +#define SHR(a,shift) (a) +#define SHL(a,shift) (a) +#define SATURATE(x,a) (x) + +#define ADD16(a,b) ((a)+(b)) +#define SUB16(a,b) ((a)-(b)) +#define ADD32(a,b) ((a)+(b)) +#define SUB32(a,b) ((a)-(b)) +#define MULT16_16_16(a,b) ((a)*(b)) +#define MULT16_16(a,b) ((spx_word32_t)(a)*(spx_word32_t)(b)) +#define MAC16_16(c,a,b) ((c)+(spx_word32_t)(a)*(spx_word32_t)(b)) + +#define MULT16_32_Q11(a,b) ((a)*(b)) +#define MULT16_32_Q13(a,b) ((a)*(b)) +#define MULT16_32_Q14(a,b) ((a)*(b)) +#define MULT16_32_Q15(a,b) ((a)*(b)) +#define MULT16_32_P15(a,b) ((a)*(b)) + +#define MAC16_32_Q11(c,a,b) ((c)+(a)*(b)) +#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b)) + +#define MAC16_16_Q11(c,a,b) ((c)+(a)*(b)) +#define MAC16_16_Q13(c,a,b) ((c)+(a)*(b)) +#define MAC16_16_P13(c,a,b) ((c)+(a)*(b)) +#define MULT16_16_Q11_32(a,b) ((a)*(b)) +#define MULT16_16_Q13(a,b) ((a)*(b)) +#define MULT16_16_Q14(a,b) ((a)*(b)) +#define MULT16_16_Q15(a,b) ((a)*(b)) +#define MULT16_16_P15(a,b) ((a)*(b)) +#define MULT16_16_P13(a,b) ((a)*(b)) +#define MULT16_16_P14(a,b) ((a)*(b)) + +#define DIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b)) +#define PDIV32_16(a,b) (((spx_word32_t)(a))/(spx_word16_t)(b)) +#define DIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b)) +#define PDIV32(a,b) (((spx_word32_t)(a))/(spx_word32_t)(b)) + + +#endif + + +#if defined (CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) + +/* 2 on TI C5x DSP */ +#define BYTES_PER_CHAR 2 +#define BITS_PER_CHAR 16 +#define LOG2_BITS_PER_CHAR 4 + +#else + +#define BYTES_PER_CHAR 1 +#define BITS_PER_CHAR 8 +#define LOG2_BITS_PER_CHAR 3 + +#endif + +#endif diff --git a/src/pulsecore/speex/fixed_generic.h b/src/pulsecore/speex/fixed_generic.h new file mode 100644 index 00000000..2948177c --- /dev/null +++ b/src/pulsecore/speex/fixed_generic.h @@ -0,0 +1,106 @@ +/* Copyright (C) 2003 Jean-Marc Valin */ +/** + @file fixed_generic.h + @brief Generic fixed-point operations +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FIXED_GENERIC_H +#define FIXED_GENERIC_H + +#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits)))) +#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits)))) + +#define NEG16(x) (-(x)) +#define NEG32(x) (-(x)) +#define EXTRACT16(x) ((spx_word16_t)(x)) +#define EXTEND32(x) ((spx_word32_t)(x)) +#define SHR16(a,shift) ((a) >> (shift)) +#define SHL16(a,shift) ((a) << (shift)) +#define SHR32(a,shift) ((a) >> (shift)) +#define SHL32(a,shift) ((a) << (shift)) +#define PSHR16(a,shift) (SHR16((a)+((1<<((shift))>>1)),shift)) +#define PSHR32(a,shift) (SHR32((a)+((1<<((shift))>>1)),shift)) +#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift))) +#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) +#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) + +#define SHR(a,shift) ((a) >> (shift)) +#define SHL(a,shift) ((spx_word32_t)(a) << (shift)) +#define PSHR(a,shift) (SHR((a)+((1<<((shift))>>1)),shift)) +#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) + + +#define ADD16(a,b) ((spx_word16_t)((spx_word16_t)(a)+(spx_word16_t)(b))) +#define SUB16(a,b) ((spx_word16_t)(a)-(spx_word16_t)(b)) +#define ADD32(a,b) ((spx_word32_t)(a)+(spx_word32_t)(b)) +#define SUB32(a,b) ((spx_word32_t)(a)-(spx_word32_t)(b)) + + +/* result fits in 16 bits */ +#define MULT16_16_16(a,b) ((((spx_word16_t)(a))*((spx_word16_t)(b)))) + +/* (spx_word32_t)(spx_word16_t) gives TI compiler a hint that it's 16x16->32 multiply */ +#define MULT16_16(a,b) (((spx_word32_t)(spx_word16_t)(a))*((spx_word32_t)(spx_word16_t)(b))) + +#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b)))) +#define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12)) +#define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13)) +#define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14)) + +#define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)) +#define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))) + +#define MULT16_32_P15(a,b) ADD32(MULT16_16((a),SHR((b),15)), PSHR(MULT16_16((a),((b)&0x00007fff)),15)) +#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)) +#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))) + + +#define MAC16_16_Q11(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),11))) +#define MAC16_16_Q13(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),13))) +#define MAC16_16_P13(c,a,b) (ADD32((c),SHR(ADD32(4096,MULT16_16((a),(b))),13))) + +#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11)) +#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13)) +#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14)) +#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15)) + +#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13)) +#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14)) +#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15)) + +#define MUL_16_32_R15(a,bh,bl) ADD32(MULT16_16((a),(bh)), SHR(MULT16_16((a),(bl)),15)) + +#define DIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a))/((spx_word16_t)(b)))) +#define PDIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word16_t)(b)))) +#define DIV32(a,b) (((spx_word32_t)(a))/((spx_word32_t)(b))) +#define PDIV32(a,b) (((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word32_t)(b))) + +#endif diff --git a/src/pulsecore/speex/resample.c b/src/pulsecore/speex/resample.c new file mode 100644 index 00000000..1cc4d490 --- /dev/null +++ b/src/pulsecore/speex/resample.c @@ -0,0 +1,1114 @@ +/* Copyright (C) 2007 Jean-Marc Valin + + File: resample.c + Arbitrary resampling code + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + The design goals of this code are: + - Very fast algorithm + - SIMD-friendly algorithm + - Low memory requirement + - Good *perceptual* quality (and not best SNR) + + The code is working, but it's in a very early stage, so it may have + artifacts, noise or subliminal messages from satan. Also, the API + isn't stable and I can actually promise that I *will* change the API + some time in the future. + +TODO list: + - Variable calculation resolution depending on quality setting + - Single vs double in float mode + - 16-bit vs 32-bit (sinc only) in fixed-point mode + - Make sure the filter update works even when changing params + after only a few samples procesed +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef OUTSIDE_SPEEX +#include +static void *speex_alloc (int size) {return calloc(size,1);} +static void *speex_realloc (void *ptr, int size) {return realloc(ptr, size);} +static void speex_free (void *ptr) {free(ptr);} +#include "speex_resampler.h" +#include "arch.h" +#else /* OUTSIDE_SPEEX */ + +#include "speex/speex_resampler.h" +#include "misc.h" +#endif /* OUTSIDE_SPEEX */ + +#include + +#ifndef M_PI +#define M_PI 3.14159263 +#endif + +#ifdef FIXED_POINT +#define WORD2INT(x) ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x))) +#else +#define WORD2INT(x) ((x) < -32767.5f ? -32768 : ((x) > 32766.5f ? 32767 : floor(.5+(x)))) +#endif + +/*#define float double*/ +#define FILTER_SIZE 64 +#define OVERSAMPLE 8 + +#define IMAX(a,b) ((a) > (b) ? (a) : (b)) +#define IMIN(a,b) ((a) < (b) ? (a) : (b)) + +#ifndef NULL +#define NULL 0 +#endif + +typedef int (*resampler_basic_func)(SpeexResamplerState *, spx_uint32_t , const spx_word16_t *, spx_uint32_t *, spx_word16_t *, spx_uint32_t *); + +struct SpeexResamplerState_ { + spx_uint32_t in_rate; + spx_uint32_t out_rate; + spx_uint32_t num_rate; + spx_uint32_t den_rate; + + int quality; + spx_uint32_t nb_channels; + spx_uint32_t filt_len; + spx_uint32_t mem_alloc_size; + int int_advance; + int frac_advance; + float cutoff; + spx_uint32_t oversample; + int initialised; + int started; + + /* These are per-channel */ + spx_int32_t *last_sample; + spx_uint32_t *samp_frac_num; + spx_uint32_t *magic_samples; + + spx_word16_t *mem; + spx_word16_t *sinc_table; + spx_uint32_t sinc_table_length; + resampler_basic_func resampler_ptr; + + int in_stride; + int out_stride; +} ; + +static double kaiser12_table[68] = { + 0.99859849, 1.00000000, 0.99859849, 0.99440475, 0.98745105, 0.97779076, + 0.96549770, 0.95066529, 0.93340547, 0.91384741, 0.89213598, 0.86843014, + 0.84290116, 0.81573067, 0.78710866, 0.75723148, 0.72629970, 0.69451601, + 0.66208321, 0.62920216, 0.59606986, 0.56287762, 0.52980938, 0.49704014, + 0.46473455, 0.43304576, 0.40211431, 0.37206735, 0.34301800, 0.31506490, + 0.28829195, 0.26276832, 0.23854851, 0.21567274, 0.19416736, 0.17404546, + 0.15530766, 0.13794294, 0.12192957, 0.10723616, 0.09382272, 0.08164178, + 0.07063950, 0.06075685, 0.05193064, 0.04409466, 0.03718069, 0.03111947, + 0.02584161, 0.02127838, 0.01736250, 0.01402878, 0.01121463, 0.00886058, + 0.00691064, 0.00531256, 0.00401805, 0.00298291, 0.00216702, 0.00153438, + 0.00105297, 0.00069463, 0.00043489, 0.00025272, 0.00013031, 0.0000527734, + 0.00001000, 0.00000000}; +/* +static double kaiser12_table[36] = { + 0.99440475, 1.00000000, 0.99440475, 0.97779076, 0.95066529, 0.91384741, + 0.86843014, 0.81573067, 0.75723148, 0.69451601, 0.62920216, 0.56287762, + 0.49704014, 0.43304576, 0.37206735, 0.31506490, 0.26276832, 0.21567274, + 0.17404546, 0.13794294, 0.10723616, 0.08164178, 0.06075685, 0.04409466, + 0.03111947, 0.02127838, 0.01402878, 0.00886058, 0.00531256, 0.00298291, + 0.00153438, 0.00069463, 0.00025272, 0.0000527734, 0.00000500, 0.00000000}; +*/ +static double kaiser10_table[36] = { + 0.99537781, 1.00000000, 0.99537781, 0.98162644, 0.95908712, 0.92831446, + 0.89005583, 0.84522401, 0.79486424, 0.74011713, 0.68217934, 0.62226347, + 0.56155915, 0.50119680, 0.44221549, 0.38553619, 0.33194107, 0.28205962, + 0.23636152, 0.19515633, 0.15859932, 0.12670280, 0.09935205, 0.07632451, + 0.05731132, 0.04193980, 0.02979584, 0.02044510, 0.01345224, 0.00839739, + 0.00488951, 0.00257636, 0.00115101, 0.00035515, 0.00000000, 0.00000000}; + +static double kaiser8_table[36] = { + 0.99635258, 1.00000000, 0.99635258, 0.98548012, 0.96759014, 0.94302200, + 0.91223751, 0.87580811, 0.83439927, 0.78875245, 0.73966538, 0.68797126, + 0.63451750, 0.58014482, 0.52566725, 0.47185369, 0.41941150, 0.36897272, + 0.32108304, 0.27619388, 0.23465776, 0.19672670, 0.16255380, 0.13219758, + 0.10562887, 0.08273982, 0.06335451, 0.04724088, 0.03412321, 0.02369490, + 0.01563093, 0.00959968, 0.00527363, 0.00233883, 0.00050000, 0.00000000}; + +static double kaiser6_table[36] = { + 0.99733006, 1.00000000, 0.99733006, 0.98935595, 0.97618418, 0.95799003, + 0.93501423, 0.90755855, 0.87598009, 0.84068475, 0.80211977, 0.76076565, + 0.71712752, 0.67172623, 0.62508937, 0.57774224, 0.53019925, 0.48295561, + 0.43647969, 0.39120616, 0.34752997, 0.30580127, 0.26632152, 0.22934058, + 0.19505503, 0.16360756, 0.13508755, 0.10953262, 0.08693120, 0.06722600, + 0.05031820, 0.03607231, 0.02432151, 0.01487334, 0.00752000, 0.00000000}; + +struct FuncDef { + double *table; + int oversample; +}; + +static struct FuncDef _KAISER12 = {kaiser12_table, 64}; +#define KAISER12 (&_KAISER12) +/*static struct FuncDef _KAISER12 = {kaiser12_table, 32}; +#define KAISER12 (&_KAISER12)*/ +static struct FuncDef _KAISER10 = {kaiser10_table, 32}; +#define KAISER10 (&_KAISER10) +static struct FuncDef _KAISER8 = {kaiser8_table, 32}; +#define KAISER8 (&_KAISER8) +static struct FuncDef _KAISER6 = {kaiser6_table, 32}; +#define KAISER6 (&_KAISER6) + +struct QualityMapping { + int base_length; + int oversample; + float downsample_bandwidth; + float upsample_bandwidth; + struct FuncDef *window_func; +}; + + +/* This table maps conversion quality to internal parameters. There are two + reasons that explain why the up-sampling bandwidth is larger than the + down-sampling bandwidth: + 1) When up-sampling, we can assume that the spectrum is already attenuated + close to the Nyquist rate (from an A/D or a previous resampling filter) + 2) Any aliasing that occurs very close to the Nyquist rate will be masked + by the sinusoids/noise just below the Nyquist rate (guaranteed only for + up-sampling). +*/ +static const struct QualityMapping quality_map[11] = { + { 8, 4, 0.830f, 0.860f, KAISER6 }, /* Q0 */ + { 16, 4, 0.850f, 0.880f, KAISER6 }, /* Q1 */ + { 32, 4, 0.882f, 0.910f, KAISER6 }, /* Q2 */ /* 82.3% cutoff ( ~60 dB stop) 6 */ + { 48, 8, 0.895f, 0.917f, KAISER8 }, /* Q3 */ /* 84.9% cutoff ( ~80 dB stop) 8 */ + { 64, 8, 0.921f, 0.940f, KAISER8 }, /* Q4 */ /* 88.7% cutoff ( ~80 dB stop) 8 */ + { 80, 16, 0.922f, 0.940f, KAISER10}, /* Q5 */ /* 89.1% cutoff (~100 dB stop) 10 */ + { 96, 16, 0.940f, 0.945f, KAISER10}, /* Q6 */ /* 91.5% cutoff (~100 dB stop) 10 */ + {128, 16, 0.950f, 0.950f, KAISER10}, /* Q7 */ /* 93.1% cutoff (~100 dB stop) 10 */ + {160, 16, 0.960f, 0.960f, KAISER10}, /* Q8 */ /* 94.5% cutoff (~100 dB stop) 10 */ + {192, 32, 0.968f, 0.968f, KAISER12}, /* Q9 */ /* 95.5% cutoff (~100 dB stop) 10 */ + {256, 32, 0.975f, 0.975f, KAISER12}, /* Q10 */ /* 96.6% cutoff (~100 dB stop) 10 */ +}; +/*8,24,40,56,80,104,128,160,200,256,320*/ +static double compute_func(float x, struct FuncDef *func) +{ + float y, frac; + double interp[4]; + int ind; + y = x*func->oversample; + ind = (int)floor(y); + frac = (y-ind); + /* CSE with handle the repeated powers */ + interp[3] = -0.1666666667*frac + 0.1666666667*(frac*frac*frac); + interp[2] = frac + 0.5*(frac*frac) - 0.5*(frac*frac*frac); + /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/ + interp[0] = -0.3333333333*frac + 0.5*(frac*frac) - 0.1666666667*(frac*frac*frac); + /* Just to make sure we don't have rounding problems */ + interp[1] = 1.f-interp[3]-interp[2]-interp[0]; + + /*sum = frac*accum[1] + (1-frac)*accum[2];*/ + return interp[0]*func->table[ind] + interp[1]*func->table[ind+1] + interp[2]*func->table[ind+2] + interp[3]*func->table[ind+3]; +} + +#if 0 +#include +int main(int argc, char **argv) +{ + int i; + for (i=0;i<256;i++) + { + printf ("%f\n", compute_func(i/256., KAISER12)); + } + return 0; +} +#endif + +#ifdef FIXED_POINT +/* The slow way of computing a sinc for the table. Should improve that some day */ +static spx_word16_t sinc(float cutoff, float x, int N, struct FuncDef *window_func) +{ + /*fprintf (stderr, "%f ", x);*/ + float xx = x * cutoff; + if (fabs(x)<1e-6f) + return WORD2INT(32768.*cutoff); + else if (fabs(x) > .5f*N) + return 0; + /*FIXME: Can it really be any slower than this? */ + return WORD2INT(32768.*cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func)); +} +#else +/* The slow way of computing a sinc for the table. Should improve that some day */ +static spx_word16_t sinc(float cutoff, float x, int N, struct FuncDef *window_func) +{ + /*fprintf (stderr, "%f ", x);*/ + float xx = x * cutoff; + if (fabs(x)<1e-6) + return cutoff; + else if (fabs(x) > .5*N) + return 0; + /*FIXME: Can it really be any slower than this? */ + return cutoff*sin(M_PI*xx)/(M_PI*xx) * compute_func(fabs(2.*x/N), window_func); +} +#endif + +#ifdef FIXED_POINT +static void cubic_coef(spx_word16_t x, spx_word16_t interp[4]) +{ + /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation + but I know it's MMSE-optimal on a sinc */ + spx_word16_t x2, x3; + x2 = MULT16_16_P15(x, x); + x3 = MULT16_16_P15(x, x2); + interp[0] = PSHR32(MULT16_16(QCONST16(-0.16667f, 15),x) + MULT16_16(QCONST16(0.16667f, 15),x3),15); + interp[1] = EXTRACT16(EXTEND32(x) + SHR32(SUB32(EXTEND32(x2),EXTEND32(x3)),1)); + interp[3] = PSHR32(MULT16_16(QCONST16(-0.33333f, 15),x) + MULT16_16(QCONST16(.5f,15),x2) - MULT16_16(QCONST16(0.16667f, 15),x3),15); + /* Just to make sure we don't have rounding problems */ + interp[2] = Q15_ONE-interp[0]-interp[1]-interp[3]; + if (interp[2]<32767) + interp[2]+=1; +} +#else +static void cubic_coef(spx_word16_t frac, spx_word16_t interp[4]) +{ + /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation + but I know it's MMSE-optimal on a sinc */ + interp[0] = -0.16667f*frac + 0.16667f*frac*frac*frac; + interp[1] = frac + 0.5f*frac*frac - 0.5f*frac*frac*frac; + /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/ + interp[3] = -0.33333f*frac + 0.5f*frac*frac - 0.16667f*frac*frac*frac; + /* Just to make sure we don't have rounding problems */ + interp[2] = 1.-interp[0]-interp[1]-interp[3]; +} +#endif + +static int resampler_basic_direct_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + int N = st->filt_len; + int out_sample = 0; + spx_word16_t *mem; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + mem = st->mem + channel_index * st->mem_alloc_size; + while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) + { + int j; + spx_word32_t sum=0; + + /* We already have all the filter coefficients pre-computed in the table */ + const spx_word16_t *ptr; + /* Do the memory part */ + for (j=0;last_sample-N+1+j < 0;j++) + { + sum += MULT16_16(mem[last_sample+j],st->sinc_table[samp_frac_num*st->filt_len+j]); + } + + /* Do the new part */ + ptr = in+st->in_stride*(last_sample-N+1+j); + for (;jsinc_table[samp_frac_num*st->filt_len+j]); + ptr += st->in_stride; + } + + *out = PSHR32(sum,15); + out += st->out_stride; + out_sample++; + last_sample += st->int_advance; + samp_frac_num += st->frac_advance; + if (samp_frac_num >= st->den_rate) + { + samp_frac_num -= st->den_rate; + last_sample++; + } + } + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; +} + +#ifdef FIXED_POINT +#else +/* This is the same as the previous function, except with a double-precision accumulator */ +static int resampler_basic_direct_double(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + int N = st->filt_len; + int out_sample = 0; + spx_word16_t *mem; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + mem = st->mem + channel_index * st->mem_alloc_size; + while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) + { + int j; + double sum=0; + + /* We already have all the filter coefficients pre-computed in the table */ + const spx_word16_t *ptr; + /* Do the memory part */ + for (j=0;last_sample-N+1+j < 0;j++) + { + sum += MULT16_16(mem[last_sample+j],(double)st->sinc_table[samp_frac_num*st->filt_len+j]); + } + + /* Do the new part */ + ptr = in+st->in_stride*(last_sample-N+1+j); + for (;jsinc_table[samp_frac_num*st->filt_len+j]); + ptr += st->in_stride; + } + + *out = sum; + out += st->out_stride; + out_sample++; + last_sample += st->int_advance; + samp_frac_num += st->frac_advance; + if (samp_frac_num >= st->den_rate) + { + samp_frac_num -= st->den_rate; + last_sample++; + } + } + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; +} +#endif + +static int resampler_basic_interpolate_single(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + int N = st->filt_len; + int out_sample = 0; + spx_word16_t *mem; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + mem = st->mem + channel_index * st->mem_alloc_size; + while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) + { + int j; + spx_word32_t sum=0; + + /* We need to interpolate the sinc filter */ + spx_word32_t accum[4] = {0.f,0.f, 0.f, 0.f}; + spx_word16_t interp[4]; + const spx_word16_t *ptr; + int offset; + spx_word16_t frac; + offset = samp_frac_num*st->oversample/st->den_rate; +#ifdef FIXED_POINT + frac = PDIV32(SHL32((samp_frac_num*st->oversample) % st->den_rate,15),st->den_rate); +#else + frac = ((float)((samp_frac_num*st->oversample) % st->den_rate))/st->den_rate; +#endif + /* This code is written like this to make it easy to optimise with SIMD. + For most DSPs, it would be best to split the loops in two because most DSPs + have only two accumulators */ + for (j=0;last_sample-N+1+j < 0;j++) + { + spx_word16_t curr_mem = mem[last_sample+j]; + accum[0] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset-2]); + accum[1] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset-1]); + accum[2] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset]); + accum[3] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset+1]); + } + ptr = in+st->in_stride*(last_sample-N+1+j); + /* Do the new part */ + for (;jin_stride; + accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]); + accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]); + accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]); + accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]); + } + cubic_coef(frac, interp); + sum = MULT16_32_Q15(interp[0],accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]); + + *out = PSHR32(sum,15); + out += st->out_stride; + out_sample++; + last_sample += st->int_advance; + samp_frac_num += st->frac_advance; + if (samp_frac_num >= st->den_rate) + { + samp_frac_num -= st->den_rate; + last_sample++; + } + } + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; +} + +#ifdef FIXED_POINT +#else +/* This is the same as the previous function, except with a double-precision accumulator */ +static int resampler_basic_interpolate_double(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + int N = st->filt_len; + int out_sample = 0; + spx_word16_t *mem; + int last_sample = st->last_sample[channel_index]; + spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index]; + mem = st->mem + channel_index * st->mem_alloc_size; + while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len)) + { + int j; + spx_word32_t sum=0; + + /* We need to interpolate the sinc filter */ + double accum[4] = {0.f,0.f, 0.f, 0.f}; + float interp[4]; + const spx_word16_t *ptr; + float alpha = ((float)samp_frac_num)/st->den_rate; + int offset = samp_frac_num*st->oversample/st->den_rate; + float frac = alpha*st->oversample - offset; + /* This code is written like this to make it easy to optimise with SIMD. + For most DSPs, it would be best to split the loops in two because most DSPs + have only two accumulators */ + for (j=0;last_sample-N+1+j < 0;j++) + { + double curr_mem = mem[last_sample+j]; + accum[0] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset-2]); + accum[1] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset-1]); + accum[2] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset]); + accum[3] += MULT16_16(curr_mem,st->sinc_table[4+(j+1)*st->oversample-offset+1]); + } + ptr = in+st->in_stride*(last_sample-N+1+j); + /* Do the new part */ + for (;jin_stride; + accum[0] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-2]); + accum[1] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset-1]); + accum[2] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset]); + accum[3] += MULT16_16(curr_in,st->sinc_table[4+(j+1)*st->oversample-offset+1]); + } + cubic_coef(frac, interp); + sum = interp[0]*accum[0] + interp[1]*accum[1] + interp[2]*accum[2] + interp[3]*accum[3]; + + *out = PSHR32(sum,15); + out += st->out_stride; + out_sample++; + last_sample += st->int_advance; + samp_frac_num += st->frac_advance; + if (samp_frac_num >= st->den_rate) + { + samp_frac_num -= st->den_rate; + last_sample++; + } + } + st->last_sample[channel_index] = last_sample; + st->samp_frac_num[channel_index] = samp_frac_num; + return out_sample; +} +#endif + +static void update_filter(SpeexResamplerState *st) +{ + spx_uint32_t old_length; + + old_length = st->filt_len; + st->oversample = quality_map[st->quality].oversample; + st->filt_len = quality_map[st->quality].base_length; + + if (st->num_rate > st->den_rate) + { + /* down-sampling */ + st->cutoff = quality_map[st->quality].downsample_bandwidth * st->den_rate / st->num_rate; + /* FIXME: divide the numerator and denominator by a certain amount if they're too large */ + st->filt_len = st->filt_len*st->num_rate / st->den_rate; + /* Round down to make sure we have a multiple of 4 */ + st->filt_len &= (~0x3); + if (2*st->den_rate < st->num_rate) + st->oversample >>= 1; + if (4*st->den_rate < st->num_rate) + st->oversample >>= 1; + if (8*st->den_rate < st->num_rate) + st->oversample >>= 1; + if (16*st->den_rate < st->num_rate) + st->oversample >>= 1; + if (st->oversample < 1) + st->oversample = 1; + } else { + /* up-sampling */ + st->cutoff = quality_map[st->quality].upsample_bandwidth; + } + + /* Choose the resampling type that requires the least amount of memory */ + if (st->den_rate <= st->oversample) + { + spx_uint32_t i; + if (!st->sinc_table) + st->sinc_table = (spx_word16_t *)speex_alloc(st->filt_len*st->den_rate*sizeof(spx_word16_t)); + else if (st->sinc_table_length < st->filt_len*st->den_rate) + { + st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,st->filt_len*st->den_rate*sizeof(spx_word16_t)); + st->sinc_table_length = st->filt_len*st->den_rate; + } + for (i=0;iden_rate;i++) + { + spx_int32_t j; + for (j=0;jfilt_len;j++) + { + st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-(spx_int32_t)st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len, quality_map[st->quality].window_func); + } + } +#ifdef FIXED_POINT + st->resampler_ptr = resampler_basic_direct_single; +#else + if (st->quality>8) + st->resampler_ptr = resampler_basic_direct_double; + else + st->resampler_ptr = resampler_basic_direct_single; +#endif + /*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff);*/ + } else { + spx_int32_t i; + if (!st->sinc_table) + st->sinc_table = (spx_word16_t *)speex_alloc((st->filt_len*st->oversample+8)*sizeof(spx_word16_t)); + else if (st->sinc_table_length < st->filt_len*st->oversample+8) + { + st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,(st->filt_len*st->oversample+8)*sizeof(spx_word16_t)); + st->sinc_table_length = st->filt_len*st->oversample+8; + } + for (i=-4;i<(spx_int32_t)(st->oversample*st->filt_len+4);i++) + st->sinc_table[i+4] = sinc(st->cutoff,(i/(float)st->oversample - st->filt_len/2), st->filt_len, quality_map[st->quality].window_func); +#ifdef FIXED_POINT + st->resampler_ptr = resampler_basic_interpolate_single; +#else + if (st->quality>8) + st->resampler_ptr = resampler_basic_interpolate_double; + else + st->resampler_ptr = resampler_basic_interpolate_single; +#endif + /*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff);*/ + } + st->int_advance = st->num_rate/st->den_rate; + st->frac_advance = st->num_rate%st->den_rate; + + + /* Here's the place where we update the filter memory to take into account + the change in filter length. It's probably the messiest part of the code + due to handling of lots of corner cases. */ + if (!st->mem) + { + spx_uint32_t i; + st->mem = (spx_word16_t*)speex_alloc(st->nb_channels*(st->filt_len-1) * sizeof(spx_word16_t)); + for (i=0;inb_channels*(st->filt_len-1);i++) + st->mem[i] = 0; + st->mem_alloc_size = st->filt_len-1; + /*speex_warning("init filter");*/ + } else if (!st->started) + { + spx_uint32_t i; + st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*(st->filt_len-1) * sizeof(spx_word16_t)); + for (i=0;inb_channels*(st->filt_len-1);i++) + st->mem[i] = 0; + st->mem_alloc_size = st->filt_len-1; + /*speex_warning("reinit filter");*/ + } else if (st->filt_len > old_length) + { + spx_int32_t i; + /* Increase the filter length */ + /*speex_warning("increase filter size");*/ + int old_alloc_size = st->mem_alloc_size; + if (st->filt_len-1 > st->mem_alloc_size) + { + st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*(st->filt_len-1) * sizeof(spx_word16_t)); + st->mem_alloc_size = st->filt_len-1; + } + for (i=st->nb_channels-1;i>=0;i--) + { + spx_int32_t j; + spx_uint32_t olen = old_length; + /*if (st->magic_samples[i])*/ + { + /* Try and remove the magic samples as if nothing had happened */ + + /* FIXME: This is wrong but for now we need it to avoid going over the array bounds */ + olen = old_length + 2*st->magic_samples[i]; + for (j=old_length-2+st->magic_samples[i];j>=0;j--) + st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]] = st->mem[i*old_alloc_size+j]; + for (j=0;jmagic_samples[i];j++) + st->mem[i*st->mem_alloc_size+j] = 0; + st->magic_samples[i] = 0; + } + if (st->filt_len > olen) + { + /* If the new filter length is still bigger than the "augmented" length */ + /* Copy data going backward */ + for (j=0;jmem[i*st->mem_alloc_size+(st->filt_len-2-j)] = st->mem[i*st->mem_alloc_size+(olen-2-j)]; + /* Then put zeros for lack of anything better */ + for (;jfilt_len-1;j++) + st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = 0; + /* Adjust last_sample */ + st->last_sample[i] += (st->filt_len - olen)/2; + } else { + /* Put back some of the magic! */ + st->magic_samples[i] = (olen - st->filt_len)/2; + for (j=0;jfilt_len-1+st->magic_samples[i];j++) + st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]]; + } + } + } else if (st->filt_len < old_length) + { + spx_uint32_t i; + /* Reduce filter length, this a bit tricky. We need to store some of the memory as "magic" + samples so they can be used directly as input the next time(s) */ + for (i=0;inb_channels;i++) + { + spx_uint32_t j; + spx_uint32_t old_magic = st->magic_samples[i]; + st->magic_samples[i] = (old_length - st->filt_len)/2; + /* We must copy some of the memory that's no longer used */ + /* Copy data going backward */ + for (j=0;jfilt_len-1+st->magic_samples[i]+old_magic;j++) + st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]]; + st->magic_samples[i] += old_magic; + } + } + +} + +SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err) +{ + return speex_resampler_init_frac(nb_channels, in_rate, out_rate, in_rate, out_rate, quality, err); +} + +SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err) +{ + spx_uint32_t i; + SpeexResamplerState *st; + if (quality > 10 || quality < 0) + { + if (err) + *err = RESAMPLER_ERR_INVALID_ARG; + return NULL; + } + st = (SpeexResamplerState *)speex_alloc(sizeof(SpeexResamplerState)); + st->initialised = 0; + st->started = 0; + st->in_rate = 0; + st->out_rate = 0; + st->num_rate = 0; + st->den_rate = 0; + st->quality = -1; + st->sinc_table_length = 0; + st->mem_alloc_size = 0; + st->filt_len = 0; + st->mem = 0; + st->resampler_ptr = 0; + + st->cutoff = 1.f; + st->nb_channels = nb_channels; + st->in_stride = 1; + st->out_stride = 1; + + /* Per channel data */ + st->last_sample = (spx_int32_t*)speex_alloc(nb_channels*sizeof(int)); + st->magic_samples = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(int)); + st->samp_frac_num = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(int)); + for (i=0;ilast_sample[i] = 0; + st->magic_samples[i] = 0; + st->samp_frac_num[i] = 0; + } + + speex_resampler_set_quality(st, quality); + speex_resampler_set_rate_frac(st, ratio_num, ratio_den, in_rate, out_rate); + + + update_filter(st); + + st->initialised = 1; + if (err) + *err = RESAMPLER_ERR_SUCCESS; + + return st; +} + +void speex_resampler_destroy(SpeexResamplerState *st) +{ + speex_free(st->mem); + speex_free(st->sinc_table); + speex_free(st->last_sample); + speex_free(st->magic_samples); + speex_free(st->samp_frac_num); + speex_free(st); +} + + + +static int speex_resampler_process_native(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_word16_t *in, spx_uint32_t *in_len, spx_word16_t *out, spx_uint32_t *out_len) +{ + int j=0; + int N = st->filt_len; + int out_sample = 0; + spx_word16_t *mem; + spx_uint32_t tmp_out_len = 0; + mem = st->mem + channel_index * st->mem_alloc_size; + st->started = 1; + + /* Handle the case where we have samples left from a reduction in filter length */ + if (st->magic_samples[channel_index]) + { + int istride_save; + spx_uint32_t tmp_in_len; + spx_uint32_t tmp_magic; + + istride_save = st->in_stride; + tmp_in_len = st->magic_samples[channel_index]; + tmp_out_len = *out_len; + /* magic_samples needs to be set to zero to avoid infinite recursion */ + tmp_magic = st->magic_samples[channel_index]; + st->magic_samples[channel_index] = 0; + st->in_stride = 1; + speex_resampler_process_native(st, channel_index, mem+N-1, &tmp_in_len, out, &tmp_out_len); + st->in_stride = istride_save; + /*speex_warning_int("extra samples:", tmp_out_len);*/ + /* If we couldn't process all "magic" input samples, save the rest for next time */ + if (tmp_in_len < tmp_magic) + { + spx_uint32_t i; + st->magic_samples[channel_index] = tmp_magic-tmp_in_len; + for (i=0;imagic_samples[channel_index];i++) + mem[N-1+i]=mem[N-1+i+tmp_in_len]; + } + out += tmp_out_len*st->out_stride; + *out_len -= tmp_out_len; + } + + /* Call the right resampler through the function ptr */ + out_sample = st->resampler_ptr(st, channel_index, in, in_len, out, out_len); + + if (st->last_sample[channel_index] < (spx_int32_t)*in_len) + *in_len = st->last_sample[channel_index]; + *out_len = out_sample+tmp_out_len; + st->last_sample[channel_index] -= *in_len; + + for (j=0;jin_stride*(j+*in_len-N+1)]; + + return RESAMPLER_ERR_SUCCESS; +} + +#define FIXED_STACK_ALLOC 1024 + +#ifdef FIXED_POINT +int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len) +{ + spx_uint32_t i; + int istride_save, ostride_save; +#ifdef VAR_ARRAYS + spx_word16_t x[*in_len]; + spx_word16_t y[*out_len]; + /*VARDECL(spx_word16_t *x); + VARDECL(spx_word16_t *y); + ALLOC(x, *in_len, spx_word16_t); + ALLOC(y, *out_len, spx_word16_t);*/ + istride_save = st->in_stride; + ostride_save = st->out_stride; + for (i=0;i<*in_len;i++) + x[i] = WORD2INT(in[i*st->in_stride]); + st->in_stride = st->out_stride = 1; + speex_resampler_process_native(st, channel_index, x, in_len, y, out_len); + st->in_stride = istride_save; + st->out_stride = ostride_save; + for (i=0;i<*out_len;i++) + out[i*st->out_stride] = y[i]; +#else + spx_word16_t x[FIXED_STACK_ALLOC]; + spx_word16_t y[FIXED_STACK_ALLOC]; + spx_uint32_t ilen=*in_len, olen=*out_len; + istride_save = st->in_stride; + ostride_save = st->out_stride; + while (ilen && olen) + { + spx_uint32_t ichunk, ochunk; + ichunk = ilen; + ochunk = olen; + if (ichunk>FIXED_STACK_ALLOC) + ichunk=FIXED_STACK_ALLOC; + if (ochunk>FIXED_STACK_ALLOC) + ochunk=FIXED_STACK_ALLOC; + for (i=0;iin_stride]); + st->in_stride = st->out_stride = 1; + speex_resampler_process_native(st, channel_index, x, &ichunk, y, &ochunk); + st->in_stride = istride_save; + st->out_stride = ostride_save; + for (i=0;iout_stride] = y[i]; + out += ochunk; + in += ichunk; + ilen -= ichunk; + olen -= ochunk; + } + *in_len -= ilen; + *out_len -= olen; +#endif + return RESAMPLER_ERR_SUCCESS; +} +int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len) +{ + return speex_resampler_process_native(st, channel_index, in, in_len, out, out_len); +} +#else +int speex_resampler_process_float(SpeexResamplerState *st, spx_uint32_t channel_index, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len) +{ + return speex_resampler_process_native(st, channel_index, in, in_len, out, out_len); +} +int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t channel_index, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len) +{ + spx_uint32_t i; + int istride_save, ostride_save; +#ifdef VAR_ARRAYS + spx_word16_t x[*in_len]; + spx_word16_t y[*out_len]; + /*VARDECL(spx_word16_t *x); + VARDECL(spx_word16_t *y); + ALLOC(x, *in_len, spx_word16_t); + ALLOC(y, *out_len, spx_word16_t);*/ + istride_save = st->in_stride; + ostride_save = st->out_stride; + for (i=0;i<*in_len;i++) + x[i] = in[i*st->in_stride]; + st->in_stride = st->out_stride = 1; + speex_resampler_process_native(st, channel_index, x, in_len, y, out_len); + st->in_stride = istride_save; + st->out_stride = ostride_save; + for (i=0;i<*out_len;i++) + out[i*st->out_stride] = WORD2INT(y[i]); +#else + spx_word16_t x[FIXED_STACK_ALLOC]; + spx_word16_t y[FIXED_STACK_ALLOC]; + spx_uint32_t ilen=*in_len, olen=*out_len; + istride_save = st->in_stride; + ostride_save = st->out_stride; + while (ilen && olen) + { + spx_uint32_t ichunk, ochunk; + ichunk = ilen; + ochunk = olen; + if (ichunk>FIXED_STACK_ALLOC) + ichunk=FIXED_STACK_ALLOC; + if (ochunk>FIXED_STACK_ALLOC) + ochunk=FIXED_STACK_ALLOC; + for (i=0;iin_stride]; + st->in_stride = st->out_stride = 1; + speex_resampler_process_native(st, channel_index, x, &ichunk, y, &ochunk); + st->in_stride = istride_save; + st->out_stride = ostride_save; + for (i=0;iout_stride] = WORD2INT(y[i]); + out += ochunk; + in += ichunk; + ilen -= ichunk; + olen -= ochunk; + } + *in_len -= ilen; + *out_len -= olen; +#endif + return RESAMPLER_ERR_SUCCESS; +} +#endif + +int speex_resampler_process_interleaved_float(SpeexResamplerState *st, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len) +{ + spx_uint32_t i; + int istride_save, ostride_save; + spx_uint32_t bak_len = *out_len; + istride_save = st->in_stride; + ostride_save = st->out_stride; + st->in_stride = st->out_stride = st->nb_channels; + for (i=0;inb_channels;i++) + { + *out_len = bak_len; + speex_resampler_process_float(st, i, in+i, in_len, out+i, out_len); + } + st->in_stride = istride_save; + st->out_stride = ostride_save; + return RESAMPLER_ERR_SUCCESS; +} + + +int speex_resampler_process_interleaved_int(SpeexResamplerState *st, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len) +{ + spx_uint32_t i; + int istride_save, ostride_save; + spx_uint32_t bak_len = *out_len; + istride_save = st->in_stride; + ostride_save = st->out_stride; + st->in_stride = st->out_stride = st->nb_channels; + for (i=0;inb_channels;i++) + { + *out_len = bak_len; + speex_resampler_process_int(st, i, in+i, in_len, out+i, out_len); + } + st->in_stride = istride_save; + st->out_stride = ostride_save; + return RESAMPLER_ERR_SUCCESS; +} + +int speex_resampler_set_rate(SpeexResamplerState *st, spx_uint32_t in_rate, spx_uint32_t out_rate) +{ + return speex_resampler_set_rate_frac(st, in_rate, out_rate, in_rate, out_rate); +} + +void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_rate, spx_uint32_t *out_rate) +{ + *in_rate = st->in_rate; + *out_rate = st->out_rate; +} + +int speex_resampler_set_rate_frac(SpeexResamplerState *st, spx_uint32_t ratio_num, spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate) +{ + spx_uint32_t fact; + spx_uint32_t old_den; + spx_uint32_t i; + if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den) + return RESAMPLER_ERR_SUCCESS; + + old_den = st->den_rate; + st->in_rate = in_rate; + st->out_rate = out_rate; + st->num_rate = ratio_num; + st->den_rate = ratio_den; + /* FIXME: This is terribly inefficient, but who cares (at least for now)? */ + for (fact=2;fact<=IMIN(st->num_rate, st->den_rate);fact++) + { + while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0)) + { + st->num_rate /= fact; + st->den_rate /= fact; + } + } + + if (old_den > 0) + { + for (i=0;inb_channels;i++) + { + st->samp_frac_num[i]=st->samp_frac_num[i]*st->den_rate/old_den; + /* Safety net */ + if (st->samp_frac_num[i] >= st->den_rate) + st->samp_frac_num[i] = st->den_rate-1; + } + } + + if (st->initialised) + update_filter(st); + return RESAMPLER_ERR_SUCCESS; +} + +void speex_resampler_get_ratio(SpeexResamplerState *st, spx_uint32_t *ratio_num, spx_uint32_t *ratio_den) +{ + *ratio_num = st->num_rate; + *ratio_den = st->den_rate; +} + +int speex_resampler_set_quality(SpeexResamplerState *st, int quality) +{ + if (quality > 10 || quality < 0) + return RESAMPLER_ERR_INVALID_ARG; + if (st->quality == quality) + return RESAMPLER_ERR_SUCCESS; + st->quality = quality; + if (st->initialised) + update_filter(st); + return RESAMPLER_ERR_SUCCESS; +} + +void speex_resampler_get_quality(SpeexResamplerState *st, int *quality) +{ + *quality = st->quality; +} + +void speex_resampler_set_input_stride(SpeexResamplerState *st, spx_uint32_t stride) +{ + st->in_stride = stride; +} + +void speex_resampler_get_input_stride(SpeexResamplerState *st, spx_uint32_t *stride) +{ + *stride = st->in_stride; +} + +void speex_resampler_set_output_stride(SpeexResamplerState *st, spx_uint32_t stride) +{ + st->out_stride = stride; +} + +void speex_resampler_get_output_stride(SpeexResamplerState *st, spx_uint32_t *stride) +{ + *stride = st->out_stride; +} + +int speex_resampler_skip_zeros(SpeexResamplerState *st) +{ + spx_uint32_t i; + for (i=0;inb_channels;i++) + st->last_sample[i] = st->filt_len/2; + return RESAMPLER_ERR_SUCCESS; +} + +int speex_resampler_reset_mem(SpeexResamplerState *st) +{ + spx_uint32_t i; + for (i=0;inb_channels*(st->filt_len-1);i++) + st->mem[i] = 0; + return RESAMPLER_ERR_SUCCESS; +} + +const char *speex_resampler_strerror(int err) +{ + switch (err) + { + case RESAMPLER_ERR_SUCCESS: + return "Success."; + case RESAMPLER_ERR_ALLOC_FAILED: + return "Memory allocation failed."; + case RESAMPLER_ERR_BAD_STATE: + return "Bad resampler state."; + case RESAMPLER_ERR_INVALID_ARG: + return "Invalid argument."; + case RESAMPLER_ERR_PTR_OVERLAP: + return "Input and output buffers overlap."; + default: + return "Unknown error. Bad error code or strange version mismatch."; + } +} diff --git a/src/pulsecore/speex/speex_resampler.h b/src/pulsecore/speex/speex_resampler.h new file mode 100644 index 00000000..c44fbcd0 --- /dev/null +++ b/src/pulsecore/speex/speex_resampler.h @@ -0,0 +1,328 @@ +/* Copyright (C) 2007 Jean-Marc Valin + + File: speex_resampler.h + Resampling code + + The design goals of this code are: + - Very fast algorithm + - Low memory requirement + - Good *perceptual* quality (and not best SNR) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef SPEEX_RESAMPLER_H +#define SPEEX_RESAMPLER_H + +#ifdef OUTSIDE_SPEEX + +/********* WARNING: MENTAL SANITY ENDS HERE *************/ + +/* If the resampler is defined outside of Speex, we change the symbol names so that + there won't be any clash if linking with Speex later on. */ + +/* #define RANDOM_PREFIX your software name here */ +#ifndef RANDOM_PREFIX +#error "Please define RANDOM_PREFIX (above) to something specific to your project to prevent symbol name clashes" +#endif + +#define CAT_PREFIX2(a,b) a ## b +#define CAT_PREFIX(a,b) CAT_PREFIX2(a, b) + +#define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init) +#define speex_resampler_init_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_init_frac) +#define speex_resampler_destroy CAT_PREFIX(RANDOM_PREFIX,_resampler_destroy) +#define speex_resampler_process_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_float) +#define speex_resampler_process_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_int) +#define speex_resampler_process_interleaved_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_float) +#define speex_resampler_process_interleaved_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_int) +#define speex_resampler_set_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate) +#define speex_resampler_get_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_get_rate) +#define speex_resampler_set_rate_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate_frac) +#define speex_resampler_get_ratio CAT_PREFIX(RANDOM_PREFIX,_resampler_get_ratio) +#define speex_resampler_set_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_set_quality) +#define speex_resampler_get_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_get_quality) +#define speex_resampler_set_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_input_stride) +#define speex_resampler_get_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_stride) +#define speex_resampler_set_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_output_stride) +#define speex_resampler_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_stride) +#define speex_resampler_skip_zeros CAT_PREFIX(RANDOM_PREFIX,_resampler_skip_zeros) +#define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem) +#define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror) + +#define spx_int16_t short +#define spx_int32_t int +#define spx_uint16_t unsigned short +#define spx_uint32_t unsigned int + +#else /* OUTSIDE_SPEEX */ + +#include "speex/speex_types.h" + +#endif /* OUTSIDE_SPEEX */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPEEX_RESAMPLER_QUALITY_MAX 10 +#define SPEEX_RESAMPLER_QUALITY_MIN 0 +#define SPEEX_RESAMPLER_QUALITY_DEFAULT 4 +#define SPEEX_RESAMPLER_QUALITY_VOIP 3 +#define SPEEX_RESAMPLER_QUALITY_DESKTOP 5 + +enum { + RESAMPLER_ERR_SUCCESS = 0, + RESAMPLER_ERR_ALLOC_FAILED = 1, + RESAMPLER_ERR_BAD_STATE = 2, + RESAMPLER_ERR_INVALID_ARG = 3, + RESAMPLER_ERR_PTR_OVERLAP = 4, + + RESAMPLER_ERR_MAX_ERROR +}; + +struct SpeexResamplerState_; +typedef struct SpeexResamplerState_ SpeexResamplerState; + +/** Create a new resampler with integer input and output rates. + * @param nb_channels Number of channels to be processed + * @param in_rate Input sampling rate (integer number of Hz). + * @param out_rate Output sampling rate (integer number of Hz). + * @param quality Resampling quality between 0 and 10, where 0 has poor quality + * and 10 has very high quality. + * @return Newly created resampler state + * @retval NULL Error: not enough memory + */ +SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, + spx_uint32_t in_rate, + spx_uint32_t out_rate, + int quality, + int *err); + +/** Create a new resampler with fractional input/output rates. The sampling + * rate ratio is an arbitrary rational number with both the numerator and + * denominator being 32-bit integers. + * @param nb_channels Number of channels to be processed + * @param ratio_num Numerator of the sampling rate ratio + * @param ratio_den Denominator of the sampling rate ratio + * @param in_rate Input sampling rate rounded to the nearest integer (in Hz). + * @param out_rate Output sampling rate rounded to the nearest integer (in Hz). + * @param quality Resampling quality between 0 and 10, where 0 has poor quality + * and 10 has very high quality. + * @return Newly created resampler state + * @retval NULL Error: not enough memory + */ +SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, + spx_uint32_t ratio_num, + spx_uint32_t ratio_den, + spx_uint32_t in_rate, + spx_uint32_t out_rate, + int quality, + int *err); + +/** Destroy a resampler state. + * @param st Resampler state + */ +void speex_resampler_destroy(SpeexResamplerState *st); + +/** Resample a float array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param channel_index Index of the channel to process for the multi-channel + * base (0 otherwise) + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the + * number of samples processed + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written + */ +int speex_resampler_process_float(SpeexResamplerState *st, + spx_uint32_t channel_index, + const float *in, + spx_uint32_t *in_len, + float *out, + spx_uint32_t *out_len); + +/** Resample an int array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param channel_index Index of the channel to process for the multi-channel + * base (0 otherwise) + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the number + * of samples processed + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written + */ +int speex_resampler_process_int(SpeexResamplerState *st, + spx_uint32_t channel_index, + const spx_int16_t *in, + spx_uint32_t *in_len, + spx_int16_t *out, + spx_uint32_t *out_len); + +/** Resample an interleaved float array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the number + * of samples processed. This is all per-channel. + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written. + * This is all per-channel. + */ +int speex_resampler_process_interleaved_float(SpeexResamplerState *st, + const float *in, + spx_uint32_t *in_len, + float *out, + spx_uint32_t *out_len); + +/** Resample an interleaved int array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the number + * of samples processed. This is all per-channel. + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written. + * This is all per-channel. + */ +int speex_resampler_process_interleaved_int(SpeexResamplerState *st, + const spx_int16_t *in, + spx_uint32_t *in_len, + spx_int16_t *out, + spx_uint32_t *out_len); + +/** Set (change) the input/output sampling rates (integer value). + * @param st Resampler state + * @param in_rate Input sampling rate (integer number of Hz). + * @param out_rate Output sampling rate (integer number of Hz). + */ +int speex_resampler_set_rate(SpeexResamplerState *st, + spx_uint32_t in_rate, + spx_uint32_t out_rate); + +/** Get the current input/output sampling rates (integer value). + * @param st Resampler state + * @param in_rate Input sampling rate (integer number of Hz) copied. + * @param out_rate Output sampling rate (integer number of Hz) copied. + */ +void speex_resampler_get_rate(SpeexResamplerState *st, + spx_uint32_t *in_rate, + spx_uint32_t *out_rate); + +/** Set (change) the input/output sampling rates and resampling ratio + * (fractional values in Hz supported). + * @param st Resampler state + * @param ratio_num Numerator of the sampling rate ratio + * @param ratio_den Denominator of the sampling rate ratio + * @param in_rate Input sampling rate rounded to the nearest integer (in Hz). + * @param out_rate Output sampling rate rounded to the nearest integer (in Hz). + */ +int speex_resampler_set_rate_frac(SpeexResamplerState *st, + spx_uint32_t ratio_num, + spx_uint32_t ratio_den, + spx_uint32_t in_rate, + spx_uint32_t out_rate); + +/** Get the current resampling ratio. This will be reduced to the least + * common denominator. + * @param st Resampler state + * @param ratio_num Numerator of the sampling rate ratio copied + * @param ratio_den Denominator of the sampling rate ratio copied + */ +void speex_resampler_get_ratio(SpeexResamplerState *st, + spx_uint32_t *ratio_num, + spx_uint32_t *ratio_den); + +/** Set (change) the conversion quality. + * @param st Resampler state + * @param quality Resampling quality between 0 and 10, where 0 has poor + * quality and 10 has very high quality. + */ +int speex_resampler_set_quality(SpeexResamplerState *st, + int quality); + +/** Get the conversion quality. + * @param st Resampler state + * @param quality Resampling quality between 0 and 10, where 0 has poor + * quality and 10 has very high quality. + */ +void speex_resampler_get_quality(SpeexResamplerState *st, + int *quality); + +/** Set (change) the input stride. + * @param st Resampler state + * @param stride Input stride + */ +void speex_resampler_set_input_stride(SpeexResamplerState *st, + spx_uint32_t stride); + +/** Get the input stride. + * @param st Resampler state + * @param stride Input stride copied + */ +void speex_resampler_get_input_stride(SpeexResamplerState *st, + spx_uint32_t *stride); + +/** Set (change) the output stride. + * @param st Resampler state + * @param stride Output stride + */ +void speex_resampler_set_output_stride(SpeexResamplerState *st, + spx_uint32_t stride); + +/** Get the output stride. + * @param st Resampler state copied + * @param stride Output stride + */ +void speex_resampler_get_output_stride(SpeexResamplerState *st, + spx_uint32_t *stride); + +/** Make sure that the first samples to go out of the resamplers don't have + * leading zeros. This is only useful before starting to use a newly created + * resampler. It is recommended to use that when resampling an audio file, as + * it will generate a file with the same length. For real-time processing, + * it is probably easier not to use this call (so that the output duration + * is the same for the first frame). + * @param st Resampler state + */ +int speex_resampler_skip_zeros(SpeexResamplerState *st); + +/** Reset a resampler so a new (unrelated) stream can be processed. + * @param st Resampler state + */ +int speex_resampler_reset_mem(SpeexResamplerState *st); + +/** Returns the English meaning for an error code + * @param err Error code + * @return English string + */ +const char *speex_resampler_strerror(int err); + +#ifdef __cplusplus +} +#endif + +#endif -- cgit From fdead579b7666f22816ff6712603a989400ecea2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 23 Aug 2007 22:31:51 +0000 Subject: build speex resampler tiwce, once for fixed point, one for floating point git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1708 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 04e57662..097b0831 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -555,10 +555,23 @@ libpulsedsp_la_CFLAGS = $(AM_CFLAGS) libpulsedsp_la_LIBADD = $(AM_LIBADD) libpulse.la libpulsedsp_la_LDFLAGS = -avoid-version +################################### +# Speex Resampler # +################################### + +noinst_LTLIBRARIES = libspeex-resampler-fixed.la libspeex-resampler-float.la + +libspeex_resampler_fixed_la_CPPFLAGS = $(AM_CPPFLAGS) -DRANDOM_PREFIX=paspfx -DOUTSIDE_SPEEX -DFIXED_POINT +libspeex_resampler_fixed_la_SOURCES = pulsecore/speex/resample.c pulsecore/speex/speex_resampler.h pulsecore/speex/arch.h pulsecore/speex/fixed_generic.h + +libspeex_resampler_float_la_CPPFLAGS = $(AM_CPPFLAGS) -DRANDOM_PREFIX=paspfl -DOUTSIDE_SPEEX +libspeex_resampler_float_la_SOURCES = pulsecore/speex/resample.c pulsecore/speex/speex_resampler.h pulsecore/speex/arch.h + ################################### # Daemon core library # ################################### + pulsecoreinclude_HEADERS = \ pulsecore/autoload.h \ pulsecore/atomic.h \ @@ -699,7 +712,7 @@ endif libpulsecore_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBOIL_CFLAGS) libpulsecore_la_LDFLAGS = -version-info $(LIBPULSECORE_VERSION_INFO) -libpulsecore_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSNDFILE_LIBS) $(WINSOCK_LIBS) $(LIBOIL_LIBS) $(LIBICONV) +libpulsecore_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSNDFILE_LIBS) $(WINSOCK_LIBS) $(LIBOIL_LIBS) $(LIBICONV) libspeex-resampler-fixed.la libspeex-resampler-float.la ################################### # Plug-in support libraries # @@ -1384,4 +1397,10 @@ install-exec-hook: massif: pulseaudio libtool --mode=execute valgrind --tool=massif --depth=6 --alloc-fn=pa_xmalloc --alloc-fn=pa_xmalloc0 --alloc-fn=pa_xrealloc --alloc-fn=dbus_realloc --alloc-fn=pa_xnew0_internal --alloc-fn=pa_xnew_internal ./pulseaudio +update-speex: + wget -O pulsecore/speex/speex_resampler.h http://svn.xiph.org/trunk/speex/include/speex/speex_resampler.h + wget -O pulsecore/speex/resample.c http://svn.xiph.org/trunk/speex/libspeex/resample.c + wget -O pulsecore/speex/arch.h http://svn.xiph.org/trunk/speex/libspeex/arch.h + wget -O pulsecore/speex/fixed_generic.h http://svn.xiph.org/trunk/speex/libspeex/fixed_generic.h + .PHONY: utils/padsp -- cgit From c72d4c6b9eeeb07e6c3ff6ff4574653b84d963c5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 23 Aug 2007 22:32:58 +0000 Subject: add a small speex wrapper so that we can include both the fp and the fixed-point resampler in the same binary git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1709 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/speexwrap.h | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/pulsecore/speexwrap.h diff --git a/src/pulsecore/speexwrap.h b/src/pulsecore/speexwrap.h new file mode 100644 index 00000000..c0d5c0c0 --- /dev/null +++ b/src/pulsecore/speexwrap.h @@ -0,0 +1,48 @@ +#ifndef foopulsespeexwraphfoo +#define foopulsespeexwraphfoo + +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +/* We define a minimal version of speex_resampler.h however define one + * version for fixed and another one for float. Yes, somewhat ugly */ + +#define spx_int16_t short +#define spx_int32_t int +#define spx_uint16_t unsigned short +#define spx_uint32_t unsigned int + +typedef struct SpeexResamplerState_ SpeexResamplerState; + +SpeexResamplerState *paspfx_resampler_init(spx_uint32_t nb_channels, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err); +void paspfx_resampler_destroy(SpeexResamplerState *st); +int paspfx_resampler_process_interleaved_int(SpeexResamplerState *st, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len); +int paspfx_resampler_set_rate(SpeexResamplerState *st, spx_uint32_t in_rate, spx_uint32_t out_rate); + +SpeexResamplerState *paspfl_resampler_init(spx_uint32_t nb_channels, spx_uint32_t in_rate, spx_uint32_t out_rate, int quality, int *err); +void paspfl_resampler_destroy(SpeexResamplerState *st); +int paspfl_resampler_process_interleaved_float(SpeexResamplerState *st, const float *in, spx_uint32_t *in_len, float *out, spx_uint32_t *out_len); +int paspfl_resampler_set_rate(SpeexResamplerState *st, spx_uint32_t in_rate, spx_uint32_t out_rate); + +#endif -- cgit From c1cdcfde7cd1efa9c37a8e12b50ccfca944e0abe Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 23 Aug 2007 22:34:10 +0000 Subject: a couple of modernizations; parse RE sample types properly git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1710 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/sample.c | 66 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/src/pulse/sample.c b/src/pulse/sample.c index 3d449f53..327e8e54 100644 --- a/src/pulse/sample.c +++ b/src/pulse/sample.c @@ -27,58 +27,58 @@ #endif #include -#include #include #include #include +#include + #include "sample.h" size_t pa_sample_size(const pa_sample_spec *spec) { - assert(spec); - - switch (spec->format) { - case PA_SAMPLE_U8: - case PA_SAMPLE_ULAW: - case PA_SAMPLE_ALAW: - return 1; - case PA_SAMPLE_S16LE: - case PA_SAMPLE_S16BE: - return 2; - case PA_SAMPLE_FLOAT32LE: - case PA_SAMPLE_FLOAT32BE: - return 4; - default: - assert(0); - return 0; - } + + static const size_t table[] = { + [PA_SAMPLE_U8] = 1, + [PA_SAMPLE_ULAW] = 1, + [PA_SAMPLE_ALAW] = 1, + [PA_SAMPLE_S16LE] = 2, + [PA_SAMPLE_S16BE] = 2, + [PA_SAMPLE_FLOAT32LE] = 4, + [PA_SAMPLE_FLOAT32BE] = 4 + }; + + pa_assert(spec); + pa_assert(spec->format >= 0); + pa_assert(spec->format < PA_SAMPLE_MAX); + + return table[spec->format]; } size_t pa_frame_size(const pa_sample_spec *spec) { - assert(spec); + pa_assert(spec); return pa_sample_size(spec) * spec->channels; } size_t pa_bytes_per_second(const pa_sample_spec *spec) { - assert(spec); + pa_assert(spec); return spec->rate*pa_frame_size(spec); } pa_usec_t pa_bytes_to_usec(uint64_t length, const pa_sample_spec *spec) { - assert(spec); + pa_assert(spec); return (pa_usec_t) (((double) length/pa_frame_size(spec)*1000000)/spec->rate); } size_t pa_usec_to_bytes(pa_usec_t t, const pa_sample_spec *spec) { - assert(spec); + pa_assert(spec); return (size_t) (((double) t * spec->rate / 1000000))*pa_frame_size(spec); } int pa_sample_spec_valid(const pa_sample_spec *spec) { - assert(spec); + pa_assert(spec); if (spec->rate <= 0 || spec->rate > PA_RATE_MAX || @@ -92,7 +92,8 @@ int pa_sample_spec_valid(const pa_sample_spec *spec) { } int pa_sample_spec_equal(const pa_sample_spec*a, const pa_sample_spec*b) { - assert(a && b); + pa_assert(a); + pa_assert(b); return (a->format == b->format) && (a->rate == b->rate) && (a->channels == b->channels); } @@ -108,14 +109,16 @@ const char *pa_sample_format_to_string(pa_sample_format_t f) { [PA_SAMPLE_FLOAT32BE] = "float32be", }; - if (f >= PA_SAMPLE_MAX) + if (f < 0 || f >= PA_SAMPLE_MAX) return NULL; return table[f]; } char *pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec) { - assert(s && l && spec); + pa_assert(s); + pa_assert(l); + pa_assert(spec); if (!pa_sample_spec_valid(spec)) pa_snprintf(s, l, "Invalid"); @@ -126,6 +129,8 @@ char *pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec) { } char* pa_bytes_snprint(char *s, size_t l, unsigned v) { + pa_assert(s); + if (v >= ((unsigned) 1024)*1024*1024) pa_snprintf(s, l, "%0.1f GiB", ((double) v)/1024/1024/1024); else if (v >= ((unsigned) 1024)*1024) @@ -139,6 +144,7 @@ char* pa_bytes_snprint(char *s, size_t l, unsigned v) { } pa_sample_format_t pa_parse_sample_format(const char *format) { + pa_assert(format); if (strcasecmp(format, "s16le") == 0) return PA_SAMPLE_S16LE; @@ -146,15 +152,19 @@ pa_sample_format_t pa_parse_sample_format(const char *format) { return PA_SAMPLE_S16BE; else if (strcasecmp(format, "s16ne") == 0 || strcasecmp(format, "s16") == 0 || strcasecmp(format, "16") == 0) return PA_SAMPLE_S16NE; + else if (strcasecmp(format, "s16re") == 0) + return PA_SAMPLE_S16RE; else if (strcasecmp(format, "u8") == 0 || strcasecmp(format, "8") == 0) return PA_SAMPLE_U8; else if (strcasecmp(format, "float32") == 0 || strcasecmp(format, "float32ne") == 0) - return PA_SAMPLE_FLOAT32; + return PA_SAMPLE_FLOAT32NE; + else if (strcasecmp(format, "float32re") == 0) + return PA_SAMPLE_FLOAT32RE; else if (strcasecmp(format, "float32le") == 0) return PA_SAMPLE_FLOAT32LE; else if (strcasecmp(format, "float32be") == 0) return PA_SAMPLE_FLOAT32BE; - else if (strcasecmp(format, "ulaw") == 0) + else if (strcasecmp(format, "ulaw") == 0 || strcasecmp(format, "mulaw") == 0) return PA_SAMPLE_ULAW; else if (strcasecmp(format, "alaw") == 0) return PA_SAMPLE_ALAW; -- cgit From 4eb9bb074653a6ebbb925c701c69d2b101098142 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 23 Aug 2007 22:34:49 +0000 Subject: fix a bad memory access when destructing pa_memimports git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1711 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/memblock.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index da996093..914e429a 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -608,10 +608,11 @@ static void memblock_replace_import(pa_memblock *b) { memblock_make_local(b); - if (-- seg->n_blocks <= 0) + if (-- seg->n_blocks <= 0) { + pa_mutex_unlock(seg->import->mutex); segment_detach(seg); - - pa_mutex_unlock(seg->import->mutex); + } else + pa_mutex_unlock(seg->import->mutex); } pa_mempool* pa_mempool_new(int shared) { -- cgit From ed4dc16b95ce73862540a9669c273b9d0b888100 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 23 Aug 2007 22:35:40 +0000 Subject: big resampler rework: support integer-only resampling, support speex resampler git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1712 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/resampler.c | 764 ++++++++++++++++++++++++++------------------ src/pulsecore/resampler.h | 5 + src/pulsecore/sconv-s16be.c | 3 + src/pulsecore/sconv-s16be.h | 15 +- src/pulsecore/sconv-s16le.c | 68 +++- src/pulsecore/sconv-s16le.h | 15 +- src/pulsecore/sconv.c | 261 +++++++++------ src/pulsecore/sconv.h | 10 +- 8 files changed, 711 insertions(+), 430 deletions(-) diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index 1405d7e1..57de0d15 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -28,6 +28,7 @@ #include #include + #include #include @@ -36,41 +37,93 @@ #include #include +#include "speexwrap.h" + #include "resampler.h" struct pa_resampler { pa_resample_method_t resample_method; pa_sample_spec i_ss, o_ss; pa_channel_map i_cm, o_cm; - size_t i_fz, o_fz; + size_t i_fz, o_fz, w_sz; pa_mempool *mempool; - void (*impl_free)(pa_resampler *r); - void (*impl_update_input_rate)(pa_resampler *r, uint32_t rate); - void (*impl_update_output_rate)(pa_resampler *r, uint32_t rate); - void (*impl_run)(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out); - void *impl_data; -}; - -struct impl_libsamplerate { pa_memchunk buf1, buf2, buf3, buf4; unsigned buf1_samples, buf2_samples, buf3_samples, buf4_samples; - pa_convert_to_float32ne_func_t to_float32ne_func; - pa_convert_from_float32ne_func_t from_float32ne_func; - SRC_STATE *src_state; + pa_sample_format_t work_format; + + pa_convert_func_t to_work_format_func; + pa_convert_func_t from_work_format_func; int map_table[PA_CHANNELS_MAX][PA_CHANNELS_MAX]; int map_required; -}; -struct impl_trivial { - unsigned o_counter; - unsigned i_counter; + void (*impl_free)(pa_resampler *r); + void (*impl_update_rates)(pa_resampler *r); + void (*impl_resample)(pa_resampler *r, const pa_memchunk *in, unsigned in_samples, pa_memchunk *out, unsigned *out_samples); + + struct { /* data specific to the trivial resampler */ + unsigned o_counter; + unsigned i_counter; + } trivial; + + struct { /* data specific to libsamplerate */ + SRC_STATE *state; + } src; + + struct { /* data specific to speex */ + SpeexResamplerState* state; + } speex; }; static int libsamplerate_init(pa_resampler*r); static int trivial_init(pa_resampler*r); +static int speex_init(pa_resampler*r); + +static void calc_map_table(pa_resampler *r); + +static int (* const init_table[])(pa_resampler*r) = { + [PA_RESAMPLER_SRC_SINC_BEST_QUALITY] = libsamplerate_init, + [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY] = libsamplerate_init, + [PA_RESAMPLER_SRC_SINC_FASTEST] = libsamplerate_init, + [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD] = libsamplerate_init, + [PA_RESAMPLER_SRC_LINEAR] = libsamplerate_init, + [PA_RESAMPLER_TRIVIAL] = trivial_init, + [PA_RESAMPLER_SPEEX_FLOAT_BASE+0] = speex_init, + [PA_RESAMPLER_SPEEX_FLOAT_BASE+1] = speex_init, + [PA_RESAMPLER_SPEEX_FLOAT_BASE+2] = speex_init, + [PA_RESAMPLER_SPEEX_FLOAT_BASE+3] = speex_init, + [PA_RESAMPLER_SPEEX_FLOAT_BASE+4] = speex_init, + [PA_RESAMPLER_SPEEX_FLOAT_BASE+5] = speex_init, + [PA_RESAMPLER_SPEEX_FLOAT_BASE+6] = speex_init, + [PA_RESAMPLER_SPEEX_FLOAT_BASE+7] = speex_init, + [PA_RESAMPLER_SPEEX_FLOAT_BASE+8] = speex_init, + [PA_RESAMPLER_SPEEX_FLOAT_BASE+9] = speex_init, + [PA_RESAMPLER_SPEEX_FLOAT_BASE+10] = speex_init, + [PA_RESAMPLER_SPEEX_FIXED_BASE+0] = speex_init, + [PA_RESAMPLER_SPEEX_FIXED_BASE+1] = speex_init, + [PA_RESAMPLER_SPEEX_FIXED_BASE+2] = speex_init, + [PA_RESAMPLER_SPEEX_FIXED_BASE+3] = speex_init, + [PA_RESAMPLER_SPEEX_FIXED_BASE+4] = speex_init, + [PA_RESAMPLER_SPEEX_FIXED_BASE+5] = speex_init, + [PA_RESAMPLER_SPEEX_FIXED_BASE+6] = speex_init, + [PA_RESAMPLER_SPEEX_FIXED_BASE+7] = speex_init, + [PA_RESAMPLER_SPEEX_FIXED_BASE+8] = speex_init, + [PA_RESAMPLER_SPEEX_FIXED_BASE+9] = speex_init, + [PA_RESAMPLER_SPEEX_FIXED_BASE+10] = speex_init, + [PA_RESAMPLER_AUTO] = NULL, +}; + +static inline size_t sample_size(pa_sample_format_t f) { + pa_sample_spec ss = { + .format = f, + .rate = 0, + .channels = 1 + }; + + return pa_sample_size(&ss); +} pa_resampler* pa_resampler_new( pa_mempool *pool, @@ -87,16 +140,25 @@ pa_resampler* pa_resampler_new( pa_assert(b); pa_assert(pa_sample_spec_valid(a)); pa_assert(pa_sample_spec_valid(b)); - pa_assert(resample_method != PA_RESAMPLER_INVALID); - + pa_assert(resample_method >= 0); + pa_assert(resample_method < PA_RESAMPLER_MAX); + + /* Fix method */ + if (resample_method == PA_RESAMPLER_AUTO) { + if (a->format == PA_SAMPLE_FLOAT32LE || a->format == PA_SAMPLE_FLOAT32BE || + b->format == PA_SAMPLE_FLOAT32LE || b->format == PA_SAMPLE_FLOAT32BE) + resample_method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 0; + else + resample_method = PA_RESAMPLER_SPEEX_FIXED_BASE + 0; + } + r = pa_xnew(pa_resampler, 1); - r->impl_data = NULL; r->mempool = pool; r->resample_method = resample_method; r->impl_free = NULL; - r->impl_update_input_rate = NULL; - r->impl_run = NULL; + r->impl_update_rates = NULL; + r->impl_resample = NULL; /* Fill sample specs */ r->i_ss = *a; @@ -115,25 +177,62 @@ pa_resampler* pa_resampler_new( r->i_fz = pa_frame_size(a); r->o_fz = pa_frame_size(b); - /* Choose implementation */ - if (a->channels != b->channels || - a->format != b->format || - !pa_channel_map_equal(&r->i_cm, &r->o_cm) || - resample_method != PA_RESAMPLER_TRIVIAL) { + pa_memchunk_reset(&r->buf1); + pa_memchunk_reset(&r->buf2); + pa_memchunk_reset(&r->buf3); + pa_memchunk_reset(&r->buf4); + + r->buf1_samples = r->buf2_samples = r->buf3_samples = r->buf4_samples = 0; - /* Use the libsamplerate based resampler for the complicated cases */ - if (resample_method == PA_RESAMPLER_TRIVIAL) - r->resample_method = PA_RESAMPLER_SRC_ZERO_ORDER_HOLD; + calc_map_table(r); - if (libsamplerate_init(r) < 0) + pa_log_info("Using resampler '%s'", pa_resample_method_to_string(resample_method)); + + if (resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) + r->work_format = PA_SAMPLE_S16NE; + else if (resample_method == PA_RESAMPLER_TRIVIAL) { + + if (r->map_required || a->format != b->format) { + + if (a->format == PA_SAMPLE_FLOAT32NE || a->format == PA_SAMPLE_FLOAT32RE) + r->work_format = PA_SAMPLE_FLOAT32NE; + else + r->work_format = PA_SAMPLE_S16NE; + + } else + r->work_format = a->format; + + } else + r->work_format = PA_SAMPLE_FLOAT32NE; + + r->w_sz = sample_size(r->work_format); + + if (r->i_ss.format == r->work_format) + r->to_work_format_func = NULL; + else if (r->work_format == PA_SAMPLE_FLOAT32NE) { + if (!(r->to_work_format_func = pa_get_convert_to_float32ne_function(r->i_ss.format))) goto fail; + } else { + pa_assert(r->work_format == PA_SAMPLE_S16NE); + if (!(r->to_work_format_func = pa_get_convert_to_s16ne_function(r->i_ss.format))) + goto fail; + } + if (r->o_ss.format == r->work_format) + r->from_work_format_func = NULL; + else if (r->work_format == PA_SAMPLE_FLOAT32NE) { + if (!(r->from_work_format_func = pa_get_convert_from_float32ne_function(r->o_ss.format))) + goto fail; } else { - /* Use our own simple non-fp resampler for the trivial cases and when the user selects it */ - if (trivial_init(r) < 0) + pa_assert(r->work_format == PA_SAMPLE_S16NE); + if (!(r->from_work_format_func = pa_get_convert_from_s16ne_function(r->o_ss.format))) goto fail; } + /* initialize implementation */ + if (init_table[resample_method](r) < 0) + goto fail; + return r; fail: @@ -149,6 +248,15 @@ void pa_resampler_free(pa_resampler *r) { if (r->impl_free) r->impl_free(r); + if (r->buf1.memblock) + pa_memblock_unref(r->buf1.memblock); + if (r->buf2.memblock) + pa_memblock_unref(r->buf2.memblock); + if (r->buf3.memblock) + pa_memblock_unref(r->buf3.memblock); + if (r->buf4.memblock) + pa_memblock_unref(r->buf4.memblock); + pa_xfree(r); } @@ -160,9 +268,7 @@ void pa_resampler_set_input_rate(pa_resampler *r, uint32_t rate) { return; r->i_ss.rate = rate; - - if (r->impl_update_input_rate) - r->impl_update_input_rate(r, rate); + r->impl_update_rates(r); } void pa_resampler_set_output_rate(pa_resampler *r, uint32_t rate) { @@ -173,15 +279,7 @@ void pa_resampler_set_output_rate(pa_resampler *r, uint32_t rate) { return; r->o_ss.rate = rate; - - if (r->impl_update_output_rate) - r->impl_update_output_rate(r, rate); -} - -void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) { - pa_assert(r && in && out && r->impl_run); - - r->impl_run(r, in, out); + r->impl_update_rates(r); } size_t pa_resampler_request(pa_resampler *r, size_t out_length) { @@ -192,6 +290,7 @@ size_t pa_resampler_request(pa_resampler *r, size_t out_length) { pa_resample_method_t pa_resampler_get_method(pa_resampler *r) { pa_assert(r); + return r->resample_method; } @@ -201,7 +300,30 @@ static const char * const resample_methods[] = { "src-sinc-fastest", "src-zero-order-hold", "src-linear", - "trivial" + "trivial", + "speex-float-0", + "speex-float-1", + "speex-float-2", + "speex-float-3", + "speex-float-4", + "speex-float-5", + "speex-float-6", + "speex-float-7", + "speex-float-8", + "speex-float-9", + "speex-float-10", + "speex-fixed-0", + "speex-fixed-1", + "speex-fixed-2", + "speex-fixed-3", + "speex-fixed-4", + "speex-fixed-5", + "speex-fixed-6", + "speex-fixed-7", + "speex-fixed-8", + "speex-fixed-9", + "speex-fixed-10", + "auto" }; const char *pa_resample_method_to_string(pa_resample_method_t m) { @@ -221,44 +343,21 @@ pa_resample_method_t pa_parse_resample_method(const char *string) { if (!strcmp(string, resample_methods[m])) return m; - return PA_RESAMPLER_INVALID; -} - + if (!strcmp(string, "speex-fixed")) + return PA_RESAMPLER_SPEEX_FIXED_BASE + 0; -/*** libsamplerate based implementation ***/ + if (!strcmp(string, "speex-float")) + return PA_RESAMPLER_SPEEX_FLOAT_BASE + 0; -static void libsamplerate_free(pa_resampler *r) { - struct impl_libsamplerate *u; - - pa_assert(r); - pa_assert(r->impl_data); - - u = r->impl_data; - - if (u->src_state) - src_delete(u->src_state); - - if (u->buf1.memblock) - pa_memblock_unref(u->buf1.memblock); - if (u->buf2.memblock) - pa_memblock_unref(u->buf2.memblock); - if (u->buf3.memblock) - pa_memblock_unref(u->buf3.memblock); - if (u->buf4.memblock) - pa_memblock_unref(u->buf4.memblock); - pa_xfree(u); + return PA_RESAMPLER_INVALID; } static void calc_map_table(pa_resampler *r) { - struct impl_libsamplerate *u; unsigned oc; pa_assert(r); - pa_assert(r->impl_data); - - u = r->impl_data; - if (!(u->map_required = (r->i_ss.channels != r->o_ss.channels || !pa_channel_map_equal(&r->i_cm, &r->o_cm)))) + if (!(r->map_required = (r->i_ss.channels != r->o_ss.channels || !pa_channel_map_equal(&r->i_cm, &r->o_cm)))) return; for (oc = 0; oc < r->o_ss.channels; oc++) { @@ -276,17 +375,16 @@ static void calc_map_table(pa_resampler *r) { (a == PA_CHANNEL_POSITION_LEFT && b == PA_CHANNEL_POSITION_MONO) || (a == PA_CHANNEL_POSITION_RIGHT && b == PA_CHANNEL_POSITION_MONO)) - u->map_table[oc][i++] = ic; + r->map_table[oc][i++] = ic; } /* Add an end marker */ if (i < PA_CHANNELS_MAX) - u->map_table[oc][i] = -1; + r->map_table[oc][i] = -1; } } -static pa_memchunk* convert_to_float(pa_resampler *r, pa_memchunk *input) { - struct impl_libsamplerate *u; +static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input) { unsigned n_samples; void *src, *dst; @@ -294,192 +392,193 @@ static pa_memchunk* convert_to_float(pa_resampler *r, pa_memchunk *input) { pa_assert(input); pa_assert(input->memblock); - pa_assert(r->impl_data); - u = r->impl_data; - - /* Convert the incoming sample into floats and place them in buf1 */ + /* Convert the incoming sample into the work sample format and place them in buf1 */ - if (!u->to_float32ne_func || !input->length) + if (!r->to_work_format_func || !input->length) return input; n_samples = (input->length / r->i_fz) * r->i_ss.channels; - if (!u->buf1.memblock || u->buf1_samples < n_samples) { - if (u->buf1.memblock) - pa_memblock_unref(u->buf1.memblock); + r->buf1.index = 0; + r->buf1.length = r->w_sz * n_samples; + + if (!r->buf1.memblock || r->buf1_samples < n_samples) { + if (r->buf1.memblock) + pa_memblock_unref(r->buf1.memblock); - u->buf1_samples = n_samples; - u->buf1.memblock = pa_memblock_new(r->mempool, u->buf1.length = sizeof(float) * n_samples); - u->buf1.index = 0; + r->buf1_samples = n_samples; + r->buf1.memblock = pa_memblock_new(r->mempool, r->buf1.length); } src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index; - dst = (uint8_t*) pa_memblock_acquire(u->buf1.memblock); + dst = (uint8_t*) pa_memblock_acquire(r->buf1.memblock); - u->to_float32ne_func(n_samples, src, dst); + r->to_work_format_func(n_samples, src, dst); pa_memblock_release(input->memblock); - pa_memblock_release(u->buf1.memblock); - - u->buf1.length = sizeof(float) * n_samples; + pa_memblock_release(r->buf1.memblock); - return &u->buf1; + return &r->buf1; } static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) { - struct impl_libsamplerate *u; unsigned in_n_samples, out_n_samples, n_frames; int i_skip, o_skip; unsigned oc; - float *src, *dst; + void *src, *dst; pa_assert(r); pa_assert(input); pa_assert(input->memblock); - pa_assert(r->impl_data); - u = r->impl_data; - /* Remap channels and place the result int buf2 */ - if (!u->map_required || !input->length) + if (!r->map_required || !input->length) return input; - in_n_samples = input->length / sizeof(float); + in_n_samples = input->length / r->w_sz; n_frames = in_n_samples / r->i_ss.channels; out_n_samples = n_frames * r->o_ss.channels; - if (!u->buf2.memblock || u->buf2_samples < out_n_samples) { - if (u->buf2.memblock) - pa_memblock_unref(u->buf2.memblock); + r->buf2.index = 0; + r->buf2.length = r->w_sz * out_n_samples; + + if (!r->buf2.memblock || r->buf2_samples < out_n_samples) { + if (r->buf2.memblock) + pa_memblock_unref(r->buf2.memblock); - u->buf2_samples = out_n_samples; - u->buf2.memblock = pa_memblock_new(r->mempool, u->buf2.length = sizeof(float) * out_n_samples); - u->buf2.index = 0; + r->buf2_samples = out_n_samples; + r->buf2.memblock = pa_memblock_new(r->mempool, r->buf2.length); } - src = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); - dst = (float*) pa_memblock_acquire(u->buf2.memblock); - - memset(dst, 0, u->buf2.length); - - o_skip = sizeof(float) * r->o_ss.channels; - i_skip = sizeof(float) * r->i_ss.channels; - - for (oc = 0; oc < r->o_ss.channels; oc++) { - unsigned i; - static const float one = 1.0; - - for (i = 0; i < PA_CHANNELS_MAX && u->map_table[oc][i] >= 0; i++) - oil_vectoradd_f32( - dst + oc, o_skip, - dst + oc, o_skip, - src + u->map_table[oc][i], i_skip, - n_frames, - &one, &one); + src = ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); + dst = pa_memblock_acquire(r->buf2.memblock); + + memset(dst, 0, r->buf2.length); + + o_skip = r->w_sz * r->o_ss.channels; + i_skip = r->w_sz * r->i_ss.channels; + + switch (r->work_format) { + case PA_SAMPLE_FLOAT32NE: + + for (oc = 0; oc < r->o_ss.channels; oc++) { + unsigned i; + static const float one = 1.0; + + for (i = 0; i < PA_CHANNELS_MAX && r->map_table[oc][i] >= 0; i++) + oil_vectoradd_f32( + (float*) dst + oc, o_skip, + (float*) dst + oc, o_skip, + (float*) src + r->map_table[oc][i], i_skip, + n_frames, + &one, &one); + } + + break; + + case PA_SAMPLE_S16NE: + + for (oc = 0; oc < r->o_ss.channels; oc++) { + unsigned i; + static const int16_t one = 1; + + for (i = 0; i < PA_CHANNELS_MAX && r->map_table[oc][i] >= 0; i++) + oil_vectoradd_s16( + (int16_t*) dst + oc, o_skip, + (int16_t*) dst + oc, o_skip, + (int16_t*) src + r->map_table[oc][i], i_skip, + n_frames, + &one, &one); + } + + break; + + default: + pa_assert_not_reached(); } pa_memblock_release(input->memblock); - pa_memblock_release(u->buf2.memblock); + pa_memblock_release(r->buf2.memblock); - u->buf2.length = out_n_samples * sizeof(float); + r->buf2.length = out_n_samples * r->w_sz; - return &u->buf2; + return &r->buf2; } static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) { - struct impl_libsamplerate *u; - SRC_DATA data; unsigned in_n_frames, in_n_samples; unsigned out_n_frames, out_n_samples; - int ret; pa_assert(r); pa_assert(input); - pa_assert(r->impl_data); - u = r->impl_data; /* Resample the data and place the result in buf3 */ - if (!u->src_state || !input->length) + if (!r->impl_resample || !input->length) return input; - in_n_samples = input->length / sizeof(float); + in_n_samples = input->length / r->w_sz; in_n_frames = in_n_samples / r->o_ss.channels; out_n_frames = ((in_n_frames*r->o_ss.rate)/r->i_ss.rate)+1024; out_n_samples = out_n_frames * r->o_ss.channels; - if (!u->buf3.memblock || u->buf3_samples < out_n_samples) { - if (u->buf3.memblock) - pa_memblock_unref(u->buf3.memblock); + r->buf3.index = 0; + r->buf3.length = r->w_sz * out_n_samples; + + if (!r->buf3.memblock || r->buf3_samples < out_n_samples) { + if (r->buf3.memblock) + pa_memblock_unref(r->buf3.memblock); - u->buf3_samples = out_n_samples; - u->buf3.memblock = pa_memblock_new(r->mempool, u->buf3.length = sizeof(float) * out_n_samples); - u->buf3.index = 0; + r->buf3_samples = out_n_samples; + r->buf3.memblock = pa_memblock_new(r->mempool, r->buf3.length); } - data.data_in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); - data.input_frames = in_n_frames; - - data.data_out = (float*) pa_memblock_acquire(u->buf3.memblock); - data.output_frames = out_n_frames; - - data.src_ratio = (double) r->o_ss.rate / r->i_ss.rate; - data.end_of_input = 0; - - ret = src_process(u->src_state, &data); - pa_assert(ret == 0); - pa_assert((unsigned) data.input_frames_used == in_n_frames); - - pa_memblock_release(input->memblock); - pa_memblock_release(u->buf3.memblock); - - u->buf3.length = data.output_frames_gen * sizeof(float) * r->o_ss.channels; - - return &u->buf3; + r->impl_resample(r, input, in_n_frames, &r->buf3, &out_n_frames); + r->buf3.length = out_n_frames * r->w_sz * r->o_ss.channels; + + return &r->buf3; } -static pa_memchunk *convert_from_float(pa_resampler *r, pa_memchunk *input) { - struct impl_libsamplerate *u; +static pa_memchunk *convert_from_work_format(pa_resampler *r, pa_memchunk *input) { unsigned n_samples, n_frames; void *src, *dst; pa_assert(r); pa_assert(input); - pa_assert(r->impl_data); - u = r->impl_data; /* Convert the data into the correct sample type and place the result in buf4 */ - if (!u->from_float32ne_func || !input->length) + if (!r->from_work_format_func || !input->length) return input; - n_frames = input->length / sizeof(float) / r->o_ss.channels; - n_samples = n_frames * r->o_ss.channels; + n_samples = input->length / r->w_sz; + n_frames = n_samples / r->o_ss.channels; - if (!u->buf4.memblock || u->buf4_samples < n_samples) { - if (u->buf4.memblock) - pa_memblock_unref(u->buf4.memblock); + r->buf4.index = 0; + r->buf4.length = r->o_fz * n_frames; + + if (!r->buf4.memblock || r->buf4_samples < n_samples) { + if (r->buf4.memblock) + pa_memblock_unref(r->buf4.memblock); - u->buf4_samples = n_samples; - u->buf4.memblock = pa_memblock_new(r->mempool, u->buf4.length = r->o_fz * n_frames); - u->buf4.index = 0; + r->buf4_samples = n_samples; + r->buf4.memblock = pa_memblock_new(r->mempool, r->buf4.length); } src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index; - dst = pa_memblock_acquire(u->buf4.memblock); - u->from_float32ne_func(n_samples, src, dst); + dst = pa_memblock_acquire(r->buf4.memblock); + r->from_work_format_func(n_samples, src, dst); pa_memblock_release(input->memblock); - pa_memblock_release(u->buf4.memblock); + pa_memblock_release(r->buf4.memblock); - u->buf4.length = r->o_fz * n_frames; + r->buf4.length = r->o_fz * n_frames; - return &u->buf4; + return &r->buf4; } -static void libsamplerate_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) { - struct impl_libsamplerate *u; +void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) { pa_memchunk *buf; pa_assert(r); @@ -488,19 +587,16 @@ static void libsamplerate_run(pa_resampler *r, const pa_memchunk *in, pa_memchun pa_assert(in->length); pa_assert(in->memblock); pa_assert(in->length % r->i_fz == 0); - pa_assert(r->impl_data); - - u = r->impl_data; buf = (pa_memchunk*) in; - buf = convert_to_float(r, buf); + buf = convert_to_work_format(r, buf); buf = remap_channels(r, buf); buf = resample(r, buf); if (buf->length) { - buf = convert_from_float(r, buf); + buf = convert_from_work_format(r, buf); *out = *buf; - + if (buf == in) pa_memblock_ref(buf->memblock); else @@ -509,188 +605,222 @@ static void libsamplerate_run(pa_resampler *r, const pa_memchunk *in, pa_memchun pa_memchunk_reset(out); } -static void libsamplerate_update_input_rate(pa_resampler *r, uint32_t rate) { - struct impl_libsamplerate *u; +/*** libsamplerate based implementation ***/ +static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) { + SRC_DATA data; + pa_assert(r); - pa_assert(rate > 0); - pa_assert(r->impl_data); - u = r->impl_data; + pa_assert(input); + pa_assert(output); + pa_assert(out_n_frames); + + memset(&data, 0, sizeof(data)); + + data.data_in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); + data.input_frames = in_n_frames; - if (!u->src_state) { - int err; - u->src_state = src_new(r->resample_method, r->o_ss.channels, &err); - pa_assert(u->src_state); - } else { - int ret = src_set_ratio(u->src_state, (double) r->o_ss.rate / rate); - pa_assert(ret == 0); - } -} + data.data_out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index); + data.output_frames = *out_n_frames; -static void libsamplerate_update_output_rate(pa_resampler *r, uint32_t rate) { - struct impl_libsamplerate *u; + data.src_ratio = (double) r->o_ss.rate / r->i_ss.rate; + data.end_of_input = 0; + + pa_assert_se(src_process(r->src.state, &data) == 0); + pa_assert((unsigned) data.input_frames_used == in_n_frames); + + pa_memblock_release(input->memblock); + pa_memblock_release(output->memblock); + *out_n_frames = data.output_frames_gen; +} + +static void libsamplerate_update_rates(pa_resampler *r) { pa_assert(r); - pa_assert(rate > 0); - pa_assert(r->impl_data); - u = r->impl_data; - if (!u->src_state) { - int err; - u->src_state = src_new(r->resample_method, r->o_ss.channels, &err); - pa_assert(u->src_state); - } else { - int ret = src_set_ratio(u->src_state, (double) rate / r->i_ss.rate); - pa_assert(ret == 0); - } + pa_assert_se(src_set_ratio(r->src.state, (double) r->o_ss.rate / r->i_ss.rate) == 0); +} + +static void libsamplerate_free(pa_resampler *r) { + pa_assert(r); + + if (r->src.state) + src_delete(r->src.state); } static int libsamplerate_init(pa_resampler *r) { - struct impl_libsamplerate *u = NULL; int err; + + pa_assert(r); + + if (!(r->src.state = src_new(r->resample_method, r->o_ss.channels, &err))) + return -1; - r->impl_data = u = pa_xnew(struct impl_libsamplerate, 1); - - pa_memchunk_reset(&u->buf1); - pa_memchunk_reset(&u->buf2); - pa_memchunk_reset(&u->buf3); - pa_memchunk_reset(&u->buf4); - u->buf1_samples = u->buf2_samples = u->buf3_samples = u->buf4_samples = 0; + r->impl_free = libsamplerate_free; + r->impl_update_rates = libsamplerate_update_rates; + r->impl_resample = libsamplerate_resample; - if (r->i_ss.format == PA_SAMPLE_FLOAT32NE) - u->to_float32ne_func = NULL; - else if (!(u->to_float32ne_func = pa_get_convert_to_float32ne_function(r->i_ss.format))) - goto fail; + return 0; +} - if (r->o_ss.format == PA_SAMPLE_FLOAT32NE) - u->from_float32ne_func = NULL; - else if (!(u->from_float32ne_func = pa_get_convert_from_float32ne_function(r->o_ss.format))) - goto fail; +/*** speex based implementation ***/ - if (r->o_ss.rate == r->i_ss.rate) - u->src_state = NULL; - else if (!(u->src_state = src_new(r->resample_method, r->o_ss.channels, &err))) - goto fail; +static void speex_resample_float(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) { + float *in, *out; + uint32_t inf = in_n_frames, outf = *out_n_frames; - r->impl_free = libsamplerate_free; - r->impl_update_input_rate = libsamplerate_update_input_rate; - r->impl_update_output_rate = libsamplerate_update_output_rate; - r->impl_run = libsamplerate_run; + pa_assert(r); + pa_assert(input); + pa_assert(output); + pa_assert(out_n_frames); + + in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); + out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index); - calc_map_table(r); + pa_assert_se(paspfl_resampler_process_interleaved_float(r->speex.state, in, &inf, out, &outf) == 0); - return 0; + pa_memblock_release(input->memblock); + pa_memblock_release(output->memblock); -fail: - pa_xfree(u); - return -1; + pa_assert(inf == in_n_frames); + *out_n_frames = outf; } -/* Trivial implementation */ - -static void trivial_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) { - size_t fz; - unsigned n_frames; - struct impl_trivial *u; +static void speex_resample_int(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) { + int16_t *in, *out; + uint32_t inf = in_n_frames, outf = *out_n_frames; pa_assert(r); - pa_assert(in); - pa_assert(out); - pa_assert(r->impl_data); - - u = r->impl_data; - - fz = r->i_fz; - pa_assert(fz == r->o_fz); + pa_assert(input); + pa_assert(output); + pa_assert(out_n_frames); + + in = (int16_t*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); + out = (int16_t*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index); - n_frames = in->length/fz; + pa_assert_se(paspfx_resampler_process_interleaved_int(r->speex.state, in, &inf, out, &outf) == 0); - if (r->i_ss.rate == r->o_ss.rate) { + pa_memblock_release(input->memblock); + pa_memblock_release(output->memblock); - /* In case there's no diefference in sample types, do nothing */ - *out = *in; - pa_memblock_ref(out->memblock); + pa_assert(inf == in_n_frames); + *out_n_frames = outf; +} - u->o_counter += n_frames; - } else { - /* Do real resampling */ - size_t l; - unsigned o_index; - void *src, *dst; +static void speex_update_rates(pa_resampler *r) { + pa_assert(r); - /* The length of the new memory block rounded up */ - l = ((((n_frames+1) * r->o_ss.rate) / r->i_ss.rate) + 1) * fz; + if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) + pa_assert_se(paspfx_resampler_set_rate(r->speex.state, r->i_ss.rate, r->o_ss.rate) == 0); + else { + pa_assert(r->resample_method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FLOAT_MAX); + pa_assert_se(paspfl_resampler_set_rate(r->speex.state, r->i_ss.rate, r->o_ss.rate) == 0); + } +} - out->index = 0; - out->memblock = pa_memblock_new(r->mempool, l); +static void speex_free(pa_resampler *r) { + pa_assert(r); + + if (r->speex.state) { + if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) + paspfx_resampler_destroy(r->speex.state); + else { + pa_assert(r->resample_method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FLOAT_MAX); + paspfl_resampler_destroy(r->speex.state); + } + } +} - src = (uint8_t*) pa_memblock_acquire(in->memblock) + in->index; - dst = pa_memblock_acquire(out->memblock); +static int speex_init(pa_resampler *r) { + int q, err; + + pa_assert(r); - for (o_index = 0;; o_index++, u->o_counter++) { - unsigned j; + r->impl_free = speex_free; + r->impl_update_rates = speex_update_rates; + + if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) { + q = r->resample_method - PA_RESAMPLER_SPEEX_FIXED_BASE; + r->impl_resample = speex_resample_int; - j = (u->o_counter * r->i_ss.rate / r->o_ss.rate); - j = j > u->i_counter ? j - u->i_counter : 0; + if (!(r->speex.state = paspfx_resampler_init(r->o_ss.channels, r->i_ss.rate, r->o_ss.rate, q, &err))) + return -1; - if (j >= n_frames) - break; + } else { + pa_assert(r->resample_method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FLOAT_MAX); + q = r->resample_method - PA_RESAMPLER_SPEEX_FLOAT_BASE; + r->impl_resample = speex_resample_float; - pa_assert(o_index*fz < pa_memblock_get_length(out->memblock)); + if (!(r->speex.state = paspfl_resampler_init(r->o_ss.channels, r->i_ss.rate, r->o_ss.rate, q, &err))) + return -1; + } + - memcpy((uint8_t*) dst + fz*o_index, - (uint8_t*) src + fz*j, fz); + return 0; +} - } +/* Trivial implementation */ - pa_memblock_release(in->memblock); - pa_memblock_release(out->memblock); +static void trivial_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) { + size_t fz; + unsigned o_index; + void *src, *dst; + + pa_assert(r); + pa_assert(input); + pa_assert(output); + pa_assert(out_n_frames); - out->length = o_index*fz; + fz = r->w_sz * r->o_ss.channels; + + src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index; + dst = (uint8_t*) pa_memblock_acquire(output->memblock) + output->index; + + for (o_index = 0;; o_index++, r->trivial.o_counter++) { + unsigned j; + + j = ((r->trivial.o_counter * r->i_ss.rate) / r->o_ss.rate); + j = j > r->trivial.i_counter ? j - r->trivial.i_counter : 0; + + if (j >= in_n_frames) + break; + + pa_assert(o_index * fz < pa_memblock_get_length(output->memblock)); + + oil_memcpy((uint8_t*) dst + fz * o_index, + (uint8_t*) src + fz * j, fz); } + + pa_memblock_release(input->memblock); + pa_memblock_release(output->memblock); + + *out_n_frames = o_index; - u->i_counter += n_frames; + r->trivial.i_counter += in_n_frames; /* Normalize counters */ - while (u->i_counter >= r->i_ss.rate) { - u->i_counter -= r->i_ss.rate; - pa_assert(u->o_counter >= r->o_ss.rate); - u->o_counter -= r->o_ss.rate; - } -} - -static void trivial_free(pa_resampler *r) { - pa_assert(r); + while (r->trivial.i_counter >= r->i_ss.rate) { + pa_assert(r->trivial.o_counter >= r->o_ss.rate); - pa_xfree(r->impl_data); + r->trivial.i_counter -= r->i_ss.rate; + r->trivial.o_counter -= r->o_ss.rate; + } } -static void trivial_update_rate(pa_resampler *r, uint32_t rate) { - struct impl_trivial *u; - +static void trivial_update_rates(pa_resampler *r) { pa_assert(r); - pa_assert(rate > 0); - pa_assert(r->impl_data); - u = r->impl_data; - u->i_counter = 0; - u->o_counter = 0; + r->trivial.i_counter = 0; + r->trivial.o_counter = 0; } static int trivial_init(pa_resampler*r) { - struct impl_trivial *u; - pa_assert(r); - pa_assert(r->i_ss.format == r->o_ss.format); - pa_assert(r->i_ss.channels == r->o_ss.channels); - r->impl_data = u = pa_xnew(struct impl_trivial, 1); - u->o_counter = u->i_counter = 0; + r->trivial.o_counter = r->trivial.i_counter = 0; - r->impl_run = trivial_run; - r->impl_free = trivial_free; - r->impl_update_input_rate = trivial_update_rate; - r->impl_update_output_rate = trivial_update_rate; + r->impl_resample = trivial_resample; + r->impl_update_rates = trivial_update_rates; return 0; } diff --git a/src/pulsecore/resampler.h b/src/pulsecore/resampler.h index ada293e5..35f53db3 100644 --- a/src/pulsecore/resampler.h +++ b/src/pulsecore/resampler.h @@ -41,6 +41,11 @@ typedef enum pa_resample_method { PA_RESAMPLER_SRC_ZERO_ORDER_HOLD = SRC_ZERO_ORDER_HOLD, PA_RESAMPLER_SRC_LINEAR = SRC_LINEAR, PA_RESAMPLER_TRIVIAL, + PA_RESAMPLER_SPEEX_FLOAT_BASE, + PA_RESAMPLER_SPEEX_FLOAT_MAX = PA_RESAMPLER_SPEEX_FLOAT_BASE + 10, + PA_RESAMPLER_SPEEX_FIXED_BASE, + PA_RESAMPLER_SPEEX_FIXED_MAX = PA_RESAMPLER_SPEEX_FIXED_BASE + 10, + PA_RESAMPLER_AUTO, /* automatic select based on sample format */ PA_RESAMPLER_MAX } pa_resample_method_t; diff --git a/src/pulsecore/sconv-s16be.c b/src/pulsecore/sconv-s16be.c index c530e79b..658b3f5c 100644 --- a/src/pulsecore/sconv-s16be.c +++ b/src/pulsecore/sconv-s16be.c @@ -33,6 +33,9 @@ #define pa_sconv_s16le_to_float32ne pa_sconv_s16be_to_float32ne #define pa_sconv_s16le_from_float32ne pa_sconv_s16be_from_float32ne +#define pa_sconv_s16le_to_float32re pa_sconv_s16be_to_float32re +#define pa_sconv_s16le_from_float32re pa_sconv_s16be_from_float32re + #ifdef WORDS_BIGENDIAN #define SWAP_WORDS 0 #else diff --git a/src/pulsecore/sconv-s16be.h b/src/pulsecore/sconv-s16be.h index 6b736f69..ad034489 100644 --- a/src/pulsecore/sconv-s16be.h +++ b/src/pulsecore/sconv-s16be.h @@ -24,7 +24,18 @@ USA. ***/ -void pa_sconv_s16be_to_float32ne(unsigned n, const void *a, float *b); -void pa_sconv_s16be_from_float32ne(unsigned n, const float *a, void *b); +#include + +void pa_sconv_s16be_to_float32ne(unsigned n, const int16_t *a, float *b); +void pa_sconv_s16be_from_float32ne(unsigned n, const float *a, int16_t *b); +void pa_sconv_s16be_to_float32re(unsigned n, const int16_t *a, float *b); +void pa_sconv_s16be_from_float32re(unsigned n, const float *a, int16_t *b); + +#ifdef WORDS_BIGENDIAN +#define pa_sconv_float32be_to_s16ne pa_sconv_s16be_from_float32ne +#define pa_sconv_float32be_from_s16ne pa_sconv_s16be_to_float32ne +#define pa_sconv_float32le_to_s16ne pa_sconv_s16be_from_float32re +#define pa_sconv_float32le_from_s16ne pa_sconv_s16be_to_float32re +#endif #endif diff --git a/src/pulsecore/sconv-s16le.c b/src/pulsecore/sconv-s16le.c index 5f45ef66..c82708ca 100644 --- a/src/pulsecore/sconv-s16le.c +++ b/src/pulsecore/sconv-s16le.c @@ -25,12 +25,12 @@ #include #endif -#include #include #include #include +#include #include #include "endianmacros.h" @@ -53,32 +53,28 @@ #endif #endif -void pa_sconv_s16le_to_float32ne(unsigned n, const void *a, float *b) { - const int16_t *ca = a; - - assert(a); - assert(b); +void pa_sconv_s16le_to_float32ne(unsigned n, const int16_t *a, float *b) { + pa_assert(a); + pa_assert(b); #if SWAP_WORDS == 1 for (; n > 0; n--) { - int16_t s = *(ca++); + int16_t s = *(a++); *(b++) = ((float) INT16_FROM(s))/0x7FFF; } #else { static const double add = 0, factor = 1.0/0x7FFF; - oil_scaleconv_f32_s16(b, ca, n, &add, &factor); + oil_scaleconv_f32_s16(b, a, n, &add, &factor); } #endif } -void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, void *b) { - int16_t *cb = b; - - assert(a); - assert(b); +void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, int16_t *b) { + pa_assert(a); + pa_assert(b); #if SWAP_WORDS == 1 @@ -93,13 +89,55 @@ void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, void *b) { v = -1; s = (int16_t) (v * 0x7FFF); - *(cb++) = INT16_TO(s); + *(b++) = INT16_TO(s); } #else { static const double add = 0, factor = 0x7FFF; - oil_scaleconv_s16_f32(cb, a, n, &add, &factor); + oil_scaleconv_s16_f32(b, a, n, &add, &factor); +} +#endif } + +void pa_sconv_s16le_to_float32re(unsigned n, const int16_t *a, float *b) { + pa_assert(a); + pa_assert(b); + +#if SWAP_WORDS == 1 + + for (; n > 0; n--) { + int16_t s = *(a++); + float k = ((float) INT16_FROM(s))/0x7FFF; + uint32_t *j = (uint32_t*) &k; + *j = UINT32_SWAP(*j); + *(b++) = k; + } + +#endif +} + +void pa_sconv_s16le_from_float32re(unsigned n, const float *a, int16_t *b) { + pa_assert(a); + pa_assert(b); + +#if SWAP_WORDS == 1 + + for (; n > 0; n--) { + int16_t s; + float v = *(a++); + uint32_t *j = (uint32_t*) &v; + *j = UINT32_SWAP(*j); + + if (v > 1) + v = 1; + + if (v < -1) + v = -1; + + s = (int16_t) (v * 0x7FFF); + *(b++) = INT16_TO(s); + } + #endif } diff --git a/src/pulsecore/sconv-s16le.h b/src/pulsecore/sconv-s16le.h index c4e4911a..4203315a 100644 --- a/src/pulsecore/sconv-s16le.h +++ b/src/pulsecore/sconv-s16le.h @@ -24,7 +24,18 @@ USA. ***/ -void pa_sconv_s16le_to_float32ne(unsigned n, const void *a, float *b); -void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, void *b); +#include + +void pa_sconv_s16le_to_float32ne(unsigned n, const int16_t *a, float *b); +void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, int16_t *b); +void pa_sconv_s16le_to_float32re(unsigned n, const int16_t *a, float *b); +void pa_sconv_s16le_from_float32re(unsigned n, const float *a, int16_t *b); + +#ifndef WORDS_BIGENDIAN +#define pa_sconv_float32be_to_s16ne pa_sconv_s16le_from_float32re +#define pa_sconv_float32be_from_s16ne pa_sconv_s16le_to_float32re +#define pa_sconv_float32le_to_s16ne pa_sconv_s16le_from_float32ne +#define pa_sconv_float32le_from_s16ne pa_sconv_s16le_to_float32ne +#endif #endif diff --git a/src/pulsecore/sconv.c b/src/pulsecore/sconv.c index d15cec84..4986ba7c 100644 --- a/src/pulsecore/sconv.c +++ b/src/pulsecore/sconv.c @@ -28,12 +28,12 @@ #include #include -#include #include #include #include +#include #include "endianmacros.h" #include "sconv-s16le.h" @@ -41,71 +41,92 @@ #include "sconv.h" -static void u8_to_float32ne(unsigned n, const void *a, float *b) { - const uint8_t *ca = a; +/* u8 */ +static void u8_to_float32ne(unsigned n, const uint8_t *a, float *b) { static const double add = -128.0/127.0, factor = 1.0/127.0; - assert(a); - assert(b); + pa_assert(a); + pa_assert(b); - oil_scaleconv_f32_u8(b, ca, n, &add, &factor); + oil_scaleconv_f32_u8(b, a, n, &add, &factor); } -static void u8_from_float32ne(unsigned n, const float *a, void *b) { - uint8_t *cb = b; +static void u8_from_float32ne(unsigned n, const float *a, uint8_t *b) { static const double add = 128.0, factor = 127.0; - assert(a); - assert(b); + pa_assert(a); + pa_assert(b); - oil_scaleconv_u8_f32(cb, a, n, &add, &factor); + oil_scaleconv_u8_f32(b, a, n, &add, &factor); } -static void float32ne_to_float32ne(unsigned n, const void *a, float *b) { - assert(a); - assert(b); +static void u8_to_s16ne(unsigned n, const uint8_t *a, int16_t *b) { + static const int16_t add = -128, factor = 0x100; - oil_memcpy(b, a, sizeof(float) * n); + pa_assert(a); + pa_assert(b); + + oil_conv_s16_u8(b, 2, a, 1, n); + oil_scalaradd_s16(b, 2, b, 2, &add, n); + oil_scalarmult_s16(b, 2, b, 2, &factor, n); +} + +static void u8_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) { + + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--, a ++, a++) + *b = (uint8_t) (*a / 0x100 + 0x80); } -static void float32ne_from_float32ne(unsigned n, const float *a, void *b) { - assert(a); - assert(b); +/* float32 */ + +static void float32ne_to_float32ne(unsigned n, const float *a, float *b) { + pa_assert(a); + pa_assert(b); oil_memcpy(b, a, sizeof(float) * n); } -static void float32re_to_float32ne(unsigned n, const void *a, float *b) { - assert(a); - assert(b); +static void float32re_to_float32ne(unsigned n, const float *a, float *b) { + pa_assert(a); + pa_assert(b); - while (n-- > 0) - ((uint32_t *)b)[n] = UINT32_SWAP (((uint32_t *)a)[n]); + for (; n > 0; n--, a++, b++) + *((uint32_t *) b) = UINT32_SWAP(*((uint32_t *) a)); } -static void float32re_from_float32ne(unsigned n, const float *a, void *b) { - assert(a); - assert(b); +/* s16 */ - while (n-- > 0) - ((uint32_t *)b)[n] = UINT32_SWAP (((uint32_t *)a)[n]); +static void s16ne_to_s16ne(unsigned n, const int16_t *a, int16_t *b) { + pa_assert(a); + pa_assert(b); + + oil_memcpy(b, a, sizeof(int16_t) * n); } -static void ulaw_to_float32ne(unsigned n, const void *a, float *b) { - const uint8_t *ca = a; +static void s16re_to_s16ne(unsigned n, const int16_t *a, int16_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--, a++, b++) + *b = UINT16_SWAP(*a); +} - assert(a); - assert(b); +/* ulaw */ + +static void ulaw_to_float32ne(unsigned n, const uint8_t *a, float *b) { + pa_assert(a); + pa_assert(b); for (; n > 0; n--) - *(b++) = st_ulaw2linear16(*(ca++)) * 1.0F / 0x7FFF; + *(b++) = st_ulaw2linear16(*(a++)) * 1.0F / 0x7FFF; } -static void ulaw_from_float32ne(unsigned n, const float *a, void *b) { - uint8_t *cb = b; - - assert(a); - assert(b); +static void ulaw_from_float32ne(unsigned n, const float *a, uint8_t *b) { + pa_assert(a); + pa_assert(b); for (; n > 0; n--) { float v = *(a++); @@ -116,28 +137,42 @@ static void ulaw_from_float32ne(unsigned n, const float *a, void *b) { if (v < -1) v = -1; - *(cb++) = st_14linear2ulaw((int16_t) (v * 0x1FFF)); + *(b++) = st_14linear2ulaw((int16_t) (v * 0x1FFF)); } } -static void alaw_to_float32ne(unsigned n, const void *a, float *b) { - const uint8_t *ca = a; +static void ulaw_to_s16ne(unsigned n, const uint8_t *a, int16_t *b) { + pa_assert(a); + pa_assert(b); - assert(a); - assert(b); + for (; n > 0; n--, a++, b++) + *b = st_ulaw2linear16(*a); +} - for (; n > 0; n--) - *(b++) = st_alaw2linear16(*(ca++)) * 1.0F / 0x7FFF; +static void ulaw_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--, a++, b++) + *b = st_14linear2ulaw(*a >> 2); } -static void alaw_from_float32ne(unsigned n, const float *a, void *b) { - uint8_t *cb = b; +/* alaw */ - assert(a); - assert(b); +static void alaw_to_float32ne(unsigned n, const uint8_t *a, float *b) { + pa_assert(a); + pa_assert(b); - for (; n > 0; n--) { - float v = *(a++); + for (; n > 0; n--, a++, b++) + *b = st_alaw2linear16(*a) * 1.0F / 0x7FFF; +} + +static void alaw_from_float32ne(unsigned n, const float *a, uint8_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--, a++, b++) { + float v = *a; if (v > 1) v = 1; @@ -145,48 +180,94 @@ static void alaw_from_float32ne(unsigned n, const float *a, void *b) { if (v < -1) v = -1; - *(cb++) = st_13linear2alaw((int16_t) (v * 0xFFF)); + *b = st_13linear2alaw((int16_t) (v * 0xFFF)); } } -pa_convert_to_float32ne_func_t pa_get_convert_to_float32ne_function(pa_sample_format_t f) { - switch(f) { - case PA_SAMPLE_U8: - return u8_to_float32ne; - case PA_SAMPLE_S16LE: - return pa_sconv_s16le_to_float32ne; - case PA_SAMPLE_S16BE: - return pa_sconv_s16be_to_float32ne; - case PA_SAMPLE_FLOAT32NE: - return float32ne_to_float32ne; - case PA_SAMPLE_FLOAT32RE: - return float32re_to_float32ne; - case PA_SAMPLE_ALAW: - return alaw_to_float32ne; - case PA_SAMPLE_ULAW: - return ulaw_to_float32ne; - default: - return NULL; - } +static void alaw_to_s16ne(unsigned n, const int8_t *a, int16_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--, a++, b++) + *b = st_alaw2linear16(*a); } -pa_convert_from_float32ne_func_t pa_get_convert_from_float32ne_function(pa_sample_format_t f) { - switch(f) { - case PA_SAMPLE_U8: - return u8_from_float32ne; - case PA_SAMPLE_S16LE: - return pa_sconv_s16le_from_float32ne; - case PA_SAMPLE_S16BE: - return pa_sconv_s16be_from_float32ne; - case PA_SAMPLE_FLOAT32NE: - return float32ne_from_float32ne; - case PA_SAMPLE_FLOAT32RE: - return float32re_from_float32ne; - case PA_SAMPLE_ALAW: - return alaw_from_float32ne; - case PA_SAMPLE_ULAW: - return ulaw_from_float32ne; - default: - return NULL; - } +static void alaw_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) + *b = st_13linear2alaw(*a >> 3); +} + +pa_convert_func_t pa_get_convert_to_float32ne_function(pa_sample_format_t f) { + + static const pa_convert_func_t table[] = { + [PA_SAMPLE_U8] = (pa_convert_func_t) u8_to_float32ne, + [PA_SAMPLE_ALAW] = (pa_convert_func_t) alaw_to_float32ne, + [PA_SAMPLE_ULAW] = (pa_convert_func_t) ulaw_to_float32ne, + [PA_SAMPLE_S16LE] = (pa_convert_func_t) pa_sconv_s16le_to_float32ne, + [PA_SAMPLE_S16BE] = (pa_convert_func_t) pa_sconv_s16be_to_float32ne, + [PA_SAMPLE_FLOAT32NE] = (pa_convert_func_t) float32ne_to_float32ne, + [PA_SAMPLE_FLOAT32RE] = (pa_convert_func_t) float32re_to_float32ne, + }; + + pa_assert(f >= 0); + pa_assert(f < PA_SAMPLE_MAX); + + return table[f]; +} + +pa_convert_func_t pa_get_convert_from_float32ne_function(pa_sample_format_t f) { + + static const pa_convert_func_t table[] = { + [PA_SAMPLE_U8] = (pa_convert_func_t) u8_from_float32ne, + [PA_SAMPLE_S16LE] = (pa_convert_func_t) pa_sconv_s16le_from_float32ne, + [PA_SAMPLE_S16BE] = (pa_convert_func_t) pa_sconv_s16be_from_float32ne, + [PA_SAMPLE_FLOAT32NE] = (pa_convert_func_t) float32ne_to_float32ne, + [PA_SAMPLE_FLOAT32RE] = (pa_convert_func_t) float32re_to_float32ne, + [PA_SAMPLE_ALAW] = (pa_convert_func_t) alaw_from_float32ne, + [PA_SAMPLE_ULAW] = (pa_convert_func_t) ulaw_from_float32ne + }; + + pa_assert(f >= 0); + pa_assert(f < PA_SAMPLE_MAX); + + return table[f]; +} + +pa_convert_func_t pa_get_convert_to_s16ne_function(pa_sample_format_t f) { + + static const pa_convert_func_t table[] = { + [PA_SAMPLE_U8] = (pa_convert_func_t) u8_to_s16ne, + [PA_SAMPLE_S16NE] = (pa_convert_func_t) s16ne_to_s16ne, + [PA_SAMPLE_S16RE] = (pa_convert_func_t) s16re_to_s16ne, + [PA_SAMPLE_FLOAT32BE] = (pa_convert_func_t) pa_sconv_float32be_to_s16ne, + [PA_SAMPLE_FLOAT32LE] = (pa_convert_func_t) pa_sconv_float32le_to_s16ne, + [PA_SAMPLE_ALAW] = (pa_convert_func_t) alaw_to_s16ne, + [PA_SAMPLE_ULAW] = (pa_convert_func_t) ulaw_to_s16ne + }; + + pa_assert(f >= 0); + pa_assert(f < PA_SAMPLE_MAX); + + return table[f]; +} + +pa_convert_func_t pa_get_convert_from_s16ne_function(pa_sample_format_t f) { + + static const pa_convert_func_t table[] = { + [PA_SAMPLE_U8] = (pa_convert_func_t) u8_from_s16ne, + [PA_SAMPLE_S16NE] = (pa_convert_func_t) s16ne_to_s16ne, + [PA_SAMPLE_S16RE] = (pa_convert_func_t) s16re_to_s16ne, + [PA_SAMPLE_FLOAT32BE] = (pa_convert_func_t) pa_sconv_float32be_from_s16ne, + [PA_SAMPLE_FLOAT32LE] = (pa_convert_func_t) pa_sconv_float32le_from_s16ne, + [PA_SAMPLE_ALAW] = (pa_convert_func_t) alaw_from_s16ne, + [PA_SAMPLE_ULAW] = (pa_convert_func_t) ulaw_from_s16ne, + }; + + pa_assert(f >= 0); + pa_assert(f < PA_SAMPLE_MAX); + + return table[f]; } diff --git a/src/pulsecore/sconv.h b/src/pulsecore/sconv.h index 1e97aad9..5e8fa684 100644 --- a/src/pulsecore/sconv.h +++ b/src/pulsecore/sconv.h @@ -27,10 +27,12 @@ #include -typedef void (*pa_convert_to_float32ne_func_t)(unsigned n, const void *a, float *b); -typedef void (*pa_convert_from_float32ne_func_t)(unsigned n, const float *a, void *b); +typedef void (*pa_convert_func_t)(unsigned n, const void *a, void *b); -pa_convert_to_float32ne_func_t pa_get_convert_to_float32ne_function(pa_sample_format_t f); -pa_convert_from_float32ne_func_t pa_get_convert_from_float32ne_function(pa_sample_format_t f); +pa_convert_func_t pa_get_convert_to_float32ne_function(pa_sample_format_t f); +pa_convert_func_t pa_get_convert_from_float32ne_function(pa_sample_format_t f); + +pa_convert_func_t pa_get_convert_to_s16ne_function(pa_sample_format_t f); +pa_convert_func_t pa_get_convert_from_s16ne_function(pa_sample_format_t f); #endif -- cgit From f754a24cd24670c580d045584b1c5c4874b239c5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 23 Aug 2007 22:35:58 +0000 Subject: make speex resampler the default git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1713 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/daemon-conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c index b6e8d540..e3ad8b3f 100644 --- a/src/daemon/daemon-conf.c +++ b/src/daemon/daemon-conf.c @@ -72,7 +72,7 @@ static const pa_daemon_conf default_conf = { .default_script_file = NULL, .log_target = PA_LOG_SYSLOG, .log_level = PA_LOG_NOTICE, - .resample_method = PA_RESAMPLER_SRC_SINC_FASTEST, + .resample_method = PA_RESAMPLER_AUTO, .config_file = NULL, .use_pid_file = 1, .system_instance = 0, -- cgit From 640ae04589286fa3de8da7155397b7196df07ce9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 24 Aug 2007 00:23:22 +0000 Subject: Copy resampler from ffmpeg into our sources git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1714 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/ffmpeg/avcodec.h | 71 +++++++++ src/pulsecore/ffmpeg/dsputil.h | 1 + src/pulsecore/ffmpeg/resample2.c | 324 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 396 insertions(+) create mode 100644 src/pulsecore/ffmpeg/avcodec.h create mode 100644 src/pulsecore/ffmpeg/dsputil.h create mode 100644 src/pulsecore/ffmpeg/resample2.c diff --git a/src/pulsecore/ffmpeg/avcodec.h b/src/pulsecore/ffmpeg/avcodec.h new file mode 100644 index 00000000..775ec962 --- /dev/null +++ b/src/pulsecore/ffmpeg/avcodec.h @@ -0,0 +1,71 @@ +/* + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_H +#define AVCODEC_H + +/* Just a heavily bastardized version of the original file from + * ffmpeg, just enough to get resample2.c to compile without + * modification -- Lennart */ + +#include +#include +#include +#include +#include +#include + +#define av_mallocz(l) calloc(1, (l)) +#define av_malloc(l) malloc(l) +#define av_realloc(p,l) realloc((p),(l)) +#define av_free(p) free(p) + +static inline void av_freep(void *k) { + void **p = k; + + if (p) { + free(*p); + *p = NULL; + } +} + +static inline int av_clip(int a, int amin, int amax) +{ + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +#define av_log(a,b,c) + +#define FFABS(a) ((a) >= 0 ? (a) : (-(a))) +#define FFSIGN(a) ((a) > 0 ? 1 : -1) + +#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) +#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) + +struct AVResampleContext; +struct AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_length, int log2_phase_count, int linear, double cutoff); +int av_resample(struct AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx); +void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance); +void av_resample_close(struct AVResampleContext *c); +void av_build_filter(int16_t *filter, double factor, int tap_count, int phase_count, int scale, int type); + +#endif /* AVCODEC_H */ diff --git a/src/pulsecore/ffmpeg/dsputil.h b/src/pulsecore/ffmpeg/dsputil.h new file mode 100644 index 00000000..8da742d0 --- /dev/null +++ b/src/pulsecore/ffmpeg/dsputil.h @@ -0,0 +1 @@ +/* empty file, just here to allow us to compile an unmodified resampler2.c */ diff --git a/src/pulsecore/ffmpeg/resample2.c b/src/pulsecore/ffmpeg/resample2.c new file mode 100644 index 00000000..da1443d9 --- /dev/null +++ b/src/pulsecore/ffmpeg/resample2.c @@ -0,0 +1,324 @@ +/* + * audio resampling + * Copyright (c) 2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file resample2.c + * audio resampling + * @author Michael Niedermayer + */ + +#include "avcodec.h" +#include "dsputil.h" + +#ifndef CONFIG_RESAMPLE_HP +#define FILTER_SHIFT 15 + +#define FELEM int16_t +#define FELEM2 int32_t +#define FELEML int64_t +#define FELEM_MAX INT16_MAX +#define FELEM_MIN INT16_MIN +#define WINDOW_TYPE 9 +#elif !defined(CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE) +#define FILTER_SHIFT 30 + +#define FELEM int32_t +#define FELEM2 int64_t +#define FELEML int64_t +#define FELEM_MAX INT32_MAX +#define FELEM_MIN INT32_MIN +#define WINDOW_TYPE 12 +#else +#define FILTER_SHIFT 0 + +#define FELEM double +#define FELEM2 double +#define FELEML double +#define WINDOW_TYPE 24 +#endif + + +typedef struct AVResampleContext{ + FELEM *filter_bank; + int filter_length; + int ideal_dst_incr; + int dst_incr; + int index; + int frac; + int src_incr; + int compensation_distance; + int phase_shift; + int phase_mask; + int linear; +}AVResampleContext; + +/** + * 0th order modified bessel function of the first kind. + */ +static double bessel(double x){ + double v=1; + double t=1; + int i; + + x= x*x/4; + for(i=1; i<50; i++){ + t *= x/(i*i); + v += t; + } + return v; +} + +/** + * builds a polyphase filterbank. + * @param factor resampling factor + * @param scale wanted sum of coefficients for each filter + * @param type 0->cubic, 1->blackman nuttall windowed sinc, 2..16->kaiser windowed sinc beta=2..16 + */ +void av_build_filter(FELEM *filter, double factor, int tap_count, int phase_count, int scale, int type){ + int ph, i; + double x, y, w, tab[tap_count]; + const int center= (tap_count-1)/2; + + /* if upsampling, only need to interpolate, no filter */ + if (factor > 1.0) + factor = 1.0; + + for(ph=0;phphase_shift= phase_shift; + c->phase_mask= phase_count-1; + c->linear= linear; + + c->filter_length= FFMAX((int)ceil(filter_size/factor), 1); + c->filter_bank= av_mallocz(c->filter_length*(phase_count+1)*sizeof(FELEM)); + av_build_filter(c->filter_bank, factor, c->filter_length, phase_count, 1<filter_bank[c->filter_length*phase_count+1], c->filter_bank, (c->filter_length-1)*sizeof(FELEM)); + c->filter_bank[c->filter_length*phase_count]= c->filter_bank[c->filter_length - 1]; + + c->src_incr= out_rate; + c->ideal_dst_incr= c->dst_incr= in_rate * phase_count; + c->index= -phase_count*((c->filter_length-1)/2); + + return c; +} + +void av_resample_close(AVResampleContext *c){ + av_freep(&c->filter_bank); + av_freep(&c); +} + +/** + * Compensates samplerate/timestamp drift. The compensation is done by changing + * the resampler parameters, so no audible clicks or similar distortions ocur + * @param compensation_distance distance in output samples over which the compensation should be performed + * @param sample_delta number of output samples which should be output less + * + * example: av_resample_compensate(c, 10, 500) + * here instead of 510 samples only 500 samples would be output + * + * note, due to rounding the actual compensation might be slightly different, + * especially if the compensation_distance is large and the in_rate used during init is small + */ +void av_resample_compensate(AVResampleContext *c, int sample_delta, int compensation_distance){ +// sample_delta += (c->ideal_dst_incr - c->dst_incr)*(int64_t)c->compensation_distance / c->ideal_dst_incr; + c->compensation_distance= compensation_distance; + c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr * (int64_t)sample_delta / compensation_distance; +} + +/** + * resamples. + * @param src an array of unconsumed samples + * @param consumed the number of samples of src which have been consumed are returned here + * @param src_size the number of unconsumed samples available + * @param dst_size the amount of space in samples available in dst + * @param update_ctx if this is 0 then the context wont be modified, that way several channels can be resampled with the same context + * @return the number of samples written in dst or -1 if an error occured + */ +int av_resample(AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx){ + int dst_index, i; + int index= c->index; + int frac= c->frac; + int dst_incr_frac= c->dst_incr % c->src_incr; + int dst_incr= c->dst_incr / c->src_incr; + int compensation_distance= c->compensation_distance; + + if(compensation_distance == 0 && c->filter_length == 1 && c->phase_shift==0){ + int64_t index2= ((int64_t)index)<<32; + int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr; + dst_size= FFMIN(dst_size, (src_size-1-index) * (int64_t)c->src_incr / c->dst_incr); + + for(dst_index=0; dst_index < dst_size; dst_index++){ + dst[dst_index] = src[index2>>32]; + index2 += incr; + } + frac += dst_index * dst_incr_frac; + index += dst_index * dst_incr; + index += frac / c->src_incr; + frac %= c->src_incr; + }else{ + for(dst_index=0; dst_index < dst_size; dst_index++){ + FELEM *filter= c->filter_bank + c->filter_length*(index & c->phase_mask); + int sample_index= index >> c->phase_shift; + FELEM2 val=0; + + if(sample_index < 0){ + for(i=0; ifilter_length; i++) + val += src[FFABS(sample_index + i) % src_size] * filter[i]; + }else if(sample_index + c->filter_length > src_size){ + break; + }else if(c->linear){ + FELEM2 v2=0; + for(i=0; ifilter_length; i++){ + val += src[sample_index + i] * (FELEM2)filter[i]; + v2 += src[sample_index + i] * (FELEM2)filter[i + c->filter_length]; + } + val+=(v2-val)*(FELEML)frac / c->src_incr; + }else{ + for(i=0; ifilter_length; i++){ + val += src[sample_index + i] * (FELEM2)filter[i]; + } + } + +#ifdef CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE + dst[dst_index] = av_clip_int16(lrintf(val)); +#else + val = (val + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT; + dst[dst_index] = (unsigned)(val + 32768) > 65535 ? (val>>31) ^ 32767 : val; +#endif + + frac += dst_incr_frac; + index += dst_incr; + if(frac >= c->src_incr){ + frac -= c->src_incr; + index++; + } + + if(dst_index + 1 == compensation_distance){ + compensation_distance= 0; + dst_incr_frac= c->ideal_dst_incr % c->src_incr; + dst_incr= c->ideal_dst_incr / c->src_incr; + } + } + } + *consumed= FFMAX(index, 0) >> c->phase_shift; + if(index>=0) index &= c->phase_mask; + + if(compensation_distance){ + compensation_distance -= dst_index; + assert(compensation_distance > 0); + } + if(update_ctx){ + c->frac= frac; + c->index= index; + c->dst_incr= dst_incr_frac + c->src_incr*dst_incr; + c->compensation_distance= compensation_distance; + } +#if 0 + if(update_ctx && !c->compensation_distance){ +#undef rand + av_resample_compensate(c, rand() % (8000*2) - 8000, 8000*2); +av_log(NULL, AV_LOG_DEBUG, "%d %d %d\n", c->dst_incr, c->ideal_dst_incr, c->compensation_distance); + } +#endif + + return dst_index; +} -- cgit From f0dbbe966ff321997e57c5e47308b1e18d962781 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 24 Aug 2007 00:23:48 +0000 Subject: add makefiles to speex/ and ffmpeg/ to easy compilation from emacs git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1715 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/ffmpeg/Makefile | 13 ++++++++ src/pulsecore/resampler.c | 78 +++++++++++++++++++++++++++++++++++++++++-- src/pulsecore/resampler.h | 4 ++- src/pulsecore/sink-input.c | 10 +++--- src/pulsecore/source-output.c | 11 +++--- src/pulsecore/speex/Makefile | 13 ++++++++ 6 files changed, 117 insertions(+), 12 deletions(-) create mode 100644 src/pulsecore/ffmpeg/Makefile create mode 100644 src/pulsecore/speex/Makefile diff --git a/src/pulsecore/ffmpeg/Makefile b/src/pulsecore/ffmpeg/Makefile new file mode 100644 index 00000000..316beb72 --- /dev/null +++ b/src/pulsecore/ffmpeg/Makefile @@ -0,0 +1,13 @@ +# This is a dirty trick just to ease compilation with emacs +# +# This file is not intended to be distributed or anything +# +# So: don't touch it, even better ignore it! + +all: + $(MAKE) -C ../.. + +clean: + $(MAKE) -C ../.. clean + +.PHONY: all clean diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index 57de0d15..47a5eac4 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -39,6 +39,8 @@ #include "speexwrap.h" +#include "ffmpeg/avcodec.h" + #include "resampler.h" struct pa_resampler { @@ -75,11 +77,17 @@ struct pa_resampler { struct { /* data specific to speex */ SpeexResamplerState* state; } speex; + + struct { /* data specific to ffmpeg */ + struct AVResampleContext *state; + unsigned initial_i_rate, initial_o_rate; + } ffmpeg; }; static int libsamplerate_init(pa_resampler*r); static int trivial_init(pa_resampler*r); static int speex_init(pa_resampler*r); +static int ffmpeg_init(pa_resampler*r); static void calc_map_table(pa_resampler *r); @@ -112,6 +120,7 @@ static int (* const init_table[])(pa_resampler*r) = { [PA_RESAMPLER_SPEEX_FIXED_BASE+8] = speex_init, [PA_RESAMPLER_SPEEX_FIXED_BASE+9] = speex_init, [PA_RESAMPLER_SPEEX_FIXED_BASE+10] = speex_init, + [PA_RESAMPLER_FFMPEG] = ffmpeg_init, [PA_RESAMPLER_AUTO] = NULL, }; @@ -131,7 +140,8 @@ pa_resampler* pa_resampler_new( const pa_channel_map *am, const pa_sample_spec *b, const pa_channel_map *bm, - pa_resample_method_t resample_method) { + pa_resample_method_t resample_method, + int variable_rate) { pa_resampler *r = NULL; @@ -144,6 +154,12 @@ pa_resampler* pa_resampler_new( pa_assert(resample_method < PA_RESAMPLER_MAX); /* Fix method */ + + if (resample_method == PA_RESAMPLER_FFMPEG && variable_rate) { + pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'." ); + resample_method = PA_RESAMPLER_AUTO; + } + if (resample_method == PA_RESAMPLER_AUTO) { if (a->format == PA_SAMPLE_FLOAT32LE || a->format == PA_SAMPLE_FLOAT32BE || b->format == PA_SAMPLE_FLOAT32LE || b->format == PA_SAMPLE_FLOAT32BE) @@ -151,7 +167,7 @@ pa_resampler* pa_resampler_new( else resample_method = PA_RESAMPLER_SPEEX_FIXED_BASE + 0; } - + r = pa_xnew(pa_resampler, 1); r->mempool = pool; r->resample_method = resample_method; @@ -188,7 +204,8 @@ pa_resampler* pa_resampler_new( pa_log_info("Using resampler '%s'", pa_resample_method_to_string(resample_method)); - if (resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) + if ((resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) || + (resample_method == PA_RESAMPLER_FFMPEG)) r->work_format = PA_SAMPLE_S16NE; else if (resample_method == PA_RESAMPLER_TRIVIAL) { @@ -268,6 +285,7 @@ void pa_resampler_set_input_rate(pa_resampler *r, uint32_t rate) { return; r->i_ss.rate = rate; + r->impl_update_rates(r); } @@ -279,6 +297,7 @@ void pa_resampler_set_output_rate(pa_resampler *r, uint32_t rate) { return; r->o_ss.rate = rate; + r->impl_update_rates(r); } @@ -323,6 +342,7 @@ static const char * const resample_methods[] = { "speex-fixed-8", "speex-fixed-9", "speex-fixed-10", + "ffmpeg", "auto" }; @@ -825,4 +845,56 @@ static int trivial_init(pa_resampler*r) { return 0; } +/*** ffmpeg based implementation ***/ + +static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) { + short *src, *dst; + int consumed; + int c; + + pa_assert(r); + pa_assert(input); + pa_assert(output); + pa_assert(out_n_frames); + + src = (short*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); + dst = (short*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index); + + for (c = 0; c < r->o_ss.channels; c++) + *out_n_frames = av_resample(r->ffmpeg.state, + dst + r->w_sz*c, + src + r->w_sz*c, + &consumed, + in_n_frames, *out_n_frames, + c >= r->o_ss.channels-1); + + pa_assert(*out_n_frames > 0); + pa_assert(consumed == in_n_frames); + + pa_memblock_release(input->memblock); + pa_memblock_release(output->memblock); +} + +static void ffmpeg_free(pa_resampler *r) { + pa_assert(r); + + if (r->ffmpeg.state) + av_resample_close(r->ffmpeg.state); +} + +static int ffmpeg_init(pa_resampler *r) { + pa_assert(r); + + /* We could probably implement different quality levels by + * adjusting the filter parameters here. However, ffmpeg + * internally only uses these hardcoded values, so let's use them + * here for now as well until ffmpeg makes this configurable. */ + + if (!(r->ffmpeg.state = av_resample_init(r->o_ss.rate, r->i_ss.rate, 16, 10, 0, 0.8))) + return -1; + + r->impl_free = ffmpeg_free; + r->impl_resample = ffmpeg_resample; + return 0; +} diff --git a/src/pulsecore/resampler.h b/src/pulsecore/resampler.h index 35f53db3..2a943e3e 100644 --- a/src/pulsecore/resampler.h +++ b/src/pulsecore/resampler.h @@ -45,6 +45,7 @@ typedef enum pa_resample_method { PA_RESAMPLER_SPEEX_FLOAT_MAX = PA_RESAMPLER_SPEEX_FLOAT_BASE + 10, PA_RESAMPLER_SPEEX_FIXED_BASE, PA_RESAMPLER_SPEEX_FIXED_MAX = PA_RESAMPLER_SPEEX_FIXED_BASE + 10, + PA_RESAMPLER_FFMPEG, PA_RESAMPLER_AUTO, /* automatic select based on sample format */ PA_RESAMPLER_MAX } pa_resample_method_t; @@ -55,7 +56,8 @@ pa_resampler* pa_resampler_new( const pa_channel_map *am, const pa_sample_spec *b, const pa_channel_map *bm, - pa_resample_method_t resample_method); + pa_resample_method_t resample_method, + int variable_rate); void pa_resampler_free(pa_resampler *r); diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 8bec5d5d..0cdcbc0b 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -153,7 +153,8 @@ pa_sink_input* pa_sink_input_new( core->mempool, &data->sample_spec, &data->channel_map, &data->sink->sample_spec, &data->sink->channel_map, - data->resample_method))) { + data->resample_method, + !!(flags & PA_SINK_INPUT_VARIABLE_RATE)))) { pa_log_warn("Unsupported resampling operation."); return NULL; } @@ -639,8 +640,8 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { new_resampler = i->thread_info.resampler; else if ((i->flags & PA_SINK_INPUT_VARIABLE_RATE) || - !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec) || - !pa_channel_map_equal(&i->channel_map, &dest->channel_map)) { + !pa_sample_spec_equal(&i->sample_spec, &dest->sample_spec) || + !pa_channel_map_equal(&i->channel_map, &dest->channel_map)) { /* Okey, we need a new resampler for the new sink */ @@ -648,7 +649,8 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { dest->core->mempool, &i->sample_spec, &i->channel_map, &dest->sample_spec, &dest->channel_map, - i->resample_method))) { + i->resample_method, + !!(i->flags & PA_SINK_INPUT_VARIABLE_RATE)))) { pa_log_warn("Unsupported resampling operation."); return -1; } diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index ce81fccb..25322469 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -121,7 +121,8 @@ pa_source_output* pa_source_output_new( core->mempool, &data->source->sample_spec, &data->source->channel_map, &data->sample_spec, &data->channel_map, - data->resample_method))) { + data->resample_method, + !!(flags & PA_SOURCE_OUTPUT_VARIABLE_RATE)))) { pa_log_warn("Unsupported resampling operation."); return NULL; } @@ -351,8 +352,9 @@ int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { /* Try to reuse the old resampler if possible */ new_resampler = o->thread_info.resampler; - else if (!pa_sample_spec_equal(&o->sample_spec, &dest->sample_spec) || - !pa_channel_map_equal(&o->channel_map, &dest->channel_map)) { + else if ((o->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) || + !pa_sample_spec_equal(&o->sample_spec, &dest->sample_spec) || + !pa_channel_map_equal(&o->channel_map, &dest->channel_map)) { /* Okey, we need a new resampler for the new source */ @@ -360,7 +362,8 @@ int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { dest->core->mempool, &dest->sample_spec, &dest->channel_map, &o->sample_spec, &o->channel_map, - o->resample_method))) { + o->resample_method, + !!(o->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE)))) { pa_log_warn("Unsupported resampling operation."); return -1; } diff --git a/src/pulsecore/speex/Makefile b/src/pulsecore/speex/Makefile new file mode 100644 index 00000000..316beb72 --- /dev/null +++ b/src/pulsecore/speex/Makefile @@ -0,0 +1,13 @@ +# This is a dirty trick just to ease compilation with emacs +# +# This file is not intended to be distributed or anything +# +# So: don't touch it, even better ignore it! + +all: + $(MAKE) -C ../.. + +clean: + $(MAKE) -C ../.. clean + +.PHONY: all clean -- cgit From 9439e81de18928ea6c373c18eebf048d51801c3a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 25 Aug 2007 22:26:59 +0000 Subject: make ffmpeg resampler actually work git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1717 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/resampler.c | 100 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 81 insertions(+), 19 deletions(-) diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index 47a5eac4..dd379b8a 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -80,7 +80,7 @@ struct pa_resampler { struct { /* data specific to ffmpeg */ struct AVResampleContext *state; - unsigned initial_i_rate, initial_o_rate; + pa_memchunk buf[PA_CHANNELS_MAX]; } ffmpeg; }; @@ -848,41 +848,100 @@ static int trivial_init(pa_resampler*r) { /*** ffmpeg based implementation ***/ static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) { - short *src, *dst; - int consumed; - int c; + unsigned used_frames = 0, c; pa_assert(r); pa_assert(input); pa_assert(output); pa_assert(out_n_frames); - - src = (short*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); - dst = (short*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index); - for (c = 0; c < r->o_ss.channels; c++) - *out_n_frames = av_resample(r->ffmpeg.state, - dst + r->w_sz*c, - src + r->w_sz*c, - &consumed, - in_n_frames, *out_n_frames, - c >= r->o_ss.channels-1); + for (c = 0; c < r->o_ss.channels; c++) { + unsigned u; + pa_memblock *b, *w; + int16_t *p, *t, *k, *q, *s; + int consumed_frames; + unsigned in, l; + + /* Allocate a new block */ + b = pa_memblock_new(r->mempool, r->ffmpeg.buf[c].length + in_n_frames * sizeof(int16_t)); + p = pa_memblock_acquire(b); + + /* Copy the remaining data into it */ + l = r->ffmpeg.buf[c].length; + if (r->ffmpeg.buf[c].memblock) { + t = (int16_t*) ((uint8_t*) pa_memblock_acquire(r->ffmpeg.buf[c].memblock) + r->ffmpeg.buf[c].index); + memcpy(p, t, l); + pa_memblock_release(r->ffmpeg.buf[c].memblock); + pa_memblock_unref(r->ffmpeg.buf[c].memblock); + pa_memchunk_reset(&r->ffmpeg.buf[c]); + } - pa_assert(*out_n_frames > 0); - pa_assert(consumed == in_n_frames); - - pa_memblock_release(input->memblock); - pa_memblock_release(output->memblock); + /* Now append the new data, splitting up channels */ + t = ((int16_t*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index)) + c; + k = (int16_t*) ((uint8_t*) p + l); + for (u = 0; u < in_n_frames; u++) { + *k = *t; + t += r->o_ss.channels; + k ++; + } + pa_memblock_release(input->memblock); + + /* Calculate the resulting number of frames */ + in = in_n_frames + l / sizeof(int16_t); + + /* Allocate buffer for the result */ + w = pa_memblock_new(r->mempool, *out_n_frames * sizeof(int16_t)); + q = pa_memblock_acquire(w); + + /* Now, resample */ + used_frames = av_resample(r->ffmpeg.state, + q, p, + &consumed_frames, + in, *out_n_frames, + c >= (unsigned) r->o_ss.channels-1); + + pa_memblock_release(b); + + /* Now store the remaining samples away */ + pa_assert(consumed_frames <= (int) in); + if (consumed_frames < (int) in) { + r->ffmpeg.buf[c].memblock = b; + r->ffmpeg.buf[c].index = consumed_frames * sizeof(int16_t); + r->ffmpeg.buf[c].length = (in - consumed_frames) * sizeof(int16_t); + } else + pa_memblock_unref(b); + + /* And place the results in the output buffer */ + s = (short*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index) + c; + for (u = 0; u < used_frames; u++) { + *s = *q; + q++; + s += r->o_ss.channels; + } + pa_memblock_release(output->memblock); + pa_memblock_release(w); + pa_memblock_unref(w); + } + + *out_n_frames = used_frames; } static void ffmpeg_free(pa_resampler *r) { + unsigned c; + pa_assert(r); if (r->ffmpeg.state) av_resample_close(r->ffmpeg.state); + + for (c = 0; c < PA_ELEMENTSOF(r->ffmpeg.buf); c++) + if (r->ffmpeg.buf[c].memblock) + pa_memblock_unref(r->ffmpeg.buf[c].memblock); } static int ffmpeg_init(pa_resampler *r) { + unsigned c; + pa_assert(r); /* We could probably implement different quality levels by @@ -896,5 +955,8 @@ static int ffmpeg_init(pa_resampler *r) { r->impl_free = ffmpeg_free; r->impl_resample = ffmpeg_resample; + for (c = 0; c < PA_ELEMENTSOF(r->ffmpeg.buf); c++) + pa_memchunk_reset(&r->ffmpeg.buf[c]); + return 0; } -- cgit From f4e2d2331afb48b304ca6b1402b43f1727343aa2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 25 Aug 2007 22:27:24 +0000 Subject: include ffmpeg resampler in build git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1718 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 097b0831..0bdc3f79 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -559,7 +559,7 @@ libpulsedsp_la_LDFLAGS = -avoid-version # Speex Resampler # ################################### -noinst_LTLIBRARIES = libspeex-resampler-fixed.la libspeex-resampler-float.la +noinst_LTLIBRARIES = libspeex-resampler-fixed.la libspeex-resampler-float.la libffmpeg-resampler.la libspeex_resampler_fixed_la_CPPFLAGS = $(AM_CPPFLAGS) -DRANDOM_PREFIX=paspfx -DOUTSIDE_SPEEX -DFIXED_POINT libspeex_resampler_fixed_la_SOURCES = pulsecore/speex/resample.c pulsecore/speex/speex_resampler.h pulsecore/speex/arch.h pulsecore/speex/fixed_generic.h @@ -567,6 +567,9 @@ libspeex_resampler_fixed_la_SOURCES = pulsecore/speex/resample.c pulsecore/speex libspeex_resampler_float_la_CPPFLAGS = $(AM_CPPFLAGS) -DRANDOM_PREFIX=paspfl -DOUTSIDE_SPEEX libspeex_resampler_float_la_SOURCES = pulsecore/speex/resample.c pulsecore/speex/speex_resampler.h pulsecore/speex/arch.h +libffmpeg_resampler_la_CPPFLAGS = $(AM_CPPFLAGS) +libffmpeg_resampler_la_SOURCES = pulsecore/ffmpeg/resample2.c + ################################### # Daemon core library # ################################### @@ -712,7 +715,7 @@ endif libpulsecore_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBOIL_CFLAGS) libpulsecore_la_LDFLAGS = -version-info $(LIBPULSECORE_VERSION_INFO) -libpulsecore_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSNDFILE_LIBS) $(WINSOCK_LIBS) $(LIBOIL_LIBS) $(LIBICONV) libspeex-resampler-fixed.la libspeex-resampler-float.la +libpulsecore_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSNDFILE_LIBS) $(WINSOCK_LIBS) $(LIBOIL_LIBS) $(LIBICONV) libspeex-resampler-fixed.la libspeex-resampler-float.la libffmpeg-resampler.la ################################### # Plug-in support libraries # @@ -1403,4 +1406,7 @@ update-speex: wget -O pulsecore/speex/arch.h http://svn.xiph.org/trunk/speex/libspeex/arch.h wget -O pulsecore/speex/fixed_generic.h http://svn.xiph.org/trunk/speex/libspeex/fixed_generic.h +update-ffmpeg: + wget -O pulsecore/ffmpeg/resample2.c http://svn.mplayerhq.hu/ffmpeg/trunk/libavcodec/resample2.c?view=co + .PHONY: utils/padsp -- cgit From f82067f6de5ecabf7c0e062b6a376651e5e829f5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 25 Aug 2007 22:27:51 +0000 Subject: lower suspend timeout to 1s git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1719 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-suspend-on-idle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/module-suspend-on-idle.c b/src/modules/module-suspend-on-idle.c index d2f9b7dd..e9226ca2 100644 --- a/src/modules/module-suspend-on-idle.c +++ b/src/modules/module-suspend-on-idle.c @@ -323,7 +323,7 @@ static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *o, s int pa__init(pa_module*m) { pa_modargs *ma = NULL; struct userdata *u; - uint32_t timeout = 5; + uint32_t timeout = 1; uint32_t idx; pa_sink *sink; pa_source *source; -- cgit From 89fcd51b7b458d7c541a0f08cfffcc67df73acf6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 25 Aug 2007 23:32:37 +0000 Subject: enable -ffast-math for gcc git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1720 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 2 +- src/pulsecore/resampler.c | 25 +++++++++++++++---------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index d9983309..718ebbff 100644 --- a/configure.ac +++ b/configure.ac @@ -93,7 +93,7 @@ if test "x$GCC" = "xyes" ; then # We use gnu99 instead of c99 because many have interpreted the standard # in a way that int64_t isn't defined on non-64 bit platforms. - DESIRED_FLAGS="-std=gnu99 -Wall -W -Wextra -pedantic -pipe -Wformat -Wold-style-definition -Wdeclaration-after-statement -Wfloat-equal -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls -Wmissing-noreturn -Wshadow -Wendif-labels -Wpointer-arith -Wcast-align -Wwrite-strings -Winline -Wno-unused-parameter" + DESIRED_FLAGS="-std=gnu99 -Wall -W -Wextra -pedantic -pipe -Wformat -Wold-style-definition -Wdeclaration-after-statement -Wfloat-equal -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls -Wmissing-noreturn -Wshadow -Wendif-labels -Wpointer-arith -Wcast-align -Wwrite-strings -Winline -Wno-unused-parameter -ffast-math" for flag in $DESIRED_FLAGS ; do AC_MSG_CHECKING([whether $CC accepts $flag]) diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index dd379b8a..c1af401c 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -741,13 +741,14 @@ static void speex_update_rates(pa_resampler *r) { static void speex_free(pa_resampler *r) { pa_assert(r); - if (r->speex.state) { - if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) - paspfx_resampler_destroy(r->speex.state); - else { - pa_assert(r->resample_method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FLOAT_MAX); - paspfl_resampler_destroy(r->speex.state); - } + if (!r->speex.state) + return; + + if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) + paspfx_resampler_destroy(r->speex.state); + else { + pa_assert(r->resample_method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FLOAT_MAX); + paspfl_resampler_destroy(r->speex.state); } } @@ -761,20 +762,24 @@ static int speex_init(pa_resampler *r) { if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) { q = r->resample_method - PA_RESAMPLER_SPEEX_FIXED_BASE; - r->impl_resample = speex_resample_int; + pa_log_info("Choosing speex quality setting %i.", q); + if (!(r->speex.state = paspfx_resampler_init(r->o_ss.channels, r->i_ss.rate, r->o_ss.rate, q, &err))) return -1; + r->impl_resample = speex_resample_int; } else { pa_assert(r->resample_method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FLOAT_MAX); q = r->resample_method - PA_RESAMPLER_SPEEX_FLOAT_BASE; - r->impl_resample = speex_resample_float; + pa_log_info("Choosing speex quality setting %i.", q); + if (!(r->speex.state = paspfl_resampler_init(r->o_ss.channels, r->i_ss.rate, r->o_ss.rate, q, &err))) return -1; + + r->impl_resample = speex_resample_float; } - return 0; } -- cgit From 782d5a53d9fcf37cc8a26496ce5e00965a6913a9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 25 Aug 2007 23:40:16 +0000 Subject: make floating point speex resampler the default git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1721 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/resampler.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index c1af401c..d98d482d 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -160,13 +160,8 @@ pa_resampler* pa_resampler_new( resample_method = PA_RESAMPLER_AUTO; } - if (resample_method == PA_RESAMPLER_AUTO) { - if (a->format == PA_SAMPLE_FLOAT32LE || a->format == PA_SAMPLE_FLOAT32BE || - b->format == PA_SAMPLE_FLOAT32LE || b->format == PA_SAMPLE_FLOAT32BE) - resample_method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 0; - else - resample_method = PA_RESAMPLER_SPEEX_FIXED_BASE + 0; - } + if (resample_method == PA_RESAMPLER_AUTO) + resample_method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 0; r = pa_xnew(pa_resampler, 1); r->mempool = pool; -- cgit From 0362350fa81bbaa8c48bc864ab386fb6be72520b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 25 Aug 2007 23:49:11 +0000 Subject: Add option --dump-resample-methods to list available resampler implementations git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1722 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/cmdline.c | 12 +++++++++--- src/daemon/daemon-conf.h | 3 ++- src/daemon/main.c | 9 +++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/daemon/cmdline.c b/src/daemon/cmdline.c index dc757c9c..705115ec 100644 --- a/src/daemon/cmdline.c +++ b/src/daemon/cmdline.c @@ -63,6 +63,7 @@ enum { ARG_CHECK, ARG_NO_CPU_LIMIT, ARG_DISABLE_SHM, + ARG_DUMP_RESAMPLE_METHODS, ARG_SYSTEM }; @@ -92,6 +93,7 @@ static struct option long_options[] = { {"system", 2, 0, ARG_SYSTEM}, {"no-cpu-limit", 2, 0, ARG_NO_CPU_LIMIT}, {"disable-shm", 2, 0, ARG_DISABLE_SHM}, + {"dump-resample-methods", 2, 0, ARG_DUMP_RESAMPLE_METHODS}, {NULL, 0, 0, 0} }; @@ -109,6 +111,7 @@ void pa_cmdline_help(const char *argv0) { " --version Show version\n" " --dump-conf Dump default configuration\n" " --dump-modules Dump list of available modules\n" + " --dump-resample-methods Dump available resample methods\n" " -k --kill Kill a running daemon\n" " --check Check for a running daemon\n\n" @@ -131,9 +134,8 @@ void pa_cmdline_help(const char *argv0) { " -p, --dl-search-path=PATH Set the search path for dynamic shared\n" " objects (plugins)\n" " --resample-method=[METHOD] Use the specified resampling method\n" - " (one of src-sinc-medium-quality,\n" - " src-sinc-best-quality,src-sinc-fastest\n" - " src-zero-order-hold,src-linear,trivial)\n" + " (See --dump-resample-methods for\n" + " possible values)\n" " --use-pid-file[=BOOL] Create a PID file\n" " --no-cpu-limit[=BOOL] Do not install CPU load limiter on\n" " platforms that support it.\n" @@ -178,6 +180,10 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d conf->cmd = PA_CMD_DUMP_MODULES; break; + case ARG_DUMP_RESAMPLE_METHODS: + conf->cmd = PA_CMD_DUMP_RESAMPLE_METHODS; + break; + case 'k': case ARG_KILL: conf->cmd = PA_CMD_KILL; diff --git a/src/daemon/daemon-conf.h b/src/daemon/daemon-conf.h index cb717ece..76334271 100644 --- a/src/daemon/daemon-conf.h +++ b/src/daemon/daemon-conf.h @@ -40,7 +40,8 @@ typedef enum pa_daemon_conf_cmd { PA_CMD_DUMP_CONF, PA_CMD_DUMP_MODULES, PA_CMD_KILL, - PA_CMD_CHECK + PA_CMD_CHECK, + PA_CMD_DUMP_RESAMPLE_METHODS } pa_daemon_conf_cmd_t; #ifdef HAVE_SYS_RESOURCE_H diff --git a/src/daemon/main.c b/src/daemon/main.c index 15d35925..7d1cf6c7 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -419,6 +419,15 @@ int main(int argc, char *argv[]) { goto finish; } + case PA_CMD_DUMP_RESAMPLE_METHODS: { + int i; + + for (i = 0; i < PA_RESAMPLER_MAX; i++) + printf("%s\n", pa_resample_method_to_string(i)); + + goto finish; + } + case PA_CMD_HELP : pa_cmdline_help(argv[0]); retval = 0; -- cgit From d88514c58c2084639fd98f1070171a819b15c048 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 26 Aug 2007 01:10:55 +0000 Subject: drop check for gid < 500, since this isn't really a security improvement, re: #111 git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1723 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/daemon/main.c b/src/daemon/main.c index 7d1cf6c7..e17e25f5 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -355,7 +355,7 @@ int main(int argc, char *argv[]) { setlocale(LC_ALL, ""); - if (suid_root && (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) <= 0 || gid >= 1000)) { + if (suid_root && (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) <= 0)) { pa_log_warn("WARNING: called SUID root, but not in group '"PA_REALTIME_GROUP"'."); pa_drop_caps(); pa_drop_root(); -- cgit From ee97c4295aa1b75c2ad37a32a152fa3c15aa59db Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 30 Aug 2007 22:38:57 +0000 Subject: add new PA_SINK_CAN_SUSPEND/PA_SOURCE_CAN_SUSPEND flag git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1724 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/def.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pulse/def.h b/src/pulse/def.h index c2816234..4102ba6e 100644 --- a/src/pulse/def.h +++ b/src/pulse/def.h @@ -300,14 +300,16 @@ typedef enum pa_seek_mode { typedef enum pa_sink_flags { PA_SINK_HW_VOLUME_CTRL = 1, /**< Supports hardware volume control */ PA_SINK_LATENCY = 2, /**< Supports latency querying */ - PA_SINK_HARDWARE = 4 /**< Is a hardware sink of some kind, in contrast to "virtual"/software sinks \since 0.9.3 */ + PA_SINK_HARDWARE = 4, /**< Is a hardware sink of some kind, in contrast to "virtual"/software sinks \since 0.9.3 */ + PA_SINK_CAN_SUSPEND = 8 /**< Can suspend \since 0.9.7 */ } pa_sink_flags_t; /** Special source flags. \since 0.8 */ typedef enum pa_source_flags { PA_SOURCE_HW_VOLUME_CTRL = 1, /**< Supports hardware volume control */ PA_SOURCE_LATENCY = 2, /**< Supports latency querying */ - PA_SOURCE_HARDWARE = 4 /**< Is a hardware source of some kind, in contrast to "virtual"/software source \since 0.9.3 */ + PA_SOURCE_HARDWARE = 4, /**< Is a hardware source of some kind, in contrast to "virtual"/software source \since 0.9.3 */ + PA_SOURCE_CAN_SUSPEND = 8 /**< Can suspend \since 0.9.7 */ } pa_source_flags_t; /** A generic free() like callback prototype */ -- cgit From 747b01be9430f82ffec0d4e726d64bb83ded3f77 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 30 Aug 2007 22:39:24 +0000 Subject: make passing a code pointer to pa_asyncmsgq_get() optional git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1725 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/asyncmsgq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pulsecore/asyncmsgq.c b/src/pulsecore/asyncmsgq.c index cc57d3a6..e3a1ba91 100644 --- a/src/pulsecore/asyncmsgq.c +++ b/src/pulsecore/asyncmsgq.c @@ -169,7 +169,6 @@ int pa_asyncmsgq_send(pa_asyncmsgq *a, pa_msgobject *object, int code, const voi int pa_asyncmsgq_get(pa_asyncmsgq *a, pa_msgobject **object, int *code, void **userdata, int64_t *offset, pa_memchunk *chunk, int wait) { pa_assert(PA_REFCNT_VALUE(a) > 0); - pa_assert(code); pa_assert(!a->current); if (!(a->current = pa_asyncq_pop(a->asyncq, wait))) { @@ -179,7 +178,8 @@ int pa_asyncmsgq_get(pa_asyncmsgq *a, pa_msgobject **object, int *code, void **u /* pa_log("success"); */ - *code = a->current->code; + if (code) + *code = a->current->code; if (userdata) *userdata = a->current->userdata; if (offset) @@ -191,7 +191,7 @@ int pa_asyncmsgq_get(pa_asyncmsgq *a, pa_msgobject **object, int *code, void **u if (chunk) *chunk = a->current->memchunk; - pa_log_debug("Get q=%p object=%p (%s) code=%i data=%p chunk.length=%lu", (void*) a, (void*) a->current->object, a->current->object ? a->current->object->parent.type_name : NULL, a->current->code, (void*) a->current->userdata, (unsigned long) a->current->memchunk.length); +/* pa_log_debug("Get q=%p object=%p (%s) code=%i data=%p chunk.length=%lu", (void*) a, (void*) a->current->object, a->current->object ? a->current->object->parent.type_name : NULL, a->current->code, (void*) a->current->userdata, (unsigned long) a->current->memchunk.length); */ return 0; } -- cgit From 681798711620ce23ae17b08673fbe14355338f83 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 30 Aug 2007 22:39:47 +0000 Subject: add pa_timespec_reset() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1726 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/rtclock.c | 7 +++++++ src/pulsecore/rtclock.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/pulsecore/rtclock.c b/src/pulsecore/rtclock.c index 507b8999..a4e9875d 100644 --- a/src/pulsecore/rtclock.c +++ b/src/pulsecore/rtclock.c @@ -46,6 +46,13 @@ struct timespec *pa_timespec_store(struct timespec *a, pa_usec_t u) { return a; } +struct timespec *pa_timespec_reset(struct timespec *a) { + pa_assert(a); + + a->tv_sec = a->tv_nsec = 0; + return a; +} + pa_usec_t pa_timespec_load(struct timespec *ts) { pa_assert(ts); diff --git a/src/pulsecore/rtclock.h b/src/pulsecore/rtclock.h index 145533cd..cfc968f8 100644 --- a/src/pulsecore/rtclock.h +++ b/src/pulsecore/rtclock.h @@ -37,6 +37,7 @@ pa_usec_t pa_rtclock_age(const struct timespec *tv); int pa_rtclock_hrtimer(void); struct timespec *pa_timespec_store(struct timespec *a, pa_usec_t u); +struct timespec *pa_timespec_reset(struct timespec *a); pa_usec_t pa_timespec_load(struct timespec *tv); struct timespec *pa_timespec_add(struct timespec *tv, pa_usec_t t); pa_usec_t pa_timespec_diff(const struct timespec *a, const struct timespec *b); -- cgit From bfe69cebf334a3df337ebab32b15a8d82654fb5d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 30 Aug 2007 22:40:11 +0000 Subject: add an assert() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1727 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/fdsem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/fdsem.c b/src/pulsecore/fdsem.c index 20d262eb..5a358e2b 100644 --- a/src/pulsecore/fdsem.c +++ b/src/pulsecore/fdsem.c @@ -137,7 +137,7 @@ void pa_fdsem_wait(pa_fdsem *f) { pa_atomic_sub(&f->in_pipe, r); } - pa_atomic_dec(&f->waiting); + pa_assert_se(pa_atomic_dec(&f->waiting) >= 1); } int pa_fdsem_try(pa_fdsem *f) { -- cgit From c2e4328c53ee32f0a49c259371945c1b19539794 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 30 Aug 2007 22:41:33 +0000 Subject: fix pa_memchunk_make_writable(), make memchunk functions return the memchunk they modify git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1728 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/memchunk.c | 13 +++++++++---- src/pulsecore/memchunk.h | 4 ++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/pulsecore/memchunk.c b/src/pulsecore/memchunk.c index f00cc9e7..20ddb11d 100644 --- a/src/pulsecore/memchunk.c +++ b/src/pulsecore/memchunk.c @@ -34,7 +34,7 @@ #include "memchunk.h" -void pa_memchunk_make_writable(pa_memchunk *c, size_t min) { +pa_memchunk* pa_memchunk_make_writable(pa_memchunk *c, size_t min) { pa_memblock *n; size_t l; void *tdata, *sdata; @@ -42,9 +42,10 @@ void pa_memchunk_make_writable(pa_memchunk *c, size_t min) { assert(c); assert(c->memblock); - if (pa_memblock_is_read_only(c->memblock) && + if (pa_memblock_ref_is_one(c->memblock) && + !pa_memblock_is_read_only(c->memblock) && pa_memblock_get_length(c->memblock) >= c->index+min) - return; + return c; l = c->length; if (l < min) @@ -59,11 +60,15 @@ void pa_memchunk_make_writable(pa_memchunk *c, size_t min) { pa_memblock_unref(c->memblock); c->memblock = n; c->index = 0; + + return c; } -void pa_memchunk_reset(pa_memchunk *c) { +pa_memchunk* pa_memchunk_reset(pa_memchunk *c) { assert(c); c->memblock = NULL; c->length = c->index = 0; + + return c; } diff --git a/src/pulsecore/memchunk.h b/src/pulsecore/memchunk.h index 0b982b6d..10cab2b9 100644 --- a/src/pulsecore/memchunk.h +++ b/src/pulsecore/memchunk.h @@ -38,10 +38,10 @@ typedef struct pa_memchunk { /* Make a memchunk writable, i.e. make sure that the caller may have * exclusive access to the memblock and it is not read_only. If needed * the memblock in the structure is replaced by a copy. */ -void pa_memchunk_make_writable(pa_memchunk *c, size_t min); +pa_memchunk* pa_memchunk_make_writable(pa_memchunk *c, size_t min); /* Invalidate a memchunk. This does not free the cotaining memblock, * but sets all members to zero. */ -void pa_memchunk_reset(pa_memchunk *c); +pa_memchunk* pa_memchunk_reset(pa_memchunk *c); #endif -- cgit From 687f1f15fc3fcd99ce79cc402c48ec6a469f0333 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 30 Aug 2007 22:42:02 +0000 Subject: add new function pa_memblock_ref_is_one() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1729 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/memblock.c | 12 ++++++++++++ src/pulsecore/memblock.h | 1 + 2 files changed, 13 insertions(+) diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index 914e429a..3e2b0064 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -384,6 +384,18 @@ int pa_memblock_is_read_only(pa_memblock *b) { return b->read_only && PA_REFCNT_VALUE(b) == 1; } +/* No lock necessary */ +int pa_memblock_ref_is_one(pa_memblock *b) { + int r; + + pa_assert(b); + + r = PA_REFCNT_VALUE(b); + pa_assert(r > 0); + + return r == 1; +} + /* No lock necessary */ void* pa_memblock_acquire(pa_memblock *b) { pa_assert(b); diff --git a/src/pulsecore/memblock.h b/src/pulsecore/memblock.h index 6f8bbef3..7fa6627e 100644 --- a/src/pulsecore/memblock.h +++ b/src/pulsecore/memblock.h @@ -107,6 +107,7 @@ manually if called from more than one thread at the same time. */ void pa_memblock_unref_fixed(pa_memblock*b); int pa_memblock_is_read_only(pa_memblock *b); +int pa_memblock_ref_is_one(pa_memblock *b); void* pa_memblock_acquire(pa_memblock *b); void pa_memblock_release(pa_memblock *b); size_t pa_memblock_get_length(pa_memblock *b); -- cgit From 821eb8e29589baed2564e52fa956d34e6f2ce4d3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 30 Aug 2007 22:42:47 +0000 Subject: move queue processing code into pa_thread_mq git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1730 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread-mq.c | 24 ++++++++++++++++++++++++ src/pulsecore/thread-mq.h | 3 +++ 2 files changed, 27 insertions(+) diff --git a/src/pulsecore/thread-mq.c b/src/pulsecore/thread-mq.c index 513409d4..3c466ceb 100644 --- a/src/pulsecore/thread-mq.c +++ b/src/pulsecore/thread-mq.c @@ -117,3 +117,27 @@ pa_thread_mq *pa_thread_mq_get(void) { return pa_tls_get(tls); } +int pa_thread_mq_process(pa_thread_mq *q) { + pa_msgobject *object; + int code; + void *data; + pa_memchunk chunk; + int64_t offset; + + pa_assert(q); + + if (pa_asyncmsgq_get(q->inq, &object, &code, &data, &offset, &chunk, 0) == 0) { + int ret; + + if (!object && code == PA_MESSAGE_SHUTDOWN) { + pa_asyncmsgq_done(q->inq, 0); + return -1; + } + + ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); + pa_asyncmsgq_done(q->inq, ret); + return 1; + } + + return 0; +} diff --git a/src/pulsecore/thread-mq.h b/src/pulsecore/thread-mq.h index 13b6e01f..2b1fd687 100644 --- a/src/pulsecore/thread-mq.h +++ b/src/pulsecore/thread-mq.h @@ -43,6 +43,9 @@ void pa_thread_mq_done(pa_thread_mq *q); /* Install the specified pa_thread_mq object for the current thread */ void pa_thread_mq_install(pa_thread_mq *q); +/* Dispatched queued events on the thread side. */ +int pa_thread_mq_process(pa_thread_mq *q); + /* Return the pa_thread_mq object that is set for the current thread */ pa_thread_mq *pa_thread_mq_get(void); -- cgit From ca72adf100fc88de0fc418955310e3c5a87a7ca3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 30 Aug 2007 22:43:35 +0000 Subject: modernize and make use of a static flist for allocating idxset entries git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1731 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/idxset.c | 129 +++++++++++++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 53 deletions(-) diff --git a/src/pulsecore/idxset.c b/src/pulsecore/idxset.c index e683eada..773d7d3a 100644 --- a/src/pulsecore/idxset.c +++ b/src/pulsecore/idxset.c @@ -27,33 +27,35 @@ #endif #include -#include #include #include #include #include +#include #include "idxset.h" -typedef struct idxset_entry { +struct idxset_entry { void *data; uint32_t index; unsigned hash_value; struct idxset_entry *hash_prev, *hash_next; struct idxset_entry* iterate_prev, *iterate_next; -} idxset_entry; +}; struct pa_idxset { pa_hash_func_t hash_func; pa_compare_func_t compare_func; unsigned hash_table_size, n_entries; - idxset_entry **hash_table, **array, *iterate_list_head, *iterate_list_tail; + struct idxset_entry **hash_table, **array, *iterate_list_head, *iterate_list_tail; uint32_t index, start_index, array_size; }; +PA_STATIC_FLIST_DECLARE(entries, 0, pa_xfree); + unsigned pa_idxset_string_hash_func(const void *p) { unsigned hash = 0; const char *c; @@ -83,7 +85,7 @@ pa_idxset* pa_idxset_new(pa_hash_func_t hash_func, pa_compare_func_t compare_fun s->hash_func = hash_func ? hash_func : pa_idxset_trivial_hash_func; s->compare_func = compare_func ? compare_func : pa_idxset_trivial_compare_func; s->hash_table_size = 127; - s->hash_table = pa_xnew0(idxset_entry*, s->hash_table_size); + s->hash_table = pa_xnew0(struct idxset_entry*, s->hash_table_size); s->array = NULL; s->array_size = 0; s->index = 0; @@ -96,15 +98,17 @@ pa_idxset* pa_idxset_new(pa_hash_func_t hash_func, pa_compare_func_t compare_fun } void pa_idxset_free(pa_idxset *s, void (*free_func) (void *p, void *userdata), void *userdata) { - assert(s); + pa_assert(s); while (s->iterate_list_head) { - idxset_entry *e = s->iterate_list_head; + struct idxset_entry *e = s->iterate_list_head; s->iterate_list_head = s->iterate_list_head->iterate_next; if (free_func) free_func(e->data, userdata); - pa_xfree(e); + + if (pa_flist_push(PA_STATIC_FLIST_GET(entries), e) < 0) + pa_xfree(e); } pa_xfree(s->hash_table); @@ -112,10 +116,10 @@ void pa_idxset_free(pa_idxset *s, void (*free_func) (void *p, void *userdata), v pa_xfree(s); } -static idxset_entry* hash_scan(pa_idxset *s, idxset_entry* e, const void *p) { - assert(p); +static struct idxset_entry* hash_scan(pa_idxset *s, struct idxset_entry* e, const void *p) { + pa_assert(p); - assert(s->compare_func); + pa_assert(s->compare_func); for (; e; e = e->hash_next) if (s->compare_func(e->data, p) == 0) return e; @@ -125,8 +129,10 @@ static idxset_entry* hash_scan(pa_idxset *s, idxset_entry* e, const void *p) { static void extend_array(pa_idxset *s, uint32_t idx) { uint32_t i, j, l; - idxset_entry** n; - assert(idx >= s->start_index); + struct idxset_entry** n; + + pa_assert(s); + pa_assert(idx >= s->start_index); if (idx < s->start_index + s->array_size) return; @@ -136,7 +142,7 @@ static void extend_array(pa_idxset *s, uint32_t idx) { break; l = idx - s->start_index - i + 100; - n = pa_xnew0(idxset_entry*, l); + n = pa_xnew0(struct idxset_entry*, l); for (j = 0; j < s->array_size-i; j++) n[j] = s->array[i+j]; @@ -148,7 +154,9 @@ static void extend_array(pa_idxset *s, uint32_t idx) { s->start_index += i; } -static idxset_entry** array_index(pa_idxset*s, uint32_t idx) { +static struct idxset_entry** array_index(pa_idxset*s, uint32_t idx) { + pa_assert(s); + if (idx >= s->start_index + s->array_size) return NULL; @@ -160,15 +168,15 @@ static idxset_entry** array_index(pa_idxset*s, uint32_t idx) { int pa_idxset_put(pa_idxset*s, void *p, uint32_t *idx) { unsigned h; - idxset_entry *e, **a; + struct idxset_entry *e, **a; - assert(s); - assert(p); + pa_assert(s); + pa_assert(p); - assert(s->hash_func); + pa_assert(s->hash_func); h = s->hash_func(p) % s->hash_table_size; - assert(s->hash_table); + pa_assert(s->hash_table); if ((e = hash_scan(s, s->hash_table[h], p))) { if (idx) *idx = e->index; @@ -176,7 +184,8 @@ int pa_idxset_put(pa_idxset*s, void *p, uint32_t *idx) { return -1; } - e = pa_xmalloc(sizeof(idxset_entry)); + if (!(e = pa_flist_pop(PA_STATIC_FLIST_GET(entries)))) + e = pa_xnew(struct idxset_entry, 1); e->data = p; e->index = s->index++; e->hash_value = h; @@ -191,23 +200,23 @@ int pa_idxset_put(pa_idxset*s, void *p, uint32_t *idx) { /* Insert into array */ extend_array(s, e->index); a = array_index(s, e->index); - assert(a && !*a); + pa_assert(a && !*a); *a = e; /* Insert into linked list */ e->iterate_next = NULL; e->iterate_prev = s->iterate_list_tail; if (s->iterate_list_tail) { - assert(s->iterate_list_head); + pa_assert(s->iterate_list_head); s->iterate_list_tail->iterate_next = e; } else { - assert(!s->iterate_list_head); + pa_assert(!s->iterate_list_head); s->iterate_list_head = e; } s->iterate_list_tail = e; s->n_entries++; - assert(s->n_entries >= 1); + pa_assert(s->n_entries >= 1); if (idx) *idx = e->index; @@ -216,8 +225,8 @@ int pa_idxset_put(pa_idxset*s, void *p, uint32_t *idx) { } void* pa_idxset_get_by_index(pa_idxset*s, uint32_t idx) { - idxset_entry **a; - assert(s); + struct idxset_entry **a; + pa_assert(s); if (!(a = array_index(s, idx))) return NULL; @@ -230,13 +239,15 @@ void* pa_idxset_get_by_index(pa_idxset*s, uint32_t idx) { void* pa_idxset_get_by_data(pa_idxset*s, const void *p, uint32_t *idx) { unsigned h; - idxset_entry *e; - assert(s && p); + struct idxset_entry *e; + + pa_assert(s); + pa_assert(p); - assert(s->hash_func); + pa_assert(s->hash_func); h = s->hash_func(p) % s->hash_table_size; - assert(s->hash_table); + pa_assert(s->hash_table); if (!(e = hash_scan(s, s->hash_table[h], p))) return NULL; @@ -246,13 +257,15 @@ void* pa_idxset_get_by_data(pa_idxset*s, const void *p, uint32_t *idx) { return e->data; } -static void remove_entry(pa_idxset *s, idxset_entry *e) { - idxset_entry **a; - assert(s && e); +static void remove_entry(pa_idxset *s, struct idxset_entry *e) { + struct idxset_entry **a; + + pa_assert(s); + pa_assert(e); /* Remove from array */ a = array_index(s, e->index); - assert(a && *a && *a == e); + pa_assert(a && *a && *a == e); *a = NULL; /* Remove from linked list */ @@ -275,17 +288,18 @@ static void remove_entry(pa_idxset *s, idxset_entry *e) { else s->hash_table[e->hash_value] = e->hash_next; - pa_xfree(e); + if (pa_flist_push(PA_STATIC_FLIST_GET(entries), e) < 0) + pa_xfree(e); - assert(s->n_entries >= 1); + pa_assert(s->n_entries >= 1); s->n_entries--; } void* pa_idxset_remove_by_index(pa_idxset*s, uint32_t idx) { - idxset_entry **a; + struct idxset_entry **a; void *data; - assert(s); + pa_assert(s); if (!(a = array_index(s, idx))) return NULL; @@ -300,14 +314,16 @@ void* pa_idxset_remove_by_index(pa_idxset*s, uint32_t idx) { } void* pa_idxset_remove_by_data(pa_idxset*s, const void *data, uint32_t *idx) { - idxset_entry *e; + struct idxset_entry *e; unsigned h; void *r; - assert(s->hash_func); + pa_assert(s); + + pa_assert(s->hash_func); h = s->hash_func(data) % s->hash_table_size; - assert(s->hash_table); + pa_assert(s->hash_table); if (!(e = hash_scan(s, s->hash_table[h], data))) return NULL; @@ -321,8 +337,10 @@ void* pa_idxset_remove_by_data(pa_idxset*s, const void *data, uint32_t *idx) { } void* pa_idxset_rrobin(pa_idxset *s, uint32_t *idx) { - idxset_entry **a, *e = NULL; - assert(s && idx); + struct idxset_entry **a, *e = NULL; + + pa_assert(s); + pa_assert(idx); if ((a = array_index(s, *idx)) && *a) e = (*a)->iterate_next; @@ -338,7 +356,7 @@ void* pa_idxset_rrobin(pa_idxset *s, uint32_t *idx) { } void* pa_idxset_first(pa_idxset *s, uint32_t *idx) { - assert(s); + pa_assert(s); if (!s->iterate_list_head) return NULL; @@ -349,9 +367,10 @@ void* pa_idxset_first(pa_idxset *s, uint32_t *idx) { } void *pa_idxset_next(pa_idxset *s, uint32_t *idx) { - idxset_entry **a, *e = NULL; - assert(s); - assert(idx); + struct idxset_entry **a, *e = NULL; + + pa_assert(s); + pa_assert(idx); if ((a = array_index(s, *idx)) && *a) e = (*a)->iterate_next; @@ -366,13 +385,15 @@ void *pa_idxset_next(pa_idxset *s, uint32_t *idx) { } int pa_idxset_foreach(pa_idxset*s, int (*func)(void *p, uint32_t idx, int *del, void*userdata), void *userdata) { - idxset_entry *e; - assert(s && func); + struct idxset_entry *e; + + pa_assert(s); + pa_assert(func); e = s->iterate_list_head; while (e) { int del = 0, r; - idxset_entry *n = e->iterate_next; + struct idxset_entry *n = e->iterate_next; r = func(e->data, e->index, &del, userdata); @@ -389,12 +410,14 @@ int pa_idxset_foreach(pa_idxset*s, int (*func)(void *p, uint32_t idx, int *del, } unsigned pa_idxset_size(pa_idxset*s) { - assert(s); + pa_assert(s); + return s->n_entries; } int pa_idxset_isempty(pa_idxset *s) { - assert(s); + pa_assert(s); + return s->n_entries == 0; } -- cgit From b552541dd1f65646a5963e7a8c8ec43e4ea416c8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 30 Aug 2007 22:44:19 +0000 Subject: reorder initialization of pa_core variables git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1732 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/main.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/daemon/main.c b/src/daemon/main.c index e17e25f5..7bdf65c1 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -604,6 +604,11 @@ int main(int argc, char *argv[]) { c->default_sample_spec = conf->default_sample_spec; c->default_n_fragments = conf->default_n_fragments; c->default_fragment_size_msec = conf->default_fragment_size_msec; + c->disallow_module_loading = conf->disallow_module_loading; + c->exit_idle_time = conf->exit_idle_time; + c->module_idle_time = conf->module_idle_time; + c->scache_idle_time = conf->scache_idle_time; + c->resample_method = conf->resample_method; pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0); pa_signal_new(SIGINT, signal_callback, c); @@ -634,7 +639,7 @@ int main(int argc, char *argv[]) { r = pa_cpu_limit_init(pa_mainloop_get_api(mainloop)); assert(r == 0); } - + buf = pa_strbuf_new(); if (conf->default_script_file) r = pa_cli_command_execute_file(c, conf->default_script_file, buf, &conf->fail); @@ -664,12 +669,6 @@ int main(int argc, char *argv[]) { pa_loop_write(daemon_pipe[1], &retval, sizeof(retval), NULL); #endif - c->disallow_module_loading = conf->disallow_module_loading; - c->exit_idle_time = conf->exit_idle_time; - c->module_idle_time = conf->module_idle_time; - c->scache_idle_time = conf->scache_idle_time; - c->resample_method = conf->resample_method; - if (c->default_sink_name && pa_namereg_get(c, c->default_sink_name, PA_NAMEREG_SINK, 1) == NULL) { pa_log_error("%s : Fatal error. Default sink name (%s) does not exist in name register.", __FILE__, c->default_sink_name); -- cgit From 4d623f0d4442148f20f2ffdc85cf95e54ef83721 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 30 Aug 2007 22:57:53 +0000 Subject: Lots of assorted minor cleanups and fixes: * s/disconnect/unlink/ at many places where it makes sense * make "start_corked" a normal pa_sink_input/pa_source_output flag instead of a seperate boolean variable * add generic process() function to pa_sink_input/pa_source_output vtable that can be used by streams to do some arbitrary processing in each rt loop iteration even the sink/source is suspended * add detach()/attach() functions to pa_sink_input/pa_source_output vtable that are called when ever the rtpoll object of the event thread changes * add suspend() functions to pa_sink_input/pa_source_output vtable which are called whenever the sink/source they are attached to suspends/resumes * add PA_SINK_INIT/PA_SOURCE_INIT/PA_SINK_INPUT_INIT/PA_SINK_OUTPUT_INIT states to state machines which is active between _new() and _put() * seperate _put() from _new() for pa_sink/pa_source * add PA_SOURCE_OUTPUT_DONT_MOVE/PA_SINK_INPUT_DONT_MOVE flags * make the pa_rtpoll object a property of pa_sink/pa_source to allow streams attached to them make use of it * fix skipping over move_silence * update module-pipe-source to make use of pa_rtpoll * add pa_sink_skip() as optimization in cases where the actualy data returned by pa_sink_render() doesn't matter git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1733 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 49 +++++------- src/modules/module-alsa-source.c | 51 ++++++------- src/modules/module-null-sink.c | 39 +++++----- src/modules/module-oss.c | 70 +++++++++-------- src/modules/module-pipe-sink.c | 39 +++++----- src/modules/module-pipe-source.c | 103 ++++++++++++------------- src/modules/module-rescue-streams.c | 4 +- src/modules/module-sine.c | 4 +- src/modules/module-suspend-on-idle.c | 93 +++++++++++++---------- src/pulsecore/cli-text.c | 28 +++++-- src/pulsecore/core.c | 2 +- src/pulsecore/core.h | 16 ++-- src/pulsecore/play-memblockq.c | 2 +- src/pulsecore/play-memchunk.c | 2 +- src/pulsecore/protocol-esound.c | 4 +- src/pulsecore/protocol-native.c | 20 ++--- src/pulsecore/protocol-simple.c | 4 +- src/pulsecore/sink-input.c | 75 +++++++++++++----- src/pulsecore/sink-input.h | 45 ++++++++++- src/pulsecore/sink.c | 143 ++++++++++++++++++++++++++++++----- src/pulsecore/sink.h | 46 ++++++----- src/pulsecore/sound-file-stream.c | 2 +- src/pulsecore/source-output.c | 45 ++++++++--- src/pulsecore/source-output.h | 44 +++++++++-- src/pulsecore/source.c | 106 ++++++++++++++++++++++---- src/pulsecore/source.h | 38 +++++++--- 26 files changed, 702 insertions(+), 372 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index a805845c..24765a04 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -347,7 +347,7 @@ static int suspend(struct userdata *u) { u->alsa_rtpoll_item = NULL; } - pa_log_debug("Device suspended..."); + pa_log_info("Device suspended..."); return 0; } @@ -361,7 +361,7 @@ static int unsuspend(struct userdata *u) { pa_assert(u); pa_assert(!u->pcm_handle); - pa_log_debug("Trying resume..."); + pa_log_info("Trying resume..."); snd_config_update_free_global(); if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { @@ -406,7 +406,7 @@ static int unsuspend(struct userdata *u) { u->first = 1; - pa_log_debug("Resumed successfully..."); + pa_log_info("Resumed successfully..."); return 0; @@ -457,7 +457,8 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse break; - case PA_SINK_DISCONNECTED: + case PA_SINK_UNLINKED: + case PA_SINK_INIT: ; } @@ -607,13 +608,7 @@ static void thread_func(void *userdata) { goto fail; for (;;) { - pa_msgobject *object; - int code; - void *data; - pa_memchunk chunk; - int64_t offset; - -/* pa_log("loop"); */ + int ret; /* Render some data and write it to the dsp */ if (PA_SINK_OPENED(u->sink->thread_info.state)) { @@ -635,28 +630,25 @@ static void thread_func(void *userdata) { } } -/* pa_log("loop2"); */ + /* Now give the sink inputs some to time to process their data */ + if ((ret = pa_sink_process_inputs(u->sink)) < 0) + goto fail; + if (ret > 0) + continue; /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { - int ret; - - if (!object && code == PA_MESSAGE_SHUTDOWN) { - pa_asyncmsgq_done(u->thread_mq.inq, 0); - goto finish; - } - - ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); - pa_asyncmsgq_done(u->thread_mq.inq, ret); + if ((ret = pa_thread_mq_process(&u->thread_mq) < 0)) + goto finish; + if (ret > 0) continue; - } - + /* Hmm, nothing to do. Let's sleep */ if (pa_rtpoll_run(u->rtpoll) < 0) { pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; } + /* Tell ALSA about this and process its response */ if (PA_SINK_OPENED(u->sink->thread_info.state)) { struct pollfd *pollfd; unsigned short revents = 0; @@ -680,9 +672,7 @@ static void thread_func(void *userdata) { goto fail; } -/* pa_log("got alsa event"); */ } - } fail: @@ -828,6 +818,7 @@ int pa__init(pa_module*m) { pa_sink_set_module(u->sink, m); pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); + pa_sink_set_rtpoll(u->sink, u->rtpoll); pa_sink_set_description(u->sink, t = pa_sprintf_malloc( "ALSA PCM on %s (%s)%s", dev, @@ -835,7 +826,7 @@ int pa__init(pa_module*m) { use_mmap ? " via DMA" : "")); pa_xfree(t); - u->sink->is_hardware = 1; + u->sink->flags = PA_SINK_HARDWARE|PA_SINK_CAN_SUSPEND|PA_SINK_HW_VOLUME_CTRL|PA_SINK_LATENCY; u->frame_size = frame_size; u->fragment_size = frag_size = period_size * frame_size; @@ -894,6 +885,8 @@ int pa__init(pa_module*m) { if (u->sink->get_mute) u->sink->get_mute(u->sink); + pa_sink_put(u->sink); + pa_modargs_free(ma); return 0; @@ -917,7 +910,7 @@ void pa__done(pa_module*m) { return; if (u->sink) - pa_sink_disconnect(u->sink); + pa_sink_unlink(u->sink); if (u->thread) { pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 6ea99ec7..0d76cabc 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -328,7 +328,7 @@ static int suspend(struct userdata *u) { u->alsa_rtpoll_item = NULL; } - pa_log_debug("Device suspended..."); + pa_log_info("Device suspended..."); return 0; } @@ -342,7 +342,7 @@ static int unsuspend(struct userdata *u) { pa_assert(u); pa_assert(!u->pcm_handle); - pa_log_debug("Trying resume..."); + pa_log_info("Trying resume..."); snd_config_update_free_global(); if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) { @@ -387,7 +387,7 @@ static int unsuspend(struct userdata *u) { /* FIXME: We need to reload the volume somehow */ - pa_log_debug("Resumed successfully..."); + pa_log_info("Resumed successfully..."); return 0; @@ -438,7 +438,8 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off break; - case PA_SOURCE_DISCONNECTED: + case PA_SOURCE_UNLINKED: + case PA_SOURCE_INIT: ; } @@ -590,15 +591,9 @@ static void thread_func(void *userdata) { snd_pcm_start(u->pcm_handle); for (;;) { - pa_msgobject *object; - int code; - void *data; - int64_t offset; - pa_memchunk chunk; + int ret; -/* pa_log("loop"); */ - - /* Render some data and write it to the dsp */ + /* Read some data and pass it to the sources */ if (PA_SOURCE_OPENED(u->source->thread_info.state)) { if (u->use_mmap) { @@ -611,29 +606,25 @@ static void thread_func(void *userdata) { } } -/* pa_log("loop2"); */ + /* Now give the source outputs some to time to process their data */ + if ((ret = pa_source_process_outputs(u->source)) < 0) + goto fail; + if (ret > 0) + continue; /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { - int ret; - -/* pa_log("processing msg"); */ - - if (!object && code == PA_MESSAGE_SHUTDOWN) { - pa_asyncmsgq_done(u->thread_mq.inq, 0); - goto finish; - } - - ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); - pa_asyncmsgq_done(u->thread_mq.inq, ret); + if ((ret = pa_thread_mq_process(&u->thread_mq) < 0)) + goto finish; + if (ret > 0) continue; - } + /* Hmm, nothing to do. Let's sleep */ if (pa_rtpoll_run(u->rtpoll) < 0) { pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; } + /* Tell ALSA about this and process its response */ if (PA_SOURCE_OPENED(u->source->thread_info.state)) { struct pollfd *pollfd; unsigned short revents = 0; @@ -657,7 +648,6 @@ static void thread_func(void *userdata) { goto fail; } -/* pa_log("got alsa event"); */ } } @@ -802,6 +792,7 @@ int pa__init(pa_module*m) { pa_source_set_module(u->source, m); pa_source_set_asyncmsgq(u->source, u->thread_mq.inq); + pa_source_set_rtpoll(u->source, u->rtpoll); pa_source_set_description(u->source, t = pa_sprintf_malloc( "ALSA PCM on %s (%s)%s", dev, @@ -809,7 +800,7 @@ int pa__init(pa_module*m) { use_mmap ? " via DMA" : "")); pa_xfree(t); - u->source->is_hardware = 1; + u->source->flags = PA_SOURCE_HARDWARE|PA_SOURCE_CAN_SUSPEND|PA_SOURCE_LATENCY|PA_SOURCE_HW_VOLUME_CTRL; u->frame_size = frame_size; u->fragment_size = frag_size = period_size * frame_size; @@ -863,6 +854,8 @@ int pa__init(pa_module*m) { if (u->source->get_mute) u->source->get_mute(u->source); + pa_source_put(u->source); + pa_modargs_free(ma); return 0; @@ -886,7 +879,7 @@ void pa__done(pa_module*m) { return; if (u->source) - pa_source_disconnect(u->source); + pa_source_unlink(u->source); if (u->thread) { pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index 3b512371..78d99ceb 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -128,11 +128,7 @@ static void thread_func(void *userdata) { pa_rtclock_get(&u->timestamp); for (;;) { - pa_msgobject *object; - int code; - void *data; - pa_memchunk chunk; - int64_t offset; + int ret; /* Render some data and drop it immediately */ if (u->sink->thread_info.state == PA_SINK_RUNNING) { @@ -141,30 +137,25 @@ static void thread_func(void *userdata) { pa_rtclock_get(&now); if (pa_timespec_cmp(&u->timestamp, &now) <= 0) { - - pa_sink_render(u->sink, u->block_size, &chunk); - pa_memblock_unref(chunk.memblock); - - pa_timespec_add(&u->timestamp, pa_bytes_to_usec(chunk.length, &u->sink->sample_spec)); + pa_sink_skip(u->sink, u->block_size); + pa_timespec_add(&u->timestamp, pa_bytes_to_usec(u->block_size, &u->sink->sample_spec)); } pa_rtpoll_set_timer_absolute(u->rtpoll, &u->timestamp); } else pa_rtpoll_set_timer_disabled(u->rtpoll); - /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { - int ret; - - if (!object && code == PA_MESSAGE_SHUTDOWN) { - pa_asyncmsgq_done(u->thread_mq.inq, 0); - goto finish; - } + /* Now give the sink inputs some to time to process their data */ + if ((ret = pa_sink_process_inputs(u->sink)) < 0) + goto fail; + if (ret > 0) + continue; - ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); - pa_asyncmsgq_done(u->thread_mq.inq, ret); + /* Check whether there is a message for us to process */ + if ((ret = pa_thread_mq_process(&u->thread_mq) < 0)) + goto finish; + if (ret > 0) continue; - } /* Hmm, nothing to do. Let's sleep */ if (pa_rtpoll_run(u->rtpoll) < 0) { @@ -217,9 +208,11 @@ int pa__init(pa_module*m) { u->sink->parent.process_msg = sink_process_msg; u->sink->userdata = u; + u->sink->flags = PA_SINK_LATENCY; pa_sink_set_module(u->sink, m); pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); + pa_sink_set_rtpoll(u->sink, u->rtpoll); pa_sink_set_description(u->sink, pa_modargs_get_value(ma, "description", "NULL sink")); u->block_size = pa_bytes_per_second(&ss) / 20; /* 50 ms */ @@ -231,6 +224,8 @@ int pa__init(pa_module*m) { goto fail; } + pa_sink_put(u->sink); + pa_modargs_free(ma); return 0; @@ -253,7 +248,7 @@ void pa__done(pa_module*m) { return; if (u->sink) - pa_sink_disconnect(u->sink); + pa_sink_unlink(u->sink); if (u->thread) { pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 85fdd9c8..bbb1e0d2 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -443,7 +443,7 @@ static int suspend(struct userdata *u) { pa_assert(u); pa_assert(u->fd >= 0); - pa_log_debug("Suspending..."); + pa_log_info("Suspending..."); if (u->out_mmap_memblocks) { unsigned i; @@ -483,7 +483,7 @@ static int suspend(struct userdata *u) { u->rtpoll_item = NULL; } - pa_log_debug("Device suspended..."); + pa_log_info("Device suspended..."); return 0; } @@ -501,7 +501,7 @@ static int unsuspend(struct userdata *u) { m = u->mode; - pa_log_debug("Trying resume..."); + pa_log_info("Trying resume..."); if ((u->fd = pa_oss_open(u->device_name, &m, NULL)) < 0) { pa_log_warn("Resume failed, device busy (%s)", pa_cstrerror(errno)); @@ -582,7 +582,7 @@ static int unsuspend(struct userdata *u) { pollfd->events = 0; pollfd->revents = 0; - pa_log_debug("Resumed successfully..."); + pa_log_info("Resumed successfully..."); return 0; @@ -651,7 +651,8 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse break; - case PA_SINK_DISCONNECTED: + case PA_SINK_UNLINKED: + case PA_SINK_INIT: ; } @@ -748,7 +749,8 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off } break; - case PA_SOURCE_DISCONNECTED: + case PA_SOURCE_UNLINKED: + case PA_SOURCE_INIT: ; } @@ -807,20 +809,15 @@ static void thread_func(void *userdata) { trigger(u, 0); for (;;) { - pa_msgobject *object; - int code; - void *data; - pa_memchunk chunk; - int64_t offset; + int ret; /* pa_log("loop"); */ /* Render some data and write it to the dsp */ - if (u->sink && u->sink->thread_info.state != PA_SINK_DISCONNECTED && u->fd >= 0 && (revents & POLLOUT)) { + if (u->sink && u->sink->thread_info.state != PA_SINK_UNLINKED && u->fd >= 0 && (revents & POLLOUT)) { if (u->use_mmap) { - int ret; if ((ret = mmap_write(u)) < 0) goto fail; @@ -908,10 +905,9 @@ static void thread_func(void *userdata) { /* Try to read some data and pass it on to the source driver */ - if (u->source && u->source->thread_info.state != PA_SOURCE_DISCONNECTED && u->fd >= 0 && ((revents & POLLIN))) { + if (u->source && u->source->thread_info.state != PA_SOURCE_UNLINKED && u->fd >= 0 && ((revents & POLLIN))) { if (u->use_mmap) { - int ret; if ((ret = mmap_read(u)) < 0) goto fail; @@ -995,21 +991,23 @@ static void thread_func(void *userdata) { /* pa_log("loop2"); */ - /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { - int ret; - -/* pa_log("processing msg"); */ - - if (!object && code == PA_MESSAGE_SHUTDOWN) { - pa_asyncmsgq_done(u->thread_mq.inq, 0); - goto finish; - } + /* Now give the sink inputs some to time to process their data */ + if ((ret = pa_sink_process_inputs(u->sink)) < 0) + goto fail; + if (ret > 0) + continue; - ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); - pa_asyncmsgq_done(u->thread_mq.inq, ret); + /* Now give the source outputs some to time to process their data */ + if ((ret = pa_source_process_outputs(u->source)) < 0) + goto fail; + if (ret > 0) + continue; + + /* Check whether there is a message for us to process */ + if ((ret = pa_thread_mq_process(&u->thread_mq) < 0)) + goto finish; + if (ret > 0) continue; - } if (u->fd >= 0) { struct pollfd *pollfd; @@ -1019,7 +1017,6 @@ static void thread_func(void *userdata) { ((u->source && PA_SOURCE_OPENED(u->source->thread_info.state)) ? POLLIN : 0) | ((u->sink && PA_SINK_OPENED(u->sink->thread_info.state)) ? POLLOUT : 0); } - /* Hmm, nothing to do. Let's sleep */ if (pa_rtpoll_run(u->rtpoll) < 0) { @@ -1212,6 +1209,7 @@ int pa__init(pa_module*m) { pa_source_set_module(u->source, m); pa_source_set_asyncmsgq(u->source, u->thread_mq.inq); + pa_source_set_rtpoll(u->source, u->rtpoll); pa_source_set_description(u->source, t = pa_sprintf_malloc( "OSS PCM on %s%s%s%s%s", dev, @@ -1220,7 +1218,7 @@ int pa__init(pa_module*m) { hwdesc[0] ? ")" : "", use_mmap ? " via DMA" : "")); pa_xfree(t); - u->source->is_hardware = 1; + u->source->flags = PA_SOURCE_HARDWARE|PA_SOURCE_CAN_SUSPEND|PA_SOURCE_LATENCY|PA_SOURCE_HW_VOLUME_CTRL; u->source->refresh_volume = 1; if (use_mmap) @@ -1266,6 +1264,7 @@ int pa__init(pa_module*m) { pa_sink_set_module(u->sink, m); pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); + pa_sink_set_rtpoll(u->sink, u->rtpoll); pa_sink_set_description(u->sink, t = pa_sprintf_malloc( "OSS PCM on %s%s%s%s%s", dev, @@ -1274,7 +1273,7 @@ int pa__init(pa_module*m) { hwdesc[0] ? ")" : "", use_mmap ? " via DMA" : "")); pa_xfree(t); - u->sink->is_hardware = 1; + u->sink->flags = PA_SINK_HARDWARE|PA_SINK_CAN_SUSPEND|PA_SINK_LATENCY|PA_SINK_HW_VOLUME_CTRL; u->sink->refresh_volume = 1; if (use_mmap) @@ -1298,6 +1297,11 @@ go_on: if (u->sink) pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_GET_VOLUME, &u->sink->volume, 0, NULL, NULL); + if (u->sink) + pa_sink_put(u->sink); + if (u->source) + pa_source_put(u->source); + pa_modargs_free(ma); return 0; @@ -1324,10 +1328,10 @@ void pa__done(pa_module*m) { return; if (u->sink) - pa_sink_disconnect(u->sink); + pa_sink_unlink(u->sink); if (u->source) - pa_source_disconnect(u->source); + pa_source_unlink(u->source); if (u->thread) { pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index a1101ab8..d5ef194f 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -124,17 +124,12 @@ static void thread_func(void *userdata) { pa_rtpoll_install(u->rtpoll); for (;;) { - pa_msgobject *object; - int code; - void *data; - pa_memchunk chunk; - int64_t offset; + int ret; struct pollfd *pollfd; - /* Render some data and write it to the fifo */ - pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); - + + /* Render some data and write it to the fifo */ if (u->sink->thread_info.state == PA_SINK_RUNNING && pollfd->revents) { ssize_t l; void *p; @@ -173,19 +168,17 @@ static void thread_func(void *userdata) { } } - /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { - int ret; - - if (!object && code == PA_MESSAGE_SHUTDOWN) { - pa_asyncmsgq_done(u->thread_mq.inq, 0); - goto finish; - } + /* Now give the sink inputs some to time to process their data */ + if ((ret = pa_sink_process_inputs(u->sink)) < 0) + goto fail; + if (ret > 0) + continue; - ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); - pa_asyncmsgq_done(u->thread_mq.inq, ret); + /* Check whether there is a message for us to process */ + if ((ret = pa_thread_mq_process(&u->thread_mq) < 0)) + goto finish; + if (ret > 0) continue; - } /* Hmm, nothing to do. Let's sleep */ pollfd->events = u->sink->thread_info.state == PA_SINK_RUNNING ? POLLOUT : 0; @@ -271,9 +264,11 @@ int pa__init(pa_module*m) { u->sink->parent.process_msg = sink_process_msg; u->sink->userdata = u; + u->sink->flags = PA_SINK_LATENCY; pa_sink_set_module(u->sink, m); pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); + pa_sink_set_rtpoll(u->sink, u->rtpoll); pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Unix FIFO sink '%s'", u->filename)); pa_xfree(t); @@ -281,12 +276,14 @@ int pa__init(pa_module*m) { pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); pollfd->fd = u->fd; pollfd->events = pollfd->revents = 0; - + if (!(u->thread = pa_thread_new(thread_func, u))) { pa_log("Failed to create thread."); goto fail; } + pa_sink_put(u->sink); + pa_modargs_free(ma); return 0; @@ -309,7 +306,7 @@ void pa__done(pa_module*m) { return; if (u->sink) - pa_sink_disconnect(u->sink); + pa_sink_unlink(u->sink); if (u->thread) { pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index 2209d1ee..6dc94648 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -45,6 +45,7 @@ #include #include #include +#include #include "module-pipe-source-symdef.h" @@ -66,13 +67,17 @@ struct userdata { pa_core *core; pa_module *module; pa_source *source; + pa_thread *thread; pa_thread_mq thread_mq; - + pa_rtpoll *rtpoll; + char *filename; int fd; pa_memchunk memchunk; + + pa_rtpoll_item *rtpoll_item; }; static const char* const valid_modargs[] = { @@ -86,14 +91,7 @@ static const char* const valid_modargs[] = { }; static void thread_func(void *userdata) { - enum { - POLLFD_ASYNCQ, - POLLFD_FIFO, - POLLFD_MAX, - }; - struct userdata *u = userdata; - struct pollfd pollfd[POLLFD_MAX]; int read_type = 0; pa_assert(u); @@ -101,40 +99,18 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); pa_thread_mq_install(&u->thread_mq); - - memset(&pollfd, 0, sizeof(pollfd)); + pa_rtpoll_install(u->rtpoll); - pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->thread_mq.inq); - pollfd[POLLFD_ASYNCQ].events = POLLIN; - pollfd[POLLFD_FIFO].fd = u->fd; - for (;;) { - pa_msgobject *object; - int code; - void *data; - pa_memchunk chunk; - int r; - int64_t offset; - - /* Check whether there is a message for us to process */ - if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &offset, &chunk, 0) == 0) { - int ret; - - if (!object && code == PA_MESSAGE_SHUTDOWN) { - pa_asyncmsgq_done(u->thread_mq.inq, 0); - goto finish; - } - - ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); - pa_asyncmsgq_done(u->thread_mq.inq, ret); - continue; - } + int ret; + struct pollfd *pollfd; + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + /* Try to read some data and pass it on to the source driver */ - - if (u->source->thread_info.state == PA_SOURCE_RUNNING && pollfd[POLLFD_FIFO].revents) { - void *p; + if (u->source->thread_info.state == PA_SOURCE_RUNNING && pollfd->revents) { ssize_t l; + void *p; if (!u->memchunk.memblock) { u->memchunk.memblock = pa_memblock_new(u->core->mempool, PIPE_BUF); @@ -169,38 +145,35 @@ static void thread_func(void *userdata) { pa_memchunk_reset(&u->memchunk); } - pollfd[POLLFD_FIFO].revents = 0; - continue; + pollfd->revents = 0; } } - pollfd[POLLFD_FIFO].events = u->source->thread_info.state == PA_SOURCE_RUNNING ? POLLIN : 0; - - /* Hmm, nothing to do. Let's sleep */ - - if (pa_asyncmsgq_before_poll(u->thread_mq.inq) < 0) + /* Now give the source outputs some to time to process their data */ + if ((ret = pa_source_process_outputs(u->source)) < 0) + goto fail; + if (ret > 0) continue; -/* pa_log("polling for %i", pollfd[POLLFD_FIFO].events); */ - r = poll(pollfd, POLLFD_MAX, -1); -/* pa_log("polling got %i (r=%i) %i", r > 0 ? pollfd[POLLFD_FIFO].revents : 0, r, r > 0 ? pollfd[POLLFD_ASYNCQ].revents: 0); */ - - pa_asyncmsgq_after_poll(u->thread_mq.inq); + /* Check whether there is a message for us to process */ + if ((ret = pa_thread_mq_process(&u->thread_mq) < 0)) + goto finish; + if (ret > 0) + continue; - if (r < 0) { - if (errno == EINTR) - continue; + /* Hmm, nothing to do. Let's sleep */ + pollfd->events = u->source->thread_info.state == PA_SOURCE_RUNNING ? POLLIN : 0; + if (pa_rtpoll_run(u->rtpoll) < 0) { pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; } - if (pollfd[POLLFD_FIFO].revents & ~POLLIN) { + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + if (pollfd->revents & ~POLLIN) { pa_log("FIFO shutdown."); goto fail; } - - pa_assert((pollfd[POLLFD_ASYNCQ].revents & ~POLLIN) == 0); } fail: @@ -220,6 +193,7 @@ int pa__init(pa_module*m) { pa_channel_map map; pa_modargs *ma; char *t; + struct pollfd *pollfd; pa_assert(m); @@ -240,6 +214,8 @@ int pa__init(pa_module*m) { m->userdata = u; pa_memchunk_reset(&u->memchunk); pa_thread_mq_init(&u->thread_mq, m->core->mainloop); + u->rtpoll = pa_rtpoll_new(); + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, u->thread_mq.inq); u->filename = pa_xstrdup(pa_modargs_get_value(ma, "file", DEFAULT_FILE_NAME)); @@ -268,17 +244,26 @@ int pa__init(pa_module*m) { } u->source->userdata = u; + u->source->flags = 0; pa_source_set_module(u->source, m); pa_source_set_asyncmsgq(u->source, u->thread_mq.inq); + pa_source_set_rtpoll(u->source, u->rtpoll); pa_source_set_description(u->source, t = pa_sprintf_malloc("Unix FIFO source '%s'", u->filename)); pa_xfree(t); + u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, 1); + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + pollfd->fd = u->fd; + pollfd->events = pollfd->revents = 0; + if (!(u->thread = pa_thread_new(thread_func, u))) { pa_log("Failed to create thread."); goto fail; } + pa_source_put(u->source); + pa_modargs_free(ma); return 0; @@ -301,7 +286,7 @@ void pa__done(pa_module*m) { return; if (u->source) - pa_source_disconnect(u->source); + pa_source_unlink(u->source); if (u->thread) { pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); @@ -316,6 +301,12 @@ void pa__done(pa_module*m) { if (u->memchunk.memblock) pa_memblock_unref(u->memchunk.memblock); + if (u->rtpoll_item) + pa_rtpoll_item_free(u->rtpoll_item); + + if (u->rtpoll) + pa_rtpoll_free(u->rtpoll); + if (u->filename) { unlink(u->filename); pa_xfree(u->filename); diff --git a/src/modules/module-rescue-streams.c b/src/modules/module-rescue-streams.c index e0eed036..24077dc2 100644 --- a/src/modules/module-rescue-streams.c +++ b/src/modules/module-rescue-streams.c @@ -138,8 +138,8 @@ int pa__init(pa_module*m) { } m->userdata = u = pa_xnew(struct userdata, 1); - u->sink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_DISCONNECT], (pa_hook_cb_t) sink_hook_callback, NULL); - u->source_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_DISCONNECT], (pa_hook_cb_t) source_hook_callback, NULL); + u->sink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], (pa_hook_cb_t) sink_hook_callback, NULL); + u->source_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], (pa_hook_cb_t) source_hook_callback, NULL); pa_modargs_free(ma); return 0; diff --git a/src/modules/module-sine.c b/src/modules/module-sine.c index f2830ff0..94036f6c 100644 --- a/src/modules/module-sine.c +++ b/src/modules/module-sine.c @@ -98,7 +98,7 @@ static void sink_input_kill_cb(pa_sink_input *i) { u = i->userdata; pa_assert(u); - pa_sink_input_disconnect(u->sink_input); + pa_sink_input_unlink(u->sink_input); pa_sink_input_unref(u->sink_input); u->sink_input = NULL; @@ -195,7 +195,7 @@ void pa__done(pa_module*m) { return; if (u->sink_input) { - pa_sink_input_disconnect(u->sink_input); + pa_sink_input_unlink(u->sink_input); pa_sink_input_unref(u->sink_input); } diff --git a/src/modules/module-suspend-on-idle.c b/src/modules/module-suspend-on-idle.c index e9226ca2..79850e71 100644 --- a/src/modules/module-suspend-on-idle.c +++ b/src/modules/module-suspend-on-idle.c @@ -53,16 +53,16 @@ struct userdata { pa_hook_slot *sink_new_slot, *source_new_slot, - *sink_disconnect_slot, - *source_disconnect_slot, + *sink_unlink_slot, + *source_unlink_slot, *sink_state_changed_slot, *source_state_changed_slot; pa_hook_slot *sink_input_new_slot, *source_output_new_slot, - *sink_input_disconnect_slot, - *source_output_disconnect_slot, + *sink_input_unlink_slot, + *source_output_unlink_slot, *sink_input_move_slot, *source_output_move_slot, *sink_input_move_post_slot, @@ -139,8 +139,8 @@ static pa_hook_result_t sink_input_new_hook_cb(pa_core *c, pa_sink_input *s, str pa_sink_input_assert_ref(s); pa_assert(u); - pa_assert_se((d = pa_hashmap_get(u->device_infos, s->sink))); - resume(d); + if ((d = pa_hashmap_get(u->device_infos, s->sink))) + resume(d); return PA_HOOK_OK; } @@ -152,35 +152,35 @@ static pa_hook_result_t source_output_new_hook_cb(pa_core *c, pa_source_output * pa_source_output_assert_ref(s); pa_assert(u); - pa_assert_se((d = pa_hashmap_get(u->device_infos, s->source))); - resume(d); + if ((d = pa_hashmap_get(u->device_infos, s->source))) + resume(d); return PA_HOOK_OK; } -static pa_hook_result_t sink_input_disconnect_hook_cb(pa_core *c, pa_sink_input *s, struct userdata *u) { +static pa_hook_result_t sink_input_unlink_hook_cb(pa_core *c, pa_sink_input *s, struct userdata *u) { pa_assert(c); pa_sink_input_assert_ref(s); pa_assert(u); if (pa_sink_used_by(s->sink) <= 0) { struct device_info *d; - pa_assert_se((d = pa_hashmap_get(u->device_infos, s->sink))); - restart(d); + if ((d = pa_hashmap_get(u->device_infos, s->sink))) + restart(d); } return PA_HOOK_OK; } -static pa_hook_result_t source_output_disconnect_hook_cb(pa_core *c, pa_source_output *s, struct userdata *u) { +static pa_hook_result_t source_output_unlink_hook_cb(pa_core *c, pa_source_output *s, struct userdata *u) { pa_assert(c); pa_source_output_assert_ref(s); pa_assert(u); if (pa_source_used_by(s->source) <= 0) { struct device_info *d; - pa_assert_se((d = pa_hashmap_get(u->device_infos, s->source))); - restart(d); + if ((d = pa_hashmap_get(u->device_infos, s->source))) + restart(d); } return PA_HOOK_OK; @@ -193,8 +193,8 @@ static pa_hook_result_t sink_input_move_hook_cb(pa_core *c, pa_sink_input *s, st if (pa_sink_used_by(s->sink) <= 1) { struct device_info *d; - pa_assert_se((d = pa_hashmap_get(u->device_infos, s->sink))); - restart(d); + if ((d = pa_hashmap_get(u->device_infos, s->sink))) + restart(d); } return PA_HOOK_OK; @@ -206,8 +206,8 @@ static pa_hook_result_t sink_input_move_post_hook_cb(pa_core *c, pa_sink_input * pa_sink_input_assert_ref(s); pa_assert(u); - pa_assert_se((d = pa_hashmap_get(u->device_infos, s->sink))); - resume(d); + if ((d = pa_hashmap_get(u->device_infos, s->sink))) + resume(d); return PA_HOOK_OK; } @@ -219,8 +219,9 @@ static pa_hook_result_t source_output_move_hook_cb(pa_core *c, pa_source_output if (pa_source_used_by(s->source) <= 1) { struct device_info *d; - pa_assert_se((d = pa_hashmap_get(u->device_infos, s->source))); - restart(d); + + if ((d = pa_hashmap_get(u->device_infos, s->source))) + restart(d); } return PA_HOOK_OK; @@ -232,24 +233,36 @@ static pa_hook_result_t source_output_move_post_hook_cb(pa_core *c, pa_source_ou pa_source_output_assert_ref(s); pa_assert(u); - pa_assert_se((d = pa_hashmap_get(u->device_infos, s->source))); - resume(d); + if ((d = pa_hashmap_get(u->device_infos, s->source))) + resume(d); return PA_HOOK_OK; } static pa_hook_result_t device_new_hook_cb(pa_core *c, pa_object *o, struct userdata *u) { struct device_info *d; + pa_source *source; + pa_sink *sink; pa_assert(c); pa_object_assert_ref(o); pa_assert(u); + source = pa_source_isinstance(o) ? PA_SOURCE(o) : NULL; + sink = pa_sink_isinstance(o) ? PA_SINK(o) : NULL; + + pa_assert(source || sink); + + if (source && !(source->flags & PA_SOURCE_CAN_SUSPEND)) + return PA_HOOK_OK; + + if (sink && !(sink->flags & PA_SINK_CAN_SUSPEND)) + return PA_HOOK_OK; + d = pa_xnew(struct device_info, 1); d->userdata = u; - d->source = pa_source_isinstance(o) ? pa_source_ref(PA_SOURCE(o)) : NULL; - d->sink = pa_sink_isinstance(o) ? pa_sink_ref(PA_SINK(o)) : NULL; - pa_assert(d->source || d->sink); + d->source = source ? pa_source_ref(source) : NULL; + d->sink = sink ? pa_sink_ref(sink) : NULL; d->time_event = c->mainloop->time_new(c->mainloop, NULL, timeout_cb, d); pa_hashmap_put(u->device_infos, o, d); @@ -273,15 +286,15 @@ static void device_info_free(struct device_info *d) { pa_xfree(d); } -static pa_hook_result_t device_disconnect_hook_cb(pa_core *c, pa_object *o, struct userdata *u) { +static pa_hook_result_t device_unlink_hook_cb(pa_core *c, pa_object *o, struct userdata *u) { struct device_info *d; pa_assert(c); pa_object_assert_ref(o); pa_assert(u); - pa_assert_se((d = pa_hashmap_remove(u->device_infos, o))); - device_info_free(d); + if ((d = pa_hashmap_remove(u->device_infos, o))) + device_info_free(d); return PA_HOOK_OK; } @@ -353,15 +366,15 @@ int pa__init(pa_module*m) { u->sink_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_NEW_POST], (pa_hook_cb_t) device_new_hook_cb, u); u->source_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_NEW_POST], (pa_hook_cb_t) device_new_hook_cb, u); - u->sink_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_DISCONNECT_POST], (pa_hook_cb_t) device_disconnect_hook_cb, u); - u->source_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_DISCONNECT_POST], (pa_hook_cb_t) device_disconnect_hook_cb, u); + u->sink_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK_POST], (pa_hook_cb_t) device_unlink_hook_cb, u); + u->source_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK_POST], (pa_hook_cb_t) device_unlink_hook_cb, u); u->sink_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], (pa_hook_cb_t) device_state_changed_hook_cb, u); u->source_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], (pa_hook_cb_t) device_state_changed_hook_cb, u); u->sink_input_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], (pa_hook_cb_t) sink_input_new_hook_cb, u); u->source_output_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PUT], (pa_hook_cb_t) source_output_new_hook_cb, u); - u->sink_input_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_DISCONNECT_POST], (pa_hook_cb_t) sink_input_disconnect_hook_cb, u); - u->source_output_disconnect_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_DISCONNECT_POST], (pa_hook_cb_t) source_output_disconnect_hook_cb, u); + u->sink_input_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST], (pa_hook_cb_t) sink_input_unlink_hook_cb, u); + u->source_output_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK_POST], (pa_hook_cb_t) source_output_unlink_hook_cb, u); u->sink_input_move_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE], (pa_hook_cb_t) sink_input_move_hook_cb, u); u->source_output_move_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE], (pa_hook_cb_t) source_output_move_hook_cb, u); u->sink_input_move_post_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_POST], (pa_hook_cb_t) sink_input_move_post_hook_cb, u); @@ -392,22 +405,22 @@ void pa__done(pa_module*m) { if (u->sink_new_slot) pa_hook_slot_free(u->sink_new_slot); - if (u->sink_disconnect_slot) - pa_hook_slot_free(u->sink_disconnect_slot); + if (u->sink_unlink_slot) + pa_hook_slot_free(u->sink_unlink_slot); if (u->sink_state_changed_slot) pa_hook_slot_free(u->sink_state_changed_slot); if (u->source_new_slot) pa_hook_slot_free(u->source_new_slot); - if (u->source_disconnect_slot) - pa_hook_slot_free(u->source_disconnect_slot); + if (u->source_unlink_slot) + pa_hook_slot_free(u->source_unlink_slot); if (u->source_state_changed_slot) pa_hook_slot_free(u->source_state_changed_slot); if (u->sink_input_new_slot) pa_hook_slot_free(u->sink_input_new_slot); - if (u->sink_input_disconnect_slot) - pa_hook_slot_free(u->sink_input_disconnect_slot); + if (u->sink_input_unlink_slot) + pa_hook_slot_free(u->sink_input_unlink_slot); if (u->sink_input_move_slot) pa_hook_slot_free(u->sink_input_move_slot); if (u->sink_input_move_post_slot) @@ -415,8 +428,8 @@ void pa__done(pa_module*m) { if (u->source_output_new_slot) pa_hook_slot_free(u->source_output_new_slot); - if (u->source_output_disconnect_slot) - pa_hook_slot_free(u->source_output_disconnect_slot); + if (u->source_output_unlink_slot) + pa_hook_slot_free(u->source_output_unlink_slot); if (u->source_output_move_slot) pa_hook_slot_free(u->source_output_move_slot); if (u->source_output_move_post_slot) diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c index c919e46d..617ae812 100644 --- a/src/pulsecore/cli-text.c +++ b/src/pulsecore/cli-text.c @@ -97,7 +97,7 @@ char *pa_sink_list_to_string(pa_core *c) { [PA_SINK_RUNNING] = "RUNNING", [PA_SINK_SUSPENDED] = "SUSPENDED", [PA_SINK_IDLE] = "IDLE", - [PA_SINK_DISCONNECTED] = "DISCONNECTED" + [PA_SINK_UNLINKED] = "UNLINKED" }; assert(c); @@ -114,7 +114,7 @@ char *pa_sink_list_to_string(pa_core *c) { " %c index: %u\n" "\tname: <%s>\n" "\tdriver: <%s>\n" - "\tis hardware: <%i>\n" + "\tflags: %s%s%s%s\n" "\tstate: %s\n" "\tvolume: <%s>\n" "\tmute: <%i>\n" @@ -127,7 +127,10 @@ char *pa_sink_list_to_string(pa_core *c) { sink->index, sink->name, sink->driver, - !!sink->is_hardware, + sink->flags & PA_SINK_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "", + sink->flags & PA_SINK_LATENCY ? "LATENCY " : "", + sink->flags & PA_SINK_HARDWARE ? "HARDWARE " : "", + sink->flags & PA_SINK_CAN_SUSPEND ? "CAN_SUSPEND " : "", state_table[pa_sink_get_state(sink)], pa_cvolume_snprint(cv, sizeof(cv), pa_sink_get_volume(sink)), !!pa_sink_get_mute(sink), @@ -154,7 +157,7 @@ char *pa_source_list_to_string(pa_core *c) { [PA_SOURCE_RUNNING] = "RUNNING", [PA_SOURCE_SUSPENDED] = "SUSPENDED", [PA_SOURCE_IDLE] = "IDLE", - [PA_SOURCE_DISCONNECTED] = "DISCONNECTED" + [PA_SOURCE_UNLINKED] = "UNLINKED" }; assert(c); @@ -172,7 +175,7 @@ char *pa_source_list_to_string(pa_core *c) { " %c index: %u\n" "\tname: <%s>\n" "\tdriver: <%s>\n" - "\tis hardware: <%i>\n" + "\tflags: %s%s%s%s\n" "\tstate: %s\n" "\tvolume: <%s>\n" "\tmute: <%u>\n" @@ -184,7 +187,10 @@ char *pa_source_list_to_string(pa_core *c) { source->index, source->name, source->driver, - !!source->is_hardware, + source->flags & PA_SOURCE_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "", + source->flags & PA_SOURCE_LATENCY ? "LATENCY " : "", + source->flags & PA_SOURCE_HARDWARE ? "HARDWARE " : "", + source->flags & PA_SOURCE_CAN_SUSPEND ? "CAN_SUSPEND " : "", state_table[pa_source_get_state(source)], pa_cvolume_snprint(cv, sizeof(cv), pa_source_get_volume(source)), !!pa_source_get_mute(source), @@ -212,7 +218,7 @@ char *pa_source_output_list_to_string(pa_core *c) { static const char* const state_table[] = { [PA_SOURCE_OUTPUT_RUNNING] = "RUNNING", [PA_SOURCE_OUTPUT_CORKED] = "CORKED", - [PA_SOURCE_OUTPUT_DISCONNECTED] = "DISCONNECTED" + [PA_SOURCE_OUTPUT_UNLINKED] = "UNLINKED" }; assert(c); @@ -231,6 +237,7 @@ char *pa_source_output_list_to_string(pa_core *c) { " index: %u\n" "\tname: '%s'\n" "\tdriver: <%s>\n" + "\tflags: %s%s\n" "\tstate: %s\n" "\tsource: <%u> '%s'\n" "\tlatency: <%0.0f usec>\n" @@ -240,6 +247,8 @@ char *pa_source_output_list_to_string(pa_core *c) { o->index, o->name, o->driver, + o->flags & PA_SOURCE_OUTPUT_VARIABLE_RATE ? "VARIABLE_RATE " : "", + o->flags & PA_SOURCE_OUTPUT_DONT_MOVE ? "DONT_MOVE " : "", state_table[pa_source_output_get_state(o)], o->source->index, o->source->name, (double) pa_source_output_get_latency(o), @@ -263,7 +272,7 @@ char *pa_sink_input_list_to_string(pa_core *c) { [PA_SINK_INPUT_RUNNING] = "RUNNING", [PA_SINK_INPUT_DRAINED] = "DRAINED", [PA_SINK_INPUT_CORKED] = "CORKED", - [PA_SINK_INPUT_DISCONNECTED] = "DISCONNECTED" + [PA_SINK_INPUT_UNLINKED] = "UNLINKED" }; assert(c); @@ -282,6 +291,7 @@ char *pa_sink_input_list_to_string(pa_core *c) { " index: %u\n" "\tname: <%s>\n" "\tdriver: <%s>\n" + "\tflags: %s%s\n" "\tstate: %s\n" "\tsink: <%u> '%s'\n" "\tvolume: <%s>\n" @@ -293,6 +303,8 @@ char *pa_sink_input_list_to_string(pa_core *c) { i->index, i->name, i->driver, + i->flags & PA_SINK_INPUT_VARIABLE_RATE ? "VARIABLE_RATE " : "", + i->flags & PA_SINK_INPUT_DONT_MOVE ? "DONT_MOVE " : "", state_table[pa_sink_input_get_state(i)], i->sink->index, i->sink->name, pa_cvolume_snprint(cv, sizeof(cv), pa_sink_input_get_volume(i)), diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c index 7ca2e753..808bc9a8 100644 --- a/src/pulsecore/core.c +++ b/src/pulsecore/core.c @@ -133,7 +133,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) { c->module_idle_time = 20; c->scache_idle_time = 20; - c->resample_method = PA_RESAMPLER_SRC_SINC_FASTEST; + c->resample_method = PA_RESAMPLER_SPEEX_FLOAT_BASE; c->is_system_instance = 0; c->disallow_module_loading = 0; diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index 61cb47d5..c8d75800 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -44,23 +44,23 @@ typedef struct pa_core pa_core; typedef enum pa_core_hook { PA_CORE_HOOK_SINK_NEW_POST, - PA_CORE_HOOK_SINK_DISCONNECT, - PA_CORE_HOOK_SINK_DISCONNECT_POST, + PA_CORE_HOOK_SINK_UNLINK, + PA_CORE_HOOK_SINK_UNLINK_POST, PA_CORE_HOOK_SINK_STATE_CHANGED, PA_CORE_HOOK_SOURCE_NEW_POST, - PA_CORE_HOOK_SOURCE_DISCONNECT, - PA_CORE_HOOK_SOURCE_DISCONNECT_POST, + PA_CORE_HOOK_SOURCE_UNLINK, + PA_CORE_HOOK_SOURCE_UNLINK_POST, PA_CORE_HOOK_SOURCE_STATE_CHANGED, PA_CORE_HOOK_SINK_INPUT_NEW, PA_CORE_HOOK_SINK_INPUT_PUT, - PA_CORE_HOOK_SINK_INPUT_DISCONNECT, - PA_CORE_HOOK_SINK_INPUT_DISCONNECT_POST, + PA_CORE_HOOK_SINK_INPUT_UNLINK, + PA_CORE_HOOK_SINK_INPUT_UNLINK_POST, PA_CORE_HOOK_SINK_INPUT_MOVE, PA_CORE_HOOK_SINK_INPUT_MOVE_POST, PA_CORE_HOOK_SOURCE_OUTPUT_NEW, PA_CORE_HOOK_SOURCE_OUTPUT_PUT, - PA_CORE_HOOK_SOURCE_OUTPUT_DISCONNECT, - PA_CORE_HOOK_SOURCE_OUTPUT_DISCONNECT_POST, + PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK, + PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK_POST, PA_CORE_HOOK_SOURCE_OUTPUT_MOVE, PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_POST, PA_CORE_HOOK_MAX diff --git a/src/pulsecore/play-memblockq.c b/src/pulsecore/play-memblockq.c index 0d7efc5c..68ce21b1 100644 --- a/src/pulsecore/play-memblockq.c +++ b/src/pulsecore/play-memblockq.c @@ -58,7 +58,7 @@ static void memblockq_stream_unlink(memblockq_stream *u) { if (!u->sink_input) return; - pa_sink_input_disconnect(u->sink_input); + pa_sink_input_unlink(u->sink_input); pa_sink_input_unref(u->sink_input); u->sink_input = NULL; diff --git a/src/pulsecore/play-memchunk.c b/src/pulsecore/play-memchunk.c index f2925d1b..3ebbc14c 100644 --- a/src/pulsecore/play-memchunk.c +++ b/src/pulsecore/play-memchunk.c @@ -58,7 +58,7 @@ static void memchunk_stream_unlink(memchunk_stream *u) { if (!u->sink_input) return; - pa_sink_input_disconnect(u->sink_input); + pa_sink_input_unlink(u->sink_input); pa_sink_input_unref(u->sink_input); u->sink_input = NULL; diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c index c5505e57..fc881c81 100644 --- a/src/pulsecore/protocol-esound.c +++ b/src/pulsecore/protocol-esound.c @@ -212,13 +212,13 @@ static void connection_unlink(connection *c) { return; if (c->sink_input) { - pa_sink_input_disconnect(c->sink_input); + pa_sink_input_unlink(c->sink_input); pa_sink_input_unref(c->sink_input); c->sink_input = NULL; } if (c->source_output) { - pa_source_output_disconnect(c->source_output); + pa_source_output_unlink(c->source_output); pa_source_output_unref(c->source_output); c->source_output = NULL; } diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index a0b70669..ea7f43ca 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -387,7 +387,7 @@ static void record_stream_unlink(record_stream *s) { return; if (s->source_output) { - pa_source_output_disconnect(s->source_output); + pa_source_output_unlink(s->source_output); pa_source_output_unref(s->source_output); s->source_output = NULL; } @@ -460,11 +460,10 @@ static record_stream* record_stream_new( data.source = source; data.driver = __FILE__; data.name = name; - data.start_corked = corked; pa_source_output_new_data_set_sample_spec(&data, ss); pa_source_output_new_data_set_channel_map(&data, map); - if (!(source_output = pa_source_output_new(c->protocol->core, &data, 0))) + if (!(source_output = pa_source_output_new(c->protocol->core, &data, corked ? PA_SOURCE_OUTPUT_START_CORKED : 0))) return NULL; s = pa_msgobject_new(record_stream); @@ -504,7 +503,7 @@ static void playback_stream_unlink(playback_stream *s) { return; if (s->sink_input) { - pa_sink_input_disconnect(s->sink_input); + pa_sink_input_unlink(s->sink_input); pa_sink_input_unref(s->sink_input); s->sink_input = NULL; } @@ -653,10 +652,9 @@ static playback_stream* playback_stream_new( pa_sink_input_new_data_set_volume(&data, volume); data.module = c->protocol->module; data.client = c->client; - data.start_corked = corked; data.sync_base = ssync ? ssync->sink_input : NULL; - if (!(sink_input = pa_sink_input_new(c->protocol->core, &data, 0))) + if (!(sink_input = pa_sink_input_new(c->protocol->core, &data, corked ? PA_SINK_INPUT_START_CORKED : 0))) return NULL; s = pa_msgobject_new(playback_stream); @@ -1729,10 +1727,7 @@ static void sink_fill_tagstruct(pa_tagstruct *t, pa_sink *sink) { PA_TAG_STRING, sink->monitor_source ? sink->monitor_source->name : NULL, PA_TAG_USEC, pa_sink_get_latency(sink), PA_TAG_STRING, sink->driver, - PA_TAG_U32, - (sink->get_volume ? PA_SINK_HW_VOLUME_CTRL : 0) | /* FIXME */ - (sink->get_latency ? PA_SINK_LATENCY : 0) | /* FIXME */ - (sink->is_hardware ? PA_SINK_HARDWARE : 0), + PA_TAG_U32, sink->flags, PA_TAG_INVALID); } @@ -1754,10 +1749,7 @@ static void source_fill_tagstruct(pa_tagstruct *t, pa_source *source) { PA_TAG_STRING, source->monitor_of ? source->monitor_of->name : NULL, PA_TAG_USEC, pa_source_get_latency(source), PA_TAG_STRING, source->driver, - PA_TAG_U32, - (source->get_volume ? PA_SOURCE_HW_VOLUME_CTRL : 0) | /* FIXME */ - (source->get_latency ? PA_SOURCE_LATENCY : 0) | /* FIXME */ - (source->is_hardware ? PA_SOURCE_HARDWARE : 0), + PA_TAG_U32, source->flags, PA_TAG_INVALID); } diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index bc48ac37..db7c9a69 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -110,13 +110,13 @@ static void connection_unlink(connection *c) { return; if (c->sink_input) { - pa_sink_input_disconnect(c->sink_input); + pa_sink_input_unlink(c->sink_input); pa_sink_input_unref(c->sink_input); c->sink_input = NULL; } if (c->source_output) { - pa_source_output_disconnect(c->source_output); + pa_source_output_unlink(c->source_output); pa_source_output_unref(c->source_output); c->source_output = NULL; } diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 0cdcbc0b..c33d8e70 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -108,7 +108,7 @@ pa_sink_input* pa_sink_input_new( data->sink = pa_namereg_get(core, NULL, PA_NAMEREG_SINK, 1); pa_return_null_if_fail(data->sink); - pa_return_null_if_fail(pa_sink_get_state(data->sink) != PA_SINK_DISCONNECTED); + pa_return_null_if_fail(pa_sink_get_state(data->sink) != PA_SINK_UNLINKED); pa_return_null_if_fail(!data->sync_base || (data->sync_base->sink == data->sink && pa_sink_input_get_state(data->sync_base) == PA_SINK_INPUT_CORKED)); if (!data->sample_spec_is_set) @@ -167,7 +167,7 @@ pa_sink_input* pa_sink_input_new( i->parent.process_msg = pa_sink_input_process_msg; i->core = core; - i->state = data->start_corked ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING; + i->state = PA_SINK_INPUT_INIT; i->flags = flags; i->name = pa_xstrdup(data->name); i->driver = pa_xstrdup(data->driver); @@ -194,9 +194,12 @@ pa_sink_input* pa_sink_input_new( i->peek = NULL; i->drop = NULL; + i->process = NULL; i->kill = NULL; i->get_latency = NULL; - i->underrun = NULL; + i->attach = NULL; + i->detach = NULL; + i->suspend = NULL; i->userdata = NULL; i->thread_info.state = i->state; @@ -245,11 +248,11 @@ static int sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) { return 0; } -void pa_sink_input_disconnect(pa_sink_input *i) { +void pa_sink_input_unlink(pa_sink_input *i) { pa_assert(i); - pa_return_if_fail(i->state != PA_SINK_INPUT_DISCONNECTED); + pa_assert(PA_SINK_INPUT_LINKED(i->state)); - pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_DISCONNECT], i); + pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], i); if (i->sync_prev) i->sync_prev->sync_next = i->sync_next; @@ -264,16 +267,19 @@ void pa_sink_input_disconnect(pa_sink_input *i) { pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE, i->index); - sink_input_set_state(i, PA_SINK_INPUT_DISCONNECTED); + sink_input_set_state(i, PA_SINK_INPUT_UNLINKED); pa_sink_update_status(i->sink); i->peek = NULL; i->drop = NULL; + i->process = NULL; i->kill = NULL; i->get_latency = NULL; - i->underrun = NULL; + i->attach = NULL; + i->detach = NULL; + i->suspend = NULL; - pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_DISCONNECT_POST], i); + pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST], i); i->sink = NULL; pa_sink_input_unref(i); } @@ -284,8 +290,8 @@ static void sink_input_free(pa_object *o) { pa_assert(i); pa_assert(pa_sink_input_refcnt(i) == 0); - if (i->state != PA_SINK_INPUT_DISCONNECTED) - pa_sink_input_disconnect(i); + if (PA_SINK_INPUT_LINKED(i->state)) + pa_sink_input_unlink(i); pa_log_info("Freeing output %u \"%s\"", i->index, i->name); @@ -306,6 +312,11 @@ static void sink_input_free(pa_object *o) { void pa_sink_input_put(pa_sink_input *i) { pa_sink_input_assert_ref(i); + pa_assert(i->state == PA_SINK_INPUT_INIT); + pa_assert(i->peek); + pa_assert(i->drop); + + i->thread_info.state = i->state = i->flags & PA_SINK_INPUT_START_CORKED ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING; i->thread_info.volume = i->volume; i->thread_info.muted = i->muted; @@ -314,10 +325,15 @@ void pa_sink_input_put(pa_sink_input *i) { pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index); pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], i); + + /* Please note that if you change something here, you have to + change something in pa_sink_input_move() with the ghost stream + registration too. */ } void pa_sink_input_kill(pa_sink_input*i) { pa_sink_input_assert_ref(i); + pa_assert(PA_SINK_INPUT_LINKED(i->state)); if (i->kill) i->kill(i); @@ -327,6 +343,7 @@ pa_usec_t pa_sink_input_get_latency(pa_sink_input *i) { pa_usec_t r = 0; pa_sink_input_assert_ref(i); + pa_assert(PA_SINK_INPUT_LINKED(i->state)); if (pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_GET_LATENCY, &r, 0, NULL) < 0) r = 0; @@ -344,10 +361,11 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) int volume_is_norm; pa_sink_input_assert_ref(i); + pa_assert(PA_SINK_INPUT_LINKED(i->thread_info.state)); pa_assert(chunk); pa_assert(volume); - if (!i->peek || !i->drop || i->thread_info.state == PA_SINK_INPUT_DISCONNECTED || i->thread_info.state == PA_SINK_INPUT_CORKED) + if (!i->peek || !i->drop || i->thread_info.state == PA_SINK_INPUT_UNLINKED || i->thread_info.state == PA_SINK_INPUT_CORKED) goto finish; pa_assert(i->thread_info.state == PA_SINK_INPUT_RUNNING || i->thread_info.state == PA_SINK_INPUT_DRAINED); @@ -420,9 +438,6 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) finish: - if (ret < 0 && !pa_atomic_load(&i->thread_info.drained) && i->underrun) - i->underrun(i); - if (ret >= 0) pa_atomic_store(&i->thread_info.drained, 0); else if (ret < 0) @@ -448,13 +463,18 @@ finish: /* Called from thread context */ void pa_sink_input_drop(pa_sink_input *i, size_t length) { pa_sink_input_assert_ref(i); + pa_assert(PA_SINK_INPUT_LINKED(i->thread_info.state)); pa_assert(length > 0); if (i->thread_info.move_silence > 0) { - pa_assert(i->thread_info.move_silence >= length); - - i->thread_info.move_silence -= length; + if (i->thread_info.move_silence >= length) { + i->thread_info.move_silence -= length; + length = 0; + } else { + length -= i->thread_info.move_silence; + i->thread_info.move_silence = 0; + } if (i->thread_info.move_silence <= 0) { pa_assert(i->thread_info.silence_memblock); @@ -462,7 +482,8 @@ void pa_sink_input_drop(pa_sink_input *i, size_t length) { i->thread_info.silence_memblock = NULL; } - return; + if (length <= 0) + return; } if (i->thread_info.resampled_chunk.memblock) { @@ -531,6 +552,7 @@ void pa_sink_input_drop(pa_sink_input *i, size_t length) { void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume) { pa_sink_input_assert_ref(i); + pa_assert(PA_SINK_INPUT_LINKED(i->state)); if (pa_cvolume_equal(&i->volume, volume)) return; @@ -543,6 +565,7 @@ void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume) { const pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i) { pa_sink_input_assert_ref(i); + pa_assert(PA_SINK_INPUT_LINKED(i->state)); return &i->volume; } @@ -550,6 +573,7 @@ const pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i) { void pa_sink_input_set_mute(pa_sink_input *i, int mute) { pa_assert(i); pa_sink_input_assert_ref(i); + pa_assert(PA_SINK_INPUT_LINKED(i->state)); if (!i->muted == !mute) return; @@ -562,18 +586,21 @@ void pa_sink_input_set_mute(pa_sink_input *i, int mute) { int pa_sink_input_get_mute(pa_sink_input *i) { pa_sink_input_assert_ref(i); + pa_assert(PA_SINK_INPUT_LINKED(i->state)); return !!i->muted; } void pa_sink_input_cork(pa_sink_input *i, int b) { pa_sink_input_assert_ref(i); + pa_assert(PA_SINK_INPUT_LINKED(i->state)); sink_input_set_state(i, b ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING); } int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) { pa_sink_input_assert_ref(i); + pa_assert(PA_SINK_INPUT_LINKED(i->state)); pa_return_val_if_fail(i->thread_info.resampler, -1); if (i->sample_spec.rate == rate) @@ -615,6 +642,7 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { pa_sink_input_move_info info; pa_sink_input_assert_ref(i); + pa_assert(PA_SINK_INPUT_LINKED(i->state)); pa_sink_assert_ref(dest); origin = i->sink; @@ -622,6 +650,9 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { if (dest == origin) return 0; + if (i->flags & PA_SINK_INPUT_DONT_MOVE) + return -1; + if (i->sync_next || i->sync_prev) { pa_log_warn("Moving synchronised streams not supported."); return -1; @@ -714,6 +745,10 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { if (info.ghost_sink_input) { /* Basically, do what pa_sink_input_put() does ...*/ + info.ghost_sink_input->thread_info.state = info.ghost_sink_input->state = PA_SINK_INPUT_RUNNING; + info.ghost_sink_input->thread_info.volume = info.ghost_sink_input->volume; + info.ghost_sink_input->thread_info.muted = info.ghost_sink_input->muted; + pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, info.ghost_sink_input->index); pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], info.ghost_sink_input); pa_sink_input_unref(info.ghost_sink_input); @@ -774,6 +809,7 @@ int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t pa_sink_input *i = PA_SINK_INPUT(o); pa_sink_input_assert_ref(i); + pa_assert(PA_SINK_INPUT_LINKED(i->thread_info.state)); switch (code) { case PA_SINK_INPUT_MESSAGE_SET_VOLUME: @@ -841,3 +877,4 @@ pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i) { return i->state; } + diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index d728d462..e1d89ffb 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -39,14 +39,21 @@ typedef struct pa_sink_input pa_sink_input; #include typedef enum pa_sink_input_state { + PA_SINK_INPUT_INIT, /*< The stream is not active yet, because pa_sink_put() has not been called yet */ PA_SINK_INPUT_DRAINED, /*< The stream stopped playing because there was no data to play */ PA_SINK_INPUT_RUNNING, /*< The stream is alive and kicking */ PA_SINK_INPUT_CORKED, /*< The stream was corked on user request */ - PA_SINK_INPUT_DISCONNECTED /*< The stream is dead */ + PA_SINK_INPUT_UNLINKED /*< The stream is dead */ } pa_sink_input_state_t; +static inline int PA_SINK_INPUT_LINKED(pa_sink_input_state_t x) { + return x == PA_SINK_INPUT_DRAINED || x == PA_SINK_INPUT_RUNNING || x == PA_SINK_INPUT_CORKED; +} + typedef enum pa_sink_input_flags { PA_SINK_INPUT_VARIABLE_RATE = 1, + PA_SINK_INPUT_DONT_MOVE = 2, + PA_SINK_INPUT_START_CORKED = 4 } pa_sink_input_flags_t; struct pa_sink_input { @@ -75,11 +82,42 @@ struct pa_sink_input { pa_cvolume volume; int muted; + /* Returns the chunk of audio data (but doesn't drop it + * yet!). Returns -1 on failure. Called from IO thread context. */ int (*peek) (pa_sink_input *i, pa_memchunk *chunk); + + /* Drops the specified number of bytes, usually called right after + * peek(), but not necessarily. Called from IO thread context. */ void (*drop) (pa_sink_input *i, size_t length); + + /* If non-NULL this function is called in each IO event loop and + * can be used to do additional processing even when the device is + * suspended and peek() is never called. Should return 1 when + * "some work" has been done and the IO event loop should be + * reiterated immediately. Called from IO thread context. */ + int (*process) (pa_sink_input *i); /* may be NULL */ + + /* If non-NULL this function is called when the input is first + * connected to a sink. Called from IO thread context */ + void (*attach) (pa_sink_input *i); /* may be NULL */ + + /* If non-NULL this function is called when the output is + * disconnected from its sink. Called from IO thread context */ + void (*detach) (pa_sink_input *i); /* may be NULL */ + + /* If non-NULL called whenever the the sink this input is attached + * to suspends or resumes. Called from main context */ + void (*suspend) (pa_sink_input *i, int b); /* may be NULL */ + + /* Supposed to unlink and destroy this stream. Called from main + * context. */ void (*kill) (pa_sink_input *i); /* may be NULL */ + + /* Return the current latency (i.e. length of bufferd audio) of + this stream. Called from main context. If NULL a + PA_SINK_INPUT_MESSAGE_GET_LATENCY message is sent to the IO thread + instead. */ pa_usec_t (*get_latency) (pa_sink_input *i); /* may be NULL */ - void (*underrun) (pa_sink_input *i); /* may be NULL */ pa_resample_method_t resample_method; @@ -138,7 +176,6 @@ typedef struct pa_sink_input_new_data { pa_resample_method_t resample_method; - int start_corked; pa_sink_input *sync_base; } pa_sink_input_new_data; @@ -156,7 +193,7 @@ pa_sink_input* pa_sink_input_new( pa_sink_input_flags_t flags); void pa_sink_input_put(pa_sink_input *i); -void pa_sink_input_disconnect(pa_sink_input* i); +void pa_sink_input_unlink(pa_sink_input* i); void pa_sink_input_set_name(pa_sink_input *i, const char *name); diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 2c7c661c..b61a8507 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -92,7 +92,8 @@ pa_sink* pa_sink_new( s->parent.process_msg = pa_sink_process_msg; s->core = core; - s->state = PA_SINK_IDLE; + s->state = PA_SINK_INIT; + s->flags = 0; s->name = pa_xstrdup(name); s->description = NULL; s->driver = pa_xstrdup(driver); @@ -107,8 +108,6 @@ pa_sink* pa_sink_new( s->muted = 0; s->refresh_volume = s->refresh_mute = 0; - s->is_hardware = 0; - s->get_latency = NULL; s->set_volume = NULL; s->get_volume = NULL; @@ -118,6 +117,7 @@ pa_sink* pa_sink_new( s->userdata = NULL; s->asyncmsgq = NULL; + s->rtpoll = NULL; s->silence = NULL; r = pa_idxset_put(core->sinks, s, &s->index); @@ -145,11 +145,22 @@ pa_sink* pa_sink_new( s->thread_info.soft_muted = s->muted; s->thread_info.state = s->state; - pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index); + return s; +} - pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_NEW_POST], s); +void pa_sink_put(pa_sink* s) { + pa_sink_assert_ref(s); - return s; + pa_assert(s->state == PA_SINK_INIT); + pa_assert(s->asyncmsgq); + pa_assert(s->rtpoll); + + s->thread_info.state = s->state = PA_SINK_IDLE; + + pa_source_put(s->monitor_source); + + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_NEW_POST], s); } static int sink_set_state(pa_sink *s, pa_sink_state_t state) { @@ -160,6 +171,21 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state) { if (s->state == state) return 0; + if (state == PA_SINK_SUSPENDED && !(s->flags & PA_SINK_CAN_SUSPEND)) + return -1; + + if ((s->state == PA_SINK_SUSPENDED && PA_SINK_OPENED(state)) || + (PA_SINK_OPENED(s->state) && state == PA_SINK_SUSPENDED)) { + pa_sink_input *i; + uint32_t idx; + + /* We're suspending or resuming, tell everyone about it */ + + for (i = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); i; i = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx))) + if (i->suspend) + i->suspend(i, state == PA_SINK_SUSPENDED); + } + if (s->set_state) if ((ret = s->set_state(s, state)) < 0) return -1; @@ -168,18 +194,19 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state) { return -1; s->state = state; - - pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], s); + + if (state != PA_SINK_UNLINKED) /* if we enter UNLINKED state pa_sink_unlink() will fire the apropriate events */ + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], s); return 0; } -void pa_sink_disconnect(pa_sink* s) { +void pa_sink_unlink(pa_sink* s) { pa_sink_input *i, *j = NULL; pa_assert(s); - pa_return_if_fail(s->state != PA_SINK_DISCONNECTED); + pa_assert(PA_SINK_LINKED(s->state)); - pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_DISCONNECT], s); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK], s); pa_namereg_unregister(s->core, s->name); pa_idxset_remove_by_data(s->core->sinks, s, NULL); @@ -191,9 +218,9 @@ void pa_sink_disconnect(pa_sink* s) { } if (s->monitor_source) - pa_source_disconnect(s->monitor_source); + pa_source_unlink(s->monitor_source); - sink_set_state(s, PA_SINK_DISCONNECTED); + sink_set_state(s, PA_SINK_UNLINKED); s->get_latency = NULL; s->get_volume = NULL; @@ -204,7 +231,7 @@ void pa_sink_disconnect(pa_sink* s) { pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_REMOVE, s->index); - pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_DISCONNECT_POST], s); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK_POST], s); } static void sink_free(pa_object *o) { @@ -214,8 +241,8 @@ static void sink_free(pa_object *o) { pa_assert(s); pa_assert(pa_sink_refcnt(s) == 0); - if (s->state != PA_SINK_DISCONNECTED) - pa_sink_disconnect(s); + if (PA_SINK_LINKED(s->state)) + pa_sink_unlink(s); pa_log_info("Freeing sink %u \"%s\"", s->index, s->name); @@ -250,8 +277,18 @@ void pa_sink_set_asyncmsgq(pa_sink *s, pa_asyncmsgq *q) { pa_source_set_asyncmsgq(s->monitor_source, q); } +void pa_sink_set_rtpoll(pa_sink *s, pa_rtpoll *p) { + pa_sink_assert_ref(s); + pa_assert(p); + + s->rtpoll = p; + if (s->monitor_source) + pa_source_set_rtpoll(s->monitor_source, p); +} + int pa_sink_update_status(pa_sink*s) { pa_sink_assert_ref(s); + pa_assert(PA_SINK_LINKED(s->state)); if (s->state == PA_SINK_SUSPENDED) return 0; @@ -261,6 +298,7 @@ int pa_sink_update_status(pa_sink*s) { int pa_sink_suspend(pa_sink *s, int suspend) { pa_sink_assert_ref(s); + pa_assert(PA_SINK_LINKED(s->state)); if (suspend) return sink_set_state(s, PA_SINK_SUSPENDED); @@ -270,6 +308,7 @@ int pa_sink_suspend(pa_sink *s, int suspend) { void pa_sink_ping(pa_sink *s) { pa_sink_assert_ref(s); + pa_assert(PA_SINK_LINKED(s->state)); pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_PING, NULL, 0, NULL, NULL); } @@ -364,6 +403,7 @@ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) { unsigned n; pa_sink_assert_ref(s); + pa_assert(PA_SINK_OPENED(s->thread_info.state)); pa_assert(length); pa_assert(result); @@ -429,6 +469,7 @@ void pa_sink_render_into(pa_sink*s, pa_memchunk *target) { unsigned n; pa_sink_assert_ref(s); + pa_assert(PA_SINK_OPENED(s->thread_info.state)); pa_assert(target); pa_assert(target->memblock); pa_assert(target->length); @@ -494,6 +535,7 @@ void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) { size_t l, d; pa_sink_assert_ref(s); + pa_assert(PA_SINK_OPENED(s->thread_info.state)); pa_assert(target); pa_assert(target->memblock); pa_assert(target->length); @@ -518,6 +560,7 @@ void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) { void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) { pa_sink_assert_ref(s); + pa_assert(PA_SINK_OPENED(s->thread_info.state)); pa_assert(length); pa_assert(result); @@ -529,10 +572,46 @@ void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) { pa_sink_render_into_full(s, result); } +void pa_sink_skip(pa_sink *s, size_t length) { + pa_sink_input *i; + void *state = NULL; + + pa_sink_assert_ref(s); + pa_assert(PA_SINK_OPENED(s->thread_info.state)); + pa_assert(length > 0); + + if (pa_source_used_by(s->monitor_source)) { + pa_memchunk chunk; + + /* If something is connected to our monitor source, we have to + * pass valid data to it */ + + while (length > 0) { + pa_sink_render(s, length, &chunk); + pa_memblock_unref(chunk.memblock); + + pa_assert(chunk.length <= length); + length -= chunk.length; + } + + } else { + /* Ok, noone cares about the rendered data, so let's not even render it */ + + while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL))) { + pa_sink_input_assert_ref(i); + pa_sink_input_drop(i, length); + } + } +} + pa_usec_t pa_sink_get_latency(pa_sink *s) { pa_usec_t usec = 0; pa_sink_assert_ref(s); + pa_assert(PA_SINK_LINKED(s->state)); + + if (!PA_SINK_OPENED(s->state)) + return 0; if (s->get_latency) return s->get_latency(s); @@ -547,6 +626,7 @@ void pa_sink_set_volume(pa_sink *s, const pa_cvolume *volume) { int changed; pa_sink_assert_ref(s); + pa_assert(PA_SINK_LINKED(s->state)); pa_assert(volume); changed = !pa_cvolume_equal(volume, &s->volume); @@ -566,6 +646,7 @@ const pa_cvolume *pa_sink_get_volume(pa_sink *s) { struct pa_cvolume old_volume; pa_sink_assert_ref(s); + pa_assert(PA_SINK_LINKED(s->state)); old_volume = s->volume; @@ -585,6 +666,7 @@ void pa_sink_set_mute(pa_sink *s, int mute) { int changed; pa_sink_assert_ref(s); + pa_assert(PA_SINK_LINKED(s->state)); changed = s->muted != mute; s->muted = mute; @@ -603,6 +685,7 @@ int pa_sink_get_mute(pa_sink *s) { int old_muted; pa_sink_assert_ref(s); + pa_assert(PA_SINK_LINKED(s->state)); old_muted = s->muted; @@ -659,6 +742,7 @@ unsigned pa_sink_used_by(pa_sink *s) { unsigned ret; pa_sink_assert_ref(s); + pa_assert(PA_SINK_LINKED(s->state)); ret = pa_idxset_size(s->inputs); @@ -671,6 +755,7 @@ unsigned pa_sink_used_by(pa_sink *s) { int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) { pa_sink *s = PA_SINK(o); pa_sink_assert_ref(s); + pa_assert(PA_SINK_LINKED(s->thread_info.state)); switch ((pa_sink_message_t) code) { @@ -694,13 +779,19 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse i->thread_info.sync_next->thread_info.sync_prev = i; } + if (i->attach) + i->attach(i); + return 0; } case PA_SINK_MESSAGE_REMOVE_INPUT: { pa_sink_input *i = PA_SINK_INPUT(userdata); - /* Since the caller sleeps in pa_sink_input_disconnect(), + if (i->detach) + i->detach(i); + + /* Since the caller sleeps in pa_sink_input_unlink(), * we can safely access data outside of thread_info even * though it is mutable */ @@ -833,3 +924,21 @@ int pa_sink_suspend_all(pa_core *c, int suspend) { return ret; } + +int pa_sink_process_inputs(pa_sink *s) { + pa_sink_input *i; + void *state = NULL; + int r; + + pa_sink_assert_ref(s); + + if (!PA_SINK_LINKED(s->thread_info.state)) + return 0; + + while ((i = PA_SINK_INPUT(pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))) + if (i->process) + if ((r = i->process(i))) + return r; + + return 0; +} diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index fadc76eb..b3fcff49 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -40,26 +40,36 @@ typedef struct pa_sink pa_sink; #include #include #include +#include #define PA_MAX_INPUTS_PER_SINK 32 typedef enum pa_sink_state { + PA_SINK_INIT, PA_SINK_RUNNING, PA_SINK_SUSPENDED, PA_SINK_IDLE, - PA_SINK_DISCONNECTED + PA_SINK_UNLINKED } pa_sink_state_t; +static inline int PA_SINK_OPENED(pa_sink_state_t x) { + return x == PA_SINK_RUNNING || x == PA_SINK_IDLE; +} + +static inline int PA_SINK_LINKED(pa_sink_state_t x) { + return x == PA_SINK_RUNNING || x == PA_SINK_IDLE || x == PA_SINK_SUSPENDED; +} + struct pa_sink { pa_msgobject parent; uint32_t index; pa_core *core; pa_sink_state_t state; + pa_sink_flags_t flags; char *name; char *description, *driver; /* may be NULL */ - int is_hardware; pa_module *module; /* may be NULL */ @@ -67,21 +77,22 @@ struct pa_sink { pa_channel_map channel_map; pa_idxset *inputs; - pa_source *monitor_source; /* may be NULL */ + pa_source *monitor_source; pa_cvolume volume; int muted; int refresh_volume; int refresh_mute; - int (*set_state)(pa_sink *s, pa_sink_state_t state); - int (*set_volume)(pa_sink *s); /* dito */ - int (*get_volume)(pa_sink *s); /* dito */ - int (*get_mute)(pa_sink *s); /* dito */ - int (*set_mute)(pa_sink *s); /* dito */ + int (*set_state)(pa_sink *s, pa_sink_state_t state); /* may be NULL */ + int (*set_volume)(pa_sink *s); /* dito */ + int (*get_volume)(pa_sink *s); /* dito */ + int (*get_mute)(pa_sink *s); /* dito */ + int (*set_mute)(pa_sink *s); /* dito */ pa_usec_t (*get_latency)(pa_sink *s); /* dito */ pa_asyncmsgq *asyncmsgq; + pa_rtpoll *rtpoll; /* Contains copies of the above data so that the real-time worker * thread can work without access locking */ @@ -114,7 +125,7 @@ typedef enum pa_sink_message { PA_SINK_MESSAGE_MAX } pa_sink_message_t; -/* To be used exclusively by the sink driver */ +/* To be called exclusively by the sink driver, from main context */ pa_sink* pa_sink_new( pa_core *core, @@ -124,18 +135,21 @@ pa_sink* pa_sink_new( const pa_sample_spec *spec, const pa_channel_map *map); -void pa_sink_disconnect(pa_sink* s); +void pa_sink_put(pa_sink *s); +void pa_sink_unlink(pa_sink* s); void pa_sink_set_module(pa_sink *sink, pa_module *m); void pa_sink_set_description(pa_sink *s, const char *description); void pa_sink_set_asyncmsgq(pa_sink *s, pa_asyncmsgq *q); +void pa_sink_set_rtpoll(pa_sink *s, pa_rtpoll *p); -/* Usable by everyone */ +/* May be called by everyone, from main context */ pa_usec_t pa_sink_get_latency(pa_sink *s); int pa_sink_update_status(pa_sink*s); int pa_sink_suspend(pa_sink *s, int suspend); +int pa_sink_suspend_all(pa_core *c, int suspend); /* Sends a ping message to the sink thread, to make it wake up and * check for data to process even if there is no real message is @@ -150,19 +164,17 @@ int pa_sink_get_mute(pa_sink *sink); unsigned pa_sink_used_by(pa_sink *s); #define pa_sink_get_state(s) ((s)->state) -/* To be used exclusively by the sink driver thread */ +/* To be called exclusively by the sink driver, from IO context */ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result); void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result); void pa_sink_render_into(pa_sink*s, pa_memchunk *target); void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target); -int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk); +void pa_sink_skip(pa_sink *s, size_t length); -static inline int PA_SINK_OPENED(pa_sink_state_t x) { - return x == PA_SINK_RUNNING || x == PA_SINK_IDLE; -} +int pa_sink_process_inputs(pa_sink *s); -int pa_sink_suspend_all(pa_core *c, int suspend); +int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk); #endif diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index e0d51a7d..36c7f03c 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -69,7 +69,7 @@ static void file_stream_unlink(file_stream *u) { if (!u->sink_input) return; - pa_sink_input_disconnect(u->sink_input); + pa_sink_input_unlink(u->sink_input); pa_sink_input_unref(u->sink_input); u->sink_input = NULL; diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 25322469..ccd968ae 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -86,7 +86,7 @@ pa_source_output* pa_source_output_new( data->source = pa_namereg_get(core, NULL, PA_NAMEREG_SOURCE, 1); pa_return_null_if_fail(data->source); - pa_return_null_if_fail(pa_source_get_state(data->source) != PA_SOURCE_DISCONNECTED); + pa_return_null_if_fail(pa_source_get_state(data->source) != PA_SOURCE_UNLINKED); if (!data->sample_spec_is_set) data->sample_spec = data->source->sample_spec; @@ -135,7 +135,7 @@ pa_source_output* pa_source_output_new( o->parent.process_msg = pa_source_output_process_msg; o->core = core; - o->state = data->start_corked ? PA_SOURCE_OUTPUT_CORKED : PA_SOURCE_OUTPUT_RUNNING; + o->state = PA_SOURCE_OUTPUT_INIT; o->flags = flags; o->name = pa_xstrdup(data->name); o->driver = pa_xstrdup(data->driver); @@ -148,8 +148,12 @@ pa_source_output* pa_source_output_new( o->channel_map = data->channel_map; o->push = NULL; + o->process = NULL; o->kill = NULL; o->get_latency = NULL; + o->detach = NULL; + o->attach = NULL; + o->suspend = NULL; o->userdata = NULL; o->thread_info.state = o->state; @@ -183,11 +187,11 @@ static int source_output_set_state(pa_source_output *o, pa_source_output_state_t return 0; } -void pa_source_output_disconnect(pa_source_output*o) { +void pa_source_output_unlink(pa_source_output*o) { pa_assert(o); - pa_return_if_fail(o->state != PA_SOURCE_OUTPUT_DISCONNECTED); + pa_assert(PA_SOURCE_OUTPUT_LINKED(o->state)); - pa_hook_fire(&o->source->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_DISCONNECT], o); + pa_hook_fire(&o->source->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK], o); pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, 0, NULL); @@ -196,14 +200,18 @@ void pa_source_output_disconnect(pa_source_output*o) { pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_REMOVE, o->index); - source_output_set_state(o, PA_SOURCE_OUTPUT_DISCONNECTED); + source_output_set_state(o, PA_SOURCE_OUTPUT_UNLINKED); pa_source_update_status(o->source); o->push = NULL; + o->process = NULL; o->kill = NULL; o->get_latency = NULL; + o->attach = NULL; + o->detach = NULL; + o->suspend = NULL; - pa_hook_fire(&o->source->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_DISCONNECT_POST], o); + pa_hook_fire(&o->source->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK_POST], o); o->source = NULL; pa_source_output_unref(o); @@ -214,8 +222,8 @@ static void source_output_free(pa_object* mo) { pa_assert(pa_source_output_refcnt(o) == 0); - if (o->state != PA_SOURCE_OUTPUT_DISCONNECTED) - pa_source_output_disconnect(o); + if (PA_SOURCE_LINKED(o->state)) + pa_source_output_unlink(o); pa_log_info("Freeing output %u \"%s\"", o->index, o->name); @@ -230,6 +238,11 @@ static void source_output_free(pa_object* mo) { void pa_source_output_put(pa_source_output *o) { pa_source_output_assert_ref(o); + pa_assert(o->state == PA_SOURCE_OUTPUT_INIT); + pa_assert(o->push); + + o->thread_info.state = o->state = o->flags & PA_SOURCE_OUTPUT_START_CORKED ? PA_SOURCE_OUTPUT_CORKED : PA_SOURCE_OUTPUT_RUNNING; + pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_ADD_OUTPUT, o, 0, NULL); pa_source_update_status(o->source); @@ -240,7 +253,8 @@ void pa_source_output_put(pa_source_output *o) { void pa_source_output_kill(pa_source_output*o) { pa_source_output_assert_ref(o); - + pa_assert(PA_SOURCE_OUTPUT_LINKED(o->state)); + if (o->kill) o->kill(o); } @@ -249,6 +263,7 @@ pa_usec_t pa_source_output_get_latency(pa_source_output *o) { pa_usec_t r = 0; pa_source_output_assert_ref(o); + pa_assert(PA_SOURCE_OUTPUT_LINKED(o->state)); if (pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY, &r, 0, NULL) < 0) r = 0; @@ -264,10 +279,11 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) { pa_memchunk rchunk; pa_source_output_assert_ref(o); + pa_assert(PA_SOURCE_OUTPUT_LINKED(o->thread_info.state)); pa_assert(chunk); pa_assert(chunk->length); - if (!o->push || o->state == PA_SOURCE_OUTPUT_DISCONNECTED || o->state == PA_SOURCE_OUTPUT_CORKED) + if (!o->push || o->state == PA_SOURCE_OUTPUT_UNLINKED || o->state == PA_SOURCE_OUTPUT_CORKED) return; pa_assert(o->state == PA_SOURCE_OUTPUT_RUNNING); @@ -288,12 +304,14 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) { void pa_source_output_cork(pa_source_output *o, int b) { pa_source_output_assert_ref(o); + pa_assert(PA_SOURCE_OUTPUT_LINKED(o->state)); source_output_set_state(o, b ? PA_SOURCE_OUTPUT_CORKED : PA_SOURCE_OUTPUT_RUNNING); } int pa_source_output_set_rate(pa_source_output *o, uint32_t rate) { pa_source_output_assert_ref(o); + pa_assert(PA_SOURCE_OUTPUT_LINKED(o->state)); pa_return_val_if_fail(o->thread_info.resampler, -1); if (o->sample_spec.rate == rate) @@ -333,6 +351,7 @@ int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { pa_resampler *new_resampler = NULL; pa_source_output_assert_ref(o); + pa_assert(PA_SOURCE_OUTPUT_LINKED(o->state)); pa_source_assert_ref(dest); origin = o->source; @@ -340,6 +359,9 @@ int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { if (dest == origin) return 0; + if (o->flags & PA_SOURCE_OUTPUT_DONT_MOVE) + return -1; + if (pa_idxset_size(dest->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) { pa_log_warn("Failed to move source output: too many outputs per source."); return -1; @@ -405,6 +427,7 @@ int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, int pa_source_output *o = PA_SOURCE_OUTPUT(mo); pa_source_output_assert_ref(o); + pa_assert(PA_SOURCE_OUTPUT_LINKED(o->thread_info.state)); switch (code) { diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h index b17adcb5..2027e37a 100644 --- a/src/pulsecore/source-output.h +++ b/src/pulsecore/source-output.h @@ -36,13 +36,20 @@ typedef struct pa_source_output pa_source_output; #include typedef enum pa_source_output_state { + PA_SOURCE_OUTPUT_INIT, PA_SOURCE_OUTPUT_RUNNING, PA_SOURCE_OUTPUT_CORKED, - PA_SOURCE_OUTPUT_DISCONNECTED + PA_SOURCE_OUTPUT_UNLINKED } pa_source_output_state_t; +static inline int PA_SOURCE_OUTPUT_LINKED(pa_source_output_state_t x) { + return x == PA_SOURCE_OUTPUT_RUNNING || x == PA_SOURCE_OUTPUT_CORKED; +} + typedef enum pa_source_output_flags { - PA_SOURCE_OUTPUT_VARIABLE_RATE = 1 + PA_SOURCE_OUTPUT_VARIABLE_RATE = 1, + PA_SOURCE_OUTPUT_DONT_MOVE = 2, + PA_SOURCE_OUTPUT_START_CORKED = 4 } pa_source_output_flags_t; struct pa_source_output { @@ -62,8 +69,37 @@ struct pa_source_output { pa_sample_spec sample_spec; pa_channel_map channel_map; + /* Pushes a new memchunk into the output. Called from IO thread + * context. */ void (*push)(pa_source_output *o, const pa_memchunk *chunk); + + /* If non-NULL this function is called in each IO event loop and + * can be used to do additional processing even when the device is + * suspended and peek() is never called. Should return 1 when + * "some work" has been done and the IO event loop should be + * reiterated immediately. Called from IO thread context. */ + int (*process) (pa_source_output *o); /* may be NULL */ + + /* If non-NULL this function is called when the output is first + * connected to a source. Called from IO thread context */ + void (*attach) (pa_source_output *o); /* may be NULL */ + + /* If non-NULL this function is called when the output is + * disconnected from its source. Called from IO thread context */ + void (*detach) (pa_source_output *o); /* may be NULL */ + + /* If non-NULL called whenever the the source this output is attached + * to suspends or resumes. Called from main context */ + void (*suspend) (pa_source_output *o, int b); /* may be NULL */ + + /* Supposed to unlink and destroy this stream. Called from main + * context. */ void (*kill)(pa_source_output* o); /* may be NULL */ + + /* Return the current latency (i.e. length of bufferd audio) of + this stream. Called from main context. If NULL a + PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY message is sent to the IO + thread instead. */ pa_usec_t (*get_latency) (pa_source_output *o); /* may be NULL */ pa_resample_method_t resample_method; @@ -102,8 +138,6 @@ typedef struct pa_source_output_new_data { int channel_map_is_set; pa_resample_method_t resample_method; - - int start_corked; } pa_source_output_new_data; pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data); @@ -119,7 +153,7 @@ pa_source_output* pa_source_output_new( pa_source_output_flags_t flags); void pa_source_output_put(pa_source_output *o); -void pa_source_output_disconnect(pa_source_output*o); +void pa_source_output_unlink(pa_source_output*o); void pa_source_output_set_name(pa_source_output *i, const char *name); diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 30a45cb6..ee2203e7 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -84,7 +84,8 @@ pa_source* pa_source_new( s->parent.process_msg = pa_source_process_msg; s->core = core; - s->state = PA_SOURCE_IDLE; + s->state = PA_SOURCE_INIT; + s->flags = 0; s->name = pa_xstrdup(name); s->description = NULL; s->driver = pa_xstrdup(driver); @@ -100,8 +101,6 @@ pa_source* pa_source_new( s->muted = 0; s->refresh_volume = s->refresh_muted = 0; - s->is_hardware = 0; - s->get_latency = NULL; s->set_volume = NULL; s->get_volume = NULL; @@ -111,6 +110,7 @@ pa_source* pa_source_new( s->userdata = NULL; s->asyncmsgq = NULL; + s->rtpoll = NULL; r = pa_idxset_put(core->sources, s, &s->index); assert(s->index != PA_IDXSET_INVALID && r >= 0); @@ -123,13 +123,22 @@ pa_source* pa_source_new( s->thread_info.soft_muted = s->muted; s->thread_info.state = s->state; - pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index); - - pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_NEW_POST], s); - return s; } +void pa_source_put(pa_source *s) { + pa_source_assert_ref(s); + + pa_assert(s->state == PA_SINK_INIT); + pa_assert(s->rtpoll); + pa_assert(s->asyncmsgq); + + s->thread_info.state = s->state = PA_SOURCE_IDLE; + + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_NEW_POST], s); +} + static int source_set_state(pa_source *s, pa_source_state_t state) { int ret; @@ -138,6 +147,21 @@ static int source_set_state(pa_source *s, pa_source_state_t state) { if (s->state == state) return 0; + if (state == PA_SOURCE_SUSPENDED && !(s->flags & PA_SOURCE_CAN_SUSPEND)) + return -1; + + if ((s->state == PA_SOURCE_SUSPENDED && PA_SOURCE_OPENED(state)) || + (PA_SOURCE_OPENED(s->state) && state == PA_SOURCE_SUSPENDED)) { + pa_source_output *o; + uint32_t idx; + + /* We're suspending or resuming, tell everyone about it */ + + for (o = PA_SOURCE_OUTPUT(pa_idxset_first(s->outputs, &idx)); o; o = PA_SOURCE_OUTPUT(pa_idxset_next(s->outputs, &idx))) + if (o->suspend) + o->suspend(o, state == PA_SINK_SUSPENDED); + } + if (s->set_state) if ((ret = s->set_state(s, state)) < 0) return -1; @@ -146,17 +170,19 @@ static int source_set_state(pa_source *s, pa_source_state_t state) { return -1; s->state = state; - pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], s); + + if (state != PA_SOURCE_UNLINKED) /* if we enter UNLINKED state pa_source_unlink() will fire the apropriate events */ + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], s); return 0; } -void pa_source_disconnect(pa_source *s) { +void pa_source_unlink(pa_source *s) { pa_source_output *o, *j = NULL; pa_assert(s); - pa_return_if_fail(s->state != PA_SOURCE_DISCONNECTED); + pa_assert(PA_SOURCE_LINKED(s->state)); - pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_DISCONNECT], s); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], s); pa_namereg_unregister(s->core, s->name); pa_idxset_remove_by_data(s->core->sources, s, NULL); @@ -167,7 +193,7 @@ void pa_source_disconnect(pa_source *s) { j = o; } - source_set_state(s, PA_SOURCE_DISCONNECTED); + source_set_state(s, PA_SOURCE_UNLINKED); s->get_latency = NULL; s->get_volume = NULL; @@ -178,7 +204,7 @@ void pa_source_disconnect(pa_source *s) { pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_REMOVE, s->index); - pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_DISCONNECT_POST], s); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK_POST], s); } static void source_free(pa_object *o) { @@ -188,8 +214,8 @@ static void source_free(pa_object *o) { pa_assert(s); pa_assert(pa_source_refcnt(s) == 0); - if (s->state != PA_SOURCE_DISCONNECTED) - pa_source_disconnect(s); + if (PA_SOURCE_LINKED(s->state)) + pa_source_unlink(s); pa_log_info("Freeing source %u \"%s\"", s->index, s->name); @@ -208,6 +234,7 @@ static void source_free(pa_object *o) { int pa_source_update_status(pa_source*s) { pa_source_assert_ref(s); + pa_assert(PA_SOURCE_LINKED(s->state)); if (s->state == PA_SOURCE_SUSPENDED) return 0; @@ -217,6 +244,7 @@ int pa_source_update_status(pa_source*s) { int pa_source_suspend(pa_source *s, int suspend) { pa_source_assert_ref(s); + pa_assert(PA_SOURCE_LINKED(s->state)); if (suspend) return source_set_state(s, PA_SOURCE_SUSPENDED); @@ -226,6 +254,7 @@ int pa_source_suspend(pa_source *s, int suspend) { void pa_source_ping(pa_source *s) { pa_source_assert_ref(s); + pa_assert(PA_SOURCE_LINKED(s->state)); pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_PING, NULL, 0, NULL, NULL); } @@ -235,6 +264,7 @@ void pa_source_post(pa_source*s, const pa_memchunk *chunk) { void *state = NULL; pa_source_assert_ref(s); + pa_assert(PA_SOURCE_OPENED(s->thread_info.state)); pa_assert(chunk); if (s->thread_info.state != PA_SOURCE_RUNNING) @@ -267,6 +297,10 @@ pa_usec_t pa_source_get_latency(pa_source *s) { pa_usec_t usec; pa_source_assert_ref(s); + pa_assert(PA_SOURCE_LINKED(s->state)); + + if (!PA_SOURCE_OPENED(s->state)) + return 0; if (s->get_latency) return s->get_latency(s); @@ -281,6 +315,7 @@ void pa_source_set_volume(pa_source *s, const pa_cvolume *volume) { int changed; pa_source_assert_ref(s); + pa_assert(PA_SOURCE_LINKED(s->state)); pa_assert(volume); changed = !pa_cvolume_equal(volume, &s->volume); @@ -298,7 +333,9 @@ void pa_source_set_volume(pa_source *s, const pa_cvolume *volume) { const pa_cvolume *pa_source_get_volume(pa_source *s) { pa_cvolume old_volume; + pa_source_assert_ref(s); + pa_assert(PA_SOURCE_LINKED(s->state)); old_volume = s->volume; @@ -318,6 +355,7 @@ void pa_source_set_mute(pa_source *s, int mute) { int changed; pa_source_assert_ref(s); + pa_assert(PA_SOURCE_LINKED(s->state)); changed = s->muted != mute; s->muted = mute; @@ -336,6 +374,7 @@ int pa_source_get_mute(pa_source *s) { int old_muted; pa_source_assert_ref(s); + pa_assert(PA_SOURCE_LINKED(s->state)); old_muted = s->muted; @@ -384,8 +423,16 @@ void pa_source_set_asyncmsgq(pa_source *s, pa_asyncmsgq *q) { s->asyncmsgq = q; } +void pa_source_set_rtpoll(pa_source *s, pa_rtpoll *p) { + pa_source_assert_ref(s); + pa_assert(p); + + s->rtpoll = p; +} + unsigned pa_source_used_by(pa_source *s) { pa_source_assert_ref(s); + pa_assert(PA_SOURCE_LINKED(s->state)); return pa_idxset_size(s->outputs); } @@ -393,19 +440,28 @@ unsigned pa_source_used_by(pa_source *s) { int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_t offset, pa_memchunk *chunk) { pa_source *s = PA_SOURCE(object); pa_source_assert_ref(s); + pa_assert(PA_SOURCE_LINKED(s->thread_info.state)); switch ((pa_source_message_t) code) { case PA_SOURCE_MESSAGE_ADD_OUTPUT: { pa_source_output *o = PA_SOURCE_OUTPUT(userdata); pa_hashmap_put(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index), pa_source_output_ref(o)); + + if (o->attach) + o->attach(o); + return 0; } case PA_SOURCE_MESSAGE_REMOVE_OUTPUT: { pa_source_output *o = PA_SOURCE_OUTPUT(userdata); + + if (o->detach) + o->detach(o); + if (pa_hashmap_remove(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index))) pa_source_output_unref(o); - + return 0; } @@ -452,3 +508,21 @@ int pa_source_suspend_all(pa_core *c, int suspend) { return ret; } + +int pa_source_process_outputs(pa_source *s) { + pa_source_output *o; + void *state = NULL; + int r; + + pa_source_assert_ref(s); + + if (!PA_SOURCE_LINKED(s->state)) + return 0; + + while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) + if (o->process) + if ((r = o->process(o))) + return r; + + return 0; +} diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index ffe51079..ddc66156 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -42,26 +42,36 @@ typedef struct pa_source pa_source; #include #include #include +#include #define PA_MAX_OUTPUTS_PER_SOURCE 32 typedef enum pa_source_state { + PA_SOURCE_INIT, PA_SOURCE_RUNNING, PA_SOURCE_SUSPENDED, PA_SOURCE_IDLE, - PA_SOURCE_DISCONNECTED + PA_SOURCE_UNLINKED } pa_source_state_t; +static inline int PA_SOURCE_OPENED(pa_source_state_t x) { + return x == PA_SOURCE_RUNNING || x == PA_SOURCE_IDLE; +} + +static inline int PA_SOURCE_LINKED(pa_source_state_t x) { + return x == PA_SOURCE_RUNNING || x == PA_SOURCE_IDLE || x == PA_SOURCE_SUSPENDED; +} + struct pa_source { pa_msgobject parent; uint32_t index; pa_core *core; pa_source_state_t state; + pa_source_flags_t flags; char *name; char *description, *driver; /* may be NULL */ - int is_hardware; pa_module *module; /* may be NULL */ @@ -76,7 +86,7 @@ struct pa_source { int refresh_volume; int refresh_muted; - int (*set_state)(pa_source*source, pa_source_state_t state); /* may be NULL */ + int (*set_state)(pa_source*source, pa_source_state_t state); /* may be NULL */ int (*set_volume)(pa_source *s); /* dito */ int (*get_volume)(pa_source *s); /* dito */ int (*set_mute)(pa_source *s); /* dito */ @@ -84,7 +94,10 @@ struct pa_source { pa_usec_t (*get_latency)(pa_source *s); /* dito */ pa_asyncmsgq *asyncmsgq; + pa_rtpoll *rtpoll; + /* Contains copies of the above data so that the real-time worker + * thread can work without access locking */ struct { pa_source_state_t state; pa_hashmap *outputs; @@ -111,7 +124,7 @@ typedef enum pa_source_message { PA_SOURCE_MESSAGE_MAX } pa_source_message_t; -/* To be used exclusively by the source driver */ +/* To be called exclusively by the source driver, from main context */ pa_source* pa_source_new( pa_core *core, @@ -121,18 +134,22 @@ pa_source* pa_source_new( const pa_sample_spec *spec, const pa_channel_map *map); -void pa_source_disconnect(pa_source *s); +void pa_source_put(pa_source *s); +void pa_source_unlink(pa_source *s); void pa_source_set_module(pa_source *s, pa_module *m); void pa_source_set_description(pa_source *s, const char *description); void pa_source_set_asyncmsgq(pa_source *s, pa_asyncmsgq *q); +void pa_source_set_rtpoll(pa_source *s, pa_rtpoll *p); -/* Callable by everyone */ +/* May be called by everyone, from main context */ pa_usec_t pa_source_get_latency(pa_source *s); int pa_source_update_status(pa_source*s); int pa_source_suspend(pa_source *s, int suspend); +int pa_source_suspend_all(pa_core *c, int suspend); + void pa_source_ping(pa_source *s); void pa_source_set_volume(pa_source *source, const pa_cvolume *volume); @@ -143,15 +160,12 @@ int pa_source_get_mute(pa_source *source); unsigned pa_source_used_by(pa_source *s); #define pa_source_get_state(s) ((pa_source_state_t) (s)->state) -/* To be used exclusively by the source driver thread */ +/* To be called exclusively by the source driver, from IO context */ void pa_source_post(pa_source*s, const pa_memchunk *b); -int pa_source_process_msg(pa_msgobject *o, int code, void *userdata, int64_t, pa_memchunk *chunk); -static inline int PA_SOURCE_OPENED(pa_source_state_t x) { - return x == PA_SOURCE_RUNNING || x == PA_SOURCE_IDLE; -} +int pa_source_process_outputs(pa_source *o); -int pa_source_suspend_all(pa_core *c, int suspend); +int pa_source_process_msg(pa_msgobject *o, int code, void *userdata, int64_t, pa_memchunk *chunk); #endif -- cgit From 241ad047c889755d4b0003f8d149e8aed4639ae9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 30 Aug 2007 22:58:12 +0000 Subject: port module-combine to new core git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1734 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 10 +- src/modules/module-combine.c | 1110 +++++++++++++++++++++++++++++++++++------- 2 files changed, 938 insertions(+), 182 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 0bdc3f79..079610ab 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -930,8 +930,8 @@ modlibexec_LTLIBRARIES += \ module-sine.la \ module-native-protocol-tcp.la \ module-native-protocol-fd.la \ - module-esound-protocol-tcp.la -# module-combine.la \ + module-esound-protocol-tcp.la \ + module-combine.la # module-tunnel-sink.la \ # module-tunnel-source.la \ # module-esound-sink.la @@ -1192,9 +1192,9 @@ module_null_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la # Couplings -#module_combine_la_SOURCES = modules/module-combine.c -#module_combine_la_LDFLAGS = -module -avoid-version -#module_combine_la_LIBADD = $(AM_LIBADD) libpulsecore.la +module_combine_la_SOURCES = modules/module-combine.c +module_combine_la_LDFLAGS = -module -avoid-version +module_combine_la_LIBADD = $(AM_LIBADD) libpulsecore.la module_match_la_SOURCES = modules/module-match.c module_match_la_LDFLAGS = -module -avoid-version diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index b6d718de..c4fab457 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -25,12 +25,13 @@ #include #endif -#include #include +#include #include #include +#include #include #include #include @@ -40,6 +41,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include "module-combine-symdef.h" @@ -55,13 +62,12 @@ PA_MODULE_USAGE( "format= " "channels= " "rate= " - "channel_map= ") + "channel_map=") #define DEFAULT_SINK_NAME "combined" #define MEMBLOCKQ_MAXLENGTH (1024*170) -#define RENDER_SIZE (1024*10) -#define DEFAULT_ADJUST_TIME 20 +#define DEFAULT_ADJUST_TIME 10 static const char* const valid_modargs[] = { "sink_name", @@ -78,95 +84,135 @@ static const char* const valid_modargs[] = { struct output { struct userdata *userdata; + pa_sink *sink; pa_sink_input *sink_input; - size_t counter; + + pa_asyncmsgq *asyncmsgq; + pa_rtpoll_item *rtpoll_item; + pa_memblockq *memblockq; + pa_usec_t total_latency; + PA_LLIST_FIELDS(struct output); }; struct userdata { - pa_module *module; pa_core *core; + pa_module *module; pa_sink *sink; - unsigned n_outputs; + + pa_thread *thread; + pa_thread_mq thread_mq; + pa_rtpoll *rtpoll; + + pa_mutex *mutex; + struct output *master; - pa_time_event *time_event; - uint32_t adjust_time; - PA_LLIST_HEAD(struct output, outputs); + pa_time_event *time_event; + uint32_t adjust_time; + + int automatic; + size_t block_size; + + struct timespec timestamp; + + pa_hook_slot *sink_new_slot, *sink_unlink_slot, *sink_state_changed_slot; + + pa_resample_method_t resample_method; + + struct timespec adjust_timestamp; + + pa_idxset* outputs; /* managed in main context */ + + struct { + PA_LLIST_HEAD(struct output, outputs); /* managed in IO thread context */ + struct output *master; + } thread_info; }; -static void output_free(struct output *o); -static void clear_up(struct userdata *u); +enum { + SINK_MESSAGE_DETACH = PA_SINK_MESSAGE_MAX, + SINK_MESSAGE_ATTACH, + SINK_MESSAGE_ADD_OUTPUT, + SINK_MESSAGE_REMOVE_OUTPUT +}; -static void update_usage(struct userdata *u) { - pa_module_set_used(u->module, u->sink ? pa_sink_used_by(u->sink) : 0); -} +static void output_free(struct output *o); +static int output_create_sink_input(struct userdata *u, struct output *o); +static int update_master(struct userdata *u, struct output *o); +static int pick_master(struct userdata *u); static void adjust_rates(struct userdata *u) { struct output *o; pa_usec_t max_sink_latency = 0, min_total_latency = (pa_usec_t) -1, target_latency; uint32_t base_rate; - assert(u && u->sink); + uint32_t idx; - for (o = u->outputs; o; o = o->next) { - uint32_t sink_latency = o->sink_input->sink ? pa_sink_get_latency(o->sink_input->sink) : 0; + pa_assert(u); + pa_sink_assert_ref(u->sink); - o->total_latency = sink_latency + pa_sink_input_get_latency(o->sink_input); + if (pa_idxset_size(u->outputs) <= 0) + return; + + if (!PA_SINK_OPENED(pa_sink_get_state(u->sink))) + return; + + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) { + uint32_t sink_latency; + + if (!o->sink_input || !PA_SINK_OPENED(pa_sink_get_state(o->sink))) + continue; + sink_latency = o->sink_input->sink ? pa_sink_get_latency(o->sink_input->sink) : 0; + o->total_latency = sink_latency + pa_sink_input_get_latency(o->sink_input); + if (sink_latency > max_sink_latency) max_sink_latency = sink_latency; - + if (o->total_latency < min_total_latency) min_total_latency = o->total_latency; } - assert(min_total_latency != (pa_usec_t) -1); - + if (min_total_latency == (pa_usec_t) -1) + return; + target_latency = max_sink_latency > min_total_latency ? max_sink_latency : min_total_latency; - + pa_log_info("[%s] target latency is %0.0f usec.", u->sink->name, (float) target_latency); - + pa_log_info("[%s] master is %s", u->sink->name, u->master->sink->description); + base_rate = u->sink->sample_spec.rate; - - for (o = u->outputs; o; o = o->next) { + + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) { uint32_t r = base_rate; + if (!o->sink_input || !PA_SINK_OPENED(pa_sink_get_state(o->sink))) + continue; + if (o->total_latency < target_latency) r -= (uint32_t) (((((double) target_latency - o->total_latency))/u->adjust_time)*r/ 1000000); else if (o->total_latency > target_latency) r += (uint32_t) (((((double) o->total_latency - target_latency))/u->adjust_time)*r/ 1000000); - - if (r < (uint32_t) (base_rate*0.9) || r > (uint32_t) (base_rate*1.1)) + + if (r < (uint32_t) (base_rate*0.9) || r > (uint32_t) (base_rate*1.1)) { pa_log_warn("[%s] sample rates too different, not adjusting (%u vs. %u).", o->sink_input->name, base_rate, r); - else { + pa_sink_input_set_rate(o->sink_input, base_rate); + } else { pa_log_info("[%s] new rate is %u Hz; ratio is %0.3f; latency is %0.0f usec.", o->sink_input->name, r, (double) r / base_rate, (float) o->total_latency); pa_sink_input_set_rate(o->sink_input, r); } } } -static void request_memblock(struct userdata *u) { - pa_memchunk chunk; - struct output *o; - assert(u && u->sink); - - update_usage(u); - - if (pa_sink_render(u->sink, RENDER_SIZE, &chunk) < 0) - return; - - for (o = u->outputs; o; o = o->next) - pa_memblockq_push_align(o->memblockq, &chunk); - - pa_memblock_unref(chunk.memblock); -} - -static void time_callback(pa_mainloop_api*a, pa_time_event* e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { +static void time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *tv, void *userdata) { struct userdata *u = userdata; struct timeval n; - assert(u && a && u->time_event == e); + + pa_assert(u); + pa_assert(a); + pa_assert(u->time_event == e); adjust_rates(u); @@ -175,166 +221,735 @@ static void time_callback(pa_mainloop_api*a, pa_time_event* e, PA_GCC_UNUSED con u->sink->core->mainloop->time_restart(e, &n); } +static void thread_func(void *userdata) { + struct userdata *u = userdata; + + pa_assert(u); + + pa_log_debug("Thread starting up"); + + pa_thread_mq_install(&u->thread_mq); + pa_rtpoll_install(u->rtpoll); + + pa_rtclock_get(&u->timestamp); + + /* This is only run when were are in NULL mode, to make sure that + * playback doesn't stop. In all other cases we hook our stuff + * into the master sink. */ + + for (;;) { + int ret; + + /* Render some data and drop it immediately */ + if (u->sink->thread_info.state == PA_SINK_RUNNING) { + struct timespec now; + + pa_rtclock_get(&now); + + if (pa_timespec_cmp(&u->timestamp, &now) <= 0) { + pa_sink_skip(u->sink, u->block_size); + pa_timespec_add(&u->timestamp, pa_bytes_to_usec(u->block_size, &u->sink->sample_spec)); + } + + pa_rtpoll_set_timer_absolute(u->rtpoll, &u->timestamp); + } else + pa_rtpoll_set_timer_disabled(u->rtpoll); + + /* Now give the sink inputs some to time to process their data */ + if ((ret = pa_sink_process_inputs(u->sink)) < 0) + goto fail; + if (ret > 0) + continue; + + /* Check whether there is a message for us to process */ + if ((ret = pa_thread_mq_process(&u->thread_mq) < 0)) + goto finish; + if (ret > 0) + continue; + + /* Hmm, nothing to do. Let's sleep */ + if (pa_rtpoll_run(u->rtpoll) < 0) { + pa_log("poll() failed: %s", pa_cstrerror(errno)); + goto fail; + } + } + +fail: + /* We have to continue processing messages until we receive the + * SHUTDOWN message */ + pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); + pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); + +finish: + pa_log_debug("Thread shutting down"); +} + +static void request_memblock(struct output *o) { + pa_memchunk chunk; + + pa_assert(o); + pa_sink_input_assert_ref(o->sink_input); + pa_sink_assert_ref(o->userdata->sink); + + /* If another thread already prepared some data we received + * the data over the asyncmsgq, hence let's first process + * it. */ + while (pa_asyncmsgq_get(o->asyncmsgq, NULL, NULL, NULL, NULL, &chunk, 0) == 0) { + pa_memblockq_push_align(o->memblockq, &chunk); + pa_asyncmsgq_done(o->asyncmsgq, 0); + } + + /* Check whether we're now readable */ + if (pa_memblockq_is_readable(o->memblockq)) + return; + + /* OK, we need to prepare new data */ + pa_mutex_lock(o->userdata->mutex); + + if (PA_SINK_OPENED(o->userdata->sink->thread_info.state)) { + + /* Maybe there's some data now? */ + while (pa_asyncmsgq_get(o->asyncmsgq, NULL, NULL, NULL, NULL, &chunk, 0) == 0) { + pa_memblockq_push_align(o->memblockq, &chunk); + pa_asyncmsgq_done(o->asyncmsgq, 0); + } + + /* Ok, now let's prepare some data if we really have to */ + while (!pa_memblockq_is_readable(o->memblockq)) { + struct output *j; + + /* Do it! */ + pa_sink_render(o->userdata->sink, o->userdata->block_size, &chunk); + + /* OK, let's send this data to the other threads */ + for (j = o->userdata->thread_info.outputs; j; j = j->next) + if (j != o && j->sink_input) + pa_asyncmsgq_post(j->asyncmsgq, NULL, 0, NULL, 0, &chunk, NULL); + + /* And push it into our own queue */ + pa_memblockq_push_align(o->memblockq, &chunk); + pa_memblock_unref(chunk.memblock); + } + } + + pa_mutex_unlock(o->userdata->mutex); +} + +/* Called from I/O trhead context */ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { - struct output *o = i->userdata; - assert(i && o && o->sink_input && chunk); + struct output *o; - if (pa_memblockq_peek(o->memblockq, chunk) >= 0) - return 0; + pa_sink_input_assert_ref(i); + o = i->userdata; + pa_assert(o); - /* Try harder */ - request_memblock(o->userdata); + /* If necessary, get some new data */ + request_memblock(o); - return pa_memblockq_peek(o->memblockq, chunk); + return pa_memblockq_peek(o->memblockq, chunk); } -static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_t length) { - struct output *o = i->userdata; - assert(i && o && o->sink_input && chunk && length); +/* Called from I/O thread context */ +static void sink_input_drop_cb(pa_sink_input *i, size_t length) { + struct output *o; + + pa_sink_input_assert_ref(i); + pa_assert(length > 0); + o = i->userdata; + pa_assert(o); - pa_memblockq_drop(o->memblockq, chunk, length); - o->counter += length; + pa_memblockq_drop(o->memblockq, length); } +/* Called from I/O thread context */ +static int sink_input_process_cb(pa_sink_input *i) { + struct output *o; + pa_memchunk chunk; + int r = 0; + + pa_sink_input_assert_ref(i); + o = i->userdata; + pa_assert(o); + + /* Move all data in the asyncmsgq into our memblockq */ + + while (pa_asyncmsgq_get(o->asyncmsgq, NULL, NULL, NULL, NULL, &chunk, 0) == 0) { + if (PA_SINK_OPENED(i->sink->thread_info.state)) + pa_memblockq_push_align(o->memblockq, &chunk); + pa_asyncmsgq_done(o->asyncmsgq, 0); + } + + /* If the sink is suspended, flush our queue */ + if (!PA_SINK_OPENED(i->sink->thread_info.state)) + pa_memblockq_flush(o->memblockq); + + if (o == o->userdata->thread_info.master) { + pa_mutex_lock(o->userdata->mutex); + r = pa_sink_process_inputs(o->userdata->sink); + pa_mutex_unlock(o->userdata->mutex); + } + + return r; +} + +/* Called from I/O thread context */ +static void sink_input_attach_cb(pa_sink_input *i) { + struct output *o; + + pa_sink_input_assert_ref(i); + o = i->userdata; + pa_assert(o); + + pa_assert(!o->rtpoll_item); + o->rtpoll_item = pa_rtpoll_item_new_asyncmsgq(i->sink->rtpoll, o->asyncmsgq); +} + +/* Called from I/O thread context */ +static void sink_input_detach_cb(pa_sink_input *i) { + struct output *o; + + pa_sink_input_assert_ref(i); + o = i->userdata; + pa_assert(o); + + pa_assert(o->rtpoll_item); + pa_rtpoll_item_free(o->rtpoll_item); + o->rtpoll_item = NULL; +} + +/* Called from main context */ static void sink_input_kill_cb(pa_sink_input *i) { - struct output *o = i->userdata; - assert(i && o && o->sink_input); + struct output *o; + + pa_sink_input_assert_ref(i); + o = i->userdata; + pa_assert(o); + + pa_sink_input_unlink(o->sink_input); + pa_sink_input_unref(o->sink_input); + o->sink_input = NULL; + pa_module_unload_request(o->userdata->module); - clear_up(o->userdata); } -static pa_usec_t sink_input_get_latency_cb(pa_sink_input *i) { - struct output *o = i->userdata; - assert(i && o && o->sink_input); +/* Called from thread context */ +static int sink_input_process_msg(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) { + struct output *o = PA_SINK_INPUT(obj)->userdata; + + switch (code) { + + case PA_SINK_INPUT_MESSAGE_GET_LATENCY: { + pa_usec_t *r = data; + + *r = pa_bytes_to_usec(pa_memblockq_get_length(o->memblockq), &o->sink_input->sample_spec); + + /* Fall through, the default handler will add in the extra + * latency added by the resampler */ + break; + } - return pa_bytes_to_usec(pa_memblockq_get_length(o->memblockq), &i->sample_spec); + } + + return pa_sink_input_process_msg(obj, code, data, offset, chunk); } -static pa_usec_t sink_get_latency_cb(pa_sink *s) { - struct userdata *u = s->userdata; - assert(s && u && u->sink && u->master); +static int suspend(struct userdata *u) { + struct output *o; + uint32_t idx; + + pa_assert(u); + + /* Let's suspend by unlinking all streams */ + + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) { + pa_sink_input_unlink(o->sink_input); + pa_sink_input_unref(o->sink_input); + o->sink_input = NULL; + } - return - pa_sink_input_get_latency(u->master->sink_input) + - pa_sink_get_latency(u->master->sink_input->sink); + if (pick_master(u) < 0) + pa_module_unload_request(u->module); + + pa_log_info("Device suspended..."); + + return 0; } -static void sink_notify(pa_sink *s) { - struct userdata *u; +static int unsuspend(struct userdata *u) { struct output *o; + uint32_t idx; + + pa_assert(u); + + /* Let's resume */ + + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) { + + if (output_create_sink_input(u, o) < 0) + output_free(o); + else + pa_sink_input_put(o->sink_input); + } + + if (pick_master(u) < 0) + pa_module_unload_request(u->module); + + pa_log_info("Resumed successfully..."); + return 0; +} + +static int sink_set_state(pa_sink *sink, pa_sink_state_t state) { + struct userdata *u; + + pa_sink_assert_ref(sink); + u = sink->userdata; + pa_assert(u); + + /* Please note that in contrast to the ALSA modules we call + * suspend/unsuspend from main context here! */ + + switch (state) { + case PA_SINK_SUSPENDED: + pa_assert(PA_SINK_OPENED(pa_sink_get_state(u->sink))); + + if (suspend(u) < 0) + return -1; + + break; + + case PA_SINK_IDLE: + case PA_SINK_RUNNING: + + if (pa_sink_get_state(u->sink) == PA_SINK_SUSPENDED) { + if (unsuspend(u) < 0) + return -1; + } + + break; + + case PA_SINK_UNLINKED: + case PA_SINK_INIT: + ; + } + + return 0; +} + +/* Called from thread context of the master */ +static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { + struct userdata *u = PA_SINK(o)->userdata; + + switch (code) { + + case PA_SINK_MESSAGE_SET_STATE: + + if ((pa_sink_state_t) PA_PTR_TO_UINT(data) == PA_SINK_RUNNING) { + /* Only useful when running in NULL mode, i.e. when no + * master sink is attached */ + pa_rtclock_get(&u->timestamp); + } + + break; + + case PA_SINK_MESSAGE_GET_LATENCY: { + struct timespec now; + + /* This code will only be called when running in NULL + * mode, i.e. when no master sink is attached. See + * sink_get_latency_cb() below */ + pa_rtclock_get(&now); + + if (pa_timespec_cmp(&u->timestamp, &now) > 0) + *((pa_usec_t*) data) = 0; + else + *((pa_usec_t*) data) = pa_timespec_diff(&u->timestamp, &now); + break; + } + + case SINK_MESSAGE_DETACH: { + pa_sink_input *i; + void *state = NULL; + + /* We're detaching all our input streams artificially, so + * that we can driver our sink from a different sink */ + + while ((i = pa_hashmap_iterate(u->sink->thread_info.inputs, &state, NULL))) + if (i->detach) + i->detach(i); + + u->thread_info.master = NULL; + + break; + } - assert(s); + case SINK_MESSAGE_ATTACH: { + pa_sink_input *i; + void *state = NULL; + + /* We're attached all our input streams artificially again */ + + while ((i = pa_hashmap_iterate(u->sink->thread_info.inputs, &state, NULL))) + if (i->attach) + i->attach(i); + + u->thread_info.master = data; + + break; + } + + case SINK_MESSAGE_ADD_OUTPUT: + PA_LLIST_PREPEND(struct output, u->thread_info.outputs, (struct output*) data); + break; + + case SINK_MESSAGE_REMOVE_OUTPUT: + PA_LLIST_REMOVE(struct output, u->thread_info.outputs, (struct output*) data); + break; + } + + return pa_sink_process_msg(o, code, data, offset, chunk); +} + +/* Called from main context */ +static pa_usec_t sink_get_latency_cb(pa_sink *s) { + struct userdata *u; + + pa_sink_assert_ref(s); u = s->userdata; - assert(u); + pa_assert(u); + + if (u->master) { + /* If we have a master sink, we just return the latency of it + * and add our own buffering on top */ + + if (!u->master->sink_input) + return 0; + + return + pa_sink_input_get_latency(u->master->sink_input) + + pa_sink_get_latency(u->master->sink_input->sink); + + } else { + pa_usec_t usec; + + /* We have no master, hence let's ask our own thread which + * implements the NULL sink */ + + if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0) + return 0; + + return usec; + } +} + +static void update_description(struct userdata *u) { + int first = 1; + char *t; + struct output *o; + uint32_t idx; + + pa_assert(u); - for (o = u->outputs; o; o = o->next) - pa_sink_notify(o->sink_input->sink); + if (pa_idxset_isempty(u->outputs)) { + pa_sink_set_description(u->sink, "Simultaneous output"); + return; + } + + t = pa_xstrdup("Simultaneous output to"); + + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) { + char *e; + + if (first) { + e = pa_sprintf_malloc("%s %s", t, o->sink->description); + first = 0; + } else + e = pa_sprintf_malloc("%s, %s", t, o->sink->description); + + pa_xfree(t); + t = e; + } + + pa_sink_set_description(u->sink, t); + pa_xfree(t); } -static struct output *output_new(struct userdata *u, pa_sink *sink, int resample_method) { - struct output *o = NULL; - char t[256]; - pa_sink_input_new_data data; +static int update_master(struct userdata *u, struct output *o) { + pa_assert(u); - assert(u && sink && u->sink); + /* Make sure everything is detached from the old thread before we move our stuff to a new thread */ + if (u->sink && PA_SINK_LINKED(pa_sink_get_state(u->sink))) + pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_DETACH, NULL, 0, NULL); + + if (o) { + /* If we have a master sink we run our own sink in its thread */ + + pa_assert(o->sink_input); + pa_assert(PA_SINK_OPENED(pa_sink_get_state(o->sink))); + + if (u->thread) { + /* If we previously were in NULL mode, let's kill the thread */ + pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); + pa_thread_free(u->thread); + u->thread = NULL; + + pa_assert(u->rtpoll); + pa_rtpoll_free(u->rtpoll); + u->rtpoll = NULL; + } - o = pa_xmalloc(sizeof(struct output)); - o->userdata = u; + pa_sink_set_asyncmsgq(u->sink, o->sink->asyncmsgq); + pa_sink_set_rtpoll(u->sink, o->sink->rtpoll); + u->master = o; - o->counter = 0; - o->memblockq = pa_memblockq_new( - 0, - MEMBLOCKQ_MAXLENGTH, - MEMBLOCKQ_MAXLENGTH, - pa_frame_size(&u->sink->sample_spec), - 1, - 0, - NULL); + pa_log_info("Master sink is now '%s'", o->sink_input->sink->name); - pa_snprintf(t, sizeof(t), "Output stream #%u of sink %s", u->n_outputs+1, u->sink->name); + } else { + /* We have no master sink, let's create our own thread */ + + pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); + u->master = NULL; + + if (!u->thread) { + pa_assert(!u->rtpoll); + + u->rtpoll = pa_rtpoll_new(); + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, u->thread_mq.inq); + + pa_sink_set_rtpoll(u->sink, u->rtpoll); + + if (!(u->thread = pa_thread_new(thread_func, u))) { + pa_log("Failed to create thread."); + return -1; + } + } + + pa_log_info("No suitable master sink found, going to NULL mode\n"); + } + + /* Now attach everything again */ + if (u->sink && PA_SINK_LINKED(pa_sink_get_state(u->sink))) + pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_ATTACH, u->master, 0, NULL); + + return 0; +} + +static int pick_master(struct userdata *u) { + struct output *o; + uint32_t idx; + pa_assert(u); + + if (u->master && u->master->sink_input && PA_SINK_OPENED(pa_sink_get_state(u->master->sink))) + return update_master(u, u->master); + + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) + if (o->sink_input && PA_SINK_OPENED(pa_sink_get_state(o->sink))) + return update_master(u, o); + + return update_master(u, NULL); +} + +static int output_create_sink_input(struct userdata *u, struct output *o) { + pa_sink_input_new_data data; + char *t; + + pa_assert(u); + pa_assert(!o->sink_input); + + t = pa_sprintf_malloc("Simultaneous output on %s", o->sink->description); + pa_sink_input_new_data_init(&data); - data.sink = sink; + data.sink = o->sink; data.driver = __FILE__; data.name = t; pa_sink_input_new_data_set_sample_spec(&data, &u->sink->sample_spec); pa_sink_input_new_data_set_channel_map(&data, &u->sink->channel_map); data.module = u->module; - if (!(o->sink_input = pa_sink_input_new(u->core, &data, PA_SINK_INPUT_VARIABLE_RATE))) - goto fail; + o->sink_input = pa_sink_input_new(u->core, &data, PA_SINK_INPUT_VARIABLE_RATE|PA_SINK_INPUT_DONT_MOVE); - o->sink_input->get_latency = sink_input_get_latency_cb; + pa_xfree(t); + + if (!o->sink_input) + return -1; + + o->sink_input->parent.process_msg = sink_input_process_msg; o->sink_input->peek = sink_input_peek_cb; o->sink_input->drop = sink_input_drop_cb; + o->sink_input->process = sink_input_process_cb; + o->sink_input->attach = sink_input_attach_cb; + o->sink_input->detach = sink_input_detach_cb; o->sink_input->kill = sink_input_kill_cb; o->sink_input->userdata = o; + + return 0; +} + +static struct output *output_new(struct userdata *u, pa_sink *sink, int resample_method) { + struct output *o; + + pa_assert(u); + pa_assert(sink); + pa_assert(u->sink); + + o = pa_xnew(struct output, 1); + o->userdata = u; + o->asyncmsgq = pa_asyncmsgq_new(0); + o->rtpoll_item = NULL; + o->sink = sink; + o->sink_input = NULL; + o->memblockq = pa_memblockq_new( + 0, + MEMBLOCKQ_MAXLENGTH, + MEMBLOCKQ_MAXLENGTH, + pa_frame_size(&u->sink->sample_spec), + 1, + 0, + NULL); + + + update_description(u); + + pa_assert_se(pa_idxset_put(u->outputs, o, NULL) == 0); + if (u->sink && PA_SINK_LINKED(pa_sink_get_state(u->sink))) + pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_ADD_OUTPUT, o, 0, NULL); + else + PA_LLIST_PREPEND(struct output, u->thread_info.outputs, o); + + if (PA_SINK_OPENED(pa_sink_get_state(sink))) + if (output_create_sink_input(u, o) < 0) + goto fail; - PA_LLIST_PREPEND(struct output, u->outputs, o); - u->n_outputs++; return o; fail: if (o) { if (o->sink_input) { - pa_sink_input_disconnect(o->sink_input); + pa_sink_input_unlink(o->sink_input); pa_sink_input_unref(o->sink_input); } if (o->memblockq) pa_memblockq_free(o->memblockq); + if (o->asyncmsgq) + pa_asyncmsgq_unref(o->asyncmsgq); + pa_xfree(o); } return NULL; } -static void output_free(struct output *o) { - assert(o); - PA_LLIST_REMOVE(struct output, o->userdata->outputs, o); - o->userdata->n_outputs--; - pa_memblockq_free(o->memblockq); - pa_sink_input_disconnect(o->sink_input); - pa_sink_input_unref(o->sink_input); - pa_xfree(o); +static pa_hook_result_t sink_new_hook_cb(pa_core *c, pa_sink *s, struct userdata* u) { + struct output *o; + + pa_core_assert_ref(c); + pa_sink_assert_ref(s); + pa_assert(u); + pa_assert(u->automatic); + + if (!(s->flags & PA_SINK_HARDWARE) || s == u->sink) + return PA_HOOK_OK; + + pa_log_info("Configuring new sink: %s", s->name); + + if (!(o = output_new(u, s, u->resample_method))) { + pa_log("Failed to create sink input on sink '%s'.", s->name); + return PA_HOOK_OK; + } + + if (pick_master(u) < 0) + pa_module_unload_request(u->module); + + if (o->sink_input) + pa_sink_input_put(o->sink_input); + + return PA_HOOK_OK; } -static void clear_up(struct userdata *u) { +static pa_hook_result_t sink_unlink_hook_cb(pa_core *c, pa_sink *s, struct userdata* u) { struct output *o; - assert(u); + uint32_t idx; + + pa_assert(c); + pa_sink_assert_ref(s); + pa_assert(u); + + if (s == u->sink) + return PA_HOOK_OK; + + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) + if (o->sink == s) + break; + + if (!o) + return PA_HOOK_OK; + + pa_log_info("Unconfiguring sink: %s", s->name); + + output_free(o); + + if (pick_master(u) < 0) + pa_module_unload_request(u->module); + + return PA_HOOK_OK; +} - if (u->time_event) { - u->core->mainloop->time_free(u->time_event); - u->time_event = NULL; - } +static pa_hook_result_t sink_state_changed_hook_cb(pa_core *c, pa_sink *s, struct userdata* u) { + struct output *o; + uint32_t idx; + pa_sink_state_t state; - while ((o = u->outputs)) - output_free(o); + if (s == u->sink) + return PA_HOOK_OK; - u->master = NULL; + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) + if (o->sink == s) + break; - if (u->sink) { - pa_sink_disconnect(u->sink); - pa_sink_unref(u->sink); - u->sink = NULL; + if (!o) + return PA_HOOK_OK; + + state = pa_sink_get_state(s); + + if (PA_SINK_OPENED(state) && !o->sink_input) { + output_create_sink_input(u, o); + + if (pick_master(u) < 0) + pa_module_unload_request(u->module); + + if (o->sink_input) + pa_sink_input_put(o->sink_input); } + + if (state == PA_SINK_SUSPENDED && o->sink_input) { + pa_sink_input_unlink(o->sink_input); + pa_sink_input_unref(o->sink_input); + o->sink_input = NULL; + + pa_memblockq_flush(o->memblockq); + + if (pick_master(u) < 0) + pa_module_unload_request(u->module); + } + + return PA_HOOK_OK; } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { struct userdata *u; pa_modargs *ma = NULL; const char *master_name, *slaves, *rm; - pa_sink *master_sink; - char *n = NULL; - const char*split_state; - struct timeval tv; + pa_sink *master_sink = NULL; int resample_method = -1; pa_sample_spec ss; pa_channel_map map; + struct output *o; + uint32_t idx; - assert(c && m); + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("failed to parse module arguments"); @@ -349,115 +964,256 @@ int pa__init(pa_core *c, pa_module*m) { } u = pa_xnew(struct userdata, 1); + u->core = m->core; + u->module = m; m->userdata = u; u->sink = NULL; - u->n_outputs = 0; - u->master = NULL; - u->module = m; - u->core = c; - u->time_event = NULL; - u->adjust_time = DEFAULT_ADJUST_TIME; - PA_LLIST_HEAD_INIT(struct output, u->outputs); - + u->thread_info.master = u->master = NULL; + u->time_event = NULL; + u->adjust_time = DEFAULT_ADJUST_TIME; + u->mutex = pa_mutex_new(0); + pa_thread_mq_init(&u->thread_mq, m->core->mainloop); + u->rtpoll = NULL; + u->thread = NULL; + PA_LLIST_HEAD_INIT(struct output, u->thread_info.outputs); + u->resample_method = resample_method; + u->outputs = pa_idxset_new(NULL, NULL); + pa_timespec_reset(&u->adjust_timestamp); + if (pa_modargs_get_value_u32(ma, "adjust_time", &u->adjust_time) < 0) { - pa_log("failed to parse adjust_time value"); + pa_log("Failed to parse adjust_time value"); goto fail; } - if (!(master_name = pa_modargs_get_value(ma, "master", NULL)) || !(slaves = pa_modargs_get_value(ma, "slaves", NULL))) { - pa_log("no master or slave sinks specified"); + master_name = pa_modargs_get_value(ma, "master", NULL); + slaves = pa_modargs_get_value(ma, "slaves", NULL); + if (!master_name != !slaves) { + pa_log("No master or slave sinks specified"); goto fail; } - if (!(master_sink = pa_namereg_get(c, master_name, PA_NAMEREG_SINK, 1))) { - pa_log("invalid master sink '%s'", master_name); - goto fail; + if (master_name) { + if (!(master_sink = pa_namereg_get(m->core, master_name, PA_NAMEREG_SINK, 1))) { + pa_log("Invalid master sink '%s'", master_name); + goto fail; + } + + ss = master_sink->sample_spec; + u->automatic = 0; + } else { + master_sink = NULL; + ss = m->core->default_sample_spec; + u->automatic = 1; } - ss = master_sink->sample_spec; if ((pa_modargs_get_sample_spec(ma, &ss) < 0)) { - pa_log("invalid sample specification."); + pa_log("Invalid sample specification."); goto fail; } - if (ss.channels == master_sink->sample_spec.channels) + if (master_sink && ss.channels == master_sink->sample_spec.channels) map = master_sink->channel_map; else pa_channel_map_init_auto(&map, ss.channels, PA_CHANNEL_MAP_DEFAULT); if ((pa_modargs_get_channel_map(ma, &map) < 0)) { - pa_log("invalid channel map."); + pa_log("Invalid channel map."); goto fail; } - + if (ss.channels != map.channels) { - pa_log("channel map and sample specification don't match."); + pa_log("Channel map and sample specification don't match."); goto fail; } - if (!(u->sink = pa_sink_new(c, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map))) { - pa_log("failed to create sink"); + if (!(u->sink = pa_sink_new(m->core, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map))) { + pa_log("Failed to create sink"); goto fail; } - pa_sink_set_owner(u->sink, m); - pa_sink_set_description(u->sink, "Combined Sink"); + u->sink->parent.process_msg = sink_process_msg; u->sink->get_latency = sink_get_latency_cb; - u->sink->notify = sink_notify; + u->sink->set_state = sink_set_state; u->sink->userdata = u; - if (!(u->master = output_new(u, master_sink, resample_method))) { - pa_log("failed to create master sink input on sink '%s'.", u->sink->name); - goto fail; - } - - split_state = NULL; - while ((n = pa_split(slaves, ",", &split_state))) { - pa_sink *slave_sink; - - if (!(slave_sink = pa_namereg_get(c, n, PA_NAMEREG_SINK, 1))) { - pa_log("invalid slave sink '%s'", n); + u->sink->flags = PA_SINK_CAN_SUSPEND|PA_SINK_LATENCY; + pa_sink_set_module(u->sink, m); + pa_sink_set_description(u->sink, "Simultaneous output"); + + u->block_size = pa_bytes_per_second(&ss) / 20; /* 50 ms */ + if (u->block_size <= 0) + u->block_size = pa_frame_size(&ss); + + if (!u->automatic) { + const char*split_state; + char *n = NULL; + pa_assert(slaves); + + /* The master and slaves have been specified manually */ + + if (!(u->master = output_new(u, master_sink, resample_method))) { + pa_log("Failed to create master sink input on sink '%s'.", master_sink->name); goto fail; } + + split_state = NULL; + while ((n = pa_split(slaves, ",", &split_state))) { + pa_sink *slave_sink; + + if (!(slave_sink = pa_namereg_get(m->core, n, PA_NAMEREG_SINK, 1)) || slave_sink == u->sink) { + pa_log("Invalid slave sink '%s'", n); + pa_xfree(n); + goto fail; + } + + pa_xfree(n); + + if (!output_new(u, slave_sink, resample_method)) { + pa_log("Failed to create slave sink input on sink '%s'.", slave_sink->name); + goto fail; + } + } - pa_xfree(n); + if (pa_idxset_size(u->outputs) <= 1) + pa_log_warn("WARNING: No slave sinks specified."); - if (!output_new(u, slave_sink, resample_method)) { - pa_log("failed to create slave sink input on sink '%s'.", slave_sink->name); - goto fail; + u->sink_new_slot = NULL; + + } else { + pa_sink *s; + + /* We're in automatic mode, we elect one hw sink to the master + * and attach all other hw sinks as slaves to it */ + + for (s = pa_idxset_first(m->core->sinks, &idx); s; s = pa_idxset_next(m->core->sinks, &idx)) { + + if (!(s->flags & PA_SINK_HARDWARE) || s == u->sink) + continue; + + if (!output_new(u, s, resample_method)) { + pa_log("Failed to create sink input on sink '%s'.", s->name); + goto fail; + } } + + u->sink_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_NEW_POST], (pa_hook_cb_t) sink_new_hook_cb, u); } - if (u->n_outputs <= 1) - pa_log_warn("WARNING: no slave sinks specified."); + u->sink_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], (pa_hook_cb_t) sink_unlink_hook_cb, u); + u->sink_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], (pa_hook_cb_t) sink_state_changed_hook_cb, u); + + if (pick_master(u) < 0) + goto fail; + /* Activate the sink and the sink inputs */ + pa_sink_put(u->sink); + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) + pa_sink_input_put(o->sink_input); + if (u->adjust_time > 0) { + struct timeval tv; pa_gettimeofday(&tv); tv.tv_sec += u->adjust_time; - u->time_event = c->mainloop->time_new(c->mainloop, &tv, time_callback, u); + u->time_event = m->core->mainloop->time_new(m->core->mainloop, &tv, time_callback, u); } pa_modargs_free(ma); + return 0; fail: - pa_xfree(n); if (ma) pa_modargs_free(ma); - pa__done(c, m); + pa__done(m); + return -1; } -void pa__done(pa_core *c, pa_module*m) { +static void output_free(struct output *o) { + pa_assert(o); + + if (o->userdata) { + if (o->userdata->sink && PA_SINK_LINKED(pa_sink_get_state(o->userdata->sink))) + pa_asyncmsgq_send(o->userdata->sink->asyncmsgq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_REMOVE_OUTPUT, o, 0, NULL); + else + PA_LLIST_REMOVE(struct output, o->userdata->thread_info.outputs, o); + } + + pa_assert_se(pa_idxset_remove_by_data(o->userdata->outputs, o, NULL)); + + if (o->userdata->master == o) { + /* Make sure the master points to a different output */ + o->userdata->master = NULL; + pick_master(o->userdata); + } + + update_description(o->userdata); + + if (o->sink_input) { + pa_sink_input_unlink(o->sink_input); + pa_sink_input_unref(o->sink_input); + } + + if (o->rtpoll_item) + pa_rtpoll_item_free(o->rtpoll_item); + + if (o->memblockq) + pa_memblockq_free(o->memblockq); + + if (o->asyncmsgq) + pa_asyncmsgq_unref(o->asyncmsgq); + + pa_xfree(o); +} + +void pa__done(pa_module*m) { struct userdata *u; - assert(c && m); + struct output *o; + + pa_assert(m); if (!(u = m->userdata)) return; - clear_up(u); + if (u->sink_new_slot) + pa_hook_slot_free(u->sink_new_slot); + + if (u->sink_unlink_slot) + pa_hook_slot_free(u->sink_unlink_slot); + + if (u->sink_state_changed_slot) + pa_hook_slot_free(u->sink_state_changed_slot); + + if (u->sink) + pa_sink_unlink(u->sink); + + if (u->outputs) { + while ((o = pa_idxset_first(u->outputs, NULL))) + output_free(o); + + pa_idxset_free(u->outputs, NULL, NULL); + } + + if (u->thread) { + pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); + pa_thread_free(u->thread); + } + + pa_thread_mq_done(&u->thread_mq); + + if (u->sink) + pa_sink_unref(u->sink); + + if (u->rtpoll) + pa_rtpoll_free(u->rtpoll); + + if (u->time_event) + u->core->mainloop->time_free(u->time_event); + + pa_mutex_free(u->mutex); + pa_xfree(u); } -- cgit From f59dd18fe62de0549fb2cffbd14d0da928c0b118 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 31 Aug 2007 00:22:31 +0000 Subject: - fix suspend handling - set sink description properly - honour resample_method setting git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1735 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-combine.c | 61 +++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index c4fab457..3e56bc67 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -462,9 +462,12 @@ static int suspend(struct userdata *u) { /* Let's suspend by unlinking all streams */ for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) { - pa_sink_input_unlink(o->sink_input); - pa_sink_input_unref(o->sink_input); - o->sink_input = NULL; + + if (o->sink_input) { + pa_sink_input_unlink(o->sink_input); + pa_sink_input_unref(o->sink_input); + o->sink_input = NULL; + } } if (pick_master(u) < 0) @@ -484,11 +487,15 @@ static int unsuspend(struct userdata *u) { /* Let's resume */ for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) { - - if (output_create_sink_input(u, o) < 0) - output_free(o); - else - pa_sink_input_put(o->sink_input); + + pa_sink_suspend(o->sink, 0); + + if (PA_SINK_OPENED(pa_sink_get_state(o->sink))) { + if (output_create_sink_input(u, o) < 0) + output_free(o); + else + pa_sink_input_put(o->sink_input); + } } if (pick_master(u) < 0) @@ -765,7 +772,8 @@ static int output_create_sink_input(struct userdata *u, struct output *o) { pa_sink_input_new_data_set_sample_spec(&data, &u->sink->sample_spec); pa_sink_input_new_data_set_channel_map(&data, &u->sink->channel_map); data.module = u->module; - + data.resample_method = u->resample_method; + o->sink_input = pa_sink_input_new(u->core, &data, PA_SINK_INPUT_VARIABLE_RATE|PA_SINK_INPUT_DONT_MOVE); pa_xfree(t); @@ -785,7 +793,7 @@ static int output_create_sink_input(struct userdata *u, struct output *o) { return 0; } -static struct output *output_new(struct userdata *u, pa_sink *sink, int resample_method) { +static struct output *output_new(struct userdata *u, pa_sink *sink) { struct output *o; pa_assert(u); @@ -808,17 +816,22 @@ static struct output *output_new(struct userdata *u, pa_sink *sink, int resample NULL); + pa_assert_se(pa_idxset_put(u->outputs, o, NULL) == 0); + update_description(u); - pa_assert_se(pa_idxset_put(u->outputs, o, NULL) == 0); if (u->sink && PA_SINK_LINKED(pa_sink_get_state(u->sink))) pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_ADD_OUTPUT, o, 0, NULL); else PA_LLIST_PREPEND(struct output, u->thread_info.outputs, o); - if (PA_SINK_OPENED(pa_sink_get_state(sink))) - if (output_create_sink_input(u, o) < 0) - goto fail; + if (PA_SINK_OPENED(pa_sink_get_state(u->sink)) || pa_sink_get_state(u->sink) == PA_SINK_INIT) { + pa_sink_suspend(sink, 0); + + if (PA_SINK_OPENED(pa_sink_get_state(sink))) + if (output_create_sink_input(u, o) < 0) + goto fail; + } return o; @@ -855,7 +868,7 @@ static pa_hook_result_t sink_new_hook_cb(pa_core *c, pa_sink *s, struct userdata pa_log_info("Configuring new sink: %s", s->name); - if (!(o = output_new(u, s, u->resample_method))) { + if (!(o = output_new(u, s))) { pa_log("Failed to create sink input on sink '%s'.", s->name); return PA_HOOK_OK; } @@ -914,7 +927,7 @@ static pa_hook_result_t sink_state_changed_hook_cb(pa_core *c, pa_sink *s, struc state = pa_sink_get_state(s); - if (PA_SINK_OPENED(state) && !o->sink_input) { + if (PA_SINK_OPENED(state) && PA_SINK_OPENED(pa_sink_get_state(u->sink)) && !o->sink_input) { output_create_sink_input(u, o); if (pick_master(u) < 0) @@ -943,7 +956,7 @@ int pa__init(pa_module*m) { pa_modargs *ma = NULL; const char *master_name, *slaves, *rm; pa_sink *master_sink = NULL; - int resample_method = -1; + int resample_method = PA_RESAMPLER_TRIVIAL; pa_sample_spec ss; pa_channel_map map; struct output *o; @@ -1051,7 +1064,7 @@ int pa__init(pa_module*m) { /* The master and slaves have been specified manually */ - if (!(u->master = output_new(u, master_sink, resample_method))) { + if (!(u->master = output_new(u, master_sink))) { pa_log("Failed to create master sink input on sink '%s'.", master_sink->name); goto fail; } @@ -1068,7 +1081,7 @@ int pa__init(pa_module*m) { pa_xfree(n); - if (!output_new(u, slave_sink, resample_method)) { + if (!output_new(u, slave_sink)) { pa_log("Failed to create slave sink input on sink '%s'.", slave_sink->name); goto fail; } @@ -1090,7 +1103,7 @@ int pa__init(pa_module*m) { if (!(s->flags & PA_SINK_HARDWARE) || s == u->sink) continue; - if (!output_new(u, s, resample_method)) { + if (!output_new(u, s)) { pa_log("Failed to create sink input on sink '%s'.", s->name); goto fail; } @@ -1104,12 +1117,14 @@ int pa__init(pa_module*m) { if (pick_master(u) < 0) goto fail; - + /* Activate the sink and the sink inputs */ pa_sink_put(u->sink); - for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) - pa_sink_input_put(o->sink_input); + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) + if (o->sink_input) + pa_sink_input_put(o->sink_input); + if (u->adjust_time > 0) { struct timeval tv; pa_gettimeofday(&tv); -- cgit From c627871fdb379761a3c75e8d191cc5b63e63be63 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 31 Aug 2007 00:22:58 +0000 Subject: replace a pa_assert() by an pa_assert_se() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1736 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/daemon/main.c b/src/daemon/main.c index 7bdf65c1..b927b2af 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -554,7 +554,7 @@ int main(int argc, char *argv[]) { #endif } - pa_assert(chdir("/") == 0); + pa_assert_se(chdir("/") == 0); umask(0022); if (conf->system_instance) { -- cgit From 6eb2f88c5dc4c74634774aa242961b1630c0419c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 31 Aug 2007 00:51:01 +0000 Subject: add two new functions pa_make_path_absolute()/pa_getcwd() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1737 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core-util.c | 33 +++++++++++++++++++++++++++++++++ src/pulsecore/core-util.h | 3 +++ 2 files changed, 36 insertions(+) diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 2c5a32e9..82c0ea3c 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -1208,3 +1208,36 @@ char *pa_truncate_utf8(char *c, size_t l) { return c; } + +char *pa_getcwd(void) { + size_t l = 128; + + for (;;) { + char *p = pa_xnew(char, l); + if (getcwd(p, l)) + return p; + + if (errno != ERANGE) + return NULL; + + pa_xfree(p); + l *= 2; + } +} + +char *pa_make_path_absolute(const char *p) { + char *r; + char *cwd; + + pa_assert(p); + + if (p[0] == '/') + return pa_xstrdup(p); + + if (!(cwd = pa_getcwd())) + return pa_xstrdup(p); + + r = pa_sprintf_malloc("%s/%s", cwd, p); + pa_xfree(cwd); + return r; +} diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index ea571e70..54749280 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -97,6 +97,9 @@ int pa_snprintf(char *str, size_t size, const char *format, ...); char *pa_truncate_utf8(char *c, size_t l); +char *pa_getcwd(void); +char *pa_make_path_absolute(const char *p); + static inline int pa_is_power_of_two(unsigned n) { return !(n & (n - 1)); } -- cgit From a1322269d5e1ea76eae07cd62ea0b70ff384e9c5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 31 Aug 2007 00:51:26 +0000 Subject: minor reformatting git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1738 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/cli-command.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c index 7440e744..0cd1f483 100644 --- a/src/pulsecore/cli-command.c +++ b/src/pulsecore/cli-command.c @@ -1131,9 +1131,9 @@ int pa_cli_command_execute_line_stateful(pa_core *c, const char *s, pa_strbuf *b if (l == sizeof(META_INCLUDE)-1 && !strncmp(cs, META_INCLUDE, l)) { const char *filename = cs+l+strspn(cs+l, whitespace); - if (pa_cli_command_execute_file(c, filename, buf, fail) < 0) - if (*fail) return -1; + if (*fail) + return -1; } else if (l == sizeof(META_IFEXISTS)-1 && !strncmp(cs, META_IFEXISTS, l)) { if (!ifstate) { pa_strbuf_printf(buf, "Meta command %s is not valid in this context\n", cs); -- cgit From 02811bfc0fff316dada8c543326720dbabe0904a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 31 Aug 2007 00:52:42 +0000 Subject: make sure that we make include paths absolute before calling chdir() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1739 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/cmdline.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/daemon/cmdline.c b/src/daemon/cmdline.c index 705115ec..384dde36 100644 --- a/src/daemon/cmdline.c +++ b/src/daemon/cmdline.c @@ -199,9 +199,12 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d break; case ARG_FILE: - case 'F': - pa_strbuf_printf(buf, ".include %s\n", optarg); + case 'F': { + char *p; + pa_strbuf_printf(buf, ".include %s\n", p = pa_make_path_absolute(optarg)); + pa_xfree(p); break; + } case 'C': pa_strbuf_puts(buf, "load-module module-cli exit_on_eof=1\n"); -- cgit From 718b1d2a56e7010c1454bc480aa52b0e4717fe29 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 31 Aug 2007 10:45:16 +0000 Subject: add pa_channel_position_to_pretty_string() for usage in pavucontrol/pavumeter git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1740 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/channelmap.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 3 deletions(-) diff --git a/src/pulse/channelmap.c b/src/pulse/channelmap.c index 5f1fa95f..c53626fd 100644 --- a/src/pulse/channelmap.c +++ b/src/pulse/channelmap.c @@ -90,13 +90,76 @@ const char *const table[] = { [PA_CHANNEL_POSITION_TOP_CENTER] = "top-center", + [PA_CHANNEL_POSITION_TOP_FRONT_CENTER] = "top-front-center", [PA_CHANNEL_POSITION_TOP_FRONT_LEFT] = "top-front-left", [PA_CHANNEL_POSITION_TOP_FRONT_RIGHT] = "top-front-right", - [PA_CHANNEL_POSITION_TOP_FRONT_CENTER] = "top-front-center", + [PA_CHANNEL_POSITION_TOP_REAR_CENTER] = "top-rear-center", [PA_CHANNEL_POSITION_TOP_REAR_LEFT] = "top-rear-left", - [PA_CHANNEL_POSITION_TOP_REAR_RIGHT] = "top-rear-right", - [PA_CHANNEL_POSITION_TOP_REAR_CENTER] = "top-rear-center" + [PA_CHANNEL_POSITION_TOP_REAR_RIGHT] = "top-rear-right" +}; + +const char *const pretty_table[] = { + [PA_CHANNEL_POSITION_MONO] = "Mono", + + [PA_CHANNEL_POSITION_FRONT_CENTER] = "Front Center", + [PA_CHANNEL_POSITION_FRONT_LEFT] = "Front Left", + [PA_CHANNEL_POSITION_FRONT_RIGHT] = "Front Right", + + [PA_CHANNEL_POSITION_REAR_CENTER] = "Rear Center", + [PA_CHANNEL_POSITION_REAR_LEFT] = "Rear Left", + [PA_CHANNEL_POSITION_REAR_RIGHT] = "Rear Right", + + [PA_CHANNEL_POSITION_LFE] = "Low Frequency Emmiter", + + [PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = "Front Left-of-center", + [PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = "Front Right-of-center", + + [PA_CHANNEL_POSITION_SIDE_LEFT] = "Side Left", + [PA_CHANNEL_POSITION_SIDE_RIGHT] = "Side Right", + + [PA_CHANNEL_POSITION_AUX0] = "Auxiliary 0", + [PA_CHANNEL_POSITION_AUX1] = "Auxiliary 1", + [PA_CHANNEL_POSITION_AUX2] = "Auxiliary 2", + [PA_CHANNEL_POSITION_AUX3] = "Auxiliary 3", + [PA_CHANNEL_POSITION_AUX4] = "Auxiliary 4", + [PA_CHANNEL_POSITION_AUX5] = "Auxiliary 5", + [PA_CHANNEL_POSITION_AUX6] = "Auxiliary 6", + [PA_CHANNEL_POSITION_AUX7] = "Auxiliary 7", + [PA_CHANNEL_POSITION_AUX8] = "Auxiliary 8", + [PA_CHANNEL_POSITION_AUX9] = "Auxiliary 9", + [PA_CHANNEL_POSITION_AUX10] = "Auxiliary 10", + [PA_CHANNEL_POSITION_AUX11] = "Auxiliary 11", + [PA_CHANNEL_POSITION_AUX12] = "Auxiliary 12", + [PA_CHANNEL_POSITION_AUX13] = "Auxiliary 13", + [PA_CHANNEL_POSITION_AUX14] = "Auxiliary 14", + [PA_CHANNEL_POSITION_AUX15] = "Auxiliary 15", + [PA_CHANNEL_POSITION_AUX16] = "Auxiliary 16", + [PA_CHANNEL_POSITION_AUX17] = "Auxiliary 17", + [PA_CHANNEL_POSITION_AUX18] = "Auxiliary 18", + [PA_CHANNEL_POSITION_AUX19] = "Auxiliary 19", + [PA_CHANNEL_POSITION_AUX20] = "Auxiliary 20", + [PA_CHANNEL_POSITION_AUX21] = "Auxiliary 21", + [PA_CHANNEL_POSITION_AUX22] = "Auxiliary 22", + [PA_CHANNEL_POSITION_AUX23] = "Auxiliary 23", + [PA_CHANNEL_POSITION_AUX24] = "Auxiliary 24", + [PA_CHANNEL_POSITION_AUX25] = "Auxiliary 25", + [PA_CHANNEL_POSITION_AUX26] = "Auxiliary 26", + [PA_CHANNEL_POSITION_AUX27] = "Auxiliary 27", + [PA_CHANNEL_POSITION_AUX28] = "Auxiliary 28", + [PA_CHANNEL_POSITION_AUX29] = "Auxiliary 29", + [PA_CHANNEL_POSITION_AUX30] = "Auxiliary 30", + [PA_CHANNEL_POSITION_AUX31] = "Auxiliary 31", + + [PA_CHANNEL_POSITION_TOP_CENTER] = "Top Center", + + [PA_CHANNEL_POSITION_TOP_FRONT_CENTER] = "Top Front Center", + [PA_CHANNEL_POSITION_TOP_FRONT_LEFT] = "Top Front Left", + [PA_CHANNEL_POSITION_TOP_FRONT_RIGHT] = "Top Front Right", + + [PA_CHANNEL_POSITION_TOP_REAR_CENTER] = "Top Rear Center", + [PA_CHANNEL_POSITION_TOP_REAR_LEFT] = "Top Rear left", + [PA_CHANNEL_POSITION_TOP_REAR_RIGHT] = "Top Rear Right" }; pa_channel_map* pa_channel_map_init(pa_channel_map *m) { @@ -342,6 +405,13 @@ const char* pa_channel_position_to_string(pa_channel_position_t pos) { return table[pos]; } +const char* pa_channel_position_to_pretty_string(pa_channel_position_t pos) { + if (pos < 0 || pos >= PA_CHANNEL_POSITION_MAX) + return NULL; + + return pretty_table[pos]; +} + int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) { unsigned c; -- cgit From 1df817cb0a7dfbcb6588df1b1b08786f825b7138 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 31 Aug 2007 10:45:49 +0000 Subject: add pa_channel_position_to_pretty_string() to header git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1741 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/channelmap.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pulse/channelmap.h b/src/pulse/channelmap.h index f0c8f475..bb8ce952 100644 --- a/src/pulse/channelmap.h +++ b/src/pulse/channelmap.h @@ -174,6 +174,9 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p /** Return a text label for the specified channel position */ const char* pa_channel_position_to_string(pa_channel_position_t pos); +/** Return a human readable text label for the specified channel position. \since 0.9.7 */ +const char* pa_channel_position_to_pretty_string(pa_channel_position_t pos); + /** The maximum length of strings returned by pa_channel_map_snprint() */ #define PA_CHANNEL_MAP_SNPRINT_MAX 336 -- cgit From fe1f55b877909a831f69497b53f2a64b952cd47d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 2 Sep 2007 20:34:57 +0000 Subject: add a couple of macros for memory page alignment git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1742 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/macro.h | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/macro.h b/src/pulsecore/macro.h index efd0f5ed..53e52fd0 100644 --- a/src/pulsecore/macro.h +++ b/src/pulsecore/macro.h @@ -25,15 +25,39 @@ ***/ #include +#include #include +#include +#include + #include +#if defined(PAGE_SIZE) +#define PA_PAGE_SIZE ((size_t) PAGE_SIZE) +#elif defined(PAGESIZE) +#define PA_PAGE_SIZE ((size_t) PAGESIZE) +#elif defined(HAVE_SYSCONF) +#define PA_PAGE_SIZE ((size_t) (sysconf(_SC_PAGE_SIZE))) +#else +/* Let's hope it's like x86. */ +#define PA_PAGE_SIZE ((size_t) 4096) +#endif + static inline size_t pa_align(size_t l) { return (((l + sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*)); } - #define PA_ALIGN(x) (pa_align(x)) +static inline void* pa_page_align_ptr(const void *p) { + return (void*) (((size_t) p) & ~(PA_PAGE_SIZE-1)); +} +#define PA_PAGE_ALIGN_PTR(x) (pa_page_align_ptr(x)) + +static inline size_t pa_page_align(size_t l) { + return l & ~(PA_PAGE_SIZE-1); +} +#define PA_PAGE_ALIGN(x) (pa_page_align(x)) + #define PA_ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0])) #define SA_MAX(a, b) ((a) > (b) ? (a) : (b)) -- cgit From b54e71a96a250783979dd5abe30e4f818f36e062 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 2 Sep 2007 20:35:36 +0000 Subject: make use of new memory page alignment macros, reindent git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1743 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/shm.c | 69 +++++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/src/pulsecore/shm.c b/src/pulsecore/shm.c index 8ef02f61..38187dd2 100644 --- a/src/pulsecore/shm.c +++ b/src/pulsecore/shm.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include "shm.h" @@ -80,7 +81,7 @@ int pa_shm_create_rw(pa_shm *m, size_t size, int shared, mode_t mode) { { int r; - if ((r = posix_memalign(&m->ptr, sysconf(_SC_PAGESIZE), size)) < 0) { + if ((r = posix_memalign(&m->ptr, PA_PAGE_SIZE, size)) < 0) { pa_log("posix_memalign() failed: %s", pa_cstrerror(r)); goto fail; } @@ -140,42 +141,43 @@ void pa_shm_free(pa_shm *m) { assert(m->size > 0); #ifdef MAP_FAILED - assert(m->ptr != MAP_FAILED); + assert(m->ptr != MAP_FAILED); #endif - - if (!m->shared) { + + if (!m->shared) { #ifdef MAP_ANONYMOUS - if (munmap(m->ptr, m->size) < 0) - pa_log("munmap() failed: %s", pa_cstrerror(errno)); + if (munmap(m->ptr, m->size) < 0) + pa_log("munmap() failed: %s", pa_cstrerror(errno)); #elif defined(HAVE_POSIX_MEMALIGN) free(m->ptr); #else pa_xfree(m->ptr); #endif - } else { + } else { #ifdef HAVE_SHM_OPEN - if (munmap(m->ptr, m->size) < 0) - pa_log("munmap() failed: %s", pa_cstrerror(errno)); - - if (m->do_unlink) { - char fn[32]; - - segment_name(fn, sizeof(fn), m->id); - - if (shm_unlink(fn) < 0) - pa_log(" shm_unlink(%s) failed: %s", fn, pa_cstrerror(errno)); - } + if (munmap(m->ptr, m->size) < 0) + pa_log("munmap() failed: %s", pa_cstrerror(errno)); + + if (m->do_unlink) { + char fn[32]; + + segment_name(fn, sizeof(fn), m->id); + + if (shm_unlink(fn) < 0) + pa_log(" shm_unlink(%s) failed: %s", fn, pa_cstrerror(errno)); + } #else - /* We shouldn't be here without shm support */ - assert(0); + /* We shouldn't be here without shm support */ + pa_assert_not_reached(); #endif - } + } memset(m, 0, sizeof(*m)); } void pa_shm_punch(pa_shm *m, size_t offset, size_t size) { void *ptr; + size_t o, ps; assert(m); assert(m->ptr); @@ -183,28 +185,21 @@ void pa_shm_punch(pa_shm *m, size_t offset, size_t size) { assert(offset+size <= m->size); #ifdef MAP_FAILED - assert(m->ptr != MAP_FAILED); + assert(m->ptr != MAP_FAILED); #endif /* You're welcome to implement this as NOOP on systems that don't * support it */ + /* Align this to multiples of the page size */ ptr = (uint8_t*) m->ptr + offset; - -#ifdef __linux__ -{ - /* On Linux ptr must be page aligned */ - long psz = sysconf(_SC_PAGESIZE); - unsigned o; - - o = ((unsigned long) ptr) - ((((unsigned long) ptr)/psz) * psz); - + o = (uint8_t*) ptr - (uint8_t*) PA_PAGE_ALIGN_PTR(ptr); + if (o > 0) { - ptr = (uint8_t*) ptr + (psz - o); - size -= psz - o; + ps = PA_PAGE_SIZE; + ptr = (uint8_t*) ptr + (ps - o); + size -= ps - o; } -} -#endif #ifdef MADV_REMOVE if (madvise(ptr, size, MADV_REMOVE) >= 0) @@ -217,7 +212,9 @@ void pa_shm_punch(pa_shm *m, size_t offset, size_t size) { #endif #ifdef MADV_DONTNEED - madvise(ptr, size, MADV_DONTNEED); + pa_assert_se(madvise(ptr, size, MADV_DONTNEED) == 0); +#elif defined(POSIX_MADV_DONTNEED) + pa_assert_se(posix_madvise(ptr, size, POSIX_MADV_DONTNEED) == 0); #endif } -- cgit From 8cf822a3d9d73f3c273ac64976995b8d3fc1fa47 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 2 Sep 2007 20:36:00 +0000 Subject: make use of new PA_PAGE_SIZE macro git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1744 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-solaris.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/module-solaris.c b/src/modules/module-solaris.c index a50f1ecf..c8ff7705 100644 --- a/src/modules/module-solaris.c +++ b/src/modules/module-solaris.c @@ -602,7 +602,7 @@ int pa__init(pa_core *c, pa_module*m) { u->memchunk.length = 0; /* We use this to get a reasonable chunk size */ - u->page_size = sysconf(_SC_PAGESIZE); + u->page_size = PA_PAGE_SIZE; u->frame_size = pa_frame_size(&ss); u->buffer_size = buffer_size; -- cgit From 2f7b6fead11e781e6071df09ea1c3ae2cadb845c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 2 Sep 2007 20:36:32 +0000 Subject: add new pa_will_need() API for paging in memory git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1745 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core-util.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++ src/pulsecore/core-util.h | 2 ++ 2 files changed, 72 insertions(+) diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 82c0ea3c..d231b658 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -54,6 +54,10 @@ #include #endif +#ifdef HAVE_SYS_MMAN_H +#include +#endif + #ifdef HAVE_PTHREAD #include #endif @@ -1241,3 +1245,69 @@ char *pa_make_path_absolute(const char *p) { pa_xfree(cwd); return r; } + +void *pa_will_need(const void *p, size_t l) { +#ifdef RLIMIT_MEMLOCK + struct rlimit rlim; +#endif + const void *a; + size_t size; + int r; + size_t bs; + + pa_assert(p); + pa_assert(l > 0); + + a = PA_PAGE_ALIGN_PTR(p); + size = (const uint8_t*) p + l - (const uint8_t*) a; + + if ((r = posix_madvise((void*) a, size, POSIX_MADV_WILLNEED)) == 0) { + pa_log_debug("posix_madvise() worked fine!"); + return (void*) p; + } + + /* Most likely the memory was not mmap()ed from a file and thus + * madvise() didn't work, so let's misuse mlock() do page this + * stuff back into RAM. Yeah, let's fuck with the MM! It's so + * inviting, the man page of mlock() tells us: "All pages that + * contain a part of the specified address range are guaranteed to + * be resident in RAM when the call returns successfully." */ + +#ifdef RLIMIT_MEMLOCK + pa_assert_se(getrlimit(RLIMIT_MEMLOCK, &rlim) == 0); + + if (rlim.rlim_cur < PA_PAGE_SIZE) { + pa_log_debug("posix_madvise() failed, resource limits don't allow mlock(), can't page in data: %s", pa_cstrerror(r)); + return (void*) p; + } + + bs = PA_PAGE_ALIGN(rlim.rlim_cur); +#else + bs = PA_PAGE_SIZE*4; +#endif + + pa_log_debug("posix_madvise() failed, trying mlock(): %s", pa_cstrerror(r)); + + while (size > 0 && bs > 0) { + + if (bs > size) + bs = size; + + if (mlock(a, bs) < 0) { + bs = PA_PAGE_ALIGN(bs / 2); + continue; + } + + pa_assert_se(munlock(a, bs) == 0); + + a = (const uint8_t*) a + bs; + size -= bs; + } + + if (bs <= 0) + pa_log_debug("mlock() failed too, giving up: %s", pa_cstrerror(errno)); + else + pa_log_debug("mlock() worked fine!"); + + return (void*) p; +} diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index 54749280..fcafe63d 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -100,6 +100,8 @@ char *pa_truncate_utf8(char *c, size_t l); char *pa_getcwd(void); char *pa_make_path_absolute(const char *p); +void *pa_will_need(const void *p, size_t l); + static inline int pa_is_power_of_two(unsigned n) { return !(n & (n - 1)); } -- cgit From f36ca797160c7eddaacf5cc18d366a74dbee229a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 2 Sep 2007 20:37:17 +0000 Subject: add new API pa_memblock_will_need() and make use of PA_PAGE_SIZE macro git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1746 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/memblock.c | 32 +++++++++++++++++++------------- src/pulsecore/memblock.h | 2 ++ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index 3e2b0064..479c74f7 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -42,6 +43,7 @@ #include #include #include +#include #include "memblock.h" @@ -596,6 +598,20 @@ void pa_memblock_unref_fixed(pa_memblock *b) { pa_memblock_unref(b); } +/* No lock necessary. */ +pa_memblock *pa_memblock_will_need(pa_memblock *b) { + void *p; + + pa_assert(b); + pa_assert(PA_REFCNT_VALUE(b) > 0); + + p = pa_memblock_acquire(b); + pa_will_need(p, b->length); + pa_memblock_release(b); + + return b; +} + /* Self-locked. This function is not multiple-caller safe */ static void memblock_replace_import(pa_memblock *b) { pa_memimport_segment *seg; @@ -628,7 +644,6 @@ static void memblock_replace_import(pa_memblock *b) { } pa_mempool* pa_mempool_new(int shared) { - size_t ps; pa_mempool *p; p = pa_xnew(pa_mempool, 1); @@ -636,18 +651,9 @@ pa_mempool* pa_mempool_new(int shared) { p->mutex = pa_mutex_new(1); p->semaphore = pa_semaphore_new(0); -#ifdef HAVE_SYSCONF - ps = (size_t) sysconf(_SC_PAGESIZE); -#elif defined(PAGE_SIZE) - ps = (size_t) PAGE_SIZE; -#else - ps = 4096; /* Let's hope it's like x86. */ -#endif - - p->block_size = (PA_MEMPOOL_SLOT_SIZE/ps)*ps; - - if (p->block_size < ps) - p->block_size = ps; + p->block_size = PA_PAGE_ALIGN(PA_MEMPOOL_SLOT_SIZE); + if (p->block_size < PA_PAGE_SIZE) + p->block_size = PA_PAGE_SIZE; p->n_blocks = PA_MEMPOOL_SLOTS_MAX; diff --git a/src/pulsecore/memblock.h b/src/pulsecore/memblock.h index 7fa6627e..9bf7d8a5 100644 --- a/src/pulsecore/memblock.h +++ b/src/pulsecore/memblock.h @@ -113,6 +113,8 @@ void pa_memblock_release(pa_memblock *b); size_t pa_memblock_get_length(pa_memblock *b); pa_mempool * pa_memblock_get_pool(pa_memblock *b); +pa_memblock *pa_memblock_will_need(pa_memblock *b); + /* The memory block manager */ pa_mempool* pa_mempool_new(int shared); void pa_mempool_free(pa_mempool *p); -- cgit From 7dbabc47bbfe517cd85e8b25b360413e511b3aec Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 2 Sep 2007 20:37:55 +0000 Subject: add new pa_memchunk_will_need() API, similar to pa_memblock_will_need() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1747 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/memchunk.c | 19 +++++++++++++++++++ src/pulsecore/memchunk.h | 3 +++ 2 files changed, 22 insertions(+) diff --git a/src/pulsecore/memchunk.c b/src/pulsecore/memchunk.c index 20ddb11d..319767f1 100644 --- a/src/pulsecore/memchunk.c +++ b/src/pulsecore/memchunk.c @@ -29,8 +29,11 @@ #include #include #include +#include #include +#include +#include #include "memchunk.h" @@ -72,3 +75,19 @@ pa_memchunk* pa_memchunk_reset(pa_memchunk *c) { return c; } + +pa_memchunk *pa_memchunk_will_need(pa_memchunk *c) { + void *p; + + pa_assert(c); + pa_assert(c->memblock); + + /* A version of pa_memblock_will_need() that works on memchunks + * instead of memblocks */ + + p = (uint8_t*) pa_memblock_acquire(c->memblock) + c->index; + pa_will_need(p, c->length); + pa_memblock_release(c->memblock); + + return c; +} diff --git a/src/pulsecore/memchunk.h b/src/pulsecore/memchunk.h index 10cab2b9..17e5f75f 100644 --- a/src/pulsecore/memchunk.h +++ b/src/pulsecore/memchunk.h @@ -44,4 +44,7 @@ pa_memchunk* pa_memchunk_make_writable(pa_memchunk *c, size_t min); * but sets all members to zero. */ pa_memchunk* pa_memchunk_reset(pa_memchunk *c); +/* Map a memory chunk back into memory if it was swapped out */ +pa_memchunk *pa_memchunk_will_need(pa_memchunk *c); + #endif -- cgit From 3e188b192c6470a0749bed4b01aad99faca4478a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 2 Sep 2007 20:38:57 +0000 Subject: make use of pa_memchunk_will_need() before handing sample cache audio to the RT threads git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1748 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/play-memchunk.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pulsecore/play-memchunk.c b/src/pulsecore/play-memchunk.c index 3ebbc14c..f60f706e 100644 --- a/src/pulsecore/play-memchunk.c +++ b/src/pulsecore/play-memchunk.c @@ -155,6 +155,8 @@ int pa_play_memchunk( if (volume && pa_cvolume_is_muted(volume)) return 0; + pa_memchunk_will_need(chunk); + u = pa_msgobject_new(memchunk_stream); u->parent.parent.free = memchunk_stream_free; u->parent.process_msg = memchunk_stream_process_msg; -- cgit From ca059ab9ef18918dd486e899482327ce157eb629 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 2 Sep 2007 20:39:45 +0000 Subject: Don't set RLIMIT_MEMBLOCK to 0 on startup. Retain 4 pages git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1749 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/daemon-conf.c | 4 ++-- src/daemon/daemon.conf.in | 4 ++-- src/daemon/main.c | 5 ++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c index e3ad8b3f..7b503f83 100644 --- a/src/daemon/daemon-conf.c +++ b/src/daemon/daemon-conf.c @@ -86,13 +86,13 @@ static const pa_daemon_conf default_conf = { .rlimit_core = { .value = 0, .is_set = 0 }, .rlimit_data = { .value = 0, .is_set = 0 }, .rlimit_fsize = { .value = 0, .is_set = 0 }, - .rlimit_nofile = { .value = 200, .is_set = 1 }, + .rlimit_nofile = { .value = 256, .is_set = 1 }, .rlimit_stack = { .value = 0, .is_set = 0 } #ifdef RLIMIT_NPROC , .rlimit_nproc = { .value = 0, .is_set = 0 } #endif #ifdef RLIMIT_MEMLOCK - , .rlimit_memlock = { .value = 0, .is_set = 1 } + , .rlimit_memlock = { .value = 16384, .is_set = 1 } #endif #endif }; diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in index 9bd5cba6..2132bf3d 100644 --- a/src/daemon/daemon.conf.in +++ b/src/daemon/daemon.conf.in @@ -92,10 +92,10 @@ ; rlimit-core = -1 ; rlimit-data = -1 ; rlimit-fsize = -1 -; rlimit-nofile = 200 +; rlimit-nofile = 256 ; rlimit-stack = -1 ; rlimit-nproc = -1 -; rlimit-memlock = 25 +; rlimit-memlock = 16384 ## Disable shared memory data transfer ; disable-shm = 0 diff --git a/src/daemon/main.c b/src/daemon/main.c index b927b2af..639d6dc9 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -80,6 +80,7 @@ #include #include #include +#include #include "cmdline.h" #include "cpulimit.h" @@ -584,8 +585,10 @@ int main(int argc, char *argv[]) { signal(SIGPIPE, SIG_IGN); #endif + pa_log_info("Page size is %lu bytes", (unsigned long) PA_PAGE_SIZE); + if (pa_rtclock_hrtimer()) - pa_log_debug("Fresh high-resolution timers available! Bon appetit!"); + pa_log_info("Fresh high-resolution timers available! Bon appetit!"); else pa_log_info("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"); -- cgit From 68981e5e97684875f5e3b796d15b90b0f948577d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 2 Sep 2007 20:51:25 +0000 Subject: fix build for dbus < 1.1.1, re #126, patch from Marc-Andre Lureau git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1750 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/dbus-util.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/modules/dbus-util.c b/src/modules/dbus-util.c index 24936faa..0a794fe1 100644 --- a/src/modules/dbus-util.c +++ b/src/modules/dbus-util.c @@ -96,7 +96,11 @@ static void handle_io_event(PA_GCC_UNUSED pa_mainloop_api *ea, pa_io_event *e, i unsigned int flags = 0; DBusWatch *watch = userdata; +#if (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR == 1 && DBUS_VERSION_MICRO >= 1) || (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MAJOR > 1) || (DBUS_VERSION_MAJOR > 1) pa_assert(fd == dbus_watch_get_unix_fd(watch)); +#else + pa_assert(fd == dbus_watch_get_fd(watch)); +#endif if (!dbus_watch_get_enabled(watch)) { pa_log_warn("Asked to handle disabled watch: %p %i", (void*) watch, fd); @@ -137,7 +141,13 @@ static dbus_bool_t add_watch(DBusWatch *watch, void *data) { pa_assert(watch); pa_assert(c); - ev = c->mainloop->io_new(c->mainloop, dbus_watch_get_unix_fd(watch), get_watch_flags(watch), handle_io_event, watch); + ev = c->mainloop->io_new(c->mainloop, +#if (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR == 1 && DBUS_VERSION_MICRO >= 1) || (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MAJOR > 1) || (DBUS_VERSION_MAJOR > 1) + dbus_watch_get_unix_fd(watch), +#else + dbus_watch_get_fd(watch), +#endif + get_watch_flags(watch), handle_io_event, watch); dbus_watch_set_data(watch, ev, NULL); -- cgit From 011dfa509bea2a799338f48018ebde09abcd7629 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 2 Sep 2007 21:13:17 +0000 Subject: make argument to pa_memchunk_will_need() const git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1751 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/memchunk.c | 4 ++-- src/pulsecore/memchunk.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pulsecore/memchunk.c b/src/pulsecore/memchunk.c index 319767f1..36df9f6b 100644 --- a/src/pulsecore/memchunk.c +++ b/src/pulsecore/memchunk.c @@ -76,7 +76,7 @@ pa_memchunk* pa_memchunk_reset(pa_memchunk *c) { return c; } -pa_memchunk *pa_memchunk_will_need(pa_memchunk *c) { +pa_memchunk *pa_memchunk_will_need(const pa_memchunk *c) { void *p; pa_assert(c); @@ -89,5 +89,5 @@ pa_memchunk *pa_memchunk_will_need(pa_memchunk *c) { pa_will_need(p, c->length); pa_memblock_release(c->memblock); - return c; + return (pa_memchunk*) c; } diff --git a/src/pulsecore/memchunk.h b/src/pulsecore/memchunk.h index 17e5f75f..99498d07 100644 --- a/src/pulsecore/memchunk.h +++ b/src/pulsecore/memchunk.h @@ -45,6 +45,6 @@ pa_memchunk* pa_memchunk_make_writable(pa_memchunk *c, size_t min); pa_memchunk* pa_memchunk_reset(pa_memchunk *c); /* Map a memory chunk back into memory if it was swapped out */ -pa_memchunk *pa_memchunk_will_need(pa_memchunk *c); +pa_memchunk *pa_memchunk_will_need(const pa_memchunk *c); #endif -- cgit From cc8c4998757702aee7c7d154fb7170d6cb7cbfbd Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 2 Sep 2007 21:18:46 +0000 Subject: fix dbus version check for dbus_watch_get_unix_fd() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1752 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/dbus-util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/dbus-util.c b/src/modules/dbus-util.c index 0a794fe1..360f7827 100644 --- a/src/modules/dbus-util.c +++ b/src/modules/dbus-util.c @@ -96,7 +96,7 @@ static void handle_io_event(PA_GCC_UNUSED pa_mainloop_api *ea, pa_io_event *e, i unsigned int flags = 0; DBusWatch *watch = userdata; -#if (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR == 1 && DBUS_VERSION_MICRO >= 1) || (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MAJOR > 1) || (DBUS_VERSION_MAJOR > 1) +#if (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR == 1 && DBUS_VERSION_MICRO >= 1) || (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR > 1) || (DBUS_VERSION_MAJOR > 1) pa_assert(fd == dbus_watch_get_unix_fd(watch)); #else pa_assert(fd == dbus_watch_get_fd(watch)); -- cgit From 2e8244b4bcaae3f7b1cb45ceb503d3b13f539d25 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 2 Sep 2007 21:20:57 +0000 Subject: Allow compilation without libsamplerate; based on patch from Marc-Andre Lureau; re #125 git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1753 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core-util.c | 2 ++ src/pulsecore/resampler.c | 15 ++++++++++++++- src/pulsecore/resampler.h | 12 +++++------- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index d231b658..67d33e7c 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -78,7 +78,9 @@ #include #endif +#ifdef HAVE_LIBSAMPLERATE #include +#endif #include #include diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index d98d482d..3e14c0e7 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -27,7 +27,9 @@ #include +#if HAVE_LIBSAMPLERATE #include +#endif #include #include @@ -70,9 +72,11 @@ struct pa_resampler { unsigned i_counter; } trivial; +#ifdef HAVE_LIBSAMPLERATE struct { /* data specific to libsamplerate */ SRC_STATE *state; } src; +#endif struct { /* data specific to speex */ SpeexResamplerState* state; @@ -84,7 +88,6 @@ struct pa_resampler { } ffmpeg; }; -static int libsamplerate_init(pa_resampler*r); static int trivial_init(pa_resampler*r); static int speex_init(pa_resampler*r); static int ffmpeg_init(pa_resampler*r); @@ -92,11 +95,19 @@ static int ffmpeg_init(pa_resampler*r); static void calc_map_table(pa_resampler *r); static int (* const init_table[])(pa_resampler*r) = { +#ifdef HAVE_LIBSAMPLERATE [PA_RESAMPLER_SRC_SINC_BEST_QUALITY] = libsamplerate_init, [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY] = libsamplerate_init, [PA_RESAMPLER_SRC_SINC_FASTEST] = libsamplerate_init, [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD] = libsamplerate_init, [PA_RESAMPLER_SRC_LINEAR] = libsamplerate_init, +#else + [PA_RESAMPLER_SRC_SINC_BEST_QUALITY] = NULL, + [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY] = NULL, + [PA_RESAMPLER_SRC_SINC_FASTEST] = NULL, + [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD] = NULL, + [PA_RESAMPLER_SRC_LINEAR] = NULL, +#endif [PA_RESAMPLER_TRIVIAL] = trivial_init, [PA_RESAMPLER_SPEEX_FLOAT_BASE+0] = speex_init, [PA_RESAMPLER_SPEEX_FLOAT_BASE+1] = speex_init, @@ -622,6 +633,7 @@ void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) /*** libsamplerate based implementation ***/ +#ifdef HAVE_LIBSAMPLERATE static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) { SRC_DATA data; @@ -677,6 +689,7 @@ static int libsamplerate_init(pa_resampler *r) { return 0; } +#endif /*** speex based implementation ***/ diff --git a/src/pulsecore/resampler.h b/src/pulsecore/resampler.h index 2a943e3e..711f9c62 100644 --- a/src/pulsecore/resampler.h +++ b/src/pulsecore/resampler.h @@ -24,8 +24,6 @@ USA. ***/ -#include - #include #include #include @@ -35,11 +33,11 @@ typedef struct pa_resampler pa_resampler; typedef enum pa_resample_method { PA_RESAMPLER_INVALID = -1, - PA_RESAMPLER_SRC_SINC_BEST_QUALITY = SRC_SINC_BEST_QUALITY, - PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY = SRC_SINC_MEDIUM_QUALITY, - PA_RESAMPLER_SRC_SINC_FASTEST = SRC_SINC_FASTEST, - PA_RESAMPLER_SRC_ZERO_ORDER_HOLD = SRC_ZERO_ORDER_HOLD, - PA_RESAMPLER_SRC_LINEAR = SRC_LINEAR, + PA_RESAMPLER_SRC_SINC_BEST_QUALITY = 0, /* = SRC_SINC_BEST_QUALITY */ + PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY = 1, /* = SRC_SINC_MEDIUM_QUALITY */ + PA_RESAMPLER_SRC_SINC_FASTEST = 2, /* = SRC_SINC_FASTEST */ + PA_RESAMPLER_SRC_ZERO_ORDER_HOLD = 3, /* = SRC_ZERO_ORDER_HOLD */ + PA_RESAMPLER_SRC_LINEAR = 4, /* = SRC_LINEAR */ PA_RESAMPLER_TRIVIAL, PA_RESAMPLER_SPEEX_FLOAT_BASE, PA_RESAMPLER_SPEEX_FLOAT_MAX = PA_RESAMPLER_SPEEX_FLOAT_BASE + 10, -- cgit From b6bfaa9249619cb4b71f05aa583c3cc34bbc6b36 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 2 Sep 2007 21:22:30 +0000 Subject: add missing configure.ac part of the libsamplerate patch from r1753, re #125 git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1754 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 718ebbff..e0453aab 100644 --- a/configure.ac +++ b/configure.ac @@ -323,12 +323,6 @@ fi PKG_PROG_PKG_CONFIG -#### Sample rate conversion #### - -PKG_CHECK_MODULES(LIBSAMPLERATE, [ samplerate >= 0.1.0 ]) -AC_SUBST(LIBSAMPLERATE_CFLAGS) -AC_SUBST(LIBSAMPLERATE_LIBS) - #### Sound file #### PKG_CHECK_MODULES(LIBSNDFILE, [ sndfile >= 1.0.10 ]) @@ -346,6 +340,37 @@ if test "x$os_is_win32" != "x1" ; then LIBS="$LIBS -latomic_ops" fi +#### Libsamplerate support (optional) #### + +AC_ARG_ENABLE([samplerate], + AC_HELP_STRING([--disable-samplerate], [Disable optional libsamplerate support]), + [ + case "${enableval}" in + yes) samplerate=yes ;; + no) samplerate=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-samplerate) ;; + esac + ], + [samplerate=auto]) + +if test "x${samplerate}" != xno ; then + PKG_CHECK_MODULES(LIBSAMPLERATE, [ samplerate >= 0.1.0 ], + HAVE_LIBSAMPLERATE=1, + [ + HAVE_LIBSAMPLERATE=0 + if test "x$samplerate" = xyes ; then + AC_MSG_ERROR([*** Libsamplerate not found]) + fi + ]) +else + HAVE_LIBSAMPLERATE=0 +fi + +AC_SUBST(LIBSAMPLERATE_CFLAGS) +AC_SUBST(LIBSAMPLERATE_LIBS) +AC_SUBST(HAVE_LIBSAMPLERATE) +AM_CONDITIONAL([HAVE_LIBSAMPLERATE], [test "x$HAVE_LIBSAMPLERATE" = x1]) + #### OSS support (optional) #### AC_ARG_ENABLE([oss], @@ -844,6 +869,11 @@ if test "x${LIBWRAP_LIBS}" != x ; then ENABLE_TCPWRAP=yes fi +ENABLE_LIBSAMPLERATE=no +if test "x${HAVE_LIBSAMPLERATE}" = "x1" ; then + ENABLE_LIBSAMPLERATE=yes +fi + echo " ---{ $PACKAGE_NAME $VERSION }--- @@ -865,6 +895,7 @@ echo " Enable LIRC: ${ENABLE_LIRC} Enable HAL: ${ENABLE_HAL} Enable TCP Wrappers: ${ENABLE_TCPWRAP} + Enable libsamplerate: ${ENABLE_LIBSAMPLERATE} System User: ${PA_SYSTEM_USER} System Group: ${PA_SYSTEM_GROUP} Realtime Group: ${PA_REALTIME_GROUP} -- cgit From b2c4779db493f9a1a52ba8147cb71c511d16042e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 2 Sep 2007 22:08:30 +0000 Subject: make libpulse-core a noinst lib, because it does not have yet a stable API and won't get one anytime. Also, don't install its header files git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1755 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 079610ab..18e06ce6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -574,8 +574,8 @@ libffmpeg_resampler_la_SOURCES = pulsecore/ffmpeg/resample2.c # Daemon core library # ################################### - -pulsecoreinclude_HEADERS = \ +#pulsecoreinclude_HEADERS = +noinst_HEADERS = \ pulsecore/autoload.h \ pulsecore/atomic.h \ pulsecore/cli-command.h \ @@ -627,7 +627,7 @@ pulsecoreinclude_HEADERS = \ pulsecore/semaphore.h \ pulsecore/once.h -lib_LTLIBRARIES += libpulsecore.la +noinst_LTLIBRARIES += libpulsecore.la # Some public stuff is used even in the core libpulsecore_la_SOURCES = \ @@ -721,7 +721,8 @@ libpulsecore_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSNDF # Plug-in support libraries # ################################### -pulsecoreinclude_HEADERS += \ +#pulsecoreinclude_HEADERS += +noinst_HEADERS += \ pulsecore/socket-util.h \ pulsecore/iochannel.h \ pulsecore/socket-server.h \ @@ -781,7 +782,8 @@ modlibexec_LTLIBRARIES += \ endif if HAVE_X11 -pulsecoreinclude_HEADERS += \ +#pulsecoreinclude_HEADERS += +noinst_HEADERS += \ pulsecore/x11wrap.h \ pulsecore/x11prop.h @@ -791,7 +793,8 @@ modlibexec_LTLIBRARIES += \ endif if HAVE_AVAHI -pulsecoreinclude_HEADERS += \ +#pulsecoreinclude_HEADERS += +noinst_HEADERS += \ pulsecore/avahi-wrap.h modlibexec_LTLIBRARIES += \ @@ -1312,15 +1315,15 @@ module_suspend_on_idle_la_LIBADD = $(AM_LIBADD) libpulsecore.la module_suspend_on_idle_la_CFLAGS = $(AM_CFLAGS) # RTP modules -module_rtp_send_la_SOURCES = modules/rtp/module-rtp-send.c -module_rtp_send_la_LDFLAGS = -module -avoid-version -module_rtp_send_la_LIBADD = $(AM_LIBADD) libpulsecore.la librtp.la -module_rtp_send_la_CFLAGS = $(AM_CFLAGS) - -module_rtp_recv_la_SOURCES = modules/rtp/module-rtp-recv.c -module_rtp_recv_la_LDFLAGS = -module -avoid-version -module_rtp_recv_la_LIBADD = $(AM_LIBADD) libpulsecore.la librtp.la -module_rtp_recv_la_CFLAGS = $(AM_CFLAGS) +#module_rtp_send_la_SOURCES = modules/rtp/module-rtp-send.c +#module_rtp_send_la_LDFLAGS = -module -avoid-version +#module_rtp_send_la_LIBADD = $(AM_LIBADD) libpulsecore.la librtp.la +#module_rtp_send_la_CFLAGS = $(AM_CFLAGS) + +#module_rtp_recv_la_SOURCES = modules/rtp/module-rtp-recv.c +#module_rtp_recv_la_LDFLAGS = -module -avoid-version +#module_rtp_recv_la_LIBADD = $(AM_LIBADD) libpulsecore.la librtp.la +#module_rtp_recv_la_CFLAGS = $(AM_CFLAGS) # JACK -- cgit From 5bc1221d40553f4c0e19cc7dfd606ff164d49cef Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 3 Sep 2007 20:39:55 +0000 Subject: actually define HAVE_LIBSAMPLERATE with AC_DEFINE git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1756 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/configure.ac b/configure.ac index e0453aab..34858087 100644 --- a/configure.ac +++ b/configure.ac @@ -366,6 +366,10 @@ else HAVE_LIBSAMPLERATE=0 fi +if test "x${HAVE_LIBSAMPLERATE}" = x1 ; then + AC_DEFINE([HAVE_LIBSAMPLERATE], 1, [Have libsamplerate?]) +fi + AC_SUBST(LIBSAMPLERATE_CFLAGS) AC_SUBST(LIBSAMPLERATE_LIBS) AC_SUBST(HAVE_LIBSAMPLERATE) -- cgit From c9a0df361794750cc075c3f0bf7835028db64ead Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 3 Sep 2007 20:50:03 +0000 Subject: add new API function pa_resample_method_supported() which tests whether a resampling method is supported. Fix building with libsamplerate enabled git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1757 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/resampler.c | 21 +++++++++++++++++++++ src/pulsecore/resampler.h | 3 +++ 2 files changed, 24 insertions(+) diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index 3e14c0e7..7493eef0 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -91,6 +91,9 @@ struct pa_resampler { static int trivial_init(pa_resampler*r); static int speex_init(pa_resampler*r); static int ffmpeg_init(pa_resampler*r); +#ifdef HAVE_LIBSAMPLERATE +static int libsamplerate_init(pa_resampler*r); +#endif static void calc_map_table(pa_resampler *r); @@ -166,6 +169,11 @@ pa_resampler* pa_resampler_new( /* Fix method */ + if (!pa_resample_method_supported(resample_method)) { + pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(resample_method)); + resample_method = PA_RESAMPLER_AUTO; + } + if (resample_method == PA_RESAMPLER_FFMPEG && variable_rate) { pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'." ); resample_method = PA_RESAMPLER_AUTO; @@ -360,6 +368,19 @@ const char *pa_resample_method_to_string(pa_resample_method_t m) { return resample_methods[m]; } +int pa_resample_method_supported(pa_resample_method_t m) { + + if (m < 0 || m >= PA_RESAMPLER_MAX) + return 0; + +#ifndef HAVE_LIBSAMPLERATE + if (m <= PA_RESAMPLER_SRC_LINEAR) + return 0; +#endif + + return 1; +} + pa_resample_method_t pa_parse_resample_method(const char *string) { pa_resample_method_t m; diff --git a/src/pulsecore/resampler.h b/src/pulsecore/resampler.h index 711f9c62..fed4d897 100644 --- a/src/pulsecore/resampler.h +++ b/src/pulsecore/resampler.h @@ -80,4 +80,7 @@ pa_resample_method_t pa_parse_resample_method(const char *string); /* return a human readable string for the specified resampling method. Inverse of pa_parse_resample_method() */ const char *pa_resample_method_to_string(pa_resample_method_t m); +/* Return 1 when the specified resampling method is supported */ +int pa_resample_method_supported(pa_resample_method_t m); + #endif -- cgit From 104feb0aac38734b59973954ff62475869a05582 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 3 Sep 2007 20:50:55 +0000 Subject: only list supported resampling methods when --dump-resample-methods is executed git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1758 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/daemon/main.c b/src/daemon/main.c index 639d6dc9..77487dc2 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -365,8 +365,7 @@ int main(int argc, char *argv[]) { LTDL_SET_PRELOADED_SYMBOLS(); - r = lt_dlinit(); - assert(r == 0); + pa_assert_se(lt_dlinit() == 0); #ifdef OS_IS_WIN32 { @@ -424,7 +423,8 @@ int main(int argc, char *argv[]) { int i; for (i = 0; i < PA_RESAMPLER_MAX; i++) - printf("%s\n", pa_resample_method_to_string(i)); + if (pa_resample_method_supported(i)) + printf("%s\n", pa_resample_method_to_string(i)); goto finish; } -- cgit From 1d3e70c7d3b9cbf45177c84989a68b7a2992386e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 3 Sep 2007 20:51:17 +0000 Subject: header file cleanup git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1759 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-volume-restore.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/modules/module-volume-restore.c b/src/modules/module-volume-restore.c index 8c916c39..77e6174f 100644 --- a/src/modules/module-volume-restore.c +++ b/src/modules/module-volume-restore.c @@ -34,6 +34,7 @@ #include #include +#include #include #include @@ -43,9 +44,7 @@ #include #include #include -#include #include -#include #include "module-volume-restore-symdef.h" -- cgit From 11bf38042f83369e0077512e0c2aefadc3b47705 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 3 Sep 2007 20:53:07 +0000 Subject: add a new module module-default-device-restore which automatically saves and restores the selected default device. Enable it by default. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1760 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 8 ++++++++ src/daemon/default.pa.in | 3 +++ 2 files changed, 11 insertions(+) diff --git a/src/Makefile.am b/src/Makefile.am index 18e06ce6..a0563ec0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -927,6 +927,7 @@ modlibexec_LTLIBRARIES += \ module-null-sink.la \ module-detect.la \ module-volume-restore.la \ + module-default-device-restore.la \ module-rescue-streams.la \ module-suspend-on-idle.la \ module-http-protocol-tcp.la \ @@ -1080,6 +1081,7 @@ SYMDEF_FILES = \ modules/module-jack-sink-symdef.h \ modules/module-jack-source-symdef.h \ modules/module-volume-restore-symdef.h \ + modules/module-default-device-restore-symdef.h \ modules/module-rescue-streams-symdef.h \ modules/module-suspend-on-idle-symdef.h \ modules/module-hal-detect-symdef.h \ @@ -1302,6 +1304,12 @@ module_volume_restore_la_LDFLAGS = -module -avoid-version module_volume_restore_la_LIBADD = $(AM_LIBADD) libpulsecore.la module_volume_restore_la_CFLAGS = $(AM_CFLAGS) +# Default sink/source restore module +module_default_device_restore_la_SOURCES = modules/module-default-device-restore.c +module_default_device_restore_la_LDFLAGS = -module -avoid-version +module_default_device_restore_la_LIBADD = $(AM_LIBADD) libpulsecore.la +module_default_device_restore_la_CFLAGS = $(AM_CFLAGS) + # Rescue streams module module_rescue_streams_la_SOURCES = modules/module-rescue-streams.c module_rescue_streams_la_LDFLAGS = -module -avoid-version diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in index 6ece607d..fb90aa64 100755 --- a/src/daemon/default.pa.in +++ b/src/daemon/default.pa.in @@ -63,6 +63,9 @@ load-module module-native-protocol-unix ### Automatically restore the volume of playback streams load-module module-volume-restore +### Automatically restore the default sink/source when changed by the user during runtime +load-module module-default-device-restore + ### Automatically move streams to the default sink if the sink they are ### connected to dies, similar for sources load-module module-rescue-streams -- cgit From c02903816450d79e4dbd708bdc7102088dc45a4b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 3 Sep 2007 20:53:44 +0000 Subject: actually add source code of module-default-device-restore git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1761 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-default-device-restore.c | 103 ++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 src/modules/module-default-device-restore.c diff --git a/src/modules/module-default-device-restore.c b/src/modules/module-default-device-restore.c new file mode 100644 index 00000000..71e19e63 --- /dev/null +++ b/src/modules/module-default-device-restore.c @@ -0,0 +1,103 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include "module-default-device-restore-symdef.h" + +PA_MODULE_AUTHOR("Lennart Poettering") +PA_MODULE_DESCRIPTION("Automatically restore the default sink and source") +PA_MODULE_VERSION(PACKAGE_VERSION) + +#define DEFAULT_SINK_FILE "default-sink" +#define DEFAULT_SOURCE_FILE "default-source" + +int pa__init(pa_module *m) { + FILE *f; + + /* We never overwrite manually configured settings */ + + if (m->core->default_sink_name) + pa_log_info("Manually configured default sink, not overwriting."); + else if ((f = pa_open_config_file(NULL, DEFAULT_SINK_FILE, NULL, NULL, "r"))) { + char ln[256] = ""; + + fgets(ln, sizeof(ln)-1, f); + pa_strip_nl(ln); + fclose(f); + + if (!ln[0]) + pa_log_debug("No previous default sink setting, ignoring."); + else if (pa_namereg_get(m->core, ln, PA_NAMEREG_SINK, 1)) { + pa_namereg_set_default(m->core, ln, PA_NAMEREG_SINK); + pa_log_debug("Restored default sink '%s'.", ln); + } else + pa_log_info("Saved default sink '%s' not existant, not restoring default sink setting.", ln); + } + + if (m->core->default_source_name) + pa_log_info("Manually configured default source, not overwriting."); + else if ((f = pa_open_config_file(NULL, DEFAULT_SOURCE_FILE, NULL, NULL, "r"))) { + char ln[256] = ""; + + fgets(ln, sizeof(ln)-1, f); + pa_strip_nl(ln); + fclose(f); + + if (!ln[0]) + pa_log_debug("No previous default source setting, ignoring."); + else if (pa_namereg_get(m->core, ln, PA_NAMEREG_SOURCE, 1)) { + pa_namereg_set_default(m->core, ln, PA_NAMEREG_SOURCE); + pa_log_debug("Restored default source '%s'.", ln); + } else + pa_log_info("Saved default source '%s' not existant, not restoring default source setting.", ln); + } + + return 0; +} + +void pa__done(pa_module*m) { + FILE *f; + + if ((f = pa_open_config_file(NULL, DEFAULT_SINK_FILE, NULL, NULL, "w"))) { + const char *n = pa_namereg_get_default_sink_name(m->core); + fprintf(f, "%s\n", n ? n : ""); + fclose(f); + } + + if ((f = pa_open_config_file(NULL, DEFAULT_SOURCE_FILE, NULL, NULL, "w"))) { + const char *n = pa_namereg_get_default_source_name(m->core); + fprintf(f, "%s\n", n ? n : ""); + fclose(f); + } +} + + + -- cgit From 65ac0ea99aa340aa1afd38277186443c5c5eb4eb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 4 Sep 2007 01:37:34 +0000 Subject: When in PA_STREAM_AUTO_TIMING_UPDATE mode, delay completion of initialization until we have the first timing data git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1762 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/stream.c | 65 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/src/pulse/stream.c b/src/pulse/stream.c index f18a5dde..07a041aa 100644 --- a/src/pulse/stream.c +++ b/src/pulse/stream.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "internal.h" @@ -218,6 +219,13 @@ void pa_stream_set_state(pa_stream *s, pa_stream_state_t st) { s->channel_valid = 0; s->context = NULL; + + s->read_callback = NULL; + s->write_callback = NULL; + s->state_callback = NULL; + s->overflow_callback = NULL; + s->underflow_callback = NULL; + s->latency_update_callback = NULL; } pa_stream_unref(s); @@ -321,7 +329,6 @@ void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, PA_GCC } static void request_auto_timing_update(pa_stream *s, int force) { - struct timeval next; assert(s); if (!(s->flags & PA_STREAM_AUTO_TIMING_UPDATE)) @@ -339,9 +346,12 @@ static void request_auto_timing_update(pa_stream *s, int force) { } } - pa_gettimeofday(&next); - pa_timeval_add(&next, LATENCY_IPOL_INTERVAL_USEC); - s->mainloop->time_restart(s->auto_timing_update_event, &next); + if (s->auto_timing_update_event) { + struct timeval next; + pa_gettimeofday(&next); + pa_timeval_add(&next, LATENCY_IPOL_INTERVAL_USEC); + s->mainloop->time_restart(s->auto_timing_update_event, &next); + } } static void invalidate_indexes(pa_stream *s, int r, int w) { @@ -387,6 +397,24 @@ static void auto_timing_update_callback(PA_GCC_UNUSED pa_mainloop_api *m, PA_GCC pa_stream_unref(s); } +static void create_stream_complete(pa_stream *s) { + pa_assert(s); + pa_assert(s->state == PA_STREAM_CREATING); + + pa_stream_set_state(s, PA_STREAM_READY); + + if (s->requested_bytes > 0 && s->write_callback) + s->write_callback(s, s->requested_bytes, s->write_userdata); + + if (s->flags & PA_STREAM_AUTO_TIMING_UPDATE) { + struct timeval tv; + pa_gettimeofday(&tv); + tv.tv_usec += LATENCY_IPOL_INTERVAL_USEC; /* every 100 ms */ + assert(!s->auto_timing_update_event); + s->auto_timing_update_event = s->mainloop->time_new(s->mainloop, &tv, &auto_timing_update_callback, s); + } +} + void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { pa_stream *s = userdata; @@ -450,23 +478,16 @@ void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED s->channel_valid = 1; pa_dynarray_put((s->direction == PA_STREAM_RECORD) ? s->context->record_streams : s->context->playback_streams, s->channel, s); - pa_stream_set_state(s, PA_STREAM_READY); - - if (s->direction != PA_STREAM_UPLOAD && - s->flags & PA_STREAM_AUTO_TIMING_UPDATE) { - struct timeval tv; - - pa_gettimeofday(&tv); - tv.tv_usec += LATENCY_IPOL_INTERVAL_USEC; /* every 100 ms */ - - assert(!s->auto_timing_update_event); - s->auto_timing_update_event = s->mainloop->time_new(s->mainloop, &tv, &auto_timing_update_callback, s); - + if (s->direction != PA_STREAM_UPLOAD && s->flags & PA_STREAM_AUTO_TIMING_UPDATE) { + /* If automatic timing updates are active, we wait for the + * first timing update before going to PA_STREAM_READY + * state */ + s->state = PA_STREAM_READY; request_auto_timing_update(s, 1); - } - - if (s->requested_bytes > 0 && s->ref > 1 && s->write_callback) - s->write_callback(s, s->requested_bytes, s->write_userdata); + s->state = PA_STREAM_CREATING; + + } else + create_stream_complete(s); finish: pa_stream_unref(s); @@ -886,6 +907,10 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command, } } + /* First, let's complete the initialization, if necessary. */ + if (o->stream->state == PA_STREAM_CREATING) + create_stream_complete(o->stream); + if (o->stream->latency_update_callback) o->stream->latency_update_callback(o->stream, o->stream->latency_update_userdata); -- cgit From d1927c7f37ad4481b54469b963bf783c208afb72 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 4 Sep 2007 02:25:44 +0000 Subject: initialize libltdl for multi-thread support git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1763 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/main.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/daemon/main.c b/src/daemon/main.c index 77487dc2..b754ee73 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -81,6 +81,9 @@ #include #include #include +#include +#include +#include #include "cmdline.h" #include "cpulimit.h" @@ -311,6 +314,39 @@ static void set_all_rlimits(const pa_daemon_conf *conf) { } #endif +static pa_mutex *libtool_mutex = NULL; + +static void libtool_lock(void) { + pa_mutex_lock(libtool_mutex); +} + +static void libtool_unlock(void) { + pa_mutex_unlock(libtool_mutex); +} + +PA_STATIC_TLS_DECLARE(libtool_tls, NULL); + +static void libtool_set_error(const char * error) { + pa_tls_set(PA_STATIC_TLS_GET(libtool_tls), (char*) error); +} + +static const char *libtool_get_error(void) { + return pa_tls_get(PA_STATIC_TLS_GET(libtool_tls)); +} + +static void libtool_init(void) { + pa_assert_se(libtool_mutex = pa_mutex_new(1)); + libtool_lock(); /* Hmm, somehow libtool expects this mutex to be initialized in locking state! */ + pa_assert_se(lt_dlmutex_register(libtool_lock, libtool_unlock, libtool_set_error, libtool_get_error) == 0); + pa_assert_se(lt_dlinit() == 0); +} + +static void libtool_done(void) { + pa_assert_se(lt_dlexit() == 0); + pa_mutex_free(libtool_mutex); + libtool_mutex = NULL; +} + int main(int argc, char *argv[]) { pa_core *c = NULL; pa_strbuf *buf = NULL; @@ -365,7 +401,7 @@ int main(int argc, char *argv[]) { LTDL_SET_PRELOADED_SYMBOLS(); - pa_assert_se(lt_dlinit() == 0); + libtool_init(); #ifdef OS_IS_WIN32 { @@ -714,7 +750,7 @@ finish: WSACleanup(); #endif - lt_dlexit(); + libtool_done(); return retval; } -- cgit From 738f7d7cd6e5cd58ea5d6e6bde07b467d761c5f4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 4 Sep 2007 02:31:15 +0000 Subject: drop initial libtool_lock() call since this is a debian-specific borkage git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1764 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/daemon/main.c b/src/daemon/main.c index b754ee73..14097612 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -336,7 +336,6 @@ static const char *libtool_get_error(void) { static void libtool_init(void) { pa_assert_se(libtool_mutex = pa_mutex_new(1)); - libtool_lock(); /* Hmm, somehow libtool expects this mutex to be initialized in locking state! */ pa_assert_se(lt_dlmutex_register(libtool_lock, libtool_unlock, libtool_set_error, libtool_get_error) == 0); pa_assert_se(lt_dlinit() == 0); } -- cgit From ac5f9781ba2f73a67d9c1b0662d61b2496bdffa7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 4 Sep 2007 02:41:15 +0000 Subject: add a few missing files for make dist git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1765 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index a0563ec0..51be9d0a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -562,13 +562,13 @@ libpulsedsp_la_LDFLAGS = -avoid-version noinst_LTLIBRARIES = libspeex-resampler-fixed.la libspeex-resampler-float.la libffmpeg-resampler.la libspeex_resampler_fixed_la_CPPFLAGS = $(AM_CPPFLAGS) -DRANDOM_PREFIX=paspfx -DOUTSIDE_SPEEX -DFIXED_POINT -libspeex_resampler_fixed_la_SOURCES = pulsecore/speex/resample.c pulsecore/speex/speex_resampler.h pulsecore/speex/arch.h pulsecore/speex/fixed_generic.h +libspeex_resampler_fixed_la_SOURCES = pulsecore/speex/resample.c pulsecore/speex/speex_resampler.h pulsecore/speex/arch.h pulsecore/speex/fixed_generic.h pulsecore/speexwrap.h libspeex_resampler_float_la_CPPFLAGS = $(AM_CPPFLAGS) -DRANDOM_PREFIX=paspfl -DOUTSIDE_SPEEX libspeex_resampler_float_la_SOURCES = pulsecore/speex/resample.c pulsecore/speex/speex_resampler.h pulsecore/speex/arch.h libffmpeg_resampler_la_CPPFLAGS = $(AM_CPPFLAGS) -libffmpeg_resampler_la_SOURCES = pulsecore/ffmpeg/resample2.c +libffmpeg_resampler_la_SOURCES = pulsecore/ffmpeg/resample2.c pulsecore/ffmpeg/avcodec.h pulsecore/ffmpeg/dsputil.h ################################### # Daemon core library # -- cgit From 31c04a9047e609764a374ebacbadfaaa470aaa3e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 4 Sep 2007 16:19:07 +0000 Subject: create config.rpath to fix build on fedora git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1766 fefdeb5f-60dc-0310-8127-8f9354f1896f --- bootstrap.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/bootstrap.sh b/bootstrap.sh index b8db16fa..f23acbfe 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -48,6 +48,7 @@ else rm -rf autom4te.cache rm -f config.cache + touch config.rpath test "x$LIBTOOLIZE" = "x" && LIBTOOLIZE=libtoolize "$LIBTOOLIZE" -c --force --ltdl -- cgit From 2dbe137daf8c74feca75ead33d5f8fbc84544af1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 4 Sep 2007 20:00:19 +0000 Subject: if available, use native gcc atomicity builtins git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1767 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/atomic.h | 93 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 84 insertions(+), 9 deletions(-) diff --git a/src/pulsecore/atomic.h b/src/pulsecore/atomic.h index 9a024f91..b5c1ad9e 100644 --- a/src/pulsecore/atomic.h +++ b/src/pulsecore/atomic.h @@ -24,22 +24,95 @@ USA. ***/ -#include - -/* atomic_ops guarantees us that sizeof(AO_t) == sizeof(void*). +/* + * atomic_ops guarantees us that sizeof(AO_t) == sizeof(void*). It is + * not guaranteed however, that sizeof(AO_t) == sizeof(size_t). + * however very likely. + * + * For now we do only full memory barriers. Eventually we might want + * to support more elaborate memory barriers, in which case we will add + * suffixes to the function names. * - * It is not guaranteed however, that sizeof(AO_t) == sizeof(size_t). - * however very likely. */ + * On gcc >= 4.1 we use the builtin atomic functions. otherwise we use + * libatomic_ops + */ + +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) + +/* gcc based implementation */ typedef struct pa_atomic { - volatile AO_t value; + volatile int value; } pa_atomic_t; #define PA_ATOMIC_INIT(v) { .value = (v) } -/* For now we do only full memory barriers. Eventually we might want - * to support more elaborate memory barriers, in which case we will add - * suffixes to the function names */ +static inline int pa_atomic_load(const pa_atomic_t *a) { + __sync_synchronize(); + return a->value; +} + +static inline void pa_atomic_store(pa_atomic_t *a, int i) { + a->value = i; + __sync_synchronize(); +} + +/* Returns the previously set value */ +static inline int pa_atomic_add(pa_atomic_t *a, int i) { + return __sync_fetch_and_add(&a->value, i); +} + +/* Returns the previously set value */ +static inline int pa_atomic_sub(pa_atomic_t *a, int i) { + return __sync_fetch_and_sub(&a->value, i); +} + +/* Returns the previously set value */ +static inline int pa_atomic_inc(pa_atomic_t *a) { + return pa_atomic_add(a, 1); +} + +/* Returns the previously set value */ +static inline int pa_atomic_dec(pa_atomic_t *a) { + return pa_atomic_sub(a, 1); +} + +/* Returns non-zero when the operation was successful. */ +static inline int pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) { + return __sync_bool_compare_and_swap(&a->value, old_i, new_i); +} + +typedef struct pa_atomic_ptr { + volatile long value; +} pa_atomic_ptr_t; + +#define PA_ATOMIC_PTR_INIT(v) { .value = (long) (v) } + +static inline void* pa_atomic_ptr_load(const pa_atomic_ptr_t *a) { + __sync_synchronize(); + return (void*) a->value; +} + +static inline void pa_atomic_ptr_store(pa_atomic_ptr_t *a, void *p) { + a->value = (long) p; + __sync_synchronize(); +} + +static inline int pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* new_p) { + return __sync_bool_compare_and_swap(&a->value, (long) old_p, (long) new_p); +} + +#else + +/* libatomic_ops based implementation */ + +#include + +typedef struct pa_atomic { + volatile AO_t value; +} pa_atomic_t; + +#define PA_ATOMIC_INIT(v) { .value = (v) } static inline int pa_atomic_load(const pa_atomic_t *a) { return (int) AO_load_full((AO_t*) &a->value); @@ -88,3 +161,5 @@ static inline int pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* n } #endif + +#endif -- cgit From 4c31ff9b452eee995e621bd877f321eea974fc7e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 4 Sep 2007 20:01:19 +0000 Subject: fix a couple of compiler warnings git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1768 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 4 ++-- src/modules/module-alsa-source.c | 4 ++-- src/pulsecore/protocol-native.c | 4 ++-- src/pulsecore/rtpoll.c | 3 ++- src/pulsecore/sound-file.c | 2 +- src/tests/interpol-test.c | 2 +- src/utils/paplay.c | 2 +- 7 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 24765a04..c75f195e 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -135,7 +135,7 @@ static int mmap_write(struct userdata *u) { if (err == -EAGAIN) return work_done; - pa_log("snd_pcm_avail_update: %s", snd_strerror(n)); + pa_log("snd_pcm_avail_update: %s", snd_strerror(err)); return -1; } @@ -225,7 +225,7 @@ static int unix_write(struct userdata *u) { int err; if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) { - pa_log("Failed to query DSP status data: %s", snd_strerror(t)); + pa_log("Failed to query DSP status data: %s", snd_strerror(err)); return -1; } diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 0d76cabc..9922668b 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -132,7 +132,7 @@ static int mmap_read(struct userdata *u) { if (err == -EAGAIN) return work_done; - pa_log("snd_pcm_avail_update: %s", snd_strerror(n)); + pa_log("snd_pcm_avail_update: %s", snd_strerror(err)); return -1; } @@ -216,7 +216,7 @@ static int unix_read(struct userdata *u) { pa_memchunk chunk; if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) { - pa_log("Failed to query DSP status data: %s", snd_strerror(t)); + pa_log("Failed to query DSP status data: %s", snd_strerror(err)); return -1; } diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index ea7f43ca..a4983a09 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -439,8 +439,8 @@ static record_stream* record_stream_new( const pa_sample_spec *ss, const pa_channel_map *map, const char *name, - size_t *maxlength, - size_t fragment_size, + uint32_t *maxlength, + uint32_t fragment_size, int corked) { record_stream *s; diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c index 0f09c7d0..e43ec610 100644 --- a/src/pulsecore/rtpoll.c +++ b/src/pulsecore/rtpoll.c @@ -383,7 +383,8 @@ finish: } } - errno = saved_errno; + if (r < 0) + errno = saved_errno; return r; } diff --git a/src/pulsecore/sound-file.c b/src/pulsecore/sound-file.c index 7c8b5970..ef43eef0 100644 --- a/src/pulsecore/sound-file.c +++ b/src/pulsecore/sound-file.c @@ -126,7 +126,7 @@ int pa_sound_file_load( ptr = pa_memblock_acquire(chunk->memblock); if ((readf_function && readf_function(sf, ptr, sfinfo.frames) != sfinfo.frames) || - (!readf_function && sf_read_raw(sf, ptr, l) != l)) { + (!readf_function && sf_read_raw(sf, ptr, l) != (sf_count_t) l)) { pa_log("Premature file end"); goto finish; } diff --git a/src/tests/interpol-test.c b/src/tests/interpol-test.c index 3953043f..85a509d4 100644 --- a/src/tests/interpol-test.c +++ b/src/tests/interpol-test.c @@ -137,7 +137,7 @@ int main(int argc, char *argv[]) { pa_gettimeofday(&now); rtc = pa_timeval_diff(&now, &start); - printf("%i\t%llu\t%llu\t%llu\t%llu\t%u\n", k, rtc, t, rtc-old_rtc, t-old_t, changed); + printf("%i\t%llu\t%llu\t%llu\t%llu\t%u\n", k, (unsigned long long) rtc, (unsigned long long) t, (unsigned long long) (rtc-old_rtc), (unsigned long long) (t-old_t), changed); old_t = t; old_rtc = rtc; } diff --git a/src/utils/paplay.c b/src/utils/paplay.c index 2c779a7a..e7076d2d 100644 --- a/src/utils/paplay.c +++ b/src/utils/paplay.c @@ -123,7 +123,7 @@ static void stream_write_callback(pa_stream *s, size_t length, void *userdata) { else pa_xfree(data); - if (bytes < length) { + if (bytes < (sf_count_t) length) { sf_close(sndfile); sndfile = NULL; pa_operation_unref(pa_stream_drain(s, stream_drain_complete, NULL)); -- cgit From 984ef82e52822abdf6492ed13b016b6b115414b4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 4 Sep 2007 21:24:45 +0000 Subject: detect whether gcc atomic builtins are available git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1769 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 34858087..626a1ce6 100644 --- a/configure.ac +++ b/configure.ac @@ -81,8 +81,8 @@ fi # GCC flags test_gcc_flag() { - AC_LANG_CONFTEST([int main() {}]) - $CC -c conftest.c $CFLAGS $@ > /dev/null 2> /dev/null + AC_LANG_CONFTEST([int main(int argc, char*argv[]) {}]) + $CC -c conftest.c $CFLAGS -o conftest.o > /dev/null 2> /dev/null ret=$? rm -f conftest.o return $ret @@ -106,6 +106,18 @@ if test "x$GCC" = "xyes" ; then done fi +AC_MSG_CHECKING([whether $CC knows __sync_bool_compare_and_swap()]) +AC_LANG_CONFTEST([int main() { int a = 4; __sync_bool_compare_and_swap(&a, 4, 5); }]) +$CC conftest.c $CFLAGS -o conftest > /dev/null 2> /dev/null +ret=$? +rm -f conftest.o conftest +if test $ret -eq 0 ; then + AC_DEFINE([HAVE_ATOMIC_BUILTINS], 1, [Have __sync_bool_compare_and_swap() and friends.]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + #### libtool stuff #### AC_LTDL_ENABLE_INSTALL -- cgit From a4757a1dd90db5d6f1115205b452a232e4af58d3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 4 Sep 2007 21:25:26 +0000 Subject: add native amd64 atomic int implementation git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1770 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/atomic.h | 87 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 4 deletions(-) diff --git a/src/pulsecore/atomic.h b/src/pulsecore/atomic.h index b5c1ad9e..6e33c993 100644 --- a/src/pulsecore/atomic.h +++ b/src/pulsecore/atomic.h @@ -37,9 +37,14 @@ * libatomic_ops */ -#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) +/* We have to include config.h here, which sucks */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_ATOMIC_BUILTINS -/* gcc based implementation */ +/* __sync based implementation */ typedef struct pa_atomic { volatile int value; @@ -83,7 +88,7 @@ static inline int pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) { } typedef struct pa_atomic_ptr { - volatile long value; + volatile unsigned long value; } pa_atomic_ptr_t; #define PA_ATOMIC_PTR_INIT(v) { .value = (long) (v) } @@ -94,7 +99,7 @@ static inline void* pa_atomic_ptr_load(const pa_atomic_ptr_t *a) { } static inline void pa_atomic_ptr_store(pa_atomic_ptr_t *a, void *p) { - a->value = (long) p; + a->value = (unsigned long) p; __sync_synchronize(); } @@ -102,6 +107,80 @@ static inline int pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* n return __sync_bool_compare_and_swap(&a->value, (long) old_p, (long) new_p); } +#elif defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__)) + +/* Addapted from glibc */ + +typedef struct pa_atomic { + volatile int value; +} pa_atomic_t; + +#define PA_ATOMIC_INIT(v) { .value = (v) } + +static inline int pa_atomic_load(const pa_atomic_t *a) { + return a->value; +} + +static inline void pa_atomic_store(pa_atomic_t *a, int i) { + a->value = i; +} + +static inline int pa_atomic_add(pa_atomic_t *a, int i) { + int result; + + __asm __volatile ("lock; xaddl %0, %1" + : "=r" (result), "=m" (a->value) + : "0" (i), "m" (a->value)); + + return result; +} + +static inline int pa_atomic_sub(pa_atomic_t *a, int i) { + return pa_atomic_add(a, -i); +} + +static inline int pa_atomic_inc(pa_atomic_t *a) { + return pa_atomic_add(a, 1); +} + +static inline int pa_atomic_dec(pa_atomic_t *a) { + return pa_atomic_sub(a, 1); +} + +static inline int pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) { + int result; + + __asm__ __volatile__ ("lock; cmpxchgl %2, %1" + : "=a" (result), "=m" (a->value) + : "r" (new_i), "m" (a->value), "0" (old_i)); + + return result == oldval; +} + +typedef struct pa_atomic_ptr { + volatile unsigned long value; +} pa_atomic_ptr_t; + +#define PA_ATOMIC_PTR_INIT(v) { .value = (long) (v) } + +static inline void* pa_atomic_ptr_load(const pa_atomic_ptr_t *a) { + return (void*) a->value; +} + +static inline void pa_atomic_ptr_store(pa_atomic_ptr_t *a, void *p) { + a->value = (unsigned long) p; +} + +static inline int pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* new_p) { + void *result; + + __asm__ __volatile__ ("lock; cmpxchgq %q2, %1" + : "=a" (result), "=m" (a->value) + : "r" (new_p), "m" (a->value), "0" (old_p)); + + return result; +} + #else /* libatomic_ops based implementation */ -- cgit From a0d19c0d13e61d1f713637cba445911cb8cfef68 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 4 Sep 2007 21:34:04 +0000 Subject: update libltdl copy git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1771 fefdeb5f-60dc-0310-8127-8f9354f1896f --- libltdl/acinclude.m4 | 35 ++++++++----- libltdl/config.guess | 4 +- libltdl/config.h | 2 +- libltdl/config.sub | 6 +-- libltdl/configure | 137 ++++++++++++++++++++++++++++++++++----------------- libltdl/ltdl.c | 17 +------ libltdl/ltmain.sh | 12 ++++- 7 files changed, 131 insertions(+), 82 deletions(-) diff --git a/libltdl/acinclude.m4 b/libltdl/acinclude.m4 index 3f1dd408..79d94868 100644 --- a/libltdl/acinclude.m4 +++ b/libltdl/acinclude.m4 @@ -7,7 +7,7 @@ ## unlimited permission to copy and/or distribute it, with or without ## modifications, as long as this notice is preserved. -# serial 51 AC_PROG_LIBTOOL +# serial 51 Debian 1.5.24-1 AC_PROG_LIBTOOL # AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) @@ -559,7 +559,6 @@ s390*-*linux*|sparc*-*linux*) esac ;; *64-bit*) - libsuff=64 case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" @@ -1618,13 +1617,11 @@ linux* | k*bsd*-gnu) # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on @@ -1636,6 +1633,18 @@ linux* | k*bsd*-gnu) dynamic_linker='GNU/Linux ld.so' ;; +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + netbsd*) version_type=sunos need_lib_prefix=no @@ -2410,7 +2419,7 @@ linux* | k*bsd*-gnu) lt_cv_deplibs_check_method=pass_all ;; -netbsd*) +netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else @@ -3448,7 +3457,7 @@ case $host_os in ;; esac ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= @@ -5137,7 +5146,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) ;; esac ;; - netbsd*) + netbsd* | netbsdelf*-gnu) ;; osf3* | osf4* | osf5*) case $cc_basename in @@ -5512,6 +5521,9 @@ ifelse([$1],[CXX],[ cygwin* | mingw*) _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' ;; + linux* | k*bsd*-gnu) + _LT_AC_TAGVAR(link_all_deplibs, $1)=no + ;; *) _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; @@ -5717,12 +5729,13 @@ EOF $echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi + _LT_AC_TAGVAR(link_all_deplibs, $1)=no else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= @@ -6154,7 +6167,7 @@ _LT_EOF _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else @@ -6738,7 +6751,7 @@ AC_CACHE_CHECK([whether deplibs are loaded by dlopen], # at 6.2 and later dlopen does load deplibs. libltdl_cv_sys_dlopen_deplibs=yes ;; - netbsd*) + netbsd* | netbsdelf*-gnu) libltdl_cv_sys_dlopen_deplibs=yes ;; openbsd*) diff --git a/libltdl/config.guess b/libltdl/config.guess index 951383e3..0f0fe712 100755 --- a/libltdl/config.guess +++ b/libltdl/config.guess @@ -4,7 +4,7 @@ # 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, # Inc. -timestamp='2007-05-17' +timestamp='2007-03-06' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -330,7 +330,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; - i86pc:SunOS:5.*:* | ix86xen:SunOS:5.*:*) + i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) diff --git a/libltdl/config.h b/libltdl/config.h index 195d2143..a04820a7 100644 --- a/libltdl/config.h +++ b/libltdl/config.h @@ -160,7 +160,7 @@ #define LTDL_SHLIB_EXT ".so" /* Define to the system default library search path. */ -#define LTDL_SYSSEARCHPATH "/usr/lib:/lib:/usr/local/lib:/usr/lib/qt-3.3/lib" +#define LTDL_SYSSEARCHPATH "/lib:/usr/lib:/usr/lib/atlas:/usr/local/lib:/lib/i486-linux-gnu:/usr/lib/i486-linux-gnu:/usr/local/lib" /* Define if dlsym() requires a leading underscore in symbol names. */ /* #undef NEED_USCORE */ diff --git a/libltdl/config.sub b/libltdl/config.sub index c060f448..5defff65 100755 --- a/libltdl/config.sub +++ b/libltdl/config.sub @@ -4,7 +4,7 @@ # 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, # Inc. -timestamp='2007-04-29' +timestamp='2007-01-18' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -683,10 +683,6 @@ case $basic_machine in basic_machine=i386-pc os=-mingw32 ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; miniframe) basic_machine=m68000-convergent ;; diff --git a/libltdl/configure b/libltdl/configure index 62dface9..aa2994e0 100755 --- a/libltdl/configure +++ b/libltdl/configure @@ -4408,7 +4408,7 @@ linux* | k*bsd*-gnu) lt_cv_deplibs_check_method=pass_all ;; -netbsd*) +netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else @@ -4593,7 +4593,6 @@ s390*-*linux*|sparc*-*linux*) esac ;; *64-bit*) - libsuff=64 case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" @@ -7565,11 +7564,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7568: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7567: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7572: \$? = $ac_status" >&5 + echo "$as_me:7571: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7855,11 +7854,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7858: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7857: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7862: \$? = $ac_status" >&5 + echo "$as_me:7861: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7959,11 +7958,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7962: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7961: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7966: \$? = $ac_status" >&5 + echo "$as_me:7965: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -8223,12 +8222,13 @@ EOF $echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi + link_all_deplibs=no else ld_shlibs=no fi ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= @@ -8772,7 +8772,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi link_all_deplibs=yes ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else @@ -9467,13 +9467,11 @@ linux* | k*bsd*-gnu) # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on @@ -9485,6 +9483,18 @@ linux* | k*bsd*-gnu) dynamic_linker='GNU/Linux ld.so' ;; +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + netbsd*) version_type=sunos need_lib_prefix=no @@ -10310,7 +10320,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext </dev/null; then archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= @@ -12725,7 +12735,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } ;; esac ;; - netbsd*) + netbsd* | netbsdelf*-gnu) ;; osf3* | osf4* | osf5*) case $cc_basename in @@ -12834,11 +12844,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12837: $lt_compile\"" >&5) + (eval echo "\"\$as_me:12847: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:12841: \$? = $ac_status" >&5 + echo "$as_me:12851: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -12938,11 +12948,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12941: $lt_compile\"" >&5) + (eval echo "\"\$as_me:12951: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:12945: \$? = $ac_status" >&5 + echo "$as_me:12955: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -13010,6 +13020,9 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar cygwin* | mingw*) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' ;; + linux* | k*bsd*-gnu) + link_all_deplibs_CXX=no + ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; @@ -13439,13 +13452,11 @@ linux* | k*bsd*-gnu) # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on @@ -13457,6 +13468,18 @@ linux* | k*bsd*-gnu) dynamic_linker='GNU/Linux ld.so' ;; +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + netbsd*) version_type=sunos need_lib_prefix=no @@ -14502,11 +14525,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14505: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14528: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14509: \$? = $ac_status" >&5 + echo "$as_me:14532: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14606,11 +14629,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14609: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14632: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14613: \$? = $ac_status" >&5 + echo "$as_me:14636: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -14870,12 +14893,13 @@ EOF $echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi + link_all_deplibs_F77=no else ld_shlibs_F77=no fi ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= @@ -15399,7 +15423,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi link_all_deplibs_F77=yes ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else @@ -16042,13 +16066,11 @@ linux* | k*bsd*-gnu) # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on @@ -16060,6 +16082,18 @@ linux* | k*bsd*-gnu) dynamic_linker='GNU/Linux ld.so' ;; +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + netbsd*) version_type=sunos need_lib_prefix=no @@ -16799,11 +16833,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16802: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16836: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:16806: \$? = $ac_status" >&5 + echo "$as_me:16840: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -17089,11 +17123,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:17092: $lt_compile\"" >&5) + (eval echo "\"\$as_me:17126: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:17096: \$? = $ac_status" >&5 + echo "$as_me:17130: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -17193,11 +17227,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:17196: $lt_compile\"" >&5) + (eval echo "\"\$as_me:17230: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:17200: \$? = $ac_status" >&5 + echo "$as_me:17234: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -17457,12 +17491,13 @@ EOF $echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi + link_all_deplibs_GCJ=no else ld_shlibs_GCJ=no fi ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= @@ -18006,7 +18041,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi link_all_deplibs_GCJ=yes ;; - netbsd*) + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else @@ -18649,13 +18684,11 @@ linux* | k*bsd*-gnu) # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on @@ -18667,6 +18700,18 @@ linux* | k*bsd*-gnu) dynamic_linker='GNU/Linux ld.so' ;; +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + netbsd*) version_type=sunos need_lib_prefix=no @@ -20929,7 +20974,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < #endif -#ifdef RTLD_GLOBAL -# define LT_GLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_GLOBAL DL_GLOBAL -# endif -#endif /* !RTLD_GLOBAL */ -#ifndef LT_GLOBAL -# define LT_GLOBAL 0 -#endif /* !LT_GLOBAL */ - /* We may have to define LT_LAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_LAZY_OR_NOW @@ -1114,7 +1103,7 @@ sys_dl_open (loader_data, filename) lt_user_data loader_data; const char *filename; { - lt_module module = dlopen (filename, LT_GLOBAL | LT_LAZY_OR_NOW); + lt_module module = dlopen (filename, LT_LAZY_OR_NOW); if (!module) { @@ -3225,9 +3214,7 @@ try_dlopen (phandle, filename) } if (!file) { - /* don't open .la files in current directory, root might get tricked to run a binary in a prepared directory */ - if(!strncmp((filename + strlen(filename) - 3), LTDL_ARCHIVE_EXT,3) || strstr(filename,"/")) - file = fopen (filename, LT_READTEXT_MODE); + file = fopen (filename, LT_READTEXT_MODE); } /* If we didn't find the file by now, it really isn't there. Set diff --git a/libltdl/ltmain.sh b/libltdl/ltmain.sh index 8e5a9304..f924d309 100644 --- a/libltdl/ltmain.sh +++ b/libltdl/ltmain.sh @@ -43,7 +43,7 @@ EXIT_FAILURE=1 PROGRAM=ltmain.sh PACKAGE=libtool -VERSION=1.5.24 +VERSION="1.5.24 Debian 1.5.24-1" TIMESTAMP=" (1.1220.2.456 2007/06/24 02:25:32)" # Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). @@ -2122,7 +2122,10 @@ EOF case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; - link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; esac fi if test "$pass" = dlopen; then @@ -3244,6 +3247,11 @@ EOF revision="$number_minor" lt_irix_increment=no ;; + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE + ;; esac ;; no) -- cgit From b1fd53b20ba77dab903eb4d83e2b9d1a8d99f2b6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 6 Sep 2007 20:06:02 +0000 Subject: explicitly test for the availability of dbus_watch_get_unix_fd() before using it. The previous version-based check didn't work anyway since the constants checked for weren't set. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1772 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 44 +++++++++++++++++++++++++++++++++++++++++++- src/modules/dbus-util.c | 15 ++++++++------- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index 626a1ce6..71e95b8e 100644 --- a/configure.ac +++ b/configure.ac @@ -713,7 +713,6 @@ AC_ARG_ENABLE([hal], esac ], [hal=auto]) - if test "x${hal}" != xno -a \( "x$HAVE_OSS" = "x1" -o "x$HAVE_ALSA" = "x1" \) ; then PKG_CHECK_MODULES(HAL, [ hal >= 0.5.7 ], HAVE_HAL=1, @@ -732,6 +731,49 @@ AC_SUBST(HAL_LIBS) AC_SUBST(HAVE_HAL) AM_CONDITIONAL([HAVE_HAL], [test "x$HAVE_HAL" = x1]) +#### D-Bus support (optional) #### + +AC_ARG_ENABLE([dbus], + AC_HELP_STRING([--disable-dbus], [Disable optional D-Bus support]), + [ + case "${enableval}" in + yes) dbus=yes ;; + no) dbus=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-dbus) ;; + esac + ], + [dbus=auto]) + +if test "x$HAVE_HAL" = x1 ; then + dbus=yes +fi + +if test "x${dbus}" != xno ; then + + PKG_CHECK_MODULES(DBUS, [ dbus-1 >= 1.0.0 ], + [ + HAVE_DBUS=1 + saved_LIBS="$LIBS" + LIBS="$LIBS $DBUS_LIBS" + AC_CHECK_FUNCS(dbus_watch_get_unix_fd) + LIBS="$saved_LIBS" + + ], + [ + HAVE_DBUS=0 + if test "x$dbus" = xyes ; then + AC_MSG_ERROR([*** D-Bus support not found]) + fi + ]) +else + HAVE_DBUS=0 +fi + +AC_SUBST(DBUS_CFLAGS) +AC_SUBST(DBUS_LIBS) +AC_SUBST(HAVE_DBUS) +AM_CONDITIONAL([HAVE_DBUS], [test "x$HAVE_DBUS" = x1]) + #### PulseAudio system group & user ##### AC_ARG_WITH(system_user, AS_HELP_STRING([--with-system-user=],[User for running the PulseAudio daemon as a system-wide instance (pulse)])) diff --git a/src/modules/dbus-util.c b/src/modules/dbus-util.c index 360f7827..9078ec72 100644 --- a/src/modules/dbus-util.c +++ b/src/modules/dbus-util.c @@ -96,7 +96,7 @@ static void handle_io_event(PA_GCC_UNUSED pa_mainloop_api *ea, pa_io_event *e, i unsigned int flags = 0; DBusWatch *watch = userdata; -#if (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR == 1 && DBUS_VERSION_MICRO >= 1) || (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR > 1) || (DBUS_VERSION_MAJOR > 1) +#if HAVE_DBUS_WATCH_GET_UNIX_FD pa_assert(fd == dbus_watch_get_unix_fd(watch)); #else pa_assert(fd == dbus_watch_get_fd(watch)); @@ -141,14 +141,15 @@ static dbus_bool_t add_watch(DBusWatch *watch, void *data) { pa_assert(watch); pa_assert(c); - ev = c->mainloop->io_new(c->mainloop, -#if (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR == 1 && DBUS_VERSION_MICRO >= 1) || (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MAJOR > 1) || (DBUS_VERSION_MAJOR > 1) - dbus_watch_get_unix_fd(watch), + ev = c->mainloop->io_new( + c->mainloop, +#if HAVE_DBUS_WATCH_GET_UNIX_FD + dbus_watch_get_unix_fd(watch), #else - dbus_watch_get_fd(watch), + dbus_watch_get_fd(watch), #endif - get_watch_flags(watch), handle_io_event, watch); - + get_watch_flags(watch), handle_io_event, watch); + dbus_watch_set_data(watch, ev, NULL); return TRUE; -- cgit From 3b2cf1ade56d90c28ace819cf82c88b7d1989182 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 6 Sep 2007 20:38:10 +0000 Subject: update default config: - check for existance of modules before loading them - disable all event sounds except hotplug by default git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1773 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 4 ++-- src/daemon/default.pa.in | 22 ++++++++++++++-------- src/pulsecore/cli-command.c | 1 + 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 51be9d0a..b0b3bb24 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1392,8 +1392,8 @@ default.pa: daemon/default.pa.win32 else default.pa: daemon/default.pa.in Makefile sed -e 's,@PA_BINARY\@,$(PA_BINARY),g' \ - -e 's,@HAVE_HAL_TRUE\@,@HAVE_HAL_TRUE@,g' \ - -e 's,@HAVE_HAL_FALSE\@,@HAVE_HAL_FALSE@,g' < $< > $@ + -e 's,@PA_DLSEARCHPATH\@,$(modlibexecdir),g' \ + -e 's,@PA_SOEXT\@,.so,g' < $< > $@ endif daemon.conf: daemon/daemon.conf.in Makefile diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in index fb90aa64..597993c4 100755 --- a/src/daemon/default.pa.in +++ b/src/daemon/default.pa.in @@ -19,10 +19,10 @@ .nofail ### Load something into the sample cache -load-sample-lazy x11-bell /usr/share/sounds/gtk-events/activate.wav -load-sample-lazy pulse-hotplug /usr/share/sounds/email.wav -load-sample-lazy pulse-coldplug /usr/share/sounds/startup3.wav -load-sample-lazy pulse-access /usr/share/sounds/generic.wav +#load-sample-lazy x11-bell /usr/share/sounds/gtk-events/activate.wav +load-sample-lazy pulse-hotplug /usr/share/sounds/startup3.wav +#load-sample-lazy pulse-coldplug /usr/share/sounds/startup3.wav +#load-sample-lazy pulse-access /usr/share/sounds/generic.wav .fail @@ -37,11 +37,13 @@ load-sample-lazy pulse-access /usr/share/sounds/generic.wav #load-module module-pipe-sink ### Automatically load driver modules depending on the hardware available -@HAVE_HAL_TRUE@load-module module-hal-detect - +.ifexists @PA_DLSEARCHPATH@/module-hal-detect@PA_SOEXT@ +load-module module-hal-detect +.else ### Alternatively use the static hardware detection module (for systems that ### lack HAL support) -@HAVE_HAL_FALSE@load-module module-detect +load-module module-detect +.endif ### Load several protocols load-module module-esound-protocol-unix @@ -74,10 +76,12 @@ load-module module-rescue-streams load-module module-suspend-on-idle ### Load X11 bell module -load-module module-x11-bell sample=x11-bell +#load-module module-x11-bell sample=x11-bell ### Publish connection data in the X11 root window +.ifexists @PA_DLSEARCHPATH@/module-x11-publish@PA_SOEXT@ load-module module-x11-publish +.endif ### Register ourselves in the X11 session manager # Deactivated by default, to avoid deadlock when PA is started as esd from gnome-session @@ -87,7 +91,9 @@ load-module module-x11-publish ### Load additional modules from GConf settings. This can be configured with the paprefs tool. ### Please keep in mind that the modules configured by paprefs might conflict with manually ### loaded modules. +.ifexists @PA_DLSEARCHPATH@/module-gconf@PA_SOEXT@ load-module module-gconf +.endif ### Make some devices default #set-default-sink output diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c index 0cd1f483..79b52d46 100644 --- a/src/pulsecore/cli-command.c +++ b/src/pulsecore/cli-command.c @@ -1145,6 +1145,7 @@ int pa_cli_command_execute_line_stateful(pa_core *c, const char *s, pa_strbuf *b const char *filename = cs+l+strspn(cs+l, whitespace); *ifstate = access(filename, F_OK) == 0 ? IFSTATE_TRUE : IFSTATE_FALSE; + pa_log_debug("Checking for existance of '%s': %s", filename, *ifstate == IFSTATE_TRUE ? "success" : "failure"); } } else { pa_strbuf_printf(buf, "Invalid meta command: %s\n", cs); -- cgit From 45ba7117dc25c5d5db783356c51c71a81d51e662 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 6 Sep 2007 20:45:43 +0000 Subject: downgrade realtime group membership warning to 'info' at be a little bit more elaborate git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1774 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/daemon/main.c b/src/daemon/main.c index 14097612..135a9ab6 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -392,7 +392,8 @@ int main(int argc, char *argv[]) { setlocale(LC_ALL, ""); if (suid_root && (pa_own_uid_in_group(PA_REALTIME_GROUP, &gid) <= 0)) { - pa_log_warn("WARNING: called SUID root, but not in group '"PA_REALTIME_GROUP"'."); + pa_log_info("Warning: Called SUID root, but not in group '"PA_REALTIME_GROUP"'. " + "For enabling real-time scheduling please become a member of '"PA_REALTIME_GROUP"' , or increase the RLIMIT_RTPRIO user limit."); pa_drop_caps(); pa_drop_root(); suid_root = real_root = 0; -- cgit From e4eefb8ce0d8e9ecc0e2ea40ee0c8b41e7e4adbc Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 6 Sep 2007 23:10:34 +0000 Subject: fix copynpaste error git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1775 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/source-output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index ccd968ae..1a9bf96b 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -222,7 +222,7 @@ static void source_output_free(pa_object* mo) { pa_assert(pa_source_output_refcnt(o) == 0); - if (PA_SOURCE_LINKED(o->state)) + if (PA_SOURCE_OUTPUT_LINKED(o->state)) pa_source_output_unlink(o); pa_log_info("Freeing output %u \"%s\"", o->index, o->name); -- cgit From d60940dbe4a6bf3acf0b458d321a1f4d449b7a01 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 6 Sep 2007 23:11:22 +0000 Subject: install libpulsecore again, since libtool otherwise links it statically into every single module git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1776 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index b0b3bb24..1dfe3c23 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -627,7 +627,7 @@ noinst_HEADERS = \ pulsecore/semaphore.h \ pulsecore/once.h -noinst_LTLIBRARIES += libpulsecore.la +lib_LTLIBRARIES += libpulsecore.la # Some public stuff is used even in the core libpulsecore_la_SOURCES = \ -- cgit From b41dbfd28d6f940004f412f3ef16a1419240786f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 6 Sep 2007 23:29:16 +0000 Subject: fix an assert when runnig module-oss in record only-mode. optimize allocation of memblocks on playback git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1777 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-source.c | 13 ++++++++++--- src/modules/module-oss.c | 35 ++++++++++++++++++++++++----------- src/pulsecore/memblock.c | 31 ++++++++++++++++++++++--------- 3 files changed, 56 insertions(+), 23 deletions(-) diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 9922668b..365f6ab2 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -210,7 +210,7 @@ static int unix_read(struct userdata *u) { for (;;) { void *p; - snd_pcm_sframes_t t; + snd_pcm_sframes_t t, k; ssize_t l; int err; pa_memchunk chunk; @@ -228,10 +228,17 @@ static int unix_read(struct userdata *u) { if (l <= 0) return work_done; - chunk.memblock = pa_memblock_new(u->core->mempool, l); + chunk.memblock = pa_memblock_new(u->core->mempool, (size_t) -1); + + k = pa_memblock_get_length(chunk.memblock); + + if (k > l) + k = l; + + k = (k/u->frame_size)*u->frame_size; p = pa_memblock_acquire(chunk.memblock); - t = snd_pcm_readi(u->pcm_handle, (uint8_t*) p, l / u->frame_size); + t = snd_pcm_readi(u->pcm_handle, (uint8_t*) p, k / u->frame_size); pa_memblock_release(chunk.memblock); /* pa_log("wrote %i bytes of %u (%u)", t*u->frame_size, u->memchunk.length, l); */ diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index bbb1e0d2..f36f21f1 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -110,6 +110,7 @@ struct userdata { pa_memchunk memchunk; + size_t frame_size; uint32_t in_fragment_size, out_fragment_size, in_nfrags, out_nfrags, in_hwbuf_size, out_hwbuf_size; int use_getospace, use_getispace; int use_getodelay; @@ -941,14 +942,21 @@ static void thread_func(void *userdata) { } do { - ssize_t t; + ssize_t t, k; pa_assert(l > 0); - memchunk.memblock = pa_memblock_new(u->core->mempool, l); + memchunk.memblock = pa_memblock_new(u->core->mempool, (size_t) -1); + + k = pa_memblock_get_length(memchunk.memblock); + + if (k > l) + k = l; + k = (k/u->frame_size)*u->frame_size; + p = pa_memblock_acquire(memchunk.memblock); - t = pa_read(u->fd, p, l, &read_type); + t = pa_read(u->fd, p, k, &read_type); pa_memblock_release(memchunk.memblock); pa_assert(t != 0); /* EOF cannot happen */ @@ -992,16 +1000,20 @@ static void thread_func(void *userdata) { /* pa_log("loop2"); */ /* Now give the sink inputs some to time to process their data */ - if ((ret = pa_sink_process_inputs(u->sink)) < 0) - goto fail; - if (ret > 0) - continue; + if (u->sink) { + if ((ret = pa_sink_process_inputs(u->sink)) < 0) + goto fail; + if (ret > 0) + continue; + } /* Now give the source outputs some to time to process their data */ - if ((ret = pa_source_process_outputs(u->source)) < 0) - goto fail; - if (ret > 0) - continue; + if (u->source) { + if ((ret = pa_source_process_outputs(u->source)) < 0) + goto fail; + if (ret > 0) + continue; + } /* Check whether there is a message for us to process */ if ((ret = pa_thread_mq_process(&u->thread_mq) < 0)) @@ -1148,6 +1160,7 @@ int pa__init(pa_module*m) { u->use_getodelay = 1; u->use_input_volume = u->use_pcm_volume = 1; u->mode = mode; + u->frame_size = pa_frame_size(&ss); u->device_name = pa_xstrdup(dev); u->in_nfrags = u->out_nfrags = u->nfrags = nfrags; u->out_fragment_size = u->in_fragment_size = u->frag_size = frag_size; diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index 479c74f7..53c60878 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -218,6 +218,11 @@ static pa_memblock *memblock_new_appended(pa_mempool *p, size_t length) { pa_assert(p); pa_assert(length > 0); + /* If -1 is passed as length we choose the size for the caller. */ + + if (length == (size_t) -1) + length = p->block_size - PA_ALIGN(sizeof(struct mempool_slot)) - PA_ALIGN(sizeof(pa_memblock)); + b = pa_xmalloc(PA_ALIGN(sizeof(pa_memblock)) + length); PA_REFCNT_INIT(b); b->pool = p; @@ -261,7 +266,7 @@ static struct mempool_slot* mempool_allocate_slot(pa_mempool *p) { static void* mempool_slot_data(struct mempool_slot *slot) { pa_assert(slot); - return (uint8_t*) slot + sizeof(struct mempool_slot); + return (uint8_t*) slot + PA_ALIGN(sizeof(struct mempool_slot)); } /* No lock necessary */ @@ -292,16 +297,22 @@ pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) { pa_assert(p); pa_assert(length > 0); - if (p->block_size - sizeof(struct mempool_slot) >= sizeof(pa_memblock) + length) { + /* If -1 is passed as length we choose the size for the caller: we + * take the largest size that fits in one of our slots. */ + + if (length == (size_t) -1) + length = p->block_size - PA_ALIGN(sizeof(struct mempool_slot)) - PA_ALIGN(sizeof(pa_memblock)); + + if (p->block_size - PA_ALIGN(sizeof(struct mempool_slot)) >= PA_ALIGN(sizeof(pa_memblock)) + length) { if (!(slot = mempool_allocate_slot(p))) return NULL; b = mempool_slot_data(slot); b->type = PA_MEMBLOCK_POOL; - pa_atomic_ptr_store(&b->data, (uint8_t*) b + sizeof(pa_memblock)); + pa_atomic_ptr_store(&b->data, (uint8_t*) b + PA_ALIGN(sizeof(pa_memblock))); - } else if (p->block_size - sizeof(struct mempool_slot) >= length) { + } else if (p->block_size - PA_ALIGN(sizeof(struct mempool_slot)) >= length) { if (!(slot = mempool_allocate_slot(p))) return NULL; @@ -313,7 +324,7 @@ pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) { pa_atomic_ptr_store(&b->data, mempool_slot_data(slot)); } else { - pa_log_debug("Memory block too large for pool: %lu > %lu", (unsigned long) length, (unsigned long) (p->block_size - sizeof(struct mempool_slot))); + pa_log_debug("Memory block too large for pool: %lu > %lu", (unsigned long) length, (unsigned long) (p->block_size - PA_ALIGN(sizeof(struct mempool_slot)))); pa_atomic_inc(&p->stat.n_too_large_for_pool); return NULL; } @@ -335,6 +346,7 @@ pa_memblock *pa_memblock_new_fixed(pa_mempool *p, void *d, size_t length, int re pa_assert(p); pa_assert(d); + pa_assert(length != (size_t) -1); pa_assert(length > 0); if (!(b = pa_flist_pop(PA_STATIC_FLIST_GET(unused_memblocks)))) @@ -359,6 +371,7 @@ pa_memblock *pa_memblock_new_user(pa_mempool *p, void *d, size_t length, void (* pa_assert(p); pa_assert(d); pa_assert(length > 0); + pa_assert(length != (size_t) -1); pa_assert(free_cb); if (!(b = pa_flist_pop(PA_STATIC_FLIST_GET(unused_memblocks)))) @@ -555,7 +568,7 @@ static void memblock_make_local(pa_memblock *b) { pa_atomic_dec(&b->pool->stat.n_allocated_by_type[b->type]); - if (b->length <= b->pool->block_size - sizeof(struct mempool_slot)) { + if (b->length <= b->pool->block_size - PA_ALIGN(sizeof(struct mempool_slot))) { struct mempool_slot *slot; if ((slot = mempool_allocate_slot(b->pool))) { @@ -657,7 +670,7 @@ pa_mempool* pa_mempool_new(int shared) { p->n_blocks = PA_MEMPOOL_SLOTS_MAX; - pa_assert(p->block_size > sizeof(struct mempool_slot)); + pa_assert(p->block_size > PA_ALIGN(sizeof(struct mempool_slot))); if (pa_shm_create_rw(&p->memory, p->n_blocks * p->block_size, shared, 0700) < 0) { pa_xfree(p); @@ -725,8 +738,8 @@ void pa_mempool_vacuum(pa_mempool *p) { while ((slot = pa_flist_pop(list))) { pa_shm_punch(&p->memory, - (uint8_t*) slot - (uint8_t*) p->memory.ptr + sizeof(struct mempool_slot), - p->block_size - sizeof(struct mempool_slot)); + (uint8_t*) slot - (uint8_t*) p->memory.ptr + PA_ALIGN(sizeof(struct mempool_slot)), + p->block_size - PA_ALIGN(sizeof(struct mempool_slot))); while (pa_flist_push(p->free_slots, slot)) ; -- cgit From dfdf1d7d9f41144231ab40b1f6eec18f834bba1d Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Sun, 9 Sep 2007 09:39:26 +0000 Subject: Changed PA_SAMPLE_S16_NE to PA_SAMPLE_S16NE in the example code in the Simple API Doxygen documentation. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1778 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/simple.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulse/simple.h b/src/pulse/simple.h index 128d2716..f76c1d67 100644 --- a/src/pulse/simple.h +++ b/src/pulse/simple.h @@ -51,7 +51,7 @@ * pa_simple *s; * pa_sample_spec ss; * - * ss.format = PA_SAMPLE_S16_NE; + * ss.format = PA_SAMPLE_S16NE; * ss.channels = 2; * ss.rate = 44100; * -- cgit From 717b1641614ed7a47c2b0188496dd39be806975c Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 10 Sep 2007 11:19:53 +0000 Subject: POSIX realtime clock functions are in time.h so make sure to include it. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1779 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/rtclock.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pulsecore/rtclock.c b/src/pulsecore/rtclock.c index a4e9875d..02abde3c 100644 --- a/src/pulsecore/rtclock.c +++ b/src/pulsecore/rtclock.c @@ -27,6 +27,7 @@ #endif #include +#include #include #include -- cgit From e1766011ca68582324802aa3e9e820c3ec899aae Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 10 Sep 2007 11:27:56 +0000 Subject: Monotonic clock is optional so treat is as such. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1780 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/rtclock.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/rtclock.c b/src/pulsecore/rtclock.c index 02abde3c..7dd83b3f 100644 --- a/src/pulsecore/rtclock.c +++ b/src/pulsecore/rtclock.c @@ -139,9 +139,11 @@ struct timespec *pa_rtclock_get(struct timespec *ts) { pa_assert(ts); if (!no_monotonic) { +#ifdef CLOCK_MONOTONIC if (clock_gettime(CLOCK_MONOTONIC, ts) >= 0) return ts; - +#endif + no_monotonic = 1; } @@ -152,8 +154,10 @@ struct timespec *pa_rtclock_get(struct timespec *ts) { int pa_rtclock_hrtimer(void) { struct timespec ts; +#ifdef CLOCK_MONOTONIC if (clock_getres(CLOCK_MONOTONIC, &ts) >= 0) return ts.tv_sec == 0 && ts.tv_nsec <= PA_HRTIMER_THRESHOLD_USEC*1000; +#endif pa_assert_se(clock_getres(CLOCK_REALTIME, &ts) == 0); return ts.tv_sec == 0 && ts.tv_nsec <= PA_HRTIMER_THRESHOLD_USEC*1000; -- cgit From 028632fd57f84a81a0f9b70cb0b7b5ac35d789df Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 10 Sep 2007 11:33:47 +0000 Subject: TIOCINQ isn't present on all systems. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1781 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-pipe-sink.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index d5ef194f..55a4e0ce 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -98,9 +98,11 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse case PA_SINK_MESSAGE_GET_LATENCY: { size_t n = 0; int l; - + +#ifdef TIOCINQ if (ioctl(u->fd, TIOCINQ, &l) >= 0 && l > 0) n = (size_t) l; +#endif n += u->memchunk.length; -- cgit From 9630e8df575ff35cab9bc95151fcbb3d56fb29fd Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 10 Sep 2007 11:34:35 +0000 Subject: Remove mkdir_p again... git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1782 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 1dfe3c23..52fa4b84 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1091,7 +1091,9 @@ EXTRA_DIST += $(SYMDEF_FILES) BUILT_SOURCES += $(SYMDEF_FILES) $(SYMDEF_FILES): modules/module-defs.h.m4 - $(mkdir_p) modules modules/gconf modules/rtp + -mkdir modules + -mkdir modules/gconf + -mkdir modules/rtp $(M4) -Dfname="$@" $< > $@ # Simple protocol -- cgit From d9b3c0eef2ba256b4e1e694c3828d1f4713ebf68 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 10 Sep 2007 11:35:30 +0000 Subject: posix_madvise and posix_fadvise aren't present on all systems. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1783 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 4 ++-- src/pulsecore/core-util.c | 8 +++++--- src/pulsecore/sound-file-stream.c | 2 ++ src/pulsecore/sound-file.c | 2 ++ 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 71e95b8e..c4f26c4e 100644 --- a/configure.ac +++ b/configure.ac @@ -247,8 +247,8 @@ AC_FUNC_FORK AC_FUNC_GETGROUPS AC_FUNC_SELECT_ARGTYPES AC_CHECK_FUNCS([chmod chown getaddrinfo getgrgid_r getpwuid_r gettimeofday \ - getuid inet_ntop inet_pton nanosleep pipe posix_memalign setpgid setsid \ - shm_open sigaction sleep sysconf]) + getuid inet_ntop inet_pton nanosleep pipe posix_fadvise posix_madvise \ + posix_memalign setpgid setsid shm_open sigaction sleep sysconf]) AC_CHECK_FUNCS([mkfifo], [HAVE_MKFIFO=1], [HAVE_MKFIFO=0]) AM_CONDITIONAL(HAVE_MKFIFO, test "x$HAVE_MKFIFO" = "x1") diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 67d33e7c..13a7252c 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -1262,11 +1262,13 @@ void *pa_will_need(const void *p, size_t l) { a = PA_PAGE_ALIGN_PTR(p); size = (const uint8_t*) p + l - (const uint8_t*) a; - + +#ifdef HAVE_POSIX_MADVISE if ((r = posix_madvise((void*) a, size, POSIX_MADV_WILLNEED)) == 0) { pa_log_debug("posix_madvise() worked fine!"); return (void*) p; } +#endif /* Most likely the memory was not mmap()ed from a file and thus * madvise() didn't work, so let's misuse mlock() do page this @@ -1279,7 +1281,7 @@ void *pa_will_need(const void *p, size_t l) { pa_assert_se(getrlimit(RLIMIT_MEMLOCK, &rlim) == 0); if (rlim.rlim_cur < PA_PAGE_SIZE) { - pa_log_debug("posix_madvise() failed, resource limits don't allow mlock(), can't page in data: %s", pa_cstrerror(r)); + pa_log_debug("posix_madvise() failed (or doesn't exist), resource limits don't allow mlock(), can't page in data: %s", pa_cstrerror(r)); return (void*) p; } @@ -1288,7 +1290,7 @@ void *pa_will_need(const void *p, size_t l) { bs = PA_PAGE_SIZE*4; #endif - pa_log_debug("posix_madvise() failed, trying mlock(): %s", pa_cstrerror(r)); + pa_log_debug("posix_madvise() failed (or doesn't exist), trying mlock(): %s", pa_cstrerror(r)); while (size > 0 && bs > 0) { diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index 36c7f03c..d5523a64 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -255,6 +255,7 @@ int pa_play_file( * file reader into the main event loop and pass the data over the * asyncmsgq. */ +#ifdef HAVE_POSIX_FADVISE if (posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL) < 0) { pa_log_warn("POSIX_FADV_SEQUENTIAL failed: %s", pa_cstrerror(errno)); goto fail; @@ -266,6 +267,7 @@ int pa_play_file( goto fail; } else pa_log_debug("POSIX_FADV_WILLNEED succeeded."); +#endif if (!(u->sndfile = sf_open_fd(fd, SFM_READ, &sfinfo, 1))) { pa_log("Failed to open file %s", fname); diff --git a/src/pulsecore/sound-file.c b/src/pulsecore/sound-file.c index ef43eef0..8727ba15 100644 --- a/src/pulsecore/sound-file.c +++ b/src/pulsecore/sound-file.c @@ -67,11 +67,13 @@ int pa_sound_file_load( goto finish; } +#ifdef HAVE_POSIX_FADVISE if (posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL) < 0) { pa_log_warn("POSIX_FADV_SEQUENTIAL failed: %s", pa_cstrerror(errno)); goto finish; } else pa_log_debug("POSIX_FADV_SEQUENTIAL succeeded."); +#endif if (!(sf = sf_open_fd(fd, SFM_READ, &sfinfo, 1))) { pa_log("Failed to open file %s", fname); -- cgit From 06db9219a0445c026e57945aabc3e6dd4be52d2e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 10 Sep 2007 14:23:00 +0000 Subject: don't call pa_source_process_msg() for PA_SOURCE_MESSAGE_GET_LATENCY, since it makes querying the latency always fail git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1784 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-oss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index f36f21f1..ccbb183f 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -711,7 +711,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off } *((pa_usec_t*) data) = r; - break; + return 0; } case PA_SOURCE_MESSAGE_SET_STATE: -- cgit From 27c3bd497d931afd30668955fd39c24c030d27ab Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 10 Sep 2007 18:55:36 +0000 Subject: document that the native amd64 atomic ops implementation is incomplete git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1785 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/atomic.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pulsecore/atomic.h b/src/pulsecore/atomic.h index 6e33c993..6fb85f09 100644 --- a/src/pulsecore/atomic.h +++ b/src/pulsecore/atomic.h @@ -109,6 +109,8 @@ static inline int pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* n #elif defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__)) +#error "The native atomic operations implementation for AMD64 has not been tested. libatomic_ops is known to not work properly on AMD64 and your gcc version is too old for the gcc-builtin atomic ops support. You have three options now: make the native atomic operations implementation for AMD64 work, fix libatomic_ops, or upgrade your GCC." + /* Addapted from glibc */ typedef struct pa_atomic { -- cgit -- cgit From 44e514c51f821863ad8efe84454a0886c4dcda2a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 10 Sep 2007 19:01:09 +0000 Subject: update todo file a little git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1787 fefdeb5f-60dc-0310-8127-8f9354f1896f --- todo | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/todo b/todo index 7b4ce786..f579bebe 100644 --- a/todo +++ b/todo @@ -4,7 +4,6 @@ Build System: - Remove symdef files and use macros (like most other projects) - Use own name mangling scheme instead of ltdl's, which will eliminate the need for .la files or extra trickery. -- build pulsecore only statically by default, it's not a public API yet Porting: - rtp module ported to Win32 (sendmsg/recvmsg emulation) @@ -13,16 +12,12 @@ I18N: - iconv stuff sent from utils to server (UTF-8) - iconv sample loading in server - Document utf8.h, timeval.h and util.h -- gettextify polypaudio +- gettextify pulseaudio Cleanups: - drop dependency of libpolyp on libX11, instead use an external mini binary -- merge module-oss-mmap into module-oss - module-tunnel: improve latency calculation - use software volume when hardware doesn't support all channels (alsa done) -- silence generation should be moved into the core to avoid races and code - duplication in the backends -- don't read/write audio data from/to ALSA devices if noone is listening - using POSIX monotonous clocks wherever possible instead of gettimeofday() Test: @@ -35,7 +30,6 @@ Auth/Crypto: - sasl auth Features: -- alsa mmap driver - alsa driver with hw mixing - "window manager for sound" - chroot() @@ -52,7 +46,8 @@ Features: - Support for device selection in waveout driver - add an API to libpulse for allocating memory from the pa_context memory pool - allow buffer metric changes during runtime -- "include" command in configuration files. should have glob support. +- better ".include" command in configuration files. should have glob support. +- recursive .if Long term: - pass meta info for hearing impaired -- cgit From 69ece668ec99e5889be3c4d9a91ef78e199f0d0d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 10 Sep 2007 19:01:33 +0000 Subject: add pulseaudio logo with text git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1788 fefdeb5f-60dc-0310-8127-8f9354f1896f --- pulseaudio-text.svg | 388 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 388 insertions(+) create mode 100644 pulseaudio-text.svg diff --git a/pulseaudio-text.svg b/pulseaudio-text.svg new file mode 100644 index 00000000..0e126130 --- /dev/null +++ b/pulseaudio-text.svg @@ -0,0 +1,388 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + PulseAudio logotype + 2006-08-28 + + + Pierre Ossman <ossman@cendio.se> for Cendio AB + + + + + + + + + + Rafael Jannone (basic idea) + + + + + + + + + + + + + + + + + + + + + + + + + + PulseAudio + + -- cgit From 98f9bd62a6aab266495ef02aa49b0903f0989896 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 10 Sep 2007 20:55:01 +0000 Subject: make sure that the device volume is properly read before we call pa_sink_put() and thus make the pa_sink available git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1789 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-oss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index ccbb183f..1e524fcf 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -1306,9 +1306,9 @@ go_on: /* Read mixer settings */ if (u->source) - pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->source), PA_SOURCE_MESSAGE_GET_VOLUME, &u->source->volume, 0, NULL, NULL); + pa_asyncmsgq_send(u->thread_mq.inq, PA_MSGOBJECT(u->source), PA_SOURCE_MESSAGE_GET_VOLUME, &u->source->volume, 0, NULL); if (u->sink) - pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_GET_VOLUME, &u->sink->volume, 0, NULL, NULL); + pa_asyncmsgq_send(u->thread_mq.inq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_GET_VOLUME, &u->sink->volume, 0, NULL); if (u->sink) pa_sink_put(u->sink); -- cgit From 841fcb4557fcb22d569733648be4dcf035a1fa9a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 10 Sep 2007 20:55:46 +0000 Subject: beef up comment git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1790 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/memchunk.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/memchunk.h b/src/pulsecore/memchunk.h index 99498d07..e6105ace 100644 --- a/src/pulsecore/memchunk.h +++ b/src/pulsecore/memchunk.h @@ -37,7 +37,9 @@ typedef struct pa_memchunk { /* Make a memchunk writable, i.e. make sure that the caller may have * exclusive access to the memblock and it is not read_only. If needed - * the memblock in the structure is replaced by a copy. */ + * the memblock in the structure is replaced by a copy. If min is not + * 0 it is made sure that the returned memblock is at least of the + * specified size, i.e. is enlarged if necessary. */ pa_memchunk* pa_memchunk_make_writable(pa_memchunk *c, size_t min); /* Invalidate a memchunk. This does not free the cotaining memblock, -- cgit From a77158e67a216168064b7552ebe0e38ad750f73b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 10 Sep 2007 20:56:13 +0000 Subject: make the memchunk writeable before silencing it git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1791 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sample-util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c index 4603f7ee..a1361f4e 100644 --- a/src/pulsecore/sample-util.c +++ b/src/pulsecore/sample-util.c @@ -82,6 +82,7 @@ void pa_silence_memchunk(pa_memchunk *c, const pa_sample_spec *spec) { pa_assert(c->memblock); pa_assert(spec); + pa_memchunk_make_writable(c, 0); data = pa_memblock_acquire(c->memblock); pa_silence_memory((uint8_t*) data+c->index, c->length, spec); pa_memblock_release(c->memblock); -- cgit From d5caa0205f0b81c7bfcce3bc244fd11a7231754d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 10 Sep 2007 20:56:36 +0000 Subject: minor cleanup git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1792 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/source-output.c | 2 +- src/pulsecore/source.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 1a9bf96b..42672341 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -283,7 +283,7 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) { pa_assert(chunk); pa_assert(chunk->length); - if (!o->push || o->state == PA_SOURCE_OUTPUT_UNLINKED || o->state == PA_SOURCE_OUTPUT_CORKED) + if (!o->push || o->state == PA_SOURCE_OUTPUT_CORKED) return; pa_assert(o->state == PA_SOURCE_OUTPUT_RUNNING); diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index ee2203e7..f33240ec 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -289,7 +289,6 @@ void pa_source_post(pa_source*s, const pa_memchunk *chunk) { while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) pa_source_output_push(o, chunk); - } } -- cgit From 662988650a020c72e626702b6282ce4df7b6d082 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 10 Sep 2007 20:57:17 +0000 Subject: make sure we send each memblock only once when recording, not twice git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1793 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-native.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index a4983a09..52cec097 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -425,8 +425,7 @@ static int record_stream_process_msg(pa_msgobject *o, int code, void*userdata, i if (!pa_pstream_is_pending(s->connection->pstream)) send_memblock(s->connection); - - pa_pstream_send_memblock(s->connection->pstream, s->index, 0, PA_SEEK_RELATIVE, chunk); + break; } -- cgit From a6f8b813aee1b387f45ff791d75d99580eab574d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 10 Sep 2007 21:48:45 +0000 Subject: simple modernizations: s/assert/pa_assert git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1794 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/thread-mainloop.c | 44 ++++++++++++++++++++++---------------------- src/pulse/timeval.c | 1 + src/pulse/utf8.c | 19 ++++++++++++++----- src/pulse/utf8.h | 2 +- src/pulse/util.c | 31 +++++++++++++++++++++---------- src/pulse/util.h | 2 +- src/pulse/volume.c | 31 ++++++++++++++++--------------- src/pulse/xmalloc.c | 14 +++++++------- 8 files changed, 83 insertions(+), 61 deletions(-) diff --git a/src/pulse/thread-mainloop.c b/src/pulse/thread-mainloop.c index 4f3cacc9..0ed54837 100644 --- a/src/pulse/thread-mainloop.c +++ b/src/pulse/thread-mainloop.c @@ -26,24 +26,24 @@ #include #endif -#include #include #include #ifdef HAVE_SYS_POLL_H #include #else -#include "../pulsecore/poll.h" +#include #endif #include +#include #include #include #include #include +#include -#include "mainloop.h" #include "thread-mainloop.h" struct pa_threaded_mainloop { @@ -63,7 +63,7 @@ static int poll_func(struct pollfd *ufds, unsigned long nfds, int timeout, void pa_mutex *mutex = userdata; int r; - assert(mutex); + pa_assert(mutex); /* Before entering poll() we unlock the mutex, so that * avahi_simple_poll_quit() can succeed from another thread. */ @@ -116,10 +116,10 @@ pa_threaded_mainloop *pa_threaded_mainloop_new(void) { } void pa_threaded_mainloop_free(pa_threaded_mainloop* m) { - assert(m); + pa_assert(m); /* Make sure that this function is not called from the helper thread */ - assert((m->thread && !pa_thread_is_running(m->thread)) || !in_worker(m)); + pa_assert((m->thread && !pa_thread_is_running(m->thread)) || !in_worker(m)); pa_threaded_mainloop_stop(m); @@ -136,9 +136,9 @@ void pa_threaded_mainloop_free(pa_threaded_mainloop* m) { } int pa_threaded_mainloop_start(pa_threaded_mainloop *m) { - assert(m); + pa_assert(m); - assert(!m->thread || !pa_thread_is_running(m->thread)); + pa_assert(!m->thread || !pa_thread_is_running(m->thread)); if (!(m->thread = pa_thread_new(thread, m))) return -1; @@ -147,13 +147,13 @@ int pa_threaded_mainloop_start(pa_threaded_mainloop *m) { } void pa_threaded_mainloop_stop(pa_threaded_mainloop *m) { - assert(m); + pa_assert(m); if (!m->thread || !pa_thread_is_running(m->thread)) return; /* Make sure that this function is not called from the helper thread */ - assert(!in_worker(m)); + pa_assert(!in_worker(m)); pa_mutex_lock(m->mutex); pa_mainloop_quit(m->real_mainloop, 0); @@ -163,25 +163,25 @@ void pa_threaded_mainloop_stop(pa_threaded_mainloop *m) { } void pa_threaded_mainloop_lock(pa_threaded_mainloop *m) { - assert(m); + pa_assert(m); /* Make sure that this function is not called from the helper thread */ - assert(!m->thread || !pa_thread_is_running(m->thread) || !in_worker(m)); + pa_assert(!m->thread || !pa_thread_is_running(m->thread) || !in_worker(m)); pa_mutex_lock(m->mutex); } void pa_threaded_mainloop_unlock(pa_threaded_mainloop *m) { - assert(m); + pa_assert(m); /* Make sure that this function is not called from the helper thread */ - assert(!m->thread || !pa_thread_is_running(m->thread) || !in_worker(m)); + pa_assert(!m->thread || !pa_thread_is_running(m->thread) || !in_worker(m)); pa_mutex_unlock(m->mutex); } void pa_threaded_mainloop_signal(pa_threaded_mainloop *m, int wait_for_accept) { - assert(m); + pa_assert(m); pa_cond_signal(m->cond, 1); @@ -190,36 +190,36 @@ void pa_threaded_mainloop_signal(pa_threaded_mainloop *m, int wait_for_accept) { } void pa_threaded_mainloop_wait(pa_threaded_mainloop *m) { - assert(m); + pa_assert(m); /* Make sure that this function is not called from the helper thread */ - assert(!m->thread || !pa_thread_is_running(m->thread) || !in_worker(m)); + pa_assert(!m->thread || !pa_thread_is_running(m->thread) || !in_worker(m)); m->n_waiting ++; pa_cond_wait(m->cond, m->mutex); - assert(m->n_waiting > 0); + pa_assert(m->n_waiting > 0); m->n_waiting --; } void pa_threaded_mainloop_accept(pa_threaded_mainloop *m) { - assert(m); + pa_assert(m); /* Make sure that this function is not called from the helper thread */ - assert(!m->thread || !pa_thread_is_running(m->thread) || !in_worker(m)); + pa_assert(!m->thread || !pa_thread_is_running(m->thread) || !in_worker(m)); pa_cond_signal(m->accept_cond, 0); } int pa_threaded_mainloop_get_retval(pa_threaded_mainloop *m) { - assert(m); + pa_assert(m); return pa_mainloop_get_retval(m->real_mainloop); } pa_mainloop_api* pa_threaded_mainloop_get_api(pa_threaded_mainloop*m) { - assert(m); + pa_assert(m); return pa_mainloop_get_api(m->real_mainloop); } diff --git a/src/pulse/timeval.c b/src/pulse/timeval.c index ba1128c4..44d74c94 100644 --- a/src/pulse/timeval.c +++ b/src/pulse/timeval.c @@ -79,6 +79,7 @@ struct timeval *pa_gettimeofday(struct timeval *tv) { pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) { pa_usec_t r; + pa_assert(a); pa_assert(b); diff --git a/src/pulse/utf8.c b/src/pulse/utf8.c index a179b3fc..a02c5d1d 100644 --- a/src/pulse/utf8.c +++ b/src/pulse/utf8.c @@ -59,14 +59,15 @@ #include #endif +#include #include #include "utf8.h" -#include "xmalloc.h" #define FILTER_CHAR '_' static inline int is_unicode_valid(uint32_t ch) { + if (ch >= 0x110000) /* End of unicode space */ return 0; if ((ch & 0xFFFFF800) == 0xD800) /* Reserved area for UTF-16 */ @@ -75,6 +76,7 @@ static inline int is_unicode_valid(uint32_t ch) { return 0; if ((ch & 0xFFFE) == 0xFFFE) /* BOM (Byte Order Mark) */ return 0; + return 1; } @@ -96,6 +98,8 @@ static char* utf8_validate(const char *str, char *output) { int size; uint8_t *o; + pa_assert(str); + o = (uint8_t*) output; for (p = (const uint8_t*) str; *p; p++) { if (*p < 128) { @@ -179,15 +183,15 @@ failure: return NULL; } -const char* pa_utf8_valid (const char *str) { +char* pa_utf8_valid (const char *str) { return utf8_validate(str, NULL); } char* pa_utf8_filter (const char *str) { char *new_str; + pa_assert(str); new_str = pa_xnew(char, strlen(str) + 1); - return utf8_validate(str, new_str); } @@ -196,18 +200,21 @@ char* pa_utf8_filter (const char *str) { static char* iconv_simple(const char *str, const char *to, const char *from) { char *new_str; size_t len, inlen; - iconv_t cd; ICONV_CONST char *inbuf; char *outbuf; size_t res, inbytes, outbytes; + pa_assert(str); + pa_assert(to); + pa_assert(from); + cd = iconv_open(to, from); if (cd == (iconv_t)-1) return NULL; inlen = len = strlen(str) + 1; - new_str = pa_xmalloc(len); + new_str = pa_xnew(char, len); for (;;) { inbuf = (ICONV_CONST char*) str; /* Brain dead prototype for iconv() */ @@ -248,10 +255,12 @@ char* pa_locale_to_utf8 (const char *str) { #else char* pa_utf8_to_locale (const char *str) { + pa_assert(str); return NULL; } char* pa_locale_to_utf8 (const char *str) { + pa_assert(str); return NULL; } diff --git a/src/pulse/utf8.h b/src/pulse/utf8.h index ff8dc215..ea08840b 100644 --- a/src/pulse/utf8.h +++ b/src/pulse/utf8.h @@ -34,7 +34,7 @@ PA_C_DECL_BEGIN /** Test if the specified strings qualifies as valid UTF8. Return the string if so, otherwise NULL */ -const char *pa_utf8_valid(const char *str); +char *pa_utf8_valid(const char *str); /** Filter all invalid UTF8 characters from the specified string, returning a new fully UTF8 valid string. Don't forget to free the returned string with pa_xfree() */ char *pa_utf8_filter(const char *str); diff --git a/src/pulse/util.c b/src/pulse/util.c index c4f2cf78..879b7bf1 100644 --- a/src/pulse/util.c +++ b/src/pulse/util.c @@ -56,11 +56,11 @@ #include #endif -#include "../pulsecore/winsock.h" - +#include #include #include #include +#include #include "util.h" @@ -78,7 +78,8 @@ char *pa_get_user_name(char *s, size_t l) { struct passwd pw, *r; #endif - assert(s && l > 0); + pa_assert(s); + pa_assert(l > 0); if (!(p = getenv("USER")) && !(p = getenv("LOGNAME")) && !(p = getenv("USERNAME"))) { #ifdef HAVE_PWD_H @@ -113,11 +114,15 @@ char *pa_get_user_name(char *s, size_t l) { } char *pa_get_host_name(char *s, size_t l) { - assert(s && l > 0); + + pa_assert(s); + pa_assert(l > 0); + if (gethostname(s, l) < 0) { pa_log("gethostname(): %s", pa_cstrerror(errno)); return NULL; } + s[l-1] = 0; return s; } @@ -130,7 +135,8 @@ char *pa_get_home_dir(char *s, size_t l) { struct passwd pw, *r; #endif - assert(s && l); + pa_assert(s); + pa_assert(l > 0); if ((e = getenv("HOME"))) return pa_strlcpy(s, e, l); @@ -159,8 +165,8 @@ char *pa_get_home_dir(char *s, size_t l) { char *pa_get_binary_name(char *s, size_t l) { - assert(s); - assert(l); + pa_assert(s); + pa_assert(l > 0); #if defined(OS_IS_WIN32) { @@ -171,7 +177,7 @@ char *pa_get_binary_name(char *s, size_t l) { } #endif -#ifdef HAVE_READLINK +#ifdef __linux__ { int i; char path[PATH_MAX]; @@ -206,13 +212,15 @@ char *pa_get_binary_name(char *s, size_t l) { return NULL; } -const char *pa_path_get_filename(const char *p) { +char *pa_path_get_filename(const char *p) { char *fn; + pa_assert(p); + if ((fn = strrchr(p, PATH_SEP))) return fn+1; - return (const char*) p; + return (char*) p; } char *pa_get_fqdn(char *s, size_t l) { @@ -221,6 +229,9 @@ char *pa_get_fqdn(char *s, size_t l) { struct addrinfo *a, hints; #endif + pa_assert(s); + pa_assert(l > 0); + if (!pa_get_host_name(hn, sizeof(hn))) return NULL; diff --git a/src/pulse/util.h b/src/pulse/util.h index 95bd86f3..764678e5 100644 --- a/src/pulse/util.h +++ b/src/pulse/util.h @@ -52,7 +52,7 @@ char *pa_get_binary_name(char *s, size_t l); /** Return a pointer to the filename inside a path (which is the last * component). */ -const char *pa_path_get_filename(const char *p); +char *pa_path_get_filename(const char *p); /** Wait t milliseconds */ int pa_msleep(unsigned long t); diff --git a/src/pulse/volume.c b/src/pulse/volume.c index 8bba834d..3688b847 100644 --- a/src/pulse/volume.c +++ b/src/pulse/volume.c @@ -25,17 +25,18 @@ #include #endif -#include #include #include #include +#include + #include "volume.h" int pa_cvolume_equal(const pa_cvolume *a, const pa_cvolume *b) { int i; - assert(a); - assert(b); + pa_assert(a); + pa_assert(b); if (a->channels != b->channels) return 0; @@ -50,9 +51,9 @@ int pa_cvolume_equal(const pa_cvolume *a, const pa_cvolume *b) { pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v) { int i; - assert(a); - assert(channels > 0); - assert(channels <= PA_CHANNELS_MAX); + pa_assert(a); + pa_assert(channels > 0); + pa_assert(channels <= PA_CHANNELS_MAX); a->channels = channels; @@ -65,7 +66,7 @@ pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v) { pa_volume_t pa_cvolume_avg(const pa_cvolume *a) { uint64_t sum = 0; int i; - assert(a); + pa_assert(a); for (i = 0; i < a->channels; i++) sum += a->values[i]; @@ -119,9 +120,9 @@ char *pa_cvolume_snprint(char *s, size_t l, const pa_cvolume *c) { int first = 1; char *e; - assert(s); - assert(l > 0); - assert(c); + pa_assert(s); + pa_assert(l > 0); + pa_assert(c); *(e = s) = 0; @@ -141,7 +142,7 @@ char *pa_cvolume_snprint(char *s, size_t l, const pa_cvolume *c) { /** Return non-zero if the volume of all channels is equal to the specified value */ int pa_cvolume_channels_equal_to(const pa_cvolume *a, pa_volume_t v) { unsigned c; - assert(a); + pa_assert(a); for (c = 0; c < a->channels; c++) if (a->values[c] != v) @@ -153,9 +154,9 @@ int pa_cvolume_channels_equal_to(const pa_cvolume *a, pa_volume_t v) { pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b) { unsigned i; - assert(dest); - assert(a); - assert(b); + pa_assert(dest); + pa_assert(a); + pa_assert(b); for (i = 0; i < a->channels && i < b->channels && i < PA_CHANNELS_MAX; i++) { @@ -170,7 +171,7 @@ pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const } int pa_cvolume_valid(const pa_cvolume *v) { - assert(v); + pa_assert(v); if (v->channels <= 0 || v->channels > PA_CHANNELS_MAX) return 0; diff --git a/src/pulse/xmalloc.c b/src/pulse/xmalloc.c index 1f0734c2..5348dda4 100644 --- a/src/pulse/xmalloc.c +++ b/src/pulse/xmalloc.c @@ -27,12 +27,12 @@ #include #include -#include #include #include #include #include +#include #include "xmalloc.h" @@ -60,8 +60,8 @@ static void oom(void) { void* pa_xmalloc(size_t size) { void *p; - assert(size > 0); - assert(size < MAX_ALLOC_SIZE); + pa_assert(size > 0); + pa_assert(size < MAX_ALLOC_SIZE); if (!(p = malloc(size))) oom(); @@ -71,8 +71,8 @@ void* pa_xmalloc(size_t size) { void* pa_xmalloc0(size_t size) { void *p; - assert(size > 0); - assert(size < MAX_ALLOC_SIZE); + pa_assert(size > 0); + pa_assert(size < MAX_ALLOC_SIZE); if (!(p = calloc(1, size))) oom(); @@ -82,8 +82,8 @@ void* pa_xmalloc0(size_t size) { void *pa_xrealloc(void *ptr, size_t size) { void *p; - assert(size > 0); - assert(size < MAX_ALLOC_SIZE); + pa_assert(size > 0); + pa_assert(size < MAX_ALLOC_SIZE); if (!(p = realloc(ptr, size))) oom(); -- cgit From de21b54bd1f1d2caa5c20da4be0dc118b0ab7c34 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 10 Sep 2007 21:58:01 +0000 Subject: add new API pa_threaded_mainloop_in_thread(), update test case for it git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1795 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/thread-mainloop.c | 6 ++++++ src/pulse/thread-mainloop.h | 3 +++ src/tests/thread-mainloop-test.c | 13 +++++++------ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/pulse/thread-mainloop.c b/src/pulse/thread-mainloop.c index 0ed54837..29769e2b 100644 --- a/src/pulse/thread-mainloop.c +++ b/src/pulse/thread-mainloop.c @@ -223,3 +223,9 @@ pa_mainloop_api* pa_threaded_mainloop_get_api(pa_threaded_mainloop*m) { return pa_mainloop_get_api(m->real_mainloop); } + +int pa_threaded_mainloop_in_thread(pa_threaded_mainloop *m) { + pa_assert(m); + + return m->thread && pa_thread_self() == m->thread; +} diff --git a/src/pulse/thread-mainloop.h b/src/pulse/thread-mainloop.h index b78c1583..ea08f72a 100644 --- a/src/pulse/thread-mainloop.h +++ b/src/pulse/thread-mainloop.h @@ -297,6 +297,9 @@ int pa_threaded_mainloop_get_retval(pa_threaded_mainloop *m); /** Return the abstract main loop abstraction layer vtable for this main loop. */ pa_mainloop_api* pa_threaded_mainloop_get_api(pa_threaded_mainloop*m); +/** Returns non-zero when called from withing the event loop thread. \since 0.9.7 */ +int pa_threaded_mainloop_in_thread(pa_threaded_mainloop *m); + PA_C_DECL_END #endif diff --git a/src/tests/thread-mainloop-test.c b/src/tests/thread-mainloop-test.c index 9d0e5de1..be1f1ec2 100644 --- a/src/tests/thread-mainloop-test.c +++ b/src/tests/thread-mainloop-test.c @@ -23,18 +23,19 @@ #include #endif -#include #include #include #include #include #include +#include #include -#include +#include static void tcb(pa_mainloop_api*a, pa_time_event *e, const struct timeval *tv, void *userdata) { + pa_assert_se(pa_threaded_mainloop_in_thread(userdata)); fprintf(stderr, "TIME EVENT START\n"); pa_threaded_mainloop_signal(userdata, 1); fprintf(stderr, "TIME EVENT END\n"); @@ -45,15 +46,15 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { pa_threaded_mainloop *m; struct timeval tv; - m = pa_threaded_mainloop_new(); - assert(m); - a = pa_threaded_mainloop_get_api(m); - assert(a); + pa_assert_se(m = pa_threaded_mainloop_new()); + pa_assert_se(a = pa_threaded_mainloop_get_api(m)); pa_threaded_mainloop_start(m); pa_threaded_mainloop_lock(m); + pa_assert_se(!pa_threaded_mainloop_in_thread(m)); + pa_gettimeofday(&tv); tv.tv_sec += 5; a->time_new(a, &tv, tcb, m); -- cgit From 3d122d0fee2e3d853ea1a1de297b249f2c125f73 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 10 Sep 2007 22:17:30 +0000 Subject: s/assert/pa_assert/ modernizations git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1796 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/mainloop-signal.c | 50 ++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/src/pulse/mainloop-signal.c b/src/pulse/mainloop-signal.c index 28ddec49..18fd86f8 100644 --- a/src/pulse/mainloop-signal.c +++ b/src/pulse/mainloop-signal.c @@ -27,7 +27,6 @@ #endif #include -#include #include #include #include @@ -39,12 +38,13 @@ #include #endif -#include #include +#include #include #include #include +#include #include "mainloop-signal.h" @@ -74,11 +74,11 @@ static void signal_handler(int sig) { } static void dispatch(pa_mainloop_api*a, int sig) { - pa_signal_event*s; + pa_signal_event *s; for (s = signals; s; s = s->next) if (s->sig == sig) { - assert(s->callback); + pa_assert(s->callback); s->callback(a, s, sig, s->userdata); break; } @@ -87,7 +87,12 @@ static void dispatch(pa_mainloop_api*a, int sig) { static void callback(pa_mainloop_api*a, pa_io_event*e, int fd, pa_io_event_flags_t f, PA_GCC_UNUSED void *userdata) { ssize_t r; int sig; - assert(a && e && f == PA_IO_EVENT_INPUT && e == io_event && fd == signal_pipe[0]); + + pa_assert(a); + pa_assert(e); + pa_assert(f == PA_IO_EVENT_INPUT); + pa_assert(e == io_event); + pa_assert(fd == signal_pipe[0]); if ((r = pa_read(signal_pipe[0], &sig, sizeof(sig), NULL)) < 0) { if (errno == EAGAIN) @@ -107,7 +112,11 @@ static void callback(pa_mainloop_api*a, pa_io_event*e, int fd, pa_io_event_flags int pa_signal_init(pa_mainloop_api *a) { - assert(!api && a && signal_pipe[0] == -1 && signal_pipe[1] == -1 && !io_event); + pa_assert(a); + pa_assert(!api); + pa_assert(signal_pipe[0] == -1); + pa_assert(signal_pipe[1] == -1); + pa_assert(!io_event); if (pipe(signal_pipe) < 0) { pa_log("pipe(): %s", pa_cstrerror(errno)); @@ -116,19 +125,21 @@ int pa_signal_init(pa_mainloop_api *a) { pa_make_nonblock_fd(signal_pipe[0]); pa_make_nonblock_fd(signal_pipe[1]); - pa_fd_set_cloexec(signal_pipe[0], 1); - pa_fd_set_cloexec(signal_pipe[1], 1); + pa_assert_se(pa_fd_set_cloexec(signal_pipe[0], 1) == 0); + pa_assert_se(pa_fd_set_cloexec(signal_pipe[1], 1) == 0); api = a; - io_event = api->io_new(api, signal_pipe[0], PA_IO_EVENT_INPUT, callback, NULL); - assert(io_event); + pa_assert_se(io_event = api->io_new(api, signal_pipe[0], PA_IO_EVENT_INPUT, callback, NULL)); return 0; } void pa_signal_done(void) { - assert(api && signal_pipe[0] >= 0 && signal_pipe[1] >= 0 && io_event); + pa_assert(api); + pa_assert(signal_pipe[0] >= 0); + pa_assert(signal_pipe[1] >= 0); + pa_assert(io_event); while (signals) pa_signal_free(signals); @@ -136,8 +147,8 @@ void pa_signal_done(void) { api->io_free(io_event); io_event = NULL; - close(signal_pipe[0]); - close(signal_pipe[1]); + pa_assert_se(close(signal_pipe[0]) == 0); + pa_assert_se(close(signal_pipe[1]) == 0); signal_pipe[0] = signal_pipe[1] = -1; api = NULL; @@ -150,13 +161,13 @@ pa_signal_event* pa_signal_new(int sig, void (*_callback) (pa_mainloop_api *api, struct sigaction sa; #endif - assert(sig > 0 && _callback); + pa_assert(sig > 0 && _callback); for (e = signals; e; e = e->next) if (e->sig == sig) goto fail; - e = pa_xmalloc(sizeof(pa_signal_event)); + e = pa_xnew(pa_signal_event, 1); e->sig = sig; e->callback = _callback; e->userdata = userdata; @@ -186,7 +197,7 @@ fail: } void pa_signal_free(pa_signal_event *e) { - assert(e); + pa_assert(e); if (e->next) e->next->previous = e->previous; @@ -196,9 +207,9 @@ void pa_signal_free(pa_signal_event *e) { signals = e->next; #ifdef HAVE_SIGACTION - sigaction(e->sig, &e->saved_sigaction, NULL); + pa_assert_se(sigaction(e->sig, &e->saved_sigaction, NULL) == 0); #else - signal(e->sig, e->saved_handler); + pa_assert_se(signal(e->sig, e->saved_handler) == signal_handler); #endif if (e->destroy_callback) @@ -208,6 +219,7 @@ void pa_signal_free(pa_signal_event *e) { } void pa_signal_set_destroy(pa_signal_event *e, void (*_callback) (pa_mainloop_api *api, pa_signal_event*e, void *userdata)) { - assert(e); + pa_assert(e); + e->destroy_callback = _callback; } -- cgit From 9b0ab39b1c443744bb7b09b03e62e51d78aab527 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 10 Sep 2007 23:57:10 +0000 Subject: unify static TLS support, make use of gcc __thread attribute if available git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1797 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 12 ++++++++++++ src/daemon/main.c | 6 +++--- src/pulsecore/atomic.h | 2 +- src/pulsecore/rtsig.c | 4 ++-- src/pulsecore/thread-mq.c | 14 ++++---------- src/pulsecore/thread-posix.c | 18 +++++------------- src/pulsecore/thread.h | 35 ++++++++++++++++++++++++++++++++--- 7 files changed, 59 insertions(+), 32 deletions(-) diff --git a/configure.ac b/configure.ac index c4f26c4e..7c8f3888 100644 --- a/configure.ac +++ b/configure.ac @@ -118,6 +118,18 @@ else AC_MSG_RESULT([no]) fi +AC_MSG_CHECKING([whether $CC knows __thread]) +AC_LANG_CONFTEST([static __thread int a = 6; int main() { a = 5; }]) +$CC conftest.c $CFLAGS -o conftest > /dev/null 2> /dev/null +ret=$? +rm -f conftest.o conftest +if test $ret -eq 0 ; then + AC_DEFINE([HAVE_TLS_BUILTIN], 1, [Have __thread().]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + #### libtool stuff #### AC_LTDL_ENABLE_INSTALL diff --git a/src/daemon/main.c b/src/daemon/main.c index 135a9ab6..ed5aa440 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -324,14 +324,14 @@ static void libtool_unlock(void) { pa_mutex_unlock(libtool_mutex); } -PA_STATIC_TLS_DECLARE(libtool_tls, NULL); +PA_STATIC_TLS_DECLARE_NO_FREE(libtool_tls); static void libtool_set_error(const char * error) { - pa_tls_set(PA_STATIC_TLS_GET(libtool_tls), (char*) error); + PA_STATIC_TLS_SET(libtool_tls, (char*) error); } static const char *libtool_get_error(void) { - return pa_tls_get(PA_STATIC_TLS_GET(libtool_tls)); + return PA_STATIC_TLS_GET(libtool_tls); } static void libtool_init(void) { diff --git a/src/pulsecore/atomic.h b/src/pulsecore/atomic.h index 6fb85f09..0e3bfb9a 100644 --- a/src/pulsecore/atomic.h +++ b/src/pulsecore/atomic.h @@ -37,7 +37,7 @@ * libatomic_ops */ -/* We have to include config.h here, which sucks */ +/* We have to include config.h here (for the __sync stuff), which sucks */ #ifdef HAVE_CONFIG_H #include #endif diff --git a/src/pulsecore/rtsig.c b/src/pulsecore/rtsig.c index a3226a0e..3513bedf 100644 --- a/src/pulsecore/rtsig.c +++ b/src/pulsecore/rtsig.c @@ -71,13 +71,13 @@ int pa_rtsig_get_for_thread(void) { int sig; void *p; - if ((p = pa_tls_get(PA_STATIC_TLS_GET(rtsig_tls)))) + if ((p = PA_STATIC_TLS_GET(rtsig_tls))) return PA_PTR_TO_INT(p); if ((sig = pa_rtsig_get()) < 0) return -1; - pa_tls_set(PA_STATIC_TLS_GET(rtsig_tls), PA_INT_TO_PTR(sig)); + PA_STATIC_TLS_SET(rtsig_tls, PA_INT_TO_PTR(sig)); return sig; } diff --git a/src/pulsecore/thread-mq.c b/src/pulsecore/thread-mq.c index 3c466ceb..3000246a 100644 --- a/src/pulsecore/thread-mq.c +++ b/src/pulsecore/thread-mq.c @@ -41,8 +41,7 @@ #include "thread-mq.h" -static pa_once once = PA_ONCE_INIT; -static pa_tls *tls; +PA_STATIC_TLS_DECLARE_NO_FREE(thread_mq); static void asyncmsgq_cb(pa_mainloop_api*api, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) { pa_thread_mq *q = userdata; @@ -101,20 +100,15 @@ void pa_thread_mq_done(pa_thread_mq *q) { q->mainloop = NULL; } -static void init_tls(void) { - tls = pa_tls_new(NULL); -} - void pa_thread_mq_install(pa_thread_mq *q) { pa_assert(q); - pa_run_once(&once, init_tls); - pa_tls_set(tls, q); + pa_assert(!(PA_STATIC_TLS_GET(thread_mq))); + PA_STATIC_TLS_SET(thread_mq, q); } pa_thread_mq *pa_thread_mq_get(void) { - pa_run_once(&once, init_tls); - return pa_tls_get(tls); + return PA_STATIC_TLS_GET(thread_mq); } int pa_thread_mq_process(pa_thread_mq *q) { diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c index 6ad5ac4a..3c69adfb 100644 --- a/src/pulsecore/thread-posix.c +++ b/src/pulsecore/thread-posix.c @@ -49,9 +49,6 @@ struct pa_tls { pthread_key_t key; }; -static pthread_key_t thread_key; -static pthread_once_t thread_once = PTHREAD_ONCE_INIT; - static void thread_free_cb(void *p) { pa_thread *t = p; @@ -62,9 +59,7 @@ static void thread_free_cb(void *p) { pa_xfree(t); } -static void thread_once_func(void) { - pa_assert_se(pthread_key_create(&thread_key, thread_free_cb) == 0); -} +PA_STATIC_TLS_DECLARE(current_thread, thread_free_cb); static void* internal_thread_func(void *userdata) { pa_thread *t = userdata; @@ -72,8 +67,7 @@ static void* internal_thread_func(void *userdata) { t->id = pthread_self(); - pthread_once(&thread_once, thread_once_func); - pthread_setspecific(thread_key, t); + PA_STATIC_TLS_SET(current_thread, t); pa_atomic_inc(&t->running); t->thread_func(t->userdata); @@ -130,11 +124,9 @@ int pa_thread_join(pa_thread *t) { pa_thread* pa_thread_self(void) { pa_thread *t; - pthread_once(&thread_once, thread_once_func); - - if ((t = pthread_getspecific(thread_key))) + if ((t = PA_STATIC_TLS_GET(current_thread))) return t; - + /* This is a foreign thread, let's create a pthread structure to * make sure that we can always return a sensible pointer */ @@ -144,7 +136,7 @@ pa_thread* pa_thread_self(void) { t->userdata = NULL; pa_atomic_store(&t->running, 2); - pthread_setspecific(thread_key, t); + PA_STATIC_TLS_SET(current_thread, t); return t; } diff --git a/src/pulsecore/thread.h b/src/pulsecore/thread.h index 44b80a06..a0e331be 100644 --- a/src/pulsecore/thread.h +++ b/src/pulsecore/thread.h @@ -26,6 +26,12 @@ ***/ #include +#include + +/* We have to include config.h here (for the __tls stuff), which sucks */ +#ifdef HAVE_CONFIG_H +#include +#endif typedef struct pa_thread pa_thread; @@ -48,8 +54,6 @@ void pa_tls_free(pa_tls *t); void * pa_tls_get(pa_tls *t); void *pa_tls_set(pa_tls *t, void *userdata); -/* To make use of the static TLS stuff you have to include once.h, as well */ - #define PA_STATIC_TLS_DECLARE(name, free_cb) \ static struct { \ pa_once once; \ @@ -61,7 +65,7 @@ void *pa_tls_set(pa_tls *t, void *userdata); static void name##_tls_init(void) { \ name##_tls.tls = pa_tls_new(free_cb); \ } \ - static inline pa_tls* name##_tls_get(void) { \ + static inline pa_tls* name##_tls_obj(void) { \ pa_run_once(&name##_tls.once, name##_tls_init); \ return name##_tls.tls; \ } \ @@ -70,8 +74,33 @@ void *pa_tls_set(pa_tls *t, void *userdata); if (name##_tls.tls) \ pa_tls_free(name##_tls.tls); \ } \ + static inline void* name##_tls_get(void) { \ + return pa_tls_get(name##_tls_obj()); \ + } \ + static inline void* name##_tls_set(void *p) { \ + return pa_tls_set(name##_tls_obj(), p); \ + } \ struct __stupid_useless_struct_to_allow_trailing_semicolon +#ifdef HAVE_TLS_BUILTIN +/* An optimized version of the above that requires no dynamic + * allocation if the compiler supports __thread */ +#define PA_STATIC_TLS_DECLARE_NO_FREE(name) \ + static __thread void *name##_tls; \ + static inline void* name##_tls_get(void) { \ + return name##_tls; \ + } \ + static inline void* name##_tls_set(void *p) { \ + void *r = name##_tls; \ + name##_tls = p; \ + return r; \ + } \ + struct __stupid_useless_struct_to_allow_trailing_semicolon +#else +#define PA_STATIC_TLS_DECLARE_NO_FREE(name) PA_STATIC_TLS_DECLARE(name, NULL) +#endif + #define PA_STATIC_TLS_GET(name) (name##_tls_get()) +#define PA_STATIC_TLS_SET(name, p) (name##_tls_set(p)) #endif -- cgit From 848a4d7487bdce14f8231698666fb24d5397e091 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Sep 2007 00:24:10 +0000 Subject: more s/assert/pa_assert/ modernizations git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1798 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/channelmap.c | 30 ++++----- src/pulse/client-conf-x11.c | 6 +- src/pulse/client-conf.c | 11 ++-- src/pulse/mainloop-api.c | 24 ++++--- src/pulse/mainloop.c | 151 ++++++++++++++++++++++---------------------- src/pulse/operation.c | 35 +++++----- 6 files changed, 132 insertions(+), 125 deletions(-) diff --git a/src/pulse/channelmap.c b/src/pulse/channelmap.c index c53626fd..2b8ef2b0 100644 --- a/src/pulse/channelmap.c +++ b/src/pulse/channelmap.c @@ -27,12 +27,12 @@ #endif #include -#include #include #include #include #include +#include #include "channelmap.h" @@ -164,7 +164,7 @@ const char *const pretty_table[] = { pa_channel_map* pa_channel_map_init(pa_channel_map *m) { unsigned c; - assert(m); + pa_assert(m); m->channels = 0; @@ -175,7 +175,7 @@ pa_channel_map* pa_channel_map_init(pa_channel_map *m) { } pa_channel_map* pa_channel_map_init_mono(pa_channel_map *m) { - assert(m); + pa_assert(m); pa_channel_map_init(m); @@ -185,7 +185,7 @@ pa_channel_map* pa_channel_map_init_mono(pa_channel_map *m) { } pa_channel_map* pa_channel_map_init_stereo(pa_channel_map *m) { - assert(m); + pa_assert(m); pa_channel_map_init(m); @@ -196,9 +196,9 @@ pa_channel_map* pa_channel_map_init_stereo(pa_channel_map *m) { } pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, pa_channel_map_def_t def) { - assert(m); - assert(channels > 0); - assert(channels <= PA_CHANNELS_MAX); + pa_assert(m); + pa_assert(channels > 0); + pa_assert(channels <= PA_CHANNELS_MAX); pa_channel_map_init(m); @@ -415,8 +415,8 @@ const char* pa_channel_position_to_pretty_string(pa_channel_position_t pos) { int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) { unsigned c; - assert(a); - assert(b); + pa_assert(a); + pa_assert(b); if (a->channels != b->channels) return 0; @@ -433,9 +433,9 @@ char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map) { int first = 1; char *e; - assert(s); - assert(l > 0); - assert(map); + pa_assert(s); + pa_assert(l > 0); + pa_assert(map); *(e = s) = 0; @@ -456,8 +456,8 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) { pa_channel_map map; char *p; - assert(rmap); - assert(s); + pa_assert(rmap); + pa_assert(s); memset(&map, 0, sizeof(map)); @@ -517,7 +517,7 @@ finish: int pa_channel_map_valid(const pa_channel_map *map) { unsigned c; - assert(map); + pa_assert(map); if (map->channels <= 0 || map->channels > PA_CHANNELS_MAX) return 0; diff --git a/src/pulse/client-conf-x11.c b/src/pulse/client-conf-x11.c index e8de9553..e240ba88 100644 --- a/src/pulse/client-conf-x11.c +++ b/src/pulse/client-conf-x11.c @@ -26,7 +26,6 @@ #endif #include -#include #include #include @@ -36,6 +35,7 @@ #include #include #include +#include #include "client-conf-x11.h" @@ -44,6 +44,8 @@ int pa_client_conf_from_x11(pa_client_conf *c, const char *dname) { int ret = -1; char t[1024]; + pa_assert(c); + if (!dname && (!(dname = getenv("DISPLAY")) || *dname == '\0')) goto finish; @@ -75,7 +77,7 @@ int pa_client_conf_from_x11(pa_client_conf *c, const char *dname) { goto finish; } - assert(sizeof(cookie) == sizeof(c->cookie)); + pa_assert(sizeof(cookie) == sizeof(c->cookie)); memcpy(c->cookie, cookie, sizeof(cookie)); c->cookie_valid = 1; diff --git a/src/pulse/client-conf.c b/src/pulse/client-conf.c index bb912335..d1e9969d 100644 --- a/src/pulse/client-conf.c +++ b/src/pulse/client-conf.c @@ -27,14 +27,14 @@ #endif #include -#include #include #include #include -#include #include +#include +#include #include #include #include @@ -81,7 +81,7 @@ pa_client_conf *pa_client_conf_new(void) { } void pa_client_conf_free(pa_client_conf *c) { - assert(c); + pa_assert(c); pa_xfree(c->daemon_binary); pa_xfree(c->extra_arguments); pa_xfree(c->default_sink); @@ -90,6 +90,7 @@ void pa_client_conf_free(pa_client_conf *c) { pa_xfree(c->cookie_file); pa_xfree(c); } + int pa_client_conf_load(pa_client_conf *c, const char *filename) { FILE *f = NULL; char *fn = NULL; @@ -122,7 +123,7 @@ int pa_client_conf_load(pa_client_conf *c, const char *filename) { pa_open_config_file(DEFAULT_CLIENT_CONFIG_FILE, DEFAULT_CLIENT_CONFIG_FILE_USER, ENV_CLIENT_CONFIG_FILE, &fn, "r"); if (!f && errno != EINTR) { - pa_log("WARNING: failed to open configuration file '%s': %s", fn, pa_cstrerror(errno)); + pa_log_warn("WARNING: failed to open configuration file '%s': %s", fn, pa_cstrerror(errno)); goto finish; } @@ -175,7 +176,7 @@ int pa_client_conf_env(pa_client_conf *c) { } int pa_client_conf_load_cookie(pa_client_conf* c) { - assert(c); + pa_assert(c); c->cookie_valid = 0; diff --git a/src/pulse/mainloop-api.c b/src/pulse/mainloop-api.c index 001ff314..989a5cc1 100644 --- a/src/pulse/mainloop-api.c +++ b/src/pulse/mainloop-api.c @@ -25,12 +25,12 @@ #include #endif -#include #include #include #include +#include #include "mainloop-api.h" @@ -41,32 +41,38 @@ struct once_info { static void once_callback(pa_mainloop_api *m, pa_defer_event *e, void *userdata) { struct once_info *i = userdata; - assert(m && i && i->callback); - + + pa_assert(m); + pa_assert(i); + + pa_assert(i->callback); i->callback(m, i->userdata); - assert(m->defer_free); + pa_assert(m->defer_free); m->defer_free(e); } static void free_callback(pa_mainloop_api *m, PA_GCC_UNUSED pa_defer_event *e, void *userdata) { struct once_info *i = userdata; - assert(m && i); + + pa_assert(m); + pa_assert(i); pa_xfree(i); } void pa_mainloop_api_once(pa_mainloop_api* m, void (*callback)(pa_mainloop_api *m, void *userdata), void *userdata) { struct once_info *i; pa_defer_event *e; - assert(m && callback); + + pa_assert(m); + pa_assert(callback); i = pa_xnew(struct once_info, 1); i->callback = callback; i->userdata = userdata; - assert(m->defer_new); - e = m->defer_new(m, once_callback, i); - assert(e); + pa_assert(m->defer_new); + pa_assert_se(e = m->defer_new(m, once_callback, i)); m->defer_set_destroy(e, free_callback); } diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index 0dd0e119..a5304ff5 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -31,29 +31,28 @@ #include #include #include -#include #include #include #ifdef HAVE_SYS_POLL_H #include #else -#include "../pulsecore/poll.h" +#include #endif -#include "../pulsecore/winsock.h" - #ifndef HAVE_PIPE -#include "../pulsecore/pipe.h" +#include #endif -#include #include #include #include #include #include +#include +#include +#include #include "mainloop.h" @@ -161,13 +160,13 @@ static pa_io_event* mainloop_io_new( pa_mainloop *m; pa_io_event *e; - assert(a); - assert(a->userdata); - assert(fd >= 0); - assert(callback); + pa_assert(a); + pa_assert(a->userdata); + pa_assert(fd >= 0); + pa_assert(callback); m = a->userdata; - assert(a == &m->api); + pa_assert(a == &m->api); e = pa_xnew(pa_io_event, 1); e->mainloop = m; @@ -211,8 +210,8 @@ static pa_io_event* mainloop_io_new( } static void mainloop_io_enable(pa_io_event *e, pa_io_event_flags_t events) { - assert(e); - assert(!e->dead); + pa_assert(e); + pa_assert(!e->dead); if (e->events == events) return; @@ -228,8 +227,8 @@ static void mainloop_io_enable(pa_io_event *e, pa_io_event_flags_t events) { } static void mainloop_io_free(pa_io_event *e) { - assert(e); - assert(!e->dead); + pa_assert(e); + pa_assert(!e->dead); e->dead = 1; e->mainloop->io_events_please_scan ++; @@ -241,7 +240,7 @@ static void mainloop_io_free(pa_io_event *e) { } static void mainloop_io_set_destroy(pa_io_event *e, pa_io_event_destroy_cb_t callback) { - assert(e); + pa_assert(e); e->destroy_callback = callback; } @@ -255,12 +254,12 @@ static pa_defer_event* mainloop_defer_new( pa_mainloop *m; pa_defer_event *e; - assert(a); - assert(a->userdata); - assert(callback); + pa_assert(a); + pa_assert(a->userdata); + pa_assert(callback); m = a->userdata; - assert(a == &m->api); + pa_assert(a == &m->api); e = pa_xnew(pa_defer_event, 1); e->mainloop = m; @@ -281,11 +280,11 @@ static pa_defer_event* mainloop_defer_new( } static void mainloop_defer_enable(pa_defer_event *e, int b) { - assert(e); - assert(!e->dead); + pa_assert(e); + pa_assert(!e->dead); if (e->enabled && !b) { - assert(e->mainloop->n_enabled_defer_events > 0); + pa_assert(e->mainloop->n_enabled_defer_events > 0); e->mainloop->n_enabled_defer_events--; } else if (!e->enabled && b) { e->mainloop->n_enabled_defer_events++; @@ -296,22 +295,22 @@ static void mainloop_defer_enable(pa_defer_event *e, int b) { } static void mainloop_defer_free(pa_defer_event *e) { - assert(e); - assert(!e->dead); + pa_assert(e); + pa_assert(!e->dead); e->dead = 1; e->mainloop->defer_events_please_scan ++; if (e->enabled) { - assert(e->mainloop->n_enabled_defer_events > 0); + pa_assert(e->mainloop->n_enabled_defer_events > 0); e->mainloop->n_enabled_defer_events--; e->enabled = 0; } } static void mainloop_defer_set_destroy(pa_defer_event *e, pa_defer_event_destroy_cb_t callback) { - assert(e); - assert(!e->dead); + pa_assert(e); + pa_assert(!e->dead); e->destroy_callback = callback; } @@ -326,12 +325,12 @@ static pa_time_event* mainloop_time_new( pa_mainloop *m; pa_time_event *e; - assert(a); - assert(a->userdata); - assert(callback); + pa_assert(a); + pa_assert(a->userdata); + pa_assert(callback); m = a->userdata; - assert(a == &m->api); + pa_assert(a == &m->api); e = pa_xnew(pa_time_event, 1); e->mainloop = m; @@ -343,7 +342,7 @@ static pa_time_event* mainloop_time_new( m->n_enabled_time_events++; if (m->cached_next_time_event) { - assert(m->cached_next_time_event->enabled); + pa_assert(m->cached_next_time_event->enabled); if (pa_timeval_cmp(tv, &m->cached_next_time_event->timeval) < 0) m->cached_next_time_event = e; @@ -363,11 +362,11 @@ static pa_time_event* mainloop_time_new( } static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) { - assert(e); - assert(!e->dead); + pa_assert(e); + pa_assert(!e->dead); if (e->enabled && !tv) { - assert(e->mainloop->n_enabled_time_events > 0); + pa_assert(e->mainloop->n_enabled_time_events > 0); e->mainloop->n_enabled_time_events--; } else if (!e->enabled && tv) e->mainloop->n_enabled_time_events++; @@ -378,7 +377,7 @@ static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) { } if (e->mainloop->cached_next_time_event && e->enabled) { - assert(e->mainloop->cached_next_time_event->enabled); + pa_assert(e->mainloop->cached_next_time_event->enabled); if (pa_timeval_cmp(tv, &e->mainloop->cached_next_time_event->timeval) < 0) e->mainloop->cached_next_time_event = e; @@ -387,14 +386,14 @@ static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) { } static void mainloop_time_free(pa_time_event *e) { - assert(e); - assert(!e->dead); + pa_assert(e); + pa_assert(!e->dead); e->dead = 1; e->mainloop->time_events_please_scan ++; if (e->enabled) { - assert(e->mainloop->n_enabled_time_events > 0); + pa_assert(e->mainloop->n_enabled_time_events > 0); e->mainloop->n_enabled_time_events--; e->enabled = 0; } @@ -406,8 +405,8 @@ static void mainloop_time_free(pa_time_event *e) { } static void mainloop_time_set_destroy(pa_time_event *e, pa_time_event_destroy_cb_t callback) { - assert(e); - assert(!e->dead); + pa_assert(e); + pa_assert(!e->dead); e->destroy_callback = callback; } @@ -417,10 +416,10 @@ static void mainloop_time_set_destroy(pa_time_event *e, pa_time_event_destroy_cb static void mainloop_quit(pa_mainloop_api*a, int retval) { pa_mainloop *m; - assert(a); - assert(a->userdata); + pa_assert(a); + pa_assert(a->userdata); m = a->userdata; - assert(a == &m->api); + pa_assert(a == &m->api); pa_mainloop_quit(m, retval); } @@ -506,7 +505,7 @@ static void cleanup_io_events(pa_mainloop *m, int force) { PA_LLIST_REMOVE(pa_io_event, m->io_events, e); if (e->dead) { - assert(m->io_events_please_scan > 0); + pa_assert(m->io_events_please_scan > 0); m->io_events_please_scan--; } @@ -521,7 +520,7 @@ static void cleanup_io_events(pa_mainloop *m, int force) { e = n; } - assert(m->io_events_please_scan == 0); + pa_assert(m->io_events_please_scan == 0); } static void cleanup_time_events(pa_mainloop *m, int force) { @@ -538,12 +537,12 @@ static void cleanup_time_events(pa_mainloop *m, int force) { PA_LLIST_REMOVE(pa_time_event, m->time_events, e); if (e->dead) { - assert(m->time_events_please_scan > 0); + pa_assert(m->time_events_please_scan > 0); m->time_events_please_scan--; } if (!e->dead && e->enabled) { - assert(m->n_enabled_time_events > 0); + pa_assert(m->n_enabled_time_events > 0); m->n_enabled_time_events--; e->enabled = 0; } @@ -557,7 +556,7 @@ static void cleanup_time_events(pa_mainloop *m, int force) { e = n; } - assert(m->time_events_please_scan == 0); + pa_assert(m->time_events_please_scan == 0); } static void cleanup_defer_events(pa_mainloop *m, int force) { @@ -574,12 +573,12 @@ static void cleanup_defer_events(pa_mainloop *m, int force) { PA_LLIST_REMOVE(pa_defer_event, m->defer_events, e); if (e->dead) { - assert(m->defer_events_please_scan > 0); + pa_assert(m->defer_events_please_scan > 0); m->defer_events_please_scan--; } if (!e->dead && e->enabled) { - assert(m->n_enabled_defer_events > 0); + pa_assert(m->n_enabled_defer_events > 0); m->n_enabled_defer_events--; e->enabled = 0; } @@ -593,12 +592,12 @@ static void cleanup_defer_events(pa_mainloop *m, int force) { e = n; } - assert(m->defer_events_please_scan == 0); + pa_assert(m->defer_events_please_scan == 0); } void pa_mainloop_free(pa_mainloop* m) { - assert(m); + pa_assert(m); cleanup_io_events(m, 1); cleanup_defer_events(m, 1); @@ -615,7 +614,7 @@ void pa_mainloop_free(pa_mainloop* m) { } static void scan_dead(pa_mainloop *m) { - assert(m); + pa_assert(m); if (m->io_events_please_scan) cleanup_io_events(m, 0); @@ -672,13 +671,13 @@ static int dispatch_pollfds(pa_mainloop *m) { pa_io_event *e; int r = 0, k; - assert(m->poll_func_ret > 0); + pa_assert(m->poll_func_ret > 0); for (e = m->io_events, k = m->poll_func_ret; e && !m->quit && k > 0; e = e->next) { if (e->dead || !e->pollfd || !e->pollfd->revents) continue; - assert(e->pollfd->fd == e->fd && e->callback); + pa_assert(e->pollfd->fd == e->fd && e->callback); e->callback(&m->api, e, e->fd, map_flags_from_libc(e->pollfd->revents), e->userdata); e->pollfd->revents = 0; r++; @@ -700,7 +699,7 @@ static int dispatch_defer(pa_mainloop *m) { if (e->dead || !e->enabled) continue; - assert(e->callback); + pa_assert(e->callback); e->callback(&m->api, e, e->userdata); r++; } @@ -710,7 +709,7 @@ static int dispatch_defer(pa_mainloop *m) { static pa_time_event* find_next_time_event(pa_mainloop *m) { pa_time_event *t, *n = NULL; - assert(m); + pa_assert(m); if (m->cached_next_time_event) return m->cached_next_time_event; @@ -742,7 +741,7 @@ static int calc_next_timeout(pa_mainloop *m) { return -1; t = find_next_time_event(m); - assert(t); + pa_assert(t); if (t->timeval.tv_sec <= 0) return 0; @@ -760,7 +759,7 @@ static int dispatch_timeout(pa_mainloop *m) { pa_time_event *e; struct timeval now; int r = 0; - assert(m); + pa_assert(m); if (m->n_enabled_time_events <= 0) return 0; @@ -773,7 +772,7 @@ static int dispatch_timeout(pa_mainloop *m) { continue; if (pa_timeval_cmp(&e->timeval, &now) <= 0) { - assert(e->callback); + pa_assert(e->callback); /* Disable time event */ mainloop_time_restart(e, NULL); @@ -789,7 +788,7 @@ static int dispatch_timeout(pa_mainloop *m) { void pa_mainloop_wakeup(pa_mainloop *m) { char c = 'W'; - assert(m); + pa_assert(m); if (m->wakeup_pipe[1] >= 0 && m->state == STATE_POLLING) { pa_write(m->wakeup_pipe[1], &c, sizeof(c), &m->wakeup_pipe_type); @@ -800,7 +799,7 @@ void pa_mainloop_wakeup(pa_mainloop *m) { static void clear_wakeup(pa_mainloop *m) { char c[10]; - assert(m); + pa_assert(m); if (m->wakeup_pipe[0] < 0) return; @@ -812,8 +811,8 @@ static void clear_wakeup(pa_mainloop *m) { } int pa_mainloop_prepare(pa_mainloop *m, int timeout) { - assert(m); - assert(m->state == STATE_PASSIVE); + pa_assert(m); + pa_assert(m->state == STATE_PASSIVE); clear_wakeup(m); scan_dead(m); @@ -839,8 +838,8 @@ quit: } int pa_mainloop_poll(pa_mainloop *m) { - assert(m); - assert(m->state == STATE_PREPARED); + pa_assert(m); + pa_assert(m->state == STATE_PREPARED); if (m->quit) goto quit; @@ -850,7 +849,7 @@ int pa_mainloop_poll(pa_mainloop *m) { if (m->n_enabled_defer_events ) m->poll_func_ret = 0; else { - assert(!m->rebuild_pollfds); + pa_assert(!m->rebuild_pollfds); if (m->poll_func) m->poll_func_ret = m->poll_func(m->pollfds, m->n_pollfds, m->prepared_timeout, m->poll_func_userdata); @@ -876,8 +875,8 @@ quit: int pa_mainloop_dispatch(pa_mainloop *m) { int dispatched = 0; - assert(m); - assert(m->state == STATE_POLLED); + pa_assert(m); + pa_assert(m->state == STATE_POLLED); if (m->quit) goto quit; @@ -908,13 +907,13 @@ quit: } int pa_mainloop_get_retval(pa_mainloop *m) { - assert(m); + pa_assert(m); return m->retval; } int pa_mainloop_iterate(pa_mainloop *m, int block, int *retval) { int r; - assert(m); + pa_assert(m); if ((r = pa_mainloop_prepare(m, block ? -1 : 0)) < 0) goto quit; @@ -948,7 +947,7 @@ int pa_mainloop_run(pa_mainloop *m, int *retval) { } void pa_mainloop_quit(pa_mainloop *m, int retval) { - assert(m); + pa_assert(m); m->quit = 1; m->retval = retval; @@ -956,12 +955,12 @@ void pa_mainloop_quit(pa_mainloop *m, int retval) { } pa_mainloop_api* pa_mainloop_get_api(pa_mainloop*m) { - assert(m); + pa_assert(m); return &m->api; } void pa_mainloop_set_poll_func(pa_mainloop *m, pa_poll_func poll_func, void *userdata) { - assert(m); + pa_assert(m); m->poll_func = poll_func; m->poll_func_userdata = userdata; diff --git a/src/pulse/operation.c b/src/pulse/operation.c index f23def50..9ea4e63e 100644 --- a/src/pulse/operation.c +++ b/src/pulse/operation.c @@ -25,16 +25,15 @@ #include #endif -#include - #include +#include #include "internal.h" #include "operation.h" pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t cb, void *userdata) { pa_operation *o; - assert(c); + pa_assert(c); o = pa_xnew(pa_operation, 1); o->ref = 1; @@ -53,27 +52,27 @@ pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t cb } pa_operation *pa_operation_ref(pa_operation *o) { - assert(o); - assert(o->ref >= 1); + pa_assert(o); + pa_assert(o->ref >= 1); o->ref++; return o; } void pa_operation_unref(pa_operation *o) { - assert(o); - assert(o->ref >= 1); + pa_assert(o); + pa_assert(o->ref >= 1); if ((--(o->ref)) == 0) { - assert(!o->context); - assert(!o->stream); + pa_assert(!o->context); + pa_assert(!o->stream); pa_xfree(o); } } static void operation_set_state(pa_operation *o, pa_operation_state_t st) { - assert(o); - assert(o->ref >= 1); + pa_assert(o); + pa_assert(o->ref >= 1); if (st == o->state) return; @@ -85,7 +84,7 @@ static void operation_set_state(pa_operation *o, pa_operation_state_t st) { if ((o->state == PA_OPERATION_DONE) || (o->state == PA_OPERATION_CANCELED)) { if (o->context) { - assert(o->ref >= 2); + pa_assert(o->ref >= 2); PA_LLIST_REMOVE(pa_operation, o->context->operations, o); pa_operation_unref(o); @@ -101,22 +100,22 @@ static void operation_set_state(pa_operation *o, pa_operation_state_t st) { } void pa_operation_cancel(pa_operation *o) { - assert(o); - assert(o->ref >= 1); + pa_assert(o); + pa_assert(o->ref >= 1); operation_set_state(o, PA_OPERATION_CANCELED); } void pa_operation_done(pa_operation *o) { - assert(o); - assert(o->ref >= 1); + pa_assert(o); + pa_assert(o->ref >= 1); operation_set_state(o, PA_OPERATION_DONE); } pa_operation_state_t pa_operation_get_state(pa_operation *o) { - assert(o); - assert(o->ref >= 1); + pa_assert(o); + pa_assert(o->ref >= 1); return o->state; } -- cgit From e2e2ce79e2697ecbd36e2cf00249dc8c59af232d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Sep 2007 00:30:53 +0000 Subject: Instead of including config.h from header files, check whether PACKAGE is defined and if not, fail (thus using PACKAGE as a check for inclusion of config.h) git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1799 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/atomic.h | 5 ++--- src/pulsecore/creds.h | 4 +++- src/pulsecore/endianmacros.h | 4 ++-- src/pulsecore/macro.h | 4 ++++ src/pulsecore/thread.h | 5 ++--- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/pulsecore/atomic.h b/src/pulsecore/atomic.h index 0e3bfb9a..25d600c0 100644 --- a/src/pulsecore/atomic.h +++ b/src/pulsecore/atomic.h @@ -37,9 +37,8 @@ * libatomic_ops */ -/* We have to include config.h here (for the __sync stuff), which sucks */ -#ifdef HAVE_CONFIG_H -#include +#ifndef PACKAGE +#error "Please include config.h before including this file!" #endif #ifdef HAVE_ATOMIC_BUILTINS diff --git a/src/pulsecore/creds.h b/src/pulsecore/creds.h index e0a025bd..51dfc33d 100644 --- a/src/pulsecore/creds.h +++ b/src/pulsecore/creds.h @@ -26,7 +26,9 @@ #include -/* config.h must be included before this file */ +#ifndef PACKAGE +#error "Please include config.h before including this file!" +#endif #ifdef HAVE_SYS_SOCKET_H #include diff --git a/src/pulsecore/endianmacros.h b/src/pulsecore/endianmacros.h index c0c3a6d8..a29699b9 100644 --- a/src/pulsecore/endianmacros.h +++ b/src/pulsecore/endianmacros.h @@ -27,8 +27,8 @@ #include -#ifdef HAVE_CONFIG_H -#include +#ifndef PACKAGE +#error "Please include config.h before including this file!" #endif #define INT16_SWAP(x) ( (int16_t) ( ((uint16_t) x >> 8) | ((uint16_t) x << 8) ) ) diff --git a/src/pulsecore/macro.h b/src/pulsecore/macro.h index 53e52fd0..c1bdb140 100644 --- a/src/pulsecore/macro.h +++ b/src/pulsecore/macro.h @@ -32,6 +32,10 @@ #include +#ifndef PACKAGE +#error "Please include config.h before including this file!" +#endif + #if defined(PAGE_SIZE) #define PA_PAGE_SIZE ((size_t) PAGE_SIZE) #elif defined(PAGESIZE) diff --git a/src/pulsecore/thread.h b/src/pulsecore/thread.h index a0e331be..4e5425d6 100644 --- a/src/pulsecore/thread.h +++ b/src/pulsecore/thread.h @@ -28,9 +28,8 @@ #include #include -/* We have to include config.h here (for the __tls stuff), which sucks */ -#ifdef HAVE_CONFIG_H -#include +#ifndef PACKAGE +#error "Please include config.h before including this file!" #endif typedef struct pa_thread pa_thread; -- cgit From 6ac66e453f9c2007e9b1c6f3776c55eca0cd9140 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Sep 2007 00:56:21 +0000 Subject: add missing config.h includes git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1800 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/authkey-prop.c | 4 ++++ src/pulsecore/props.c | 4 ++++ src/pulsecore/x11wrap.c | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/pulsecore/authkey-prop.c b/src/pulsecore/authkey-prop.c index 3b8304b2..146d7ca0 100644 --- a/src/pulsecore/authkey-prop.c +++ b/src/pulsecore/authkey-prop.c @@ -21,6 +21,10 @@ USA. ***/ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include diff --git a/src/pulsecore/props.c b/src/pulsecore/props.c index 4a39f0fb..37e74194 100644 --- a/src/pulsecore/props.c +++ b/src/pulsecore/props.c @@ -21,6 +21,10 @@ USA. ***/ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include diff --git a/src/pulsecore/x11wrap.c b/src/pulsecore/x11wrap.c index 067b7df0..1bcbcd48 100644 --- a/src/pulsecore/x11wrap.c +++ b/src/pulsecore/x11wrap.c @@ -21,6 +21,10 @@ USA. ***/ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include -- cgit From 55d9fcb126247041a8934a060e1a441a26b2be8d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Sep 2007 01:00:33 +0000 Subject: add globally defined PA_PATH_SEP macro, replacing private per-file macros git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1801 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/daemon-conf.c | 14 ++++---------- src/pulse/client-conf.c | 8 +------- src/pulse/util.c | 8 +------- src/pulsecore/core-util.c | 8 +++----- src/pulsecore/macro.h | 8 ++++++++ 5 files changed, 17 insertions(+), 29 deletions(-) diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c index 7b503f83..ff628166 100644 --- a/src/daemon/daemon-conf.c +++ b/src/daemon/daemon-conf.c @@ -42,16 +42,10 @@ #include "daemon-conf.h" -#ifndef OS_IS_WIN32 -# define PATH_SEP "/" -#else -# define PATH_SEP "\\" -#endif - -#define DEFAULT_SCRIPT_FILE PA_DEFAULT_CONFIG_DIR PATH_SEP "default.pa" -#define DEFAULT_SCRIPT_FILE_USER PATH_SEP "default.pa" -#define DEFAULT_CONFIG_FILE PA_DEFAULT_CONFIG_DIR PATH_SEP "daemon.conf" -#define DEFAULT_CONFIG_FILE_USER PATH_SEP "daemon.conf" +#define DEFAULT_SCRIPT_FILE PA_DEFAULT_CONFIG_DIR PA_PATH_SEP "default.pa" +#define DEFAULT_SCRIPT_FILE_USER PA_PATH_SEP "default.pa" +#define DEFAULT_CONFIG_FILE PA_DEFAULT_CONFIG_DIR PA_PATH_SEP "daemon.conf" +#define DEFAULT_CONFIG_FILE_USER PA_PATH_SEP "daemon.conf" #define ENV_SCRIPT_FILE "PULSE_SCRIPT" #define ENV_CONFIG_FILE "PULSE_CONFIG" diff --git a/src/pulse/client-conf.c b/src/pulse/client-conf.c index d1e9969d..447d1857 100644 --- a/src/pulse/client-conf.c +++ b/src/pulse/client-conf.c @@ -42,13 +42,7 @@ #include "client-conf.h" -#ifndef OS_IS_WIN32 -# define PATH_SEP "/" -#else -# define PATH_SEP "\\" -#endif - -#define DEFAULT_CLIENT_CONFIG_FILE PA_DEFAULT_CONFIG_DIR PATH_SEP "client.conf" +#define DEFAULT_CLIENT_CONFIG_FILE PA_DEFAULT_CONFIG_DIR PA_PATH_SEP "client.conf" #define DEFAULT_CLIENT_CONFIG_FILE_USER "client.conf" #define ENV_CLIENT_CONFIG_FILE "PULSE_CLIENTCONFIG" diff --git a/src/pulse/util.c b/src/pulse/util.c index 879b7bf1..32f4137f 100644 --- a/src/pulse/util.c +++ b/src/pulse/util.c @@ -64,12 +64,6 @@ #include "util.h" -#ifndef OS_IS_WIN32 -#define PATH_SEP '/' -#else -#define PATH_SEP '\\' -#endif - char *pa_get_user_name(char *s, size_t l) { char *p; char buf[1024]; @@ -217,7 +211,7 @@ char *pa_path_get_filename(const char *p) { pa_assert(p); - if ((fn = strrchr(p, PATH_SEP))) + if ((fn = strrchr(p, PA_PATH_SEP_CHAR))) return fn+1; return (char*) p; diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 13a7252c..d37a11cc 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -100,10 +100,8 @@ #ifndef OS_IS_WIN32 #define PA_USER_RUNTIME_PATH_PREFIX "/tmp/pulse-" -#define PATH_SEP '/' #else #define PA_USER_RUNTIME_PATH_PREFIX "%TEMP%\\pulse-" -#define PATH_SEP '\\' #endif #ifdef OS_IS_WIN32 @@ -118,7 +116,7 @@ int pa_set_root(HANDLE handle) { if (!GetModuleFileName(handle, library_path + sizeof(PULSE_ROOTENV), MAX_PATH)) return 0; - sep = strrchr(library_path, '\\'); + sep = strrchr(library_path, PA_PATH_SEP_CHAR); if (sep) *sep = '\0'; @@ -1123,7 +1121,7 @@ char *pa_runtime_path(const char *fn, char *s, size_t l) { if ((e = getenv("PULSE_RUNTIME_PATH"))) { if (fn) - pa_snprintf(s, l, "%s%c%s", e, PATH_SEP, fn); + pa_snprintf(s, l, "%s%c%s", e, PA_PATH_SEP_CHAR, fn); else pa_snprintf(s, l, "%s", e); @@ -1131,7 +1129,7 @@ char *pa_runtime_path(const char *fn, char *s, size_t l) { char u[256]; if (fn) - pa_snprintf(s, l, "%s%s%c%s", PA_USER_RUNTIME_PATH_PREFIX, pa_get_user_name(u, sizeof(u)), PATH_SEP, fn); + pa_snprintf(s, l, "%s%s%c%s", PA_USER_RUNTIME_PATH_PREFIX, pa_get_user_name(u, sizeof(u)), PA_PATH_SEP_CHAR, fn); else pa_snprintf(s, l, "%s%s", PA_USER_RUNTIME_PATH_PREFIX, pa_get_user_name(u, sizeof(u))); } diff --git a/src/pulsecore/macro.h b/src/pulsecore/macro.h index c1bdb140..c46ae524 100644 --- a/src/pulsecore/macro.h +++ b/src/pulsecore/macro.h @@ -114,4 +114,12 @@ static inline size_t pa_page_align(size_t l) { #define PA_PTR_TO_INT32(p) ((int32_t) PA_PTR_TO_UINT(p)) #define PA_INT32_TO_PTR(u) PA_UINT_TO_PTR((int32_t) u) +#ifdef OS_IS_WIN32 +#define PA_PATH_SEP "\\" +#define PA_PATH_SEP_CHAR '\\' +#else +#define PA_PATH_SEP "/" +#define PA_PATH_SEP_CHAR '/' +#endif + #endif -- cgit From 597a1c4e82f2bb84e983d0cbb9be7e79c5607c00 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Sep 2007 12:42:17 +0000 Subject: port client libs to refcnt.h git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1802 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/context.c | 52 ++++++++++++++-------------- src/pulse/internal.h | 8 +++-- src/pulse/introspect.c | 92 +++++++++++++++++++++++++------------------------- src/pulse/operation.c | 20 +++++------ src/pulse/scache.c | 4 +-- src/pulse/stream.c | 76 ++++++++++++++++++++--------------------- src/pulse/subscribe.c | 4 +-- 7 files changed, 129 insertions(+), 127 deletions(-) diff --git a/src/pulse/context.c b/src/pulse/context.c index 8125c64f..c1685025 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -110,7 +110,7 @@ pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) { assert(name); c = pa_xnew(pa_context, 1); - c->ref = 1; + PA_REFCNT_INIT(c); c->name = pa_xstrdup(name); c->mainloop = mainloop; c->client = NULL; @@ -207,23 +207,23 @@ static void context_free(pa_context *c) { pa_context* pa_context_ref(pa_context *c) { assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); - c->ref++; + PA_REFCNT_INC(c); return c; } void pa_context_unref(pa_context *c) { assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); - if (--c->ref <= 0) + if (PA_REFCNT_DEC(c) <= 0) context_free(c); } void pa_context_set_state(pa_context *c, pa_context_state_t st) { assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); if (c->state == st) return; @@ -265,7 +265,7 @@ void pa_context_set_state(pa_context *c, pa_context_state_t st) { void pa_context_fail(pa_context *c, int error) { assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); pa_context_set_error(c, error); pa_context_set_state(c, PA_CONTEXT_FAILED); @@ -314,7 +314,7 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o assert(chunk->memblock); assert(chunk->length); assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); pa_context_ref(c); @@ -338,7 +338,7 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t) { assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); if (command == PA_COMMAND_ERROR) { assert(t); @@ -684,7 +684,7 @@ int pa_context_connect( int r = -1; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_UNCONNECTED, PA_ERR_BADSTATE); PA_CHECK_VALIDITY(c, !(flags & ~PA_CONTEXT_NOAUTOSPAWN), PA_ERR_INVALID); @@ -756,28 +756,28 @@ finish: void pa_context_disconnect(pa_context *c) { assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); pa_context_set_state(c, PA_CONTEXT_TERMINATED); } pa_context_state_t pa_context_get_state(pa_context *c) { assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); return c->state; } int pa_context_errno(pa_context *c) { assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); return c->error; } void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, void *userdata) { assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); c->state_callback = cb; c->state_userdata = userdata; @@ -785,7 +785,7 @@ void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, voi int pa_context_is_pending(pa_context *c) { assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_CONNECTING || @@ -812,9 +812,9 @@ static void set_dispatch_callbacks(pa_operation *o) { int done = 1; assert(o); - assert(o->ref >= 1); + assert(PA_REFCNT_VALUE(o) >= 1); assert(o->context); - assert(o->context->ref >= 1); + assert(PA_REFCNT_VALUE(o->context) >= 1); assert(o->context->state == PA_CONTEXT_READY); pa_pstream_set_drain_callback(o->context->pstream, NULL, NULL); @@ -845,7 +845,7 @@ pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *u pa_operation *o; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, pa_context_is_pending(c), PA_ERR_BADSTATE); @@ -862,7 +862,7 @@ void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_U assert(pd); assert(o); - assert(o->ref >= 1); + assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -893,7 +893,7 @@ pa_operation* pa_context_exit_daemon(pa_context *c, pa_context_success_cb_t cb, uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -912,7 +912,7 @@ pa_operation* pa_context_send_simple_command(pa_context *c, uint32_t command, pa uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -931,7 +931,7 @@ pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_co uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -951,7 +951,7 @@ pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_ uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -977,7 +977,7 @@ pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_su uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(name); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -998,7 +998,7 @@ const char* pa_get_library_version(void) { const char* pa_context_get_server(pa_context *c) { assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); if (!c->server) return NULL; @@ -1017,7 +1017,7 @@ uint32_t pa_context_get_protocol_version(PA_GCC_UNUSED pa_context *c) { uint32_t pa_context_get_server_protocol_version(pa_context *c) { assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); return c->version; } diff --git a/src/pulse/internal.h b/src/pulse/internal.h index e5c9ef12..95593adb 100644 --- a/src/pulse/internal.h +++ b/src/pulse/internal.h @@ -41,13 +41,14 @@ #include #include #include +#include #include "client-conf.h" #define DEFAULT_TIMEOUT (30) struct pa_context { - int ref; + PA_REFCNT_DECLARE; char *name; pa_mainloop_api* mainloop; @@ -96,7 +97,7 @@ typedef struct pa_index_correction { } pa_index_correction; struct pa_stream { - int ref; + PA_REFCNT_DECLARE; pa_context *context; pa_mainloop_api *mainloop; PA_LLIST_FIELDS(pa_stream); @@ -161,7 +162,8 @@ struct pa_stream { typedef void (*pa_operation_cb_t)(void); struct pa_operation { - int ref; + PA_REFCNT_DECLARE; + pa_context *context; pa_stream *stream; diff --git a/src/pulse/introspect.c b/src/pulse/introspect.c index 568749d7..1d2f52e0 100644 --- a/src/pulse/introspect.c +++ b/src/pulse/introspect.c @@ -45,7 +45,7 @@ static void context_stat_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNU assert(pd); assert(o); - assert(o->ref >= 1); + assert(PA_REFCNT_VALUE(o) >= 1); memset(&i, 0, sizeof(i)); @@ -88,7 +88,7 @@ static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command, assert(pd); assert(o); - assert(o->ref >= 1); + assert(PA_REFCNT_VALUE(o) >= 1); memset(&i, 0, sizeof(i)); @@ -135,7 +135,7 @@ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, P assert(pd); assert(o); - assert(o->ref >= 1); + assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -199,7 +199,7 @@ pa_operation* pa_context_get_sink_info_by_index(pa_context *c, uint32_t idx, pa_ uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -221,7 +221,7 @@ pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name, uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -246,7 +246,7 @@ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, assert(pd); assert(o); - assert(o->ref >= 1); + assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -310,7 +310,7 @@ pa_operation* pa_context_get_source_info_by_index(pa_context *c, uint32_t idx, p uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -332,7 +332,7 @@ pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -357,7 +357,7 @@ static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, assert(pd); assert(o); - assert(o->ref >= 1); + assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -404,7 +404,7 @@ pa_operation* pa_context_get_client_info(pa_context *c, uint32_t idx, pa_client_ uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -432,7 +432,7 @@ static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, assert(pd); assert(o); - assert(o->ref >= 1); + assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -480,7 +480,7 @@ pa_operation* pa_context_get_module_info(pa_context *c, uint32_t idx, pa_module_ uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -508,7 +508,7 @@ static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t comm assert(pd); assert(o); - assert(o->ref >= 1); + assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -565,7 +565,7 @@ pa_operation* pa_context_get_sink_input_info(pa_context *c, uint32_t idx, pa_sin uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -593,7 +593,7 @@ static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t c assert(pd); assert(o); - assert(o->ref >= 1); + assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -649,7 +649,7 @@ pa_operation* pa_context_get_source_output_info(pa_context *c, uint32_t idx, pa_ uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -677,7 +677,7 @@ pa_operation* pa_context_set_sink_volume_by_index(pa_context *c, uint32_t idx, c uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(volume); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -701,7 +701,7 @@ pa_operation* pa_context_set_sink_volume_by_name(pa_context *c, const char *name uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(name); assert(volume); @@ -727,7 +727,7 @@ pa_operation* pa_context_set_sink_mute_by_index(pa_context *c, uint32_t idx, int uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -749,7 +749,7 @@ pa_operation* pa_context_set_sink_mute_by_name(pa_context *c, const char *name, uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(name); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -773,7 +773,7 @@ pa_operation* pa_context_set_sink_input_volume(pa_context *c, uint32_t idx, cons uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(volume); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -797,7 +797,7 @@ pa_operation* pa_context_set_sink_input_mute(pa_context *c, uint32_t idx, int mu uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID); @@ -820,7 +820,7 @@ pa_operation* pa_context_set_source_volume_by_index(pa_context *c, uint32_t idx, uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(volume); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -844,7 +844,7 @@ pa_operation* pa_context_set_source_volume_by_name(pa_context *c, const char *na uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(name); assert(volume); @@ -870,7 +870,7 @@ pa_operation* pa_context_set_source_mute_by_index(pa_context *c, uint32_t idx, i uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -892,7 +892,7 @@ pa_operation* pa_context_set_source_mute_by_name(pa_context *c, const char *name uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(name); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -918,7 +918,7 @@ static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, assert(pd); assert(o); - assert(o->ref >= 1); + assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -972,7 +972,7 @@ pa_operation* pa_context_get_sample_info_by_name(pa_context *c, const char *name uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -995,7 +995,7 @@ pa_operation* pa_context_get_sample_info_by_index(pa_context *c, uint32_t idx, p uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -1022,7 +1022,7 @@ static pa_operation* command_kill(pa_context *c, uint32_t command, uint32_t idx, uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID); @@ -1055,7 +1055,7 @@ static void context_index_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UN assert(pd); assert(o); - assert(o->ref >= 1); + assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -1088,7 +1088,7 @@ pa_operation* pa_context_load_module(pa_context *c, const char*name, const char uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID); @@ -1116,7 +1116,7 @@ static void context_get_autoload_info_callback(pa_pdispatch *pd, uint32_t comman assert(pd); assert(o); - assert(o->ref >= 1); + assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -1165,7 +1165,7 @@ pa_operation* pa_context_get_autoload_info_by_name(pa_context *c, const char *na uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -1189,7 +1189,7 @@ pa_operation* pa_context_get_autoload_info_by_index(pa_context *c, uint32_t idx, uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -1215,7 +1215,7 @@ pa_operation* pa_context_add_autoload(pa_context *c, const char *name, pa_autolo uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID); @@ -1241,7 +1241,7 @@ pa_operation* pa_context_remove_autoload_by_name(pa_context *c, const char *name uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID); @@ -1264,7 +1264,7 @@ pa_operation* pa_context_remove_autoload_by_index(pa_context *c, uint32_t idx, p uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID); @@ -1285,7 +1285,7 @@ pa_operation* pa_context_move_sink_input_by_name(pa_context *c, uint32_t idx, ch uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED); @@ -1310,7 +1310,7 @@ pa_operation* pa_context_move_sink_input_by_index(pa_context *c, uint32_t idx, u uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED); @@ -1335,7 +1335,7 @@ pa_operation* pa_context_move_source_output_by_name(pa_context *c, uint32_t idx, uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED); @@ -1360,7 +1360,7 @@ pa_operation* pa_context_move_source_output_by_index(pa_context *c, uint32_t idx uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED); @@ -1385,7 +1385,7 @@ pa_operation* pa_context_suspend_sink_by_name(pa_context *c, char *sink_name, in uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED); @@ -1409,7 +1409,7 @@ pa_operation* pa_context_suspend_sink_by_index(pa_context *c, uint32_t idx, int uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED); @@ -1432,7 +1432,7 @@ pa_operation* pa_context_suspend_source_by_name(pa_context *c, char *source_name uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED); @@ -1456,7 +1456,7 @@ pa_operation* pa_context_suspend_source_by_index(pa_context *c, uint32_t idx, in uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED); diff --git a/src/pulse/operation.c b/src/pulse/operation.c index 9ea4e63e..ed5eb4aa 100644 --- a/src/pulse/operation.c +++ b/src/pulse/operation.c @@ -36,7 +36,7 @@ pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t cb pa_assert(c); o = pa_xnew(pa_operation, 1); - o->ref = 1; + PA_REFCNT_INIT(o); o->context = c; o->stream = s; @@ -53,17 +53,17 @@ pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t cb pa_operation *pa_operation_ref(pa_operation *o) { pa_assert(o); - pa_assert(o->ref >= 1); + pa_assert(PA_REFCNT_VALUE(o) >= 1); - o->ref++; + PA_REFCNT_INC(o); return o; } void pa_operation_unref(pa_operation *o) { pa_assert(o); - pa_assert(o->ref >= 1); + pa_assert(PA_REFCNT_VALUE(o) >= 1); - if ((--(o->ref)) == 0) { + if (PA_REFCNT_DEC(o) <= 0) { pa_assert(!o->context); pa_assert(!o->stream); pa_xfree(o); @@ -72,7 +72,7 @@ void pa_operation_unref(pa_operation *o) { static void operation_set_state(pa_operation *o, pa_operation_state_t st) { pa_assert(o); - pa_assert(o->ref >= 1); + pa_assert(PA_REFCNT_VALUE(o) >= 1); if (st == o->state) return; @@ -84,7 +84,7 @@ static void operation_set_state(pa_operation *o, pa_operation_state_t st) { if ((o->state == PA_OPERATION_DONE) || (o->state == PA_OPERATION_CANCELED)) { if (o->context) { - pa_assert(o->ref >= 2); + pa_assert(PA_REFCNT_VALUE(o) >= 2); PA_LLIST_REMOVE(pa_operation, o->context->operations, o); pa_operation_unref(o); @@ -101,21 +101,21 @@ static void operation_set_state(pa_operation *o, pa_operation_state_t st) { void pa_operation_cancel(pa_operation *o) { pa_assert(o); - pa_assert(o->ref >= 1); + pa_assert(PA_REFCNT_VALUE(o) >= 1); operation_set_state(o, PA_OPERATION_CANCELED); } void pa_operation_done(pa_operation *o) { pa_assert(o); - pa_assert(o->ref >= 1); + pa_assert(PA_REFCNT_VALUE(o) >= 1); operation_set_state(o, PA_OPERATION_DONE); } pa_operation_state_t pa_operation_get_state(pa_operation *o) { pa_assert(o); - pa_assert(o->ref >= 1); + pa_assert(PA_REFCNT_VALUE(o) >= 1); return o->state; } diff --git a/src/pulse/scache.c b/src/pulse/scache.c index 09bc1078..1b8356b8 100644 --- a/src/pulse/scache.c +++ b/src/pulse/scache.c @@ -88,7 +88,7 @@ pa_operation *pa_context_play_sample(pa_context *c, const char *name, const char uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID); @@ -116,7 +116,7 @@ pa_operation* pa_context_remove_sample(pa_context *c, const char *name, pa_conte uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID); diff --git a/src/pulse/stream.c b/src/pulse/stream.c index 07a041aa..8f5aeb7a 100644 --- a/src/pulse/stream.c +++ b/src/pulse/stream.c @@ -54,7 +54,7 @@ pa_stream *pa_stream_new(pa_context *c, const char *name, const pa_sample_spec * PA_CHECK_VALIDITY_RETURN_NULL(c, !map || (pa_channel_map_valid(map) && map->channels == ss->channels), PA_ERR_INVALID); s = pa_xnew(pa_stream, 1); - s->ref = 1; + PA_REFCNT_INIT(s); s->context = c; s->mainloop = c->mainloop; @@ -142,37 +142,37 @@ static void stream_free(pa_stream *s) { void pa_stream_unref(pa_stream *s) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); - if (--(s->ref) == 0) + if (PA_REFCNT_DEC(s) <= 0) stream_free(s); } pa_stream* pa_stream_ref(pa_stream *s) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); - s->ref++; + PA_REFCNT_INC(s); return s; } pa_stream_state_t pa_stream_get_state(pa_stream *s) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); return s->state; } pa_context* pa_stream_get_context(pa_stream *s) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); return s->context; } uint32_t pa_stream_get_index(pa_stream *s) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE, PA_INVALID_INDEX); @@ -181,7 +181,7 @@ uint32_t pa_stream_get_index(pa_stream *s) { void pa_stream_set_state(pa_stream *s, pa_stream_state_t st) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); if (s->state == st) return; @@ -506,7 +506,7 @@ static int create_stream( uint32_t tag; assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_UNCONNECTED, PA_ERR_BADSTATE); PA_CHECK_VALIDITY(s->context, !(flags & ~((direction != PA_STREAM_UPLOAD ? @@ -591,7 +591,7 @@ int pa_stream_connect_playback( pa_stream *sync_stream) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); return create_stream(PA_STREAM_PLAYBACK, s, dev, attr, flags, volume, sync_stream); } @@ -603,7 +603,7 @@ int pa_stream_connect_record( pa_stream_flags_t flags) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); return create_stream(PA_STREAM_RECORD, s, dev, attr, flags, NULL, NULL); } @@ -619,7 +619,7 @@ int pa_stream_write( pa_memchunk chunk; assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); assert(data); PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); @@ -689,7 +689,7 @@ int pa_stream_write( int pa_stream_peek(pa_stream *s, const void **data, size_t *length) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); assert(data); assert(length); @@ -715,7 +715,7 @@ int pa_stream_peek(pa_stream *s, const void **data, size_t *length) { int pa_stream_drop(pa_stream *s) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY(s->context, s->direction == PA_STREAM_RECORD, PA_ERR_BADSTATE); @@ -739,7 +739,7 @@ int pa_stream_drop(pa_stream *s) { size_t pa_stream_writable_size(pa_stream *s) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE, (size_t) -1); PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->direction != PA_STREAM_RECORD, PA_ERR_BADSTATE, (size_t) -1); @@ -749,7 +749,7 @@ size_t pa_stream_writable_size(pa_stream *s) { size_t pa_stream_readable_size(pa_stream *s) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE, (size_t) -1); PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->direction == PA_STREAM_RECORD, PA_ERR_BADSTATE, (size_t) -1); @@ -763,7 +763,7 @@ pa_operation * pa_stream_drain(pa_stream *s, pa_stream_success_cb_t cb, void *us uint32_t tag; assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE); @@ -933,7 +933,7 @@ pa_operation* pa_stream_update_timing_info(pa_stream *s, pa_stream_success_cb_t int cidx = 0; assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); @@ -977,7 +977,7 @@ void pa_stream_disconnect_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UN assert(pd); assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); pa_stream_ref(s); @@ -1003,7 +1003,7 @@ int pa_stream_disconnect(pa_stream *s) { uint32_t tag; assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY(s->context, s->channel_valid, PA_ERR_BADSTATE); PA_CHECK_VALIDITY(s->context, s->context->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -1025,7 +1025,7 @@ int pa_stream_disconnect(pa_stream *s) { void pa_stream_set_read_callback(pa_stream *s, pa_stream_request_cb_t cb, void *userdata) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); s->read_callback = cb; s->read_userdata = userdata; @@ -1033,7 +1033,7 @@ void pa_stream_set_read_callback(pa_stream *s, pa_stream_request_cb_t cb, void * void pa_stream_set_write_callback(pa_stream *s, pa_stream_request_cb_t cb, void *userdata) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); s->write_callback = cb; s->write_userdata = userdata; @@ -1041,7 +1041,7 @@ void pa_stream_set_write_callback(pa_stream *s, pa_stream_request_cb_t cb, void void pa_stream_set_state_callback(pa_stream *s, pa_stream_notify_cb_t cb, void *userdata) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); s->state_callback = cb; s->state_userdata = userdata; @@ -1049,7 +1049,7 @@ void pa_stream_set_state_callback(pa_stream *s, pa_stream_notify_cb_t cb, void * void pa_stream_set_overflow_callback(pa_stream *s, pa_stream_notify_cb_t cb, void *userdata) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); s->overflow_callback = cb; s->overflow_userdata = userdata; @@ -1057,7 +1057,7 @@ void pa_stream_set_overflow_callback(pa_stream *s, pa_stream_notify_cb_t cb, voi void pa_stream_set_underflow_callback(pa_stream *s, pa_stream_notify_cb_t cb, void *userdata) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); s->underflow_callback = cb; s->underflow_userdata = userdata; @@ -1065,7 +1065,7 @@ void pa_stream_set_underflow_callback(pa_stream *s, pa_stream_notify_cb_t cb, vo void pa_stream_set_latency_update_callback(pa_stream *s, pa_stream_notify_cb_t cb, void *userdata) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); s->latency_update_callback = cb; s->latency_update_userdata = userdata; @@ -1077,7 +1077,7 @@ void pa_stream_simple_ack_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UN assert(pd); assert(o); - assert(o->ref >= 1); + assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -1108,7 +1108,7 @@ pa_operation* pa_stream_cork(pa_stream *s, int b, pa_stream_success_cb_t cb, voi uint32_t tag; assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); @@ -1138,7 +1138,7 @@ static pa_operation* stream_send_simple_command(pa_stream *s, uint32_t command, uint32_t tag; assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); @@ -1207,7 +1207,7 @@ pa_operation* pa_stream_set_name(pa_stream *s, const char *name, pa_stream_succe uint32_t tag; assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); assert(name); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); @@ -1231,7 +1231,7 @@ int pa_stream_get_time(pa_stream *s, pa_usec_t *r_usec) { pa_usec_t usec = 0; assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); @@ -1315,7 +1315,7 @@ int pa_stream_get_time(pa_stream *s, pa_usec_t *r_usec) { static pa_usec_t time_counter_diff(pa_stream *s, pa_usec_t a, pa_usec_t b, int *negative) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); if (negative) *negative = 0; @@ -1337,7 +1337,7 @@ int pa_stream_get_latency(pa_stream *s, pa_usec_t *r_usec, int *negative) { int64_t cindex; assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); assert(r_usec); PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); @@ -1369,7 +1369,7 @@ int pa_stream_get_latency(pa_stream *s, pa_usec_t *r_usec, int *negative) { const pa_timing_info* pa_stream_get_timing_info(pa_stream *s) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); @@ -1380,21 +1380,21 @@ const pa_timing_info* pa_stream_get_timing_info(pa_stream *s) { const pa_sample_spec* pa_stream_get_sample_spec(pa_stream *s) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); return &s->sample_spec; } const pa_channel_map* pa_stream_get_channel_map(pa_stream *s) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); return &s->channel_map; } const pa_buffer_attr* pa_stream_get_buffer_attr(pa_stream *s) { assert(s); - assert(s->ref >= 1); + assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); diff --git a/src/pulse/subscribe.c b/src/pulse/subscribe.c index 5d8f1252..76b93759 100644 --- a/src/pulse/subscribe.c +++ b/src/pulse/subscribe.c @@ -68,7 +68,7 @@ pa_operation* pa_context_subscribe(pa_context *c, pa_subscription_mask_t m, pa_c uint32_t tag; assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -84,7 +84,7 @@ pa_operation* pa_context_subscribe(pa_context *c, pa_subscription_mask_t m, pa_c void pa_context_set_subscribe_callback(pa_context *c, pa_context_subscribe_cb_t cb, void *userdata) { assert(c); - assert(c->ref >= 1); + assert(PA_REFCNT_VALUE(c) >= 1); c->subscribe_callback = cb; c->subscribe_userdata = userdata; -- cgit From 391d09cd6e8d47ad8255736be5cb512b04843ed1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Sep 2007 13:15:39 +0000 Subject: add 'wait' parameter to pa_rtpoll_run(), if zero pa_rtpoll_runn will only update the struct pollfd but not wait for an event git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1803 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 2 +- src/modules/module-alsa-source.c | 2 +- src/modules/module-combine.c | 2 +- src/modules/module-null-sink.c | 2 +- src/modules/module-oss.c | 2 +- src/modules/module-pipe-sink.c | 2 +- src/modules/module-pipe-source.c | 2 +- src/pulsecore/rtpoll.c | 7 +++++-- src/pulsecore/rtpoll.h | 5 ++++- src/tests/rtpoll-test.c | 4 ++-- 10 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index c75f195e..bb7392d8 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -643,7 +643,7 @@ static void thread_func(void *userdata) { continue; /* Hmm, nothing to do. Let's sleep */ - if (pa_rtpoll_run(u->rtpoll) < 0) { + if (pa_rtpoll_run(u->rtpoll, 1) < 0) { pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; } diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 365f6ab2..fef7b01e 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -626,7 +626,7 @@ static void thread_func(void *userdata) { continue; /* Hmm, nothing to do. Let's sleep */ - if (pa_rtpoll_run(u->rtpoll) < 0) { + if (pa_rtpoll_run(u->rtpoll, 1) < 0) { pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; } diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 3e56bc67..390b6e5c 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -268,7 +268,7 @@ static void thread_func(void *userdata) { continue; /* Hmm, nothing to do. Let's sleep */ - if (pa_rtpoll_run(u->rtpoll) < 0) { + if (pa_rtpoll_run(u->rtpoll, 1) < 0) { pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; } diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index 78d99ceb..2fe541fc 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -158,7 +158,7 @@ static void thread_func(void *userdata) { continue; /* Hmm, nothing to do. Let's sleep */ - if (pa_rtpoll_run(u->rtpoll) < 0) { + if (pa_rtpoll_run(u->rtpoll, 1) < 0) { pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; } diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 1e524fcf..9273a393 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -1031,7 +1031,7 @@ static void thread_func(void *userdata) { } /* Hmm, nothing to do. Let's sleep */ - if (pa_rtpoll_run(u->rtpoll) < 0) { + if (pa_rtpoll_run(u->rtpoll, 1) < 0) { pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; } diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index 55a4e0ce..5cafaada 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -185,7 +185,7 @@ static void thread_func(void *userdata) { /* Hmm, nothing to do. Let's sleep */ pollfd->events = u->sink->thread_info.state == PA_SINK_RUNNING ? POLLOUT : 0; - if (pa_rtpoll_run(u->rtpoll) < 0) { + if (pa_rtpoll_run(u->rtpoll, 1) < 0) { pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; } diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index 6dc94648..291010e1 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -164,7 +164,7 @@ static void thread_func(void *userdata) { /* Hmm, nothing to do. Let's sleep */ pollfd->events = u->source->thread_info.state == PA_SOURCE_RUNNING ? POLLIN : 0; - if (pa_rtpoll_run(u->rtpoll) < 0) { + if (pa_rtpoll_run(u->rtpoll, 1) < 0) { pa_log("poll() failed: %s", pa_cstrerror(errno)); goto fail; } diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c index e43ec610..be1c83c0 100644 --- a/src/pulsecore/rtpoll.c +++ b/src/pulsecore/rtpoll.c @@ -257,7 +257,7 @@ void pa_rtpoll_free(pa_rtpoll *p) { pa_xfree(p); } -int pa_rtpoll_run(pa_rtpoll *p) { +int pa_rtpoll_run(pa_rtpoll *p, int wait) { pa_rtpoll_item *i; int r = 0; int no_events = 0; @@ -301,7 +301,10 @@ int pa_rtpoll_run(pa_rtpoll *p) { rtpoll_rebuild(p); /* Calculate timeout */ - if (p->timer_enabled) { + if (!wait) { + timeout.tv_sec = 0; + timeout.tv_nsec = 0; + } else if (p->timer_enabled) { struct timespec now; pa_rtclock_get(&now); diff --git a/src/pulsecore/rtpoll.h b/src/pulsecore/rtpoll.h index 7fe5cb37..f393f918 100644 --- a/src/pulsecore/rtpoll.h +++ b/src/pulsecore/rtpoll.h @@ -58,7 +58,10 @@ void pa_rtpoll_free(pa_rtpoll *p); void pa_rtpoll_install(pa_rtpoll *p); -int pa_rtpoll_run(pa_rtpoll *f); +/* Sleep on the rtpoll until the time event, or any of the fd events + * is triggered. If "wait" is 0 we don't sleep but only update the + * struct pollfd. */ +int pa_rtpoll_run(pa_rtpoll *f, int wait); void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timespec *ts); void pa_rtpoll_set_timer_periodic(pa_rtpoll *p, pa_usec_t usec); diff --git a/src/tests/rtpoll-test.c b/src/tests/rtpoll-test.c index 2a90684e..20913e7f 100644 --- a/src/tests/rtpoll-test.c +++ b/src/tests/rtpoll-test.c @@ -58,7 +58,7 @@ int main(int argc, char *argv[]) { pa_rtpoll_install(p); pa_rtpoll_set_timer_periodic(p, 10000000); /* 10 s */ - pa_rtpoll_run(p); + pa_rtpoll_run(p, 1); pa_rtpoll_item_free(i); @@ -70,7 +70,7 @@ int main(int argc, char *argv[]) { pollfd->fd = 0; pollfd->events = POLLIN; - pa_rtpoll_run(p); + pa_rtpoll_run(p, 1); pa_rtpoll_item_free(i); -- cgit From 038e560152b7765d85cc399bcf26fe982b395dab Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Sep 2007 14:04:38 +0000 Subject: More s/assert/pa_assert/ modernizations git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1804 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/introspect.c | 251 ++++++++++++++++++++++++------------------------- src/pulse/scache.c | 17 ++-- src/pulse/stream.c | 230 ++++++++++++++++++++++++-------------------- src/pulse/subscribe.c | 18 ++-- 4 files changed, 271 insertions(+), 245 deletions(-) diff --git a/src/pulse/introspect.c b/src/pulse/introspect.c index 1d2f52e0..d2b48f04 100644 --- a/src/pulse/introspect.c +++ b/src/pulse/introspect.c @@ -26,11 +26,10 @@ #include #endif -#include - #include #include +#include #include #include "internal.h" @@ -43,9 +42,9 @@ static void context_stat_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNU pa_operation *o = userdata; pa_stat_info i, *p = &i; - assert(pd); - assert(o); - assert(PA_REFCNT_VALUE(o) >= 1); + pa_assert(pd); + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); memset(&i, 0, sizeof(i)); @@ -86,9 +85,9 @@ static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command, pa_operation *o = userdata; pa_server_info i, *p = &i; - assert(pd); - assert(o); - assert(PA_REFCNT_VALUE(o) >= 1); + pa_assert(pd); + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); memset(&i, 0, sizeof(i)); @@ -133,9 +132,9 @@ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, P pa_operation *o = userdata; int eol = 1; - assert(pd); - assert(o); - assert(PA_REFCNT_VALUE(o) >= 1); + pa_assert(pd); + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -198,9 +197,9 @@ pa_operation* pa_context_get_sink_info_by_index(pa_context *c, uint32_t idx, pa_ pa_operation *o; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(cb); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -220,9 +219,9 @@ pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name, pa_operation *o; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(cb); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID); @@ -244,9 +243,9 @@ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, pa_operation *o = userdata; int eol = 1; - assert(pd); - assert(o); - assert(PA_REFCNT_VALUE(o) >= 1); + pa_assert(pd); + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -309,9 +308,9 @@ pa_operation* pa_context_get_source_info_by_index(pa_context *c, uint32_t idx, p pa_operation *o; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(cb); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -331,9 +330,9 @@ pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name pa_operation *o; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(cb); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID); @@ -355,9 +354,9 @@ static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, pa_operation *o = userdata; int eol = 1; - assert(pd); - assert(o); - assert(PA_REFCNT_VALUE(o) >= 1); + pa_assert(pd); + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -403,9 +402,9 @@ pa_operation* pa_context_get_client_info(pa_context *c, uint32_t idx, pa_client_ pa_operation *o; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(cb); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID); @@ -430,9 +429,9 @@ static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, pa_operation *o = userdata; int eol = 1; - assert(pd); - assert(o); - assert(PA_REFCNT_VALUE(o) >= 1); + pa_assert(pd); + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -479,9 +478,9 @@ pa_operation* pa_context_get_module_info(pa_context *c, uint32_t idx, pa_module_ pa_operation *o; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(cb); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID); @@ -506,9 +505,9 @@ static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t comm pa_operation *o = userdata; int eol = 1; - assert(pd); - assert(o); - assert(PA_REFCNT_VALUE(o) >= 1); + pa_assert(pd); + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -564,9 +563,9 @@ pa_operation* pa_context_get_sink_input_info(pa_context *c, uint32_t idx, pa_sin pa_operation *o; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(cb); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID); @@ -591,9 +590,9 @@ static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t c pa_operation *o = userdata; int eol = 1; - assert(pd); - assert(o); - assert(PA_REFCNT_VALUE(o) >= 1); + pa_assert(pd); + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -648,9 +647,9 @@ pa_operation* pa_context_get_source_output_info(pa_context *c, uint32_t idx, pa_ pa_operation *o; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(cb); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID); @@ -676,9 +675,9 @@ pa_operation* pa_context_set_sink_volume_by_index(pa_context *c, uint32_t idx, c pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(volume); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(volume); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID); @@ -700,10 +699,10 @@ pa_operation* pa_context_set_sink_volume_by_name(pa_context *c, const char *name pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(name); - assert(volume); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(name); + pa_assert(volume); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID); @@ -726,8 +725,8 @@ pa_operation* pa_context_set_sink_mute_by_index(pa_context *c, uint32_t idx, int pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -748,9 +747,9 @@ pa_operation* pa_context_set_sink_mute_by_name(pa_context *c, const char *name, pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(name); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(name); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID); @@ -772,9 +771,9 @@ pa_operation* pa_context_set_sink_input_volume(pa_context *c, uint32_t idx, cons pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(volume); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(volume); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID); @@ -796,8 +795,8 @@ pa_operation* pa_context_set_sink_input_mute(pa_context *c, uint32_t idx, int mu pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID); @@ -819,9 +818,9 @@ pa_operation* pa_context_set_source_volume_by_index(pa_context *c, uint32_t idx, pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(volume); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(volume); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID); @@ -843,10 +842,10 @@ pa_operation* pa_context_set_source_volume_by_name(pa_context *c, const char *na pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(name); - assert(volume); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(name); + pa_assert(volume); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, pa_cvolume_valid(volume), PA_ERR_INVALID); @@ -869,8 +868,8 @@ pa_operation* pa_context_set_source_mute_by_index(pa_context *c, uint32_t idx, i pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -891,9 +890,9 @@ pa_operation* pa_context_set_source_mute_by_name(pa_context *c, const char *name pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(name); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(name); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID); @@ -916,9 +915,9 @@ static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, pa_operation *o = userdata; int eol = 1; - assert(pd); - assert(o); - assert(PA_REFCNT_VALUE(o) >= 1); + pa_assert(pd); + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -971,9 +970,9 @@ pa_operation* pa_context_get_sample_info_by_name(pa_context *c, const char *name pa_operation *o; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(cb); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID); @@ -994,9 +993,9 @@ pa_operation* pa_context_get_sample_info_by_index(pa_context *c, uint32_t idx, p pa_operation *o; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(cb); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID); @@ -1021,8 +1020,8 @@ static pa_operation* command_kill(pa_context *c, uint32_t command, uint32_t idx, pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID); @@ -1053,9 +1052,9 @@ static void context_index_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UN pa_operation *o = userdata; uint32_t idx; - assert(pd); - assert(o); - assert(PA_REFCNT_VALUE(o) >= 1); + pa_assert(pd); + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -1087,8 +1086,8 @@ pa_operation* pa_context_load_module(pa_context *c, const char*name, const char pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID); @@ -1114,9 +1113,9 @@ static void context_get_autoload_info_callback(pa_pdispatch *pd, uint32_t comman pa_operation *o = userdata; int eol = 1; - assert(pd); - assert(o); - assert(PA_REFCNT_VALUE(o) >= 1); + pa_assert(pd); + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -1164,9 +1163,9 @@ pa_operation* pa_context_get_autoload_info_by_name(pa_context *c, const char *na pa_operation *o; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(cb); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID); @@ -1188,9 +1187,9 @@ pa_operation* pa_context_get_autoload_info_by_index(pa_context *c, uint32_t idx, pa_operation *o; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(cb); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(cb); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID); @@ -1214,8 +1213,8 @@ pa_operation* pa_context_add_autoload(pa_context *c, const char *name, pa_autolo pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID); @@ -1240,8 +1239,8 @@ pa_operation* pa_context_remove_autoload_by_name(pa_context *c, const char *name pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID); @@ -1263,8 +1262,8 @@ pa_operation* pa_context_remove_autoload_by_index(pa_context *c, uint32_t idx, p pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID); @@ -1284,8 +1283,8 @@ pa_operation* pa_context_move_sink_input_by_name(pa_context *c, uint32_t idx, ch pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED); @@ -1309,8 +1308,8 @@ pa_operation* pa_context_move_sink_input_by_index(pa_context *c, uint32_t idx, u pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED); @@ -1334,8 +1333,8 @@ pa_operation* pa_context_move_source_output_by_name(pa_context *c, uint32_t idx, pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED); @@ -1359,8 +1358,8 @@ pa_operation* pa_context_move_source_output_by_index(pa_context *c, uint32_t idx pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 10, PA_ERR_NOTSUPPORTED); @@ -1384,8 +1383,8 @@ pa_operation* pa_context_suspend_sink_by_name(pa_context *c, char *sink_name, in pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED); @@ -1408,8 +1407,8 @@ pa_operation* pa_context_suspend_sink_by_index(pa_context *c, uint32_t idx, int pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED); @@ -1431,8 +1430,8 @@ pa_operation* pa_context_suspend_source_by_name(pa_context *c, char *source_name pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED); @@ -1455,8 +1454,8 @@ pa_operation* pa_context_suspend_source_by_index(pa_context *c, uint32_t idx, in pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 11, PA_ERR_NOTSUPPORTED); diff --git a/src/pulse/scache.c b/src/pulse/scache.c index 1b8356b8..a4a7244a 100644 --- a/src/pulse/scache.c +++ b/src/pulse/scache.c @@ -25,12 +25,12 @@ #include #endif -#include #include #include #include #include +#include #include "internal.h" @@ -40,7 +40,8 @@ int pa_stream_connect_upload(pa_stream *s, size_t length) { pa_tagstruct *t; uint32_t tag; - assert(s); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_UNCONNECTED, PA_ERR_BADSTATE); PA_CHECK_VALIDITY(s->context, length > 0, PA_ERR_INVALID); @@ -66,7 +67,9 @@ int pa_stream_connect_upload(pa_stream *s, size_t length) { int pa_stream_finish_upload(pa_stream *s) { pa_tagstruct *t; uint32_t tag; - assert(s); + + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY(s->context, s->channel_valid, PA_ERR_BADSTATE); PA_CHECK_VALIDITY(s->context, s->context->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -87,8 +90,8 @@ pa_operation *pa_context_play_sample(pa_context *c, const char *name, const char pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID); @@ -115,8 +118,8 @@ pa_operation* pa_context_remove_sample(pa_context *c, const char *name, pa_conte pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, name && *name, PA_ERR_INVALID); diff --git a/src/pulse/stream.c b/src/pulse/stream.c index 8f5aeb7a..6d14a70a 100644 --- a/src/pulse/stream.c +++ b/src/pulse/stream.c @@ -26,7 +26,6 @@ #include #endif -#include #include #include #include @@ -48,7 +47,8 @@ pa_stream *pa_stream_new(pa_context *c, const char *name, const pa_sample_spec * pa_stream *s; int i; - assert(c); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, ss && pa_sample_spec_valid(ss), PA_ERR_INVALID); PA_CHECK_VALIDITY_RETURN_NULL(c, !map || (pa_channel_map_valid(map) && map->channels == ss->channels), PA_ERR_INVALID); @@ -120,10 +120,12 @@ pa_stream *pa_stream_new(pa_context *c, const char *name, const pa_sample_spec * } static void stream_free(pa_stream *s) { - assert(s && !s->context && !s->channel_valid); + pa_assert(s); + pa_assert(!s->context); + pa_assert(!s->channel_valid); if (s->auto_timing_update_event) { - assert(s->mainloop); + pa_assert(s->mainloop); s->mainloop->time_free(s->auto_timing_update_event); } @@ -141,38 +143,38 @@ static void stream_free(pa_stream *s) { } void pa_stream_unref(pa_stream *s) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); if (PA_REFCNT_DEC(s) <= 0) stream_free(s); } pa_stream* pa_stream_ref(pa_stream *s) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); PA_REFCNT_INC(s); return s; } pa_stream_state_t pa_stream_get_state(pa_stream *s) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); return s->state; } pa_context* pa_stream_get_context(pa_stream *s) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); return s->context; } uint32_t pa_stream_get_index(pa_stream *s) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE, PA_INVALID_INDEX); @@ -180,8 +182,8 @@ uint32_t pa_stream_get_index(pa_stream *s) { } void pa_stream_set_state(pa_stream *s, pa_stream_state_t st) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); if (s->state == st) return; @@ -236,10 +238,11 @@ void pa_command_stream_killed(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED pa_stream *s; uint32_t channel; - assert(pd); - assert(command == PA_COMMAND_PLAYBACK_STREAM_KILLED || command == PA_COMMAND_RECORD_STREAM_KILLED); - assert(t); - assert(c); + pa_assert(pd); + pa_assert(command == PA_COMMAND_PLAYBACK_STREAM_KILLED || command == PA_COMMAND_RECORD_STREAM_KILLED); + pa_assert(t); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); pa_context_ref(c); @@ -264,10 +267,11 @@ void pa_command_request(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32 pa_context *c = userdata; uint32_t bytes, channel; - assert(pd); - assert(command == PA_COMMAND_REQUEST); - assert(t); - assert(c); + pa_assert(pd); + pa_assert(command == PA_COMMAND_REQUEST); + pa_assert(t); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); pa_context_ref(c); @@ -297,10 +301,11 @@ void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, PA_GCC pa_context *c = userdata; uint32_t channel; - assert(pd); - assert(command == PA_COMMAND_OVERFLOW || command == PA_COMMAND_UNDERFLOW); - assert(t); - assert(c); + pa_assert(pd); + pa_assert(command == PA_COMMAND_OVERFLOW || command == PA_COMMAND_UNDERFLOW); + pa_assert(t); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); pa_context_ref(c); @@ -329,7 +334,8 @@ void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, PA_GCC } static void request_auto_timing_update(pa_stream *s, int force) { - assert(s); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); if (!(s->flags & PA_STREAM_AUTO_TIMING_UPDATE)) return; @@ -355,7 +361,8 @@ static void request_auto_timing_update(pa_stream *s, int force) { } static void invalidate_indexes(pa_stream *s, int r, int w) { - assert(s); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); /* pa_log("invalidate r:%u w:%u tag:%u", r, w, s->context->ctag); */ @@ -390,6 +397,9 @@ static void invalidate_indexes(pa_stream *s, int r, int w) { static void auto_timing_update_callback(PA_GCC_UNUSED pa_mainloop_api *m, PA_GCC_UNUSED pa_time_event *e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { pa_stream *s = userdata; + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); + /* pa_log("time event"); */ pa_stream_ref(s); @@ -399,6 +409,7 @@ static void auto_timing_update_callback(PA_GCC_UNUSED pa_mainloop_api *m, PA_GCC static void create_stream_complete(pa_stream *s) { pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); pa_assert(s->state == PA_STREAM_CREATING); pa_stream_set_state(s, PA_STREAM_READY); @@ -410,7 +421,7 @@ static void create_stream_complete(pa_stream *s) { struct timeval tv; pa_gettimeofday(&tv); tv.tv_usec += LATENCY_IPOL_INTERVAL_USEC; /* every 100 ms */ - assert(!s->auto_timing_update_event); + pa_assert(!s->auto_timing_update_event); s->auto_timing_update_event = s->mainloop->time_new(s->mainloop, &tv, &auto_timing_update_callback, s); } } @@ -418,9 +429,10 @@ static void create_stream_complete(pa_stream *s) { void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { pa_stream *s = userdata; - assert(pd); - assert(s); - assert(s->state == PA_STREAM_CREATING); + pa_assert(pd); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s->state == PA_STREAM_CREATING); pa_stream_ref(s); @@ -463,7 +475,7 @@ void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED } if (s->direction == PA_STREAM_RECORD) { - assert(!s->record_memblockq); + pa_assert(!s->record_memblockq); s->record_memblockq = pa_memblockq_new( 0, @@ -505,8 +517,8 @@ static int create_stream( pa_tagstruct *t; uint32_t tag; - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_UNCONNECTED, PA_ERR_BADSTATE); PA_CHECK_VALIDITY(s->context, !(flags & ~((direction != PA_STREAM_UPLOAD ? @@ -590,8 +602,8 @@ int pa_stream_connect_playback( pa_cvolume *volume, pa_stream *sync_stream) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); return create_stream(PA_STREAM_PLAYBACK, s, dev, attr, flags, volume, sync_stream); } @@ -602,8 +614,8 @@ int pa_stream_connect_record( const pa_buffer_attr *attr, pa_stream_flags_t flags) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); return create_stream(PA_STREAM_RECORD, s, dev, attr, flags, NULL, NULL); } @@ -618,9 +630,9 @@ int pa_stream_write( pa_memchunk chunk; - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); - assert(data); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(data); PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY(s->context, s->direction == PA_STREAM_PLAYBACK || s->direction == PA_STREAM_UPLOAD, PA_ERR_BADSTATE); @@ -688,10 +700,10 @@ int pa_stream_write( } int pa_stream_peek(pa_stream *s, const void **data, size_t *length) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); - assert(data); - assert(length); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(data); + pa_assert(length); PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY(s->context, s->direction == PA_STREAM_RECORD, PA_ERR_BADSTATE); @@ -707,15 +719,15 @@ int pa_stream_peek(pa_stream *s, const void **data, size_t *length) { s->peek_data = pa_memblock_acquire(s->peek_memchunk.memblock); } - assert(s->peek_data); + pa_assert(s->peek_data); *data = (uint8_t*) s->peek_data + s->peek_memchunk.index; *length = s->peek_memchunk.length; return 0; } int pa_stream_drop(pa_stream *s) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY(s->context, s->direction == PA_STREAM_RECORD, PA_ERR_BADSTATE); @@ -727,7 +739,7 @@ int pa_stream_drop(pa_stream *s) { if (s->timing_info_valid && !s->timing_info.read_index_corrupt) s->timing_info.read_index += s->peek_memchunk.length; - assert(s->peek_data); + pa_assert(s->peek_data); pa_memblock_release(s->peek_memchunk.memblock); pa_memblock_unref(s->peek_memchunk.memblock); s->peek_memchunk.length = 0; @@ -738,8 +750,8 @@ int pa_stream_drop(pa_stream *s) { } size_t pa_stream_writable_size(pa_stream *s) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE, (size_t) -1); PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->direction != PA_STREAM_RECORD, PA_ERR_BADSTATE, (size_t) -1); @@ -748,8 +760,8 @@ size_t pa_stream_writable_size(pa_stream *s) { } size_t pa_stream_readable_size(pa_stream *s) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE, (size_t) -1); PA_CHECK_VALIDITY_RETURN_ANY(s->context, s->direction == PA_STREAM_RECORD, PA_ERR_BADSTATE, (size_t) -1); @@ -762,8 +774,8 @@ pa_operation * pa_stream_drain(pa_stream *s, pa_stream_success_cb_t cb, void *us pa_tagstruct *t; uint32_t tag; - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE); @@ -783,8 +795,9 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command, struct timeval local, remote, now; pa_timing_info *i; - assert(pd); - assert(o); + pa_assert(pd); + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context || !o->stream) goto finish; @@ -932,8 +945,8 @@ pa_operation* pa_stream_update_timing_info(pa_stream *s, pa_stream_success_cb_t struct timeval now; int cidx = 0; - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); @@ -975,9 +988,9 @@ pa_operation* pa_stream_update_timing_info(pa_stream *s, pa_stream_success_cb_t void pa_stream_disconnect_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { pa_stream *s = userdata; - assert(pd); - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(pd); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); pa_stream_ref(s); @@ -1002,8 +1015,8 @@ int pa_stream_disconnect(pa_stream *s) { pa_tagstruct *t; uint32_t tag; - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY(s->context, s->channel_valid, PA_ERR_BADSTATE); PA_CHECK_VALIDITY(s->context, s->context->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -1024,48 +1037,48 @@ int pa_stream_disconnect(pa_stream *s) { } void pa_stream_set_read_callback(pa_stream *s, pa_stream_request_cb_t cb, void *userdata) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); s->read_callback = cb; s->read_userdata = userdata; } void pa_stream_set_write_callback(pa_stream *s, pa_stream_request_cb_t cb, void *userdata) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); s->write_callback = cb; s->write_userdata = userdata; } void pa_stream_set_state_callback(pa_stream *s, pa_stream_notify_cb_t cb, void *userdata) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); s->state_callback = cb; s->state_userdata = userdata; } void pa_stream_set_overflow_callback(pa_stream *s, pa_stream_notify_cb_t cb, void *userdata) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); s->overflow_callback = cb; s->overflow_userdata = userdata; } void pa_stream_set_underflow_callback(pa_stream *s, pa_stream_notify_cb_t cb, void *userdata) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); s->underflow_callback = cb; s->underflow_userdata = userdata; } void pa_stream_set_latency_update_callback(pa_stream *s, pa_stream_notify_cb_t cb, void *userdata) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); s->latency_update_callback = cb; s->latency_update_userdata = userdata; @@ -1075,9 +1088,9 @@ void pa_stream_simple_ack_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UN pa_operation *o = userdata; int success = 1; - assert(pd); - assert(o); - assert(PA_REFCNT_VALUE(o) >= 1); + pa_assert(pd); + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -1107,8 +1120,8 @@ pa_operation* pa_stream_cork(pa_stream *s, int b, pa_stream_success_cb_t cb, voi pa_tagstruct *t; uint32_t tag; - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); @@ -1137,8 +1150,8 @@ static pa_operation* stream_send_simple_command(pa_stream *s, uint32_t command, pa_operation *o; uint32_t tag; - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); @@ -1155,6 +1168,9 @@ static pa_operation* stream_send_simple_command(pa_stream *s, uint32_t command, pa_operation* pa_stream_flush(pa_stream *s, pa_stream_success_cb_t cb, void *userdata) { pa_operation *o; + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); + PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); if ((o = stream_send_simple_command(s, s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_FLUSH_PLAYBACK_STREAM : PA_COMMAND_FLUSH_RECORD_STREAM, cb, userdata))) { @@ -1180,6 +1196,9 @@ pa_operation* pa_stream_flush(pa_stream *s, pa_stream_success_cb_t cb, void *use pa_operation* pa_stream_prebuf(pa_stream *s, pa_stream_success_cb_t cb, void *userdata) { pa_operation *o; + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); + PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->buffer_attr.prebuf > 0, PA_ERR_BADSTATE); @@ -1192,6 +1211,9 @@ pa_operation* pa_stream_prebuf(pa_stream *s, pa_stream_success_cb_t cb, void *us pa_operation* pa_stream_trigger(pa_stream *s, pa_stream_success_cb_t cb, void *userdata) { pa_operation *o; + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); + PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->buffer_attr.prebuf > 0, PA_ERR_BADSTATE); @@ -1206,9 +1228,9 @@ pa_operation* pa_stream_set_name(pa_stream *s, const char *name, pa_stream_succe pa_tagstruct *t; uint32_t tag; - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); - assert(name); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(name); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); @@ -1230,8 +1252,8 @@ pa_operation* pa_stream_set_name(pa_stream *s, const char *name, pa_stream_succe int pa_stream_get_time(pa_stream *s, pa_usec_t *r_usec) { pa_usec_t usec = 0; - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); @@ -1314,8 +1336,8 @@ int pa_stream_get_time(pa_stream *s, pa_usec_t *r_usec) { } static pa_usec_t time_counter_diff(pa_stream *s, pa_usec_t a, pa_usec_t b, int *negative) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); if (negative) *negative = 0; @@ -1336,9 +1358,9 @@ int pa_stream_get_latency(pa_stream *s, pa_usec_t *r_usec, int *negative) { int r; int64_t cindex; - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); - assert(r_usec); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(r_usec); PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); @@ -1368,8 +1390,8 @@ int pa_stream_get_latency(pa_stream *s, pa_usec_t *r_usec, int *negative) { } const pa_timing_info* pa_stream_get_timing_info(pa_stream *s) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); @@ -1379,22 +1401,22 @@ const pa_timing_info* pa_stream_get_timing_info(pa_stream *s) { } const pa_sample_spec* pa_stream_get_sample_spec(pa_stream *s) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); return &s->sample_spec; } const pa_channel_map* pa_stream_get_channel_map(pa_stream *s) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); return &s->channel_map; } const pa_buffer_attr* pa_stream_get_buffer_attr(pa_stream *s) { - assert(s); - assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE); diff --git a/src/pulse/subscribe.c b/src/pulse/subscribe.c index 76b93759..31b76369 100644 --- a/src/pulse/subscribe.c +++ b/src/pulse/subscribe.c @@ -29,6 +29,7 @@ #include #include +#include #include #include "internal.h" @@ -40,10 +41,11 @@ void pa_command_subscribe_event(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSE pa_subscription_event_type_t e; uint32_t idx; - assert(pd); - assert(command == PA_COMMAND_SUBSCRIBE_EVENT); - assert(t); - assert(c); + pa_assert(pd); + pa_assert(command == PA_COMMAND_SUBSCRIBE_EVENT); + pa_assert(t); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); pa_context_ref(c); @@ -67,8 +69,8 @@ pa_operation* pa_context_subscribe(pa_context *c, pa_subscription_mask_t m, pa_c pa_tagstruct *t; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -83,8 +85,8 @@ pa_operation* pa_context_subscribe(pa_context *c, pa_subscription_mask_t m, pa_c } void pa_context_set_subscribe_callback(pa_context *c, pa_context_subscribe_cb_t cb, void *userdata) { - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); c->subscribe_callback = cb; c->subscribe_userdata = userdata; -- cgit From 27f13b3853c0d613c2edfb0ae11cffa72004ebf0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Sep 2007 14:23:38 +0000 Subject: finish modernizations in pulse/, s/assert/pa_assert/g git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1805 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/browser.c | 58 +++++++++------ src/pulse/context.c | 171 ++++++++++++++++++++++---------------------- src/pulse/mainloop-signal.c | 3 +- src/pulse/mainloop.c | 3 +- src/pulse/simple.c | 49 ++++++------- 5 files changed, 151 insertions(+), 133 deletions(-) diff --git a/src/pulse/browser.c b/src/pulse/browser.c index a35fe810..af56e47d 100644 --- a/src/pulse/browser.c +++ b/src/pulse/browser.c @@ -25,7 +25,6 @@ #include "config.h" #endif -#include #include #include @@ -36,8 +35,9 @@ #include #include - #include +#include +#include #include "browser.h" @@ -46,7 +46,8 @@ #define SERVICE_TYPE_SERVER "_pulse-server._tcp." struct pa_browser { - int ref; + PA_REFCNT_DECLARE; + pa_mainloop_api *mainloop; AvahiPoll* avahi_poll; @@ -62,6 +63,7 @@ struct pa_browser { }; static int map_to_opcode(const char *type, int new) { + if (avahi_domain_equal(type, SERVICE_TYPE_SINK)) return new ? PA_BROWSE_NEW_SINK : PA_BROWSE_REMOVE_SINK; else if (avahi_domain_equal(type, SERVICE_TYPE_SOURCE)) @@ -97,7 +99,8 @@ static void resolve_callback( int ss_valid = 0; char *key = NULL, *value = NULL; - assert(b); + pa_assert(b); + pa_assert(PA_REFCNT_VALUE(b) >= 1); memset(&i, 0, sizeof(i)); i.name = name; @@ -109,12 +112,12 @@ static void resolve_callback( goto fail; opcode = map_to_opcode(type, 1); - assert(opcode >= 0); + pa_assert(opcode >= 0); if (aa->proto == AVAHI_PROTO_INET) pa_snprintf(a, sizeof(a), "tcp:%s:%u", avahi_address_snprint(ip, sizeof(ip), aa), port); else { - assert(aa->proto == AVAHI_PROTO_INET6); + pa_assert(aa->proto == AVAHI_PROTO_INET6); pa_snprintf(a, sizeof(a), "tcp6:%s:%u", avahi_address_snprint(ip, sizeof(ip), aa), port); } i.server = a; @@ -146,7 +149,7 @@ static void resolve_callback( value = NULL; l = strlen(a); - assert(l+1 <= sizeof(a)); + pa_assert(l+1 <= sizeof(a)); strncat(a, " ", sizeof(a)-l-1); strncat(a, i.fqdn, sizeof(a)-l-2); } else if (!strcmp(key, "cookie")) { @@ -211,7 +214,9 @@ fail: static void handle_failure(pa_browser *b) { const char *e = NULL; - assert(b); + + pa_assert(b); + pa_assert(PA_REFCNT_VALUE(b) >= 1); if (b->sink_browser) avahi_service_browser_free(b->sink_browser); @@ -245,7 +250,9 @@ static void browse_callback( void *userdata) { pa_browser *b = userdata; - assert(b); + + pa_assert(b); + pa_assert(PA_REFCNT_VALUE(b) >= 1); switch (event) { case AVAHI_BROWSER_NEW: { @@ -276,7 +283,7 @@ static void browse_callback( i.name = name; opcode = map_to_opcode(type, 0); - assert(opcode >= 0); + pa_assert(opcode >= 0); b->callback(b, opcode, &i, b->userdata); } @@ -295,7 +302,10 @@ static void browse_callback( static void client_callback(AvahiClient *s, AvahiClientState state, void *userdata) { pa_browser *b = userdata; - assert(s); + + pa_assert(s); + pa_assert(b); + pa_assert(PA_REFCNT_VALUE(b) >= 1); if (state == AVAHI_CLIENT_FAILURE) handle_failure(b); @@ -311,14 +321,14 @@ pa_browser *pa_browser_new_full(pa_mainloop_api *mainloop, pa_browse_flags_t fla pa_browser *b; int error; - assert(mainloop); + pa_assert(mainloop); if (flags & ~(PA_BROWSE_FOR_SERVERS|PA_BROWSE_FOR_SINKS|PA_BROWSE_FOR_SOURCES) || flags == 0) return NULL; b = pa_xnew(pa_browser, 1); b->mainloop = mainloop; - b->ref = 1; + PA_REFCNT_INIT(b); b->callback = NULL; b->userdata = NULL; b->error_callback = NULL; @@ -391,7 +401,8 @@ fail: } static void browser_free(pa_browser *b) { - assert(b && b->mainloop); + pa_assert(b); + pa_assert(b->mainloop); if (b->sink_browser) avahi_service_browser_free(b->sink_browser); @@ -410,29 +421,32 @@ static void browser_free(pa_browser *b) { } pa_browser *pa_browser_ref(pa_browser *b) { - assert(b); - assert(b->ref >= 1); - b->ref++; + pa_assert(b); + pa_assert(PA_REFCNT_VALUE(b) >= 1); + + PA_REFCNT_INC(b); return b; } void pa_browser_unref(pa_browser *b) { - assert(b); - assert(b->ref >= 1); + pa_assert(b); + pa_assert(PA_REFCNT_VALUE(b) >= 1); - if ((-- (b->ref)) <= 0) + if (PA_REFCNT_DEC(b) <= 0) browser_free(b); } void pa_browser_set_callback(pa_browser *b, pa_browse_cb_t cb, void *userdata) { - assert(b); + pa_assert(b); + pa_assert(PA_REFCNT_VALUE(b) >= 1); b->callback = cb; b->userdata = userdata; } void pa_browser_set_error_callback(pa_browser *b, pa_browser_error_cb_t cb, void *userdata) { - assert(b); + pa_assert(b); + pa_assert(PA_REFCNT_VALUE(b) >= 1); b->error_callback = cb; b->error_userdata = userdata; diff --git a/src/pulse/context.c b/src/pulse/context.c index c1685025..ab06aeb9 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -27,7 +27,6 @@ #endif #include -#include #include #include #include @@ -67,6 +66,7 @@ #include #include #include +#include #include "internal.h" @@ -90,7 +90,7 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = { }; static void unlock_autospawn_lock_file(pa_context *c) { - assert(c); + pa_assert(c); if (c->autospawn_lock_fd >= 0) { char lf[PATH_MAX]; @@ -106,8 +106,8 @@ static void context_free(pa_context *c); pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) { pa_context *c; - assert(mainloop); - assert(name); + pa_assert(mainloop); + pa_assert(name); c = pa_xnew(pa_context, 1); PA_REFCNT_INIT(c); @@ -168,7 +168,7 @@ pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) { } static void context_free(pa_context *c) { - assert(c); + pa_assert(c); unlock_autospawn_lock_file(c); @@ -206,24 +206,24 @@ static void context_free(pa_context *c) { } pa_context* pa_context_ref(pa_context *c) { - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_REFCNT_INC(c); return c; } void pa_context_unref(pa_context *c) { - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); if (PA_REFCNT_DEC(c) <= 0) context_free(c); } void pa_context_set_state(pa_context *c, pa_context_state_t st) { - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); if (c->state == st) return; @@ -264,16 +264,16 @@ void pa_context_set_state(pa_context *c, pa_context_state_t st) { } void pa_context_fail(pa_context *c, int error) { - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); pa_context_set_error(c, error); pa_context_set_state(c, PA_CONTEXT_FAILED); } int pa_context_set_error(pa_context *c, int error) { - assert(error >= 0); - assert(error < PA_ERR_MAX); + pa_assert(error >= 0); + pa_assert(error < PA_ERR_MAX); if (c) c->error = error; @@ -284,8 +284,8 @@ int pa_context_set_error(pa_context *c, int error) { static void pstream_die_callback(pa_pstream *p, void *userdata) { pa_context *c = userdata; - assert(p); - assert(c); + pa_assert(p); + pa_assert(c); pa_context_fail(c, PA_ERR_CONNECTIONTERMINATED); } @@ -293,9 +293,9 @@ static void pstream_die_callback(pa_pstream *p, void *userdata) { static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_creds *creds, void *userdata) { pa_context *c = userdata; - assert(p); - assert(packet); - assert(c); + pa_assert(p); + pa_assert(packet); + pa_assert(c); pa_context_ref(c); @@ -309,18 +309,19 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o pa_context *c = userdata; pa_stream *s; - assert(p); - assert(chunk); - assert(chunk->memblock); - assert(chunk->length); - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(p); + pa_assert(chunk); + pa_assert(chunk->memblock); + pa_assert(chunk->length); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); pa_context_ref(c); if ((s = pa_dynarray_get(c->record_streams, channel))) { - assert(seek == PA_SEEK_RELATIVE && offset == 0); + pa_assert(seek == PA_SEEK_RELATIVE); + pa_assert(offset == 0); pa_memblockq_seek(s->record_memblockq, offset, seek); pa_memblockq_push_align(s->record_memblockq, chunk); @@ -337,11 +338,11 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o } int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t) { - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); if (command == PA_COMMAND_ERROR) { - assert(t); + pa_assert(t); if (pa_tagstruct_getu32(t, &c->error) < 0) { pa_context_fail(c, PA_ERR_PROTOCOL); @@ -361,9 +362,9 @@ int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t) { static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_context *c = userdata; - assert(pd); - assert(c); - assert(c->state == PA_CONTEXT_AUTHORIZING || c->state == PA_CONTEXT_SETTING_NAME); + pa_assert(pd); + pa_assert(c); + pa_assert(c->state == PA_CONTEXT_AUTHORIZING || c->state == PA_CONTEXT_SETTING_NAME); pa_context_ref(c); @@ -423,7 +424,7 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t break; default: - assert(0); + pa_assert(0); } finish: @@ -434,19 +435,19 @@ static void setup_context(pa_context *c, pa_iochannel *io) { pa_tagstruct *t; uint32_t tag; - assert(c); - assert(io); + pa_assert(c); + pa_assert(io); pa_context_ref(c); - assert(!c->pstream); + pa_assert(!c->pstream); c->pstream = pa_pstream_new(c->mainloop, io, c->mempool); pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c); pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_callback, c); pa_pstream_set_recieve_memblock_callback(c->pstream, pstream_memblock_callback, c); - assert(!c->pdispatch); + pa_assert(!c->pdispatch); c->pdispatch = pa_pdispatch_new(c->mainloop, command_table, PA_COMMAND_MAX); if (!c->conf->cookie_valid) @@ -602,8 +603,8 @@ static int try_next_connection(pa_context *c) { char *u = NULL; int r = -1; - assert(c); - assert(!c->client); + pa_assert(c); + pa_assert(!c->client); for (;;) { pa_xfree(u); @@ -648,9 +649,9 @@ finish: static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata) { pa_context *c = userdata; - assert(client); - assert(c); - assert(c->state == PA_CONTEXT_CONNECTING); + pa_assert(client); + pa_assert(c); + pa_assert(c->state == PA_CONTEXT_CONNECTING); pa_context_ref(c); @@ -683,8 +684,8 @@ int pa_context_connect( int r = -1; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_UNCONNECTED, PA_ERR_BADSTATE); PA_CHECK_VALIDITY(c, !(flags & ~PA_CONTEXT_NOAUTOSPAWN), PA_ERR_INVALID); @@ -695,7 +696,7 @@ int pa_context_connect( pa_context_ref(c); - assert(!c->server_list); + pa_assert(!c->server_list); if (server) { if (!(c->server_list = pa_strlist_parse(server))) { @@ -735,7 +736,7 @@ int pa_context_connect( pa_runtime_path(AUTOSPAWN_LOCK, lf, sizeof(lf)); pa_make_secure_parent_dir(lf, 0700, (uid_t)-1, (gid_t)-1); - assert(c->autospawn_lock_fd <= 0); + pa_assert(c->autospawn_lock_fd <= 0); c->autospawn_lock_fd = pa_lock_lockfile(lf); if (api) @@ -755,37 +756,37 @@ finish: } void pa_context_disconnect(pa_context *c) { - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); pa_context_set_state(c, PA_CONTEXT_TERMINATED); } pa_context_state_t pa_context_get_state(pa_context *c) { - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); return c->state; } int pa_context_errno(pa_context *c) { - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); return c->error; } void pa_context_set_state_callback(pa_context *c, pa_context_notify_cb_t cb, void *userdata) { - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); c->state_callback = cb; c->state_userdata = userdata; } int pa_context_is_pending(pa_context *c) { - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY(c, c->state == PA_CONTEXT_CONNECTING || @@ -811,11 +812,11 @@ static void pstream_drain_callback(PA_GCC_UNUSED pa_pstream *s, void *userdata) static void set_dispatch_callbacks(pa_operation *o) { int done = 1; - assert(o); - assert(PA_REFCNT_VALUE(o) >= 1); - assert(o->context); - assert(PA_REFCNT_VALUE(o->context) >= 1); - assert(o->context->state == PA_CONTEXT_READY); + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); + pa_assert(o->context); + pa_assert(PA_REFCNT_VALUE(o->context) >= 1); + pa_assert(o->context->state == PA_CONTEXT_READY); pa_pstream_set_drain_callback(o->context->pstream, NULL, NULL); pa_pdispatch_set_drain_callback(o->context->pdispatch, NULL, NULL); @@ -844,8 +845,8 @@ static void set_dispatch_callbacks(pa_operation *o) { pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *userdata) { pa_operation *o; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); PA_CHECK_VALIDITY_RETURN_NULL(c, pa_context_is_pending(c), PA_ERR_BADSTATE); @@ -860,9 +861,9 @@ void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_U pa_operation *o = userdata; int success = 1; - assert(pd); - assert(o); - assert(PA_REFCNT_VALUE(o) >= 1); + pa_assert(pd); + pa_assert(o); + pa_assert(PA_REFCNT_VALUE(o) >= 1); if (!o->context) goto finish; @@ -892,8 +893,8 @@ pa_operation* pa_context_exit_daemon(pa_context *c, pa_context_success_cb_t cb, pa_operation *o; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -911,8 +912,8 @@ pa_operation* pa_context_send_simple_command(pa_context *c, uint32_t command, pa pa_operation *o; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -930,8 +931,8 @@ pa_operation* pa_context_set_default_sink(pa_context *c, const char *name, pa_co pa_operation *o; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -950,8 +951,8 @@ pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_ pa_operation *o; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -966,7 +967,7 @@ pa_operation* pa_context_set_default_source(pa_context *c, const char *name, pa_ } int pa_context_is_local(pa_context *c) { - assert(c); + pa_assert(c); return c->is_local; } @@ -976,9 +977,9 @@ pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_su pa_operation *o; uint32_t tag; - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); - assert(name); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(name); PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); @@ -997,8 +998,8 @@ const char* pa_get_library_version(void) { } const char* pa_context_get_server(pa_context *c) { - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); if (!c->server) return NULL; @@ -1016,8 +1017,8 @@ uint32_t pa_context_get_protocol_version(PA_GCC_UNUSED pa_context *c) { } uint32_t pa_context_get_server_protocol_version(pa_context *c) { - assert(c); - assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); return c->version; } @@ -1025,8 +1026,8 @@ uint32_t pa_context_get_server_protocol_version(pa_context *c) { pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *tag) { pa_tagstruct *t; - assert(c); - assert(tag); + pa_assert(c); + pa_assert(tag); t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, command); diff --git a/src/pulse/mainloop-signal.c b/src/pulse/mainloop-signal.c index 18fd86f8..d2d42d99 100644 --- a/src/pulse/mainloop-signal.c +++ b/src/pulse/mainloop-signal.c @@ -161,7 +161,8 @@ pa_signal_event* pa_signal_new(int sig, void (*_callback) (pa_mainloop_api *api, struct sigaction sa; #endif - pa_assert(sig > 0 && _callback); + pa_assert(sig > 0); + pa_assert(_callback); for (e = signals; e; e = e->next) if (e->sig == sig) diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index a5304ff5..419b74d6 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -677,7 +677,8 @@ static int dispatch_pollfds(pa_mainloop *m) { if (e->dead || !e->pollfd || !e->pollfd->revents) continue; - pa_assert(e->pollfd->fd == e->fd && e->callback); + pa_assert(e->pollfd->fd == e->fd); + pa_assert(e->callback); e->callback(&m->api, e, e->fd, map_flags_from_libc(e->pollfd->revents), e->userdata); e->pollfd->revents = 0; r++; diff --git a/src/pulse/simple.c b/src/pulse/simple.c index 3cf862d2..1072fb4d 100644 --- a/src/pulse/simple.c +++ b/src/pulse/simple.c @@ -1,3 +1,4 @@ + /* $Id$ */ /*** @@ -27,7 +28,6 @@ #include #include -#include #include #include @@ -36,6 +36,7 @@ #include #include +#include #include "simple.h" @@ -83,8 +84,8 @@ if (!(p)->context || pa_context_get_state((p)->context) != PA_CONTEXT_READY || \ static void context_state_cb(pa_context *c, void *userdata) { pa_simple *p = userdata; - assert(c); - assert(p); + pa_assert(c); + pa_assert(p); switch (pa_context_get_state(c)) { case PA_CONTEXT_READY: @@ -103,8 +104,8 @@ static void context_state_cb(pa_context *c, void *userdata) { static void stream_state_cb(pa_stream *s, void * userdata) { pa_simple *p = userdata; - assert(s); - assert(p); + pa_assert(s); + pa_assert(p); switch (pa_stream_get_state(s)) { @@ -122,7 +123,7 @@ static void stream_state_cb(pa_stream *s, void * userdata) { static void stream_request_cb(pa_stream *s, size_t length, void *userdata) { pa_simple *p = userdata; - assert(p); + pa_assert(p); pa_threaded_mainloop_signal(p->mainloop, 0); } @@ -130,21 +131,21 @@ static void stream_request_cb(pa_stream *s, size_t length, void *userdata) { static void stream_latency_update_cb(pa_stream *s, void *userdata) { pa_simple *p = userdata; - assert(p); + pa_assert(p); pa_threaded_mainloop_signal(p->mainloop, 0); } 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) { + 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; @@ -232,7 +233,7 @@ fail: } void pa_simple_free(pa_simple *s) { - assert(s); + pa_assert(s); if (s->mainloop) pa_threaded_mainloop_stop(s->mainloop); @@ -250,7 +251,7 @@ void pa_simple_free(pa_simple *s) { } int pa_simple_write(pa_simple *p, const void*data, size_t length, int *rerror) { - assert(p); + pa_assert(p); CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE, -1); CHECK_VALIDITY_RETURN_ANY(rerror, data && length, PA_ERR_INVALID, -1); @@ -289,7 +290,7 @@ unlock_and_fail: } int pa_simple_read(pa_simple *p, void*data, size_t length, int *rerror) { - assert(p); + pa_assert(p); CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_RECORD, PA_ERR_BADSTATE, -1); CHECK_VALIDITY_RETURN_ANY(rerror, data && length, PA_ERR_INVALID, -1); @@ -346,8 +347,8 @@ unlock_and_fail: static void success_cb(pa_stream *s, int success, void *userdata) { pa_simple *p = userdata; - assert(s); - assert(p); + pa_assert(s); + pa_assert(p); p->operation_success = success; pa_threaded_mainloop_signal(p->mainloop, 0); @@ -356,7 +357,7 @@ static void success_cb(pa_stream *s, int success, void *userdata) { int pa_simple_drain(pa_simple *p, int *rerror) { pa_operation *o = NULL; - assert(p); + pa_assert(p); CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE, -1); @@ -392,7 +393,7 @@ unlock_and_fail: int pa_simple_flush(pa_simple *p, int *rerror) { pa_operation *o = NULL; - assert(p); + pa_assert(p); CHECK_VALIDITY_RETURN_ANY(rerror, p->direction == PA_STREAM_PLAYBACK, PA_ERR_BADSTATE, -1); @@ -429,7 +430,7 @@ pa_usec_t pa_simple_get_latency(pa_simple *p, int *rerror) { pa_usec_t t; int negative; - assert(p); + pa_assert(p); pa_threaded_mainloop_lock(p->mainloop); -- cgit From 9c523e060749d1a762c264025a653803a246894e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Sep 2007 14:58:25 +0000 Subject: more modernizations, s/assert/pa_assert/g git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1806 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/authkey-prop.c | 44 ++++-- src/pulsecore/autoload.c | 43 ++++-- src/pulsecore/avahi-wrap.c | 52 ++++--- src/pulsecore/cli-command.c | 333 ++++++++++++++++++++++++++++++++----------- src/pulsecore/cli-text.c | 30 ++-- src/pulsecore/cli.c | 29 ++-- src/pulsecore/client.c | 25 ++-- src/pulsecore/core.c | 15 +- src/pulsecore/strbuf.c | 5 +- 9 files changed, 387 insertions(+), 189 deletions(-) diff --git a/src/pulsecore/authkey-prop.c b/src/pulsecore/authkey-prop.c index 146d7ca0..35b62d45 100644 --- a/src/pulsecore/authkey-prop.c +++ b/src/pulsecore/authkey-prop.c @@ -25,44 +25,53 @@ #include #endif -#include #include #include #include +#include #include +#include #include "authkey-prop.h" struct authkey_data { + PA_REFCNT_DECLARE; int ref; size_t length; }; int pa_authkey_prop_get(pa_core *c, const char *name, void *data, size_t len) { struct authkey_data *a; - assert(c && name && data && len > 0); + + pa_assert(c); + pa_assert(name); + pa_assert(data); + pa_assert(len > 0); if (!(a = pa_property_get(c, name))) return -1; - assert(a->length == len); - memcpy(data, a+1, len); + pa_assert(a->length == len); + memcpy(data, (uint8_t*) a + PA_ALIGN(sizeof(struct authkey_data)), len); + return 0; } int pa_authkey_prop_put(pa_core *c, const char *name, const void *data, size_t len) { struct authkey_data *a; - assert(c && name); + + pa_assert(c); + pa_assert(name); if (pa_property_get(c, name)) return -1; - a = pa_xmalloc(sizeof(struct authkey_data) + len); - a->ref = 1; + a = pa_xmalloc(PA_ALIGN(sizeof(struct authkey_data)) + len); + PA_REFCNT_INIT(a); a->length = len; - memcpy(a+1, data, len); + memcpy((uint8_t*) a + PA_ALIGN(sizeof(struct authkey_data)), data, len); pa_property_set(c, name, a); @@ -71,22 +80,27 @@ int pa_authkey_prop_put(pa_core *c, const char *name, const void *data, size_t l void pa_authkey_prop_ref(pa_core *c, const char *name) { struct authkey_data *a; - assert(c && name); - a = pa_property_get(c, name); - assert(a && a->ref >= 1); + pa_assert(c); + pa_assert(name); - a->ref++; + a = pa_property_get(c, name); + pa_assert(a); + pa_assert(PA_REFCNT_VALUE(a) >= 1); + PA_REFCNT_INC(a); } void pa_authkey_prop_unref(pa_core *c, const char *name) { struct authkey_data *a; - assert(c && name); + + pa_assert(c); + pa_assert(name); a = pa_property_get(c, name); - assert(a && a->ref >= 1); + pa_assert(a); + pa_assert(PA_REFCNT_VALUE(a) >= 1); - if (!(--a->ref)) { + if (PA_REFCNT_DEC(a) <= 0) { pa_property_remove(c, name); pa_xfree(a); } diff --git a/src/pulsecore/autoload.c b/src/pulsecore/autoload.c index 6f888526..0caaa295 100644 --- a/src/pulsecore/autoload.c +++ b/src/pulsecore/autoload.c @@ -26,7 +26,6 @@ #include #endif -#include #include #include @@ -36,13 +35,14 @@ #include #include #include +#include #include #include #include "autoload.h" static void entry_free(pa_autoload_entry *e) { - assert(e); + pa_assert(e); pa_subscription_post(e->core, PA_SUBSCRIPTION_EVENT_AUTOLOAD|PA_SUBSCRIPTION_EVENT_REMOVE, PA_INVALID_INDEX); pa_xfree(e->name); pa_xfree(e->module); @@ -51,7 +51,8 @@ static void entry_free(pa_autoload_entry *e) { } static void entry_remove_and_free(pa_autoload_entry *e) { - assert(e && e->core); + pa_assert(e); + pa_assert(e->core); pa_idxset_remove_by_data(e->core->autoload_idxset, e, NULL); pa_hashmap_remove(e->core->autoload_hashmap, e->name); @@ -60,12 +61,14 @@ static void entry_remove_and_free(pa_autoload_entry *e) { static pa_autoload_entry* entry_new(pa_core *c, const char *name) { pa_autoload_entry *e = NULL; - assert(c && name); + + pa_core_assert_ref(c); + pa_assert(name); if (c->autoload_hashmap && (e = pa_hashmap_get(c->autoload_hashmap, name))) return NULL; - e = pa_xmalloc(sizeof(pa_autoload_entry)); + e = pa_xnew(pa_autoload_entry, 1); e->core = c; e->name = pa_xstrdup(name); e->module = e->argument = NULL; @@ -73,7 +76,7 @@ static pa_autoload_entry* entry_new(pa_core *c, const char *name) { if (!c->autoload_hashmap) c->autoload_hashmap = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - assert(c->autoload_hashmap); + pa_assert(c->autoload_hashmap); pa_hashmap_put(c->autoload_hashmap, e->name, e); @@ -88,7 +91,11 @@ static pa_autoload_entry* entry_new(pa_core *c, const char *name) { int pa_autoload_add(pa_core *c, const char*name, pa_namereg_type_t type, const char*module, const char *argument, uint32_t *idx) { pa_autoload_entry *e = NULL; - assert(c && name && module && (type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE)); + + pa_assert(c); + pa_assert(name); + pa_assert(module); + pa_assert(type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE); if (!(e = entry_new(c, name))) return -1; @@ -105,7 +112,10 @@ int pa_autoload_add(pa_core *c, const char*name, pa_namereg_type_t type, const c int pa_autoload_remove_by_name(pa_core *c, const char*name, pa_namereg_type_t type) { pa_autoload_entry *e; - assert(c && name && (type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE)); + + pa_assert(c); + pa_assert(name); + pa_assert(type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE); if (!c->autoload_hashmap || !(e = pa_hashmap_get(c->autoload_hashmap, name)) || e->type != type) return -1; @@ -116,7 +126,9 @@ int pa_autoload_remove_by_name(pa_core *c, const char*name, pa_namereg_type_t ty int pa_autoload_remove_by_index(pa_core *c, uint32_t idx) { pa_autoload_entry *e; - assert(c && idx != PA_IDXSET_INVALID); + + pa_assert(c); + pa_assert(idx != PA_IDXSET_INVALID); if (!c->autoload_idxset || !(e = pa_idxset_get_by_index(c->autoload_idxset, idx))) return -1; @@ -128,7 +140,9 @@ int pa_autoload_remove_by_index(pa_core *c, uint32_t idx) { void pa_autoload_request(pa_core *c, const char *name, pa_namereg_type_t type) { pa_autoload_entry *e; pa_module *m; - assert(c && name); + + pa_assert(c); + pa_assert(name); if (!c->autoload_hashmap || !(e = pa_hashmap_get(c->autoload_hashmap, name)) || (e->type != type)) return; @@ -153,6 +167,7 @@ static void free_func(void *p, PA_GCC_UNUSED void *userdata) { } void pa_autoload_free(pa_core *c) { + if (c->autoload_hashmap) { pa_hashmap_free(c->autoload_hashmap, free_func, NULL); c->autoload_hashmap = NULL; @@ -166,7 +181,9 @@ void pa_autoload_free(pa_core *c) { const pa_autoload_entry* pa_autoload_get_by_name(pa_core *c, const char*name, pa_namereg_type_t type) { pa_autoload_entry *e; - assert(c && name); + + pa_core_assert_ref(c); + pa_assert(name); if (!c->autoload_hashmap || !(e = pa_hashmap_get(c->autoload_hashmap, name)) || e->type != type) return NULL; @@ -176,7 +193,9 @@ const pa_autoload_entry* pa_autoload_get_by_name(pa_core *c, const char*name, pa const pa_autoload_entry* pa_autoload_get_by_index(pa_core *c, uint32_t idx) { pa_autoload_entry *e; - assert(c && idx != PA_IDXSET_INVALID); + + pa_core_assert_ref(c); + pa_assert(idx != PA_IDXSET_INVALID); if (!c->autoload_idxset || !(e = pa_idxset_get_by_index(c->autoload_idxset, idx))) return NULL; diff --git a/src/pulsecore/avahi-wrap.c b/src/pulsecore/avahi-wrap.c index 855ed567..fae54810 100644 --- a/src/pulsecore/avahi-wrap.c +++ b/src/pulsecore/avahi-wrap.c @@ -21,11 +21,14 @@ USA. ***/ -#include +#ifdef HAVE_CONFIG_H +#include +#endif #include #include +#include #include "avahi-wrap.h" @@ -61,9 +64,9 @@ static pa_io_event_flags_t translate_io_flags(AvahiWatchEvent e) { static void watch_callback(pa_mainloop_api*a, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) { AvahiWatch *w = userdata; - assert(a); - assert(e); - assert(w); + pa_assert(a); + pa_assert(e); + pa_assert(w); w->current_event = translate_io_flags_back(events); w->callback(w, fd, w->current_event, w->userdata); @@ -74,12 +77,10 @@ static AvahiWatch* watch_new(const AvahiPoll *api, int fd, AvahiWatchEvent event pa_avahi_poll *p; AvahiWatch *w; - assert(api); - assert(fd >= 0); - assert(callback); - - p = api->userdata; - assert(p); + pa_assert(api); + pa_assert(fd >= 0); + pa_assert(callback); + pa_assert_se(p = api->userdata); w = pa_xnew(AvahiWatch, 1); w->avahi_poll = p; @@ -92,19 +93,19 @@ static AvahiWatch* watch_new(const AvahiPoll *api, int fd, AvahiWatchEvent event } static void watch_update(AvahiWatch *w, AvahiWatchEvent event) { - assert(w); + pa_assert(w); w->avahi_poll->mainloop->io_enable(w->io_event, translate_io_flags(event)); } static AvahiWatchEvent watch_get_events(AvahiWatch *w) { - assert(w); + pa_assert(w); return w->current_event; } static void watch_free(AvahiWatch *w) { - assert(w); + pa_assert(w); w->avahi_poll->mainloop->io_free(w->io_event); pa_xfree(w); @@ -120,9 +121,9 @@ struct AvahiTimeout { static void timeout_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *tv, void *userdata) { AvahiTimeout *t = userdata; - assert(a); - assert(e); - assert(t); + pa_assert(a); + pa_assert(e); + pa_assert(t); t->callback(t, t->userdata); } @@ -131,11 +132,9 @@ static AvahiTimeout* timeout_new(const AvahiPoll *api, const struct timeval *tv, pa_avahi_poll *p; AvahiTimeout *t; - assert(api); - assert(callback); - - p = api->userdata; - assert(p); + pa_assert(api); + pa_assert(callback); + pa_assert_se(p = api->userdata); t = pa_xnew(AvahiTimeout, 1); t->avahi_poll = p; @@ -148,7 +147,7 @@ static AvahiTimeout* timeout_new(const AvahiPoll *api, const struct timeval *tv, } static void timeout_update(AvahiTimeout *t, const struct timeval *tv) { - assert(t); + pa_assert(t); if (t->time_event && tv) t->avahi_poll->mainloop->time_restart(t->time_event, tv); @@ -161,7 +160,7 @@ static void timeout_update(AvahiTimeout *t, const struct timeval *tv) { } static void timeout_free(AvahiTimeout *t) { - assert(t); + pa_assert(t); if (t->time_event) t->avahi_poll->mainloop->time_free(t->time_event); @@ -171,7 +170,7 @@ static void timeout_free(AvahiTimeout *t) { AvahiPoll* pa_avahi_poll_new(pa_mainloop_api *m) { pa_avahi_poll *p; - assert(m); + pa_assert(m); p = pa_xnew(pa_avahi_poll, 1); @@ -190,9 +189,8 @@ AvahiPoll* pa_avahi_poll_new(pa_mainloop_api *m) { void pa_avahi_poll_free(AvahiPoll *api) { pa_avahi_poll *p; - assert(api); - p = api->userdata; - assert(p); + pa_assert(api); + pa_assert_se(p = api->userdata); pa_xfree(p); } diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c index 79b52d46..3a1ce5a8 100644 --- a/src/pulsecore/cli-command.c +++ b/src/pulsecore/cli-command.c @@ -182,15 +182,23 @@ static uint32_t parse_index(const char *n) { return idx; } -static int pa_cli_command_exit(pa_core *c, pa_tokenizer *t, PA_GCC_UNUSED pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - assert(c && c->mainloop && t); +static int pa_cli_command_exit(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + c->mainloop->quit(c->mainloop, 0); return 0; } -static int pa_cli_command_help(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_help(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const struct command*command; - assert(c && t && buf); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); pa_strbuf_puts(buf, "Available commands:\n"); @@ -200,67 +208,91 @@ static int pa_cli_command_help(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_G return 0; } -static int pa_cli_command_modules(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_modules(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { char *s; - assert(c && t); - s = pa_module_list_to_string(c); - assert(s); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + + pa_assert_se(s = pa_module_list_to_string(c)); pa_strbuf_puts(buf, s); pa_xfree(s); return 0; } -static int pa_cli_command_clients(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_clients(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { char *s; - assert(c && t); - s = pa_client_list_to_string(c); - assert(s); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + + pa_assert_se(s = pa_client_list_to_string(c)); pa_strbuf_puts(buf, s); pa_xfree(s); return 0; } -static int pa_cli_command_sinks(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_sinks(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { char *s; - assert(c && t); - s = pa_sink_list_to_string(c); - assert(s); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + + pa_assert_se(s = pa_sink_list_to_string(c)); pa_strbuf_puts(buf, s); pa_xfree(s); return 0; } -static int pa_cli_command_sources(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_sources(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { char *s; - assert(c && t); - s = pa_source_list_to_string(c); - assert(s); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + + pa_assert_se(s = pa_source_list_to_string(c)); pa_strbuf_puts(buf, s); pa_xfree(s); return 0; } -static int pa_cli_command_sink_inputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_sink_inputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { char *s; - assert(c && t); - s = pa_sink_input_list_to_string(c); - assert(s); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + + pa_assert_se(s = pa_sink_input_list_to_string(c)); pa_strbuf_puts(buf, s); pa_xfree(s); return 0; } -static int pa_cli_command_source_outputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_source_outputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { char *s; - assert(c && t); - s = pa_source_output_list_to_string(c); - assert(s); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + + pa_assert_se(s = pa_source_output_list_to_string(c)); pa_strbuf_puts(buf, s); pa_xfree(s); return 0; } -static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { char s[256]; const pa_mempool_stat *stat; unsigned k; @@ -275,8 +307,10 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_G [PA_MEMBLOCK_IMPORTED] = "IMPORTED", }; - assert(c); - assert(t); + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); stat = pa_mempool_get_stat(c->mempool); @@ -320,7 +354,11 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_G } static int pa_cli_command_info(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { - assert(c && t); + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + pa_cli_command_stat(c, t, buf, fail); pa_cli_command_modules(c, t, buf, fail); pa_cli_command_sinks(c, t, buf, fail); @@ -333,10 +371,14 @@ static int pa_cli_command_info(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int return 0; } -static int pa_cli_command_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { pa_module *m; const char *name; - assert(c && t); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); if (!(name = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify the module name and optionally arguments.\n"); @@ -351,12 +393,16 @@ static int pa_cli_command_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_G return 0; } -static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { pa_module *m; uint32_t idx; const char *i; char *e; - assert(c && t); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); if (!(i = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify the module index.\n"); @@ -373,12 +419,17 @@ static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA return 0; } -static int pa_cli_command_sink_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_sink_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *n, *v; pa_sink *sink; uint32_t volume; pa_cvolume cvolume; + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + if (!(n = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n"); return -1; @@ -404,13 +455,18 @@ static int pa_cli_command_sink_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *bu return 0; } -static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *n, *v; pa_sink_input *si; pa_volume_t volume; pa_cvolume cvolume; uint32_t idx; + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + if (!(n = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n"); return -1; @@ -441,12 +497,17 @@ static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strb return 0; } -static int pa_cli_command_source_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_source_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *n, *v; pa_source *source; uint32_t volume; pa_cvolume cvolume; + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + if (!(n = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n"); return -1; @@ -472,11 +533,16 @@ static int pa_cli_command_source_volume(pa_core *c, pa_tokenizer *t, pa_strbuf * return 0; } -static int pa_cli_command_sink_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_sink_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *n, *m; pa_sink *sink; int mute; + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + if (!(n = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n"); return -1; @@ -501,11 +567,16 @@ static int pa_cli_command_sink_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, return 0; } -static int pa_cli_command_source_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_source_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *n, *m; pa_source *source; int mute; + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + if (!(n = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n"); return -1; @@ -530,12 +601,17 @@ static int pa_cli_command_source_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *bu return 0; } -static int pa_cli_command_sink_input_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_sink_input_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *n, *v; pa_sink_input *si; uint32_t idx; int mute; + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + if (!(n = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n"); return -1; @@ -565,9 +641,13 @@ static int pa_cli_command_sink_input_mute(pa_core *c, pa_tokenizer *t, pa_strbuf return 0; } -static int pa_cli_command_sink_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_sink_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *n; - assert(c && t); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); if (!(n = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n"); @@ -578,9 +658,13 @@ static int pa_cli_command_sink_default(pa_core *c, pa_tokenizer *t, pa_strbuf *b return 0; } -static int pa_cli_command_source_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_source_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *n; - assert(c && t); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); if (!(n = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n"); @@ -591,11 +675,15 @@ static int pa_cli_command_source_default(pa_core *c, pa_tokenizer *t, pa_strbuf return 0; } -static int pa_cli_command_kill_client(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_kill_client(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *n; pa_client *client; uint32_t idx; - assert(c && t); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); if (!(n = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a client by its index.\n"); @@ -616,11 +704,15 @@ static int pa_cli_command_kill_client(pa_core *c, pa_tokenizer *t, pa_strbuf *bu return 0; } -static int pa_cli_command_kill_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_kill_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *n; pa_sink_input *sink_input; uint32_t idx; - assert(c && t); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); if (!(n = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n"); @@ -641,11 +733,15 @@ static int pa_cli_command_kill_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf return 0; } -static int pa_cli_command_kill_source_output(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_kill_source_output(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *n; pa_source_output *source_output; uint32_t idx; - assert(c && t); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); if (!(n = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a source output by its index.\n"); @@ -666,20 +762,29 @@ static int pa_cli_command_kill_source_output(pa_core *c, pa_tokenizer *t, pa_str return 0; } -static int pa_cli_command_scache_list(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_scache_list(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { char *s; - assert(c && t); - s = pa_scache_list_to_string(c); - assert(s); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + + pa_assert_se(s = pa_scache_list_to_string(c)); pa_strbuf_puts(buf, s); pa_xfree(s); + return 0; } static int pa_cli_command_scache_play(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *n, *sink_name; pa_sink *sink; - assert(c && t && buf && fail); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); if (!(n = pa_tokenizer_get(t, 1)) || !(sink_name = pa_tokenizer_get(t, 2))) { pa_strbuf_puts(buf, "You need to specify a sample name and a sink name.\n"); @@ -701,7 +806,11 @@ static int pa_cli_command_scache_play(pa_core *c, pa_tokenizer *t, pa_strbuf *bu static int pa_cli_command_scache_remove(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *n; - assert(c && t && buf && fail); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); if (!(n = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a sample name.\n"); @@ -719,7 +828,11 @@ static int pa_cli_command_scache_remove(pa_core *c, pa_tokenizer *t, pa_strbuf * static int pa_cli_command_scache_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *fname, *n; int r; - assert(c && t && buf && fail); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); if (!(fname = pa_tokenizer_get(t, 2)) || !(n = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a file name and a sample name.\n"); @@ -739,7 +852,11 @@ static int pa_cli_command_scache_load(pa_core *c, pa_tokenizer *t, pa_strbuf *bu static int pa_cli_command_scache_load_dir(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *pname; - assert(c && t && buf && fail); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); if (!(pname = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a path name.\n"); @@ -757,7 +874,11 @@ static int pa_cli_command_scache_load_dir(pa_core *c, pa_tokenizer *t, pa_strbuf static int pa_cli_command_play_file(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *fname, *sink_name; pa_sink *sink; - assert(c && t && buf && fail); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); if (!(fname = pa_tokenizer_get(t, 1)) || !(sink_name = pa_tokenizer_get(t, 2))) { pa_strbuf_puts(buf, "You need to specify a file name and a sink name.\n"); @@ -775,7 +896,11 @@ static int pa_cli_command_play_file(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, static int pa_cli_command_autoload_add(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *a, *b; - assert(c && t && buf && fail); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); if (!(a = pa_tokenizer_get(t, 1)) || !(b = pa_tokenizer_get(t, 2))) { pa_strbuf_puts(buf, "You need to specify a device name, a filename or a module name and optionally module arguments\n"); @@ -789,7 +914,11 @@ static int pa_cli_command_autoload_add(pa_core *c, pa_tokenizer *t, pa_strbuf *b static int pa_cli_command_autoload_remove(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { const char *name; - assert(c && t && buf && fail); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); if (!(name = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a device name\n"); @@ -804,25 +933,36 @@ static int pa_cli_command_autoload_remove(pa_core *c, pa_tokenizer *t, pa_strbuf return 0; } -static int pa_cli_command_autoload_list(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_autoload_list(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { char *s; - assert(c && t); - s = pa_autoload_list_to_string(c); - assert(s); + + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + + pa_assert_se(s = pa_autoload_list_to_string(c)); pa_strbuf_puts(buf, s); pa_xfree(s); + return 0; } -static int pa_cli_command_list_props(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - assert(c && t); +static int pa_cli_command_list_props(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + pa_property_dump(c, buf); return 0; } static int pa_cli_command_vacuum(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { - assert(c); - assert(t); + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); pa_mempool_vacuum(c->mempool); @@ -835,6 +975,11 @@ static int pa_cli_command_move_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf pa_sink *sink; uint32_t idx; + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + if (!(n = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n"); return -1; @@ -873,6 +1018,11 @@ static int pa_cli_command_move_source_output(pa_core *c, pa_tokenizer *t, pa_str pa_source *source; uint32_t idx; + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + if (!(n = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a source output by its index.\n"); return -1; @@ -910,6 +1060,11 @@ static int pa_cli_command_suspend_sink(pa_core *c, pa_tokenizer *t, pa_strbuf *b pa_sink *sink; int suspend; + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + if (!(n = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n"); return -1; @@ -939,6 +1094,11 @@ static int pa_cli_command_suspend_source(pa_core *c, pa_tokenizer *t, pa_strbuf pa_source *source; int suspend; + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + if (!(n = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n"); return -1; @@ -968,6 +1128,11 @@ static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, i int suspend; int ret; + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); + if (!(m = pa_tokenizer_get(t, 1))) { pa_strbuf_puts(buf, "You need to specify a suspend switch setting (0/1).\n"); return -1; @@ -988,7 +1153,7 @@ static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, i return 0; } -static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { +static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { pa_module *m; pa_sink *sink; pa_source *source; @@ -1000,7 +1165,10 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_G void *i; pa_autoload_entry *a; - assert(c && t); + pa_core_assert_ref(c); + pa_assert(t); + pa_assert(buf); + pa_assert(fail); time(&now); @@ -1097,6 +1265,10 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_G int pa_cli_command_execute_line_stateful(pa_core *c, const char *s, pa_strbuf *buf, int *fail, int *ifstate) { const char *cs; + pa_assert(c); + pa_assert(s); + pa_assert(buf); + cs = s+strspn(s, whitespace); if (*cs == '#' || !*cs) @@ -1160,14 +1332,13 @@ int pa_cli_command_execute_line_stateful(pa_core *c, const char *s, pa_strbuf *b if (ifstate && *ifstate == IFSTATE_FALSE) return 0; - l = strcspn(cs, whitespace); for (command = commands; command->name; command++) if (strlen(command->name) == l && !strncmp(cs, command->name, l)) { int ret; pa_tokenizer *t = pa_tokenizer_new(cs, command->args); - assert(t); + pa_assert(t); ret = command->proc(c, t, buf, fail); pa_tokenizer_free(t); unknown = 0; @@ -1198,9 +1369,9 @@ int pa_cli_command_execute_file(pa_core *c, const char *fn, pa_strbuf *buf, int int ifstate = IFSTATE_NONE; int ret = -1; - assert(c); - assert(fn); - assert(buf); + pa_assert(c); + pa_assert(fn); + pa_assert(buf); if (!(f = fopen(fn, "r"))) { pa_strbuf_printf(buf, "open('%s') failed: %s\n", fn, pa_cstrerror(errno)); @@ -1230,9 +1401,9 @@ int pa_cli_command_execute(pa_core *c, const char *s, pa_strbuf *buf, int *fail) const char *p; int ifstate = IFSTATE_NONE; - assert(c); - assert(s); - assert(buf); + pa_assert(c); + pa_assert(s); + pa_assert(buf); p = s; while (*p) { diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c index 617ae812..bac61dc9 100644 --- a/src/pulsecore/cli-text.c +++ b/src/pulsecore/cli-text.c @@ -25,7 +25,6 @@ #include #endif -#include #include #include @@ -41,6 +40,7 @@ #include #include #include +#include #include "cli-text.h" @@ -48,10 +48,9 @@ char *pa_module_list_to_string(pa_core *c) { pa_strbuf *s; pa_module *m; uint32_t idx = PA_IDXSET_INVALID; - assert(c); + pa_assert(c); s = pa_strbuf_new(); - assert(s); pa_strbuf_printf(s, "%u module(s) loaded.\n", pa_idxset_size(c->modules)); @@ -72,10 +71,9 @@ char *pa_client_list_to_string(pa_core *c) { pa_strbuf *s; pa_client *client; uint32_t idx = PA_IDXSET_INVALID; - assert(c); + pa_assert(c); s = pa_strbuf_new(); - assert(s); pa_strbuf_printf(s, "%u client(s) logged in.\n", pa_idxset_size(c->clients)); @@ -99,10 +97,9 @@ char *pa_sink_list_to_string(pa_core *c) { [PA_SINK_IDLE] = "IDLE", [PA_SINK_UNLINKED] = "UNLINKED" }; - assert(c); + pa_assert(c); s = pa_strbuf_new(); - assert(s); pa_strbuf_printf(s, "%u sink(s) available.\n", pa_idxset_size(c->sinks)); @@ -159,10 +156,9 @@ char *pa_source_list_to_string(pa_core *c) { [PA_SOURCE_IDLE] = "IDLE", [PA_SOURCE_UNLINKED] = "UNLINKED" }; - assert(c); + pa_assert(c); s = pa_strbuf_new(); - assert(s); pa_strbuf_printf(s, "%u source(s) available.\n", pa_idxset_size(c->sources)); @@ -220,17 +216,16 @@ char *pa_source_output_list_to_string(pa_core *c) { [PA_SOURCE_OUTPUT_CORKED] = "CORKED", [PA_SOURCE_OUTPUT_UNLINKED] = "UNLINKED" }; - assert(c); + pa_assert(c); s = pa_strbuf_new(); - assert(s); pa_strbuf_printf(s, "%u source outputs(s) available.\n", pa_idxset_size(c->source_outputs)); for (o = pa_idxset_first(c->source_outputs, &idx); o; o = pa_idxset_next(c->source_outputs, &idx)) { char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX]; - assert(o->source); + pa_assert(o->source); pa_strbuf_printf( s, @@ -275,16 +270,15 @@ char *pa_sink_input_list_to_string(pa_core *c) { [PA_SINK_INPUT_UNLINKED] = "UNLINKED" }; - assert(c); + pa_assert(c); s = pa_strbuf_new(); - assert(s); pa_strbuf_printf(s, "%u sink input(s) available.\n", pa_idxset_size(c->sink_inputs)); for (i = pa_idxset_first(c->sink_inputs, &idx); i; i = pa_idxset_next(c->sink_inputs, &idx)) { char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX]; - assert(i->sink); + pa_assert(i->sink); pa_strbuf_printf( s, @@ -325,10 +319,9 @@ char *pa_sink_input_list_to_string(pa_core *c) { char *pa_scache_list_to_string(pa_core *c) { pa_strbuf *s; - assert(c); + pa_assert(c); s = pa_strbuf_new(); - assert(s); pa_strbuf_printf(s, "%u cache entries available.\n", c->scache ? pa_idxset_size(c->scache) : 0); @@ -374,10 +367,9 @@ char *pa_scache_list_to_string(pa_core *c) { char *pa_autoload_list_to_string(pa_core *c) { pa_strbuf *s; - assert(c); + pa_assert(c); s = pa_strbuf_new(); - assert(s); pa_strbuf_printf(s, "%u autoload entries available.\n", c->autoload_hashmap ? pa_hashmap_size(c->autoload_hashmap) : 0); diff --git a/src/pulsecore/cli.c b/src/pulsecore/cli.c index ee05d7f9..bb80e908 100644 --- a/src/pulsecore/cli.c +++ b/src/pulsecore/cli.c @@ -45,6 +45,7 @@ #include #include #include +#include #include "cli.h" @@ -68,19 +69,17 @@ static void client_kill(pa_client *c); pa_cli* pa_cli_new(pa_core *core, pa_iochannel *io, pa_module *m) { char cname[256]; pa_cli *c; - assert(io); + pa_assert(io); - c = pa_xmalloc(sizeof(pa_cli)); + c = pa_xnew(pa_cli, 1); c->core = core; - c->line = pa_ioline_new(io); - assert(c->line); + pa_assert_se(c->line = pa_ioline_new(io)); c->userdata = NULL; c->eof_callback = NULL; pa_iochannel_socket_peer_to_string(io, cname, sizeof(cname)); - c->client = pa_client_new(core, __FILE__, cname); - assert(c->client); + pa_assert_se(c->client = pa_client_new(core, __FILE__, cname)); c->client->kill = client_kill; c->client->userdata = c; c->client->owner = m; @@ -94,7 +93,8 @@ pa_cli* pa_cli_new(pa_core *core, pa_iochannel *io, pa_module *m) { } void pa_cli_free(pa_cli *c) { - assert(c); + pa_assert(c); + pa_ioline_close(c->line); pa_ioline_unref(c->line); pa_client_free(c->client); @@ -103,8 +103,9 @@ void pa_cli_free(pa_cli *c) { static void client_kill(pa_client *client) { pa_cli *c; - assert(client && client->userdata); - c = client->userdata; + + pa_assert(client); + pa_assert_se(c = client->userdata); pa_log_debug("CLI client killed."); if (c->defer_kill) @@ -119,7 +120,9 @@ static void line_callback(pa_ioline *line, const char *s, void *userdata) { pa_strbuf *buf; pa_cli *c = userdata; char *p; - assert(line && c); + + pa_assert(line); + pa_assert(c); if (!s) { pa_log_debug("CLI got EOF from user."); @@ -129,8 +132,7 @@ static void line_callback(pa_ioline *line, const char *s, void *userdata) { return; } - buf = pa_strbuf_new(); - assert(buf); + pa_assert_se(buf = pa_strbuf_new()); c->defer_kill++; pa_cli_command_execute_line(c->core, s, buf, &c->fail); c->defer_kill--; @@ -145,7 +147,8 @@ static void line_callback(pa_ioline *line, const char *s, void *userdata) { } void pa_cli_set_eof_callback(pa_cli *c, void (*cb)(pa_cli*c, void *userdata), void *userdata) { - assert(c); + pa_assert(c); + c->eof_callback = cb; c->userdata = userdata; } diff --git a/src/pulsecore/client.c b/src/pulsecore/client.c index 0d792bb4..99cbeb83 100644 --- a/src/pulsecore/client.c +++ b/src/pulsecore/client.c @@ -27,7 +27,6 @@ #endif #include -#include #include #include @@ -35,15 +34,16 @@ #include #include +#include #include "client.h" pa_client *pa_client_new(pa_core *core, const char *driver, const char *name) { pa_client *c; - int r; - assert(core); + + pa_core_assert_ref(core); - c = pa_xmalloc(sizeof(pa_client)); + c = pa_xnew(pa_client, 1); c->name = pa_xstrdup(name); c->driver = pa_xstrdup(driver); c->owner = NULL; @@ -52,10 +52,9 @@ pa_client *pa_client_new(pa_core *core, const char *driver, const char *name) { c->kill = NULL; c->userdata = NULL; - r = pa_idxset_put(core->clients, c, &c->index); - assert(c->index != PA_IDXSET_INVALID && r >= 0); + pa_assert_se(pa_idxset_put(core->clients, c, &c->index) >= 0); - pa_log_info("created %u \"%s\"", c->index, c->name); + pa_log_info("Created %u \"%s\"", c->index, c->name); pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_NEW, c->index); pa_core_check_quit(core); @@ -64,13 +63,14 @@ pa_client *pa_client_new(pa_core *core, const char *driver, const char *name) { } void pa_client_free(pa_client *c) { - assert(c && c->core); + pa_assert(c); + pa_assert(c->core); pa_idxset_remove_by_data(c->core->clients, c, NULL); pa_core_check_quit(c->core); - pa_log_info("freed %u \"%s\"", c->index, c->name); + pa_log_info("Freed %u \"%s\"", c->index, c->name); pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_REMOVE, c->index); pa_xfree(c->name); pa_xfree(c->driver); @@ -78,7 +78,8 @@ void pa_client_free(pa_client *c) { } void pa_client_kill(pa_client *c) { - assert(c); + pa_assert(c); + if (!c->kill) { pa_log_warn("kill() operation not implemented for client %u", c->index); return; @@ -88,9 +89,9 @@ void pa_client_kill(pa_client *c) { } void pa_client_set_name(pa_client *c, const char *name) { - assert(c); + pa_assert(c); - pa_log_info("client %u changed name from \"%s\" to \"%s\"", c->index, c->name, name); + pa_log_info("Client %u changed name from \"%s\" to \"%s\"", c->index, c->name, name); pa_xfree(c->name); c->name = pa_xstrdup(name); diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c index 808bc9a8..c5386522 100644 --- a/src/pulsecore/core.c +++ b/src/pulsecore/core.c @@ -27,7 +27,6 @@ #endif #include -#include #include #include @@ -160,21 +159,21 @@ static void core_free(pa_object *o) { pa_assert(c); pa_module_unload_all(c); - assert(!c->modules); + pa_assert(!c->modules); - assert(pa_idxset_isempty(c->clients)); + pa_assert(pa_idxset_isempty(c->clients)); pa_idxset_free(c->clients, NULL, NULL); - assert(pa_idxset_isempty(c->sinks)); + pa_assert(pa_idxset_isempty(c->sinks)); pa_idxset_free(c->sinks, NULL, NULL); - assert(pa_idxset_isempty(c->sources)); + pa_assert(pa_idxset_isempty(c->sources)); pa_idxset_free(c->sources, NULL, NULL); - assert(pa_idxset_isempty(c->source_outputs)); + pa_assert(pa_idxset_isempty(c->source_outputs)); pa_idxset_free(c->source_outputs, NULL, NULL); - assert(pa_idxset_isempty(c->sink_inputs)); + pa_assert(pa_idxset_isempty(c->sink_inputs)); pa_idxset_free(c->sink_inputs, NULL, NULL); pa_scache_free(c); @@ -200,7 +199,7 @@ static void core_free(pa_object *o) { static void quit_callback(pa_mainloop_api*m, pa_time_event *e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { pa_core *c = userdata; - pa_assert(c->quit_event = e); + pa_assert(c->quit_event == e); m->quit(m, 0); } diff --git a/src/pulsecore/strbuf.c b/src/pulsecore/strbuf.c index ca88c59f..122343f4 100644 --- a/src/pulsecore/strbuf.c +++ b/src/pulsecore/strbuf.c @@ -50,8 +50,9 @@ struct pa_strbuf { }; pa_strbuf *pa_strbuf_new(void) { - - pa_strbuf *sb = pa_xnew(pa_strbuf, 1); + pa_strbuf *sb; + + sb = pa_xnew(pa_strbuf, 1); sb->length = 0; sb->head = sb->tail = NULL; -- cgit From abb18d9c4c684c8513bc1a8d897dd04fc82ed1e7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Sep 2007 15:14:46 +0000 Subject: explcitly initialize tls memory to NULL git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1807 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/thread.h b/src/pulsecore/thread.h index 4e5425d6..4a2b1bb8 100644 --- a/src/pulsecore/thread.h +++ b/src/pulsecore/thread.h @@ -85,7 +85,7 @@ void *pa_tls_set(pa_tls *t, void *userdata); /* An optimized version of the above that requires no dynamic * allocation if the compiler supports __thread */ #define PA_STATIC_TLS_DECLARE_NO_FREE(name) \ - static __thread void *name##_tls; \ + static __thread void *name##_tls = NULL; \ static inline void* name##_tls_get(void) { \ return name##_tls; \ } \ -- cgit From 2988c3d9fbe52ba0429b4962446273bceda391f6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Sep 2007 15:27:32 +0000 Subject: Rework core-error.c on top of PA_STATIC_TLS_DECLARE, the windows specific parts need to be moved to thread-win32.c git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1808 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core-error.c | 180 +++++++-------------------------------------- 1 file changed, 26 insertions(+), 154 deletions(-) diff --git a/src/pulsecore/core-error.c b/src/pulsecore/core-error.c index 044bea12..64464132 100644 --- a/src/pulsecore/core-error.c +++ b/src/pulsecore/core-error.c @@ -31,178 +31,50 @@ #include #include -#ifdef HAVE_PTHREAD -#include -#endif - -#ifdef HAVE_WINDOWS_H -#include -#endif - #include #include #include #include +#include +#include +#include #include "core-error.h" -#ifdef HAVE_PTHREAD - -static pthread_once_t cstrerror_once = PTHREAD_ONCE_INIT; -static pthread_key_t tlsstr_key; - -static void inittls(void) { - int ret; - - ret = pthread_key_create(&tlsstr_key, pa_xfree); - if (ret) { - fprintf(stderr, __FILE__ ": CRITICAL: Unable to allocate TLS key (%d)\n", errno); - exit(-1); - } -} - -#elif HAVE_WINDOWS_H - -static DWORD tlsstr_key = TLS_OUT_OF_INDEXES; -static DWORD monitor_key = TLS_OUT_OF_INDEXES; - -static void inittls(void) { - HANDLE mutex; - char name[64]; - - sprintf(name, "pulse%d", (int)GetCurrentProcessId()); - - mutex = CreateMutex(NULL, FALSE, name); - if (!mutex) { - fprintf(stderr, __FILE__ ": CRITICAL: Unable to create named mutex (%d)\n", (int)GetLastError()); - exit(-1); - } - - WaitForSingleObject(mutex, INFINITE); - - if (tlsstr_key == TLS_OUT_OF_INDEXES) { - tlsstr_key = TlsAlloc(); - monitor_key = TlsAlloc(); - if ((tlsstr_key == TLS_OUT_OF_INDEXES) || (monitor_key == TLS_OUT_OF_INDEXES)) { - fprintf(stderr, __FILE__ ": CRITICAL: Unable to allocate TLS key (%d)\n", (int)GetLastError()); - exit(-1); - } - } - - ReleaseMutex(mutex); - - CloseHandle(mutex); -} - -/* - * This is incredibly brain dead, but this is necessary when dealing with - * the hell that is Win32. - */ -struct monitor_data { - HANDLE thread; - void *data; -}; - -static DWORD WINAPI monitor_thread(LPVOID param) { - struct monitor_data *data; - - data = (struct monitor_data*)param; - assert(data); - - WaitForSingleObject(data->thread, INFINITE); - - CloseHandle(data->thread); - pa_xfree(data->data); - pa_xfree(data); - - return 0; -} - -static void start_monitor(void) { - HANDLE thread; - struct monitor_data *data; - - data = pa_xnew(struct monitor_data, 1); - assert(data); - - DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), - GetCurrentProcess(), &data->thread, 0, FALSE, DUPLICATE_SAME_ACCESS); - - thread = CreateThread(NULL, 0, monitor_thread, data, 0, NULL); - assert(thread); - - TlsSetValue(monitor_key, data); - - CloseHandle(thread); -} - -#else - -/* Unsafe, but we have no choice */ -static char *tlsstr; - -#endif +PA_STATIC_TLS_DECLARE(cstrerror, pa_xfree); const char* pa_cstrerror(int errnum) { - const char *origbuf; - -#ifdef HAVE_STRERROR_R + const char *original = NULL; + char *translated, *t; char errbuf[128]; -#endif - -#ifdef HAVE_PTHREAD - char *tlsstr; - pthread_once(&cstrerror_once, inittls); - - tlsstr = pthread_getspecific(tlsstr_key); -#elif defined(HAVE_WINDOWS_H) - char *tlsstr; - struct monitor_data *data; - - inittls(); - - tlsstr = TlsGetValue(tlsstr_key); - if (!tlsstr) - start_monitor(); - data = TlsGetValue(monitor_key); -#endif - - if (tlsstr) - pa_xfree(tlsstr); - -#ifdef HAVE_STRERROR_R - -#ifdef __GLIBC__ - origbuf = strerror_r(errnum, errbuf, sizeof(errbuf)); - if (origbuf == NULL) - origbuf = ""; -#else + if ((t = PA_STATIC_TLS_GET(cstrerror))) + pa_xfree(t); + +#if defined(HAVE_STRERROR_R) && defined(__GLIBC__) + original = strerror_r(errnum, errbuf, sizeof(errbuf)); +#elif defined(HAVE_STRERROR_R) if (strerror_r(errnum, errbuf, sizeof(errbuf)) == 0) { - origbuf = errbuf; - errbuf[sizeof(errbuf) - 1] = '\0'; - } else - origbuf = ""; -#endif - + errbuf[sizeof(errbuf) - 1] = 0; + original = errbuf; + } #else /* This might not be thread safe, but we hope for the best */ - origbuf = strerror(errnum); + original = strerror(errnum); #endif - tlsstr = pa_locale_to_utf8(origbuf); - if (!tlsstr) { - fprintf(stderr, "Unable to convert, filtering\n"); - tlsstr = pa_utf8_filter(origbuf); + if (!original) { + pa_snprintf(errbuf, sizeof(errbuf), "Unknown error %i", errnum); + original = errbuf; } -#ifdef HAVE_PTHREAD - pthread_setspecific(tlsstr_key, tlsstr); -#elif defined(HAVE_WINDOWS_H) - TlsSetValue(tlsstr_key, tlsstr); - data->data = tlsstr; -#endif + if (!(translated = pa_locale_to_utf8(original))) { + pa_log_warn("Unable to convert error string to locale, filtering."); + translated = pa_utf8_filter(original); + } + + PA_STATIC_TLS_SET(cstrerror, translated); - return tlsstr; + return translated; } -- cgit From d5bedbcd98c10ef187f1daa326b32c6f3ba8d3af Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Sep 2007 20:48:33 +0000 Subject: remaining s/assert/pa_assert/ and refcnt.h modernizations git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1809 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/cmdline.c | 9 +- src/daemon/cpulimit.c | 36 +++---- src/daemon/dumpmodules.c | 13 ++- src/daemon/main.c | 18 ++-- src/modules/alsa-util.c | 2 +- src/modules/module-alsa-source.c | 3 +- src/modules/module-cli.c | 14 +-- src/modules/module-detect.c | 2 +- src/modules/module-lirc.c | 5 +- src/modules/module-sine.c | 1 - src/modules/module-zeroconf-publish.c | 1 - src/pulse/glib-mainloop.c | 2 - src/pulse/subscribe.c | 1 - src/pulse/util.c | 1 - src/pulsecore/authkey-prop.c | 1 - src/pulsecore/cli-command.c | 1 - src/pulsecore/cli.c | 1 - src/pulsecore/core-scache.c | 78 ++++++++++----- src/pulsecore/core-subscribe.c | 34 +++---- src/pulsecore/core-util.c | 60 +++++++----- src/pulsecore/dynarray.c | 20 ++-- src/pulsecore/flist.c | 14 +-- src/pulsecore/hashmap.c | 28 +++--- src/pulsecore/hook-list.c | 26 +++-- src/pulsecore/iochannel.c | 96 +++++++++---------- src/pulsecore/iochannel.h | 4 + src/pulsecore/ioline.c | 84 ++++++++++------- src/pulsecore/ipacl.c | 20 ++-- src/pulsecore/mcalign.c | 43 ++++----- src/pulsecore/memblock.c | 1 - src/pulsecore/memchunk.c | 7 +- src/pulsecore/modargs.c | 46 +++++---- src/pulsecore/modinfo.c | 2 +- src/pulsecore/module.c | 3 +- src/pulsecore/mutex-posix.c | 41 ++++---- src/pulsecore/namereg.c | 33 +++---- src/pulsecore/packet.c | 28 +++--- src/pulsecore/packet.h | 4 +- src/pulsecore/parseaddr.c | 14 ++- src/pulsecore/pdispatch.c | 71 +++++++++----- src/pulsecore/pid.c | 13 ++- src/pulsecore/props.c | 41 +++++--- src/pulsecore/protocol-cli.c | 22 +++-- src/pulsecore/protocol-http.c | 35 ++++--- src/pulsecore/pstream-util.c | 24 ++--- src/pulsecore/queue.c | 3 + src/pulsecore/random.c | 19 ++-- src/pulsecore/shm.c | 69 +++++++------- src/pulsecore/sink.c | 5 +- src/pulsecore/sioman.c | 14 +-- src/pulsecore/socket-client.c | 172 +++++++++++++++++++++------------- src/pulsecore/socket-server.c | 89 +++++++++++------- src/pulsecore/socket-util.c | 53 ++++++----- src/pulsecore/source.c | 11 +-- src/pulsecore/strbuf.c | 4 +- src/pulsecore/tagstruct.c | 127 ++++++++++++++++--------- src/pulsecore/tokenizer.c | 34 ++++--- src/pulsecore/x11prop.c | 1 - src/pulsecore/x11wrap.c | 87 ++++++++++------- 59 files changed, 967 insertions(+), 724 deletions(-) diff --git a/src/daemon/cmdline.c b/src/daemon/cmdline.c index 384dde36..a3f1ff03 100644 --- a/src/daemon/cmdline.c +++ b/src/daemon/cmdline.c @@ -26,7 +26,6 @@ #endif #include -#include #include #include #include @@ -36,6 +35,7 @@ #include #include +#include #include "cmdline.h" @@ -100,6 +100,8 @@ static struct option long_options[] = { void pa_cmdline_help(const char *argv0) { const char *e; + pa_assert(argv0); + if ((e = strrchr(argv0, '/'))) e++; else @@ -154,7 +156,10 @@ void pa_cmdline_help(const char *argv0) { int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d) { pa_strbuf *buf = NULL; int c; - assert(conf && argc && argv); + + pa_assert(conf); + pa_assert(argc > 0); + pa_assert(argv); buf = pa_strbuf_new(); diff --git a/src/daemon/cpulimit.c b/src/daemon/cpulimit.c index 6536f468..37f7976b 100644 --- a/src/daemon/cpulimit.c +++ b/src/daemon/cpulimit.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "cpulimit.h" @@ -38,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -92,23 +92,18 @@ static enum { /* Reset the SIGXCPU timer to the next t seconds */ static void reset_cpu_time(int t) { - int r; long n; struct rlimit rl; struct rusage ru; /* Get the current CPU time of the current process */ - r = getrusage(RUSAGE_SELF, &ru); - assert(r >= 0); + pa_assert_se(getrusage(RUSAGE_SELF, &ru) >= 0); n = ru.ru_utime.tv_sec + ru.ru_stime.tv_sec + t; - - r = getrlimit(RLIMIT_CPU, &rl); - assert(r >= 0); + pa_assert_se(getrlimit(RLIMIT_CPU, &rl) >= 0); rl.rlim_cur = n; - r = setrlimit(RLIMIT_CPU, &rl); - assert(r >= 0); + pa_assert_se(setrlimit(RLIMIT_CPU, &rl) >= 0); } /* A simple, thread-safe puts() work-alike */ @@ -118,7 +113,7 @@ static void write_err(const char *p) { /* The signal handler, called on every SIGXCPU */ static void signal_handler(int sig) { - assert(sig == SIGXCPU); + pa_assert(sig == SIGXCPU); if (phase == PHASE_IDLE) { time_t now; @@ -160,7 +155,12 @@ static void signal_handler(int sig) { /* Callback for IO events on the FIFO */ static void callback(pa_mainloop_api*m, pa_io_event*e, int fd, pa_io_event_flags_t f, void *userdata) { char c; - assert(m && e && f == PA_IO_EVENT_INPUT && e == io_event && fd == the_pipe[0]); + pa_assert(m); + pa_assert(e); + pa_assert(f == PA_IO_EVENT_INPUT); + pa_assert(e == io_event); + pa_assert(fd == the_pipe[0]); + pa_read(the_pipe[0], &c, sizeof(c), NULL); m->quit(m, 1); /* Quit the main loop */ } @@ -168,7 +168,13 @@ static void callback(pa_mainloop_api*m, pa_io_event*e, int fd, pa_io_event_flags /* Initializes CPU load limiter */ int pa_cpu_limit_init(pa_mainloop_api *m) { struct sigaction sa; - assert(m && !api && !io_event && the_pipe[0] == -1 && the_pipe[1] == -1 && !installed); + + pa_assert(m); + pa_assert(!api); + pa_assert(!io_event); + pa_assert(the_pipe[0] == -1); + pa_assert(the_pipe[1] == -1); + pa_assert(!installed); time(&last_time); @@ -208,10 +214,9 @@ int pa_cpu_limit_init(pa_mainloop_api *m) { /* Shutdown CPU load limiter */ void pa_cpu_limit_done(void) { - int r; if (io_event) { - assert(api); + pa_assert(api); api->io_free(io_event); io_event = NULL; api = NULL; @@ -224,8 +229,7 @@ void pa_cpu_limit_done(void) { the_pipe[0] = the_pipe[1] = -1; if (installed) { - r = sigaction(SIGXCPU, &sigaction_prev, NULL); - assert(r >= 0); + pa_assert_se(sigaction(SIGXCPU, &sigaction_prev, NULL) >= 0); installed = 0; } } diff --git a/src/daemon/dumpmodules.c b/src/daemon/dumpmodules.c index cbbf94f3..01547a30 100644 --- a/src/daemon/dumpmodules.c +++ b/src/daemon/dumpmodules.c @@ -28,7 +28,6 @@ #include #include -#include #include #include @@ -36,19 +35,23 @@ #include #include +#include #include "dumpmodules.h" #define PREFIX "module-" static void short_info(const char *name, PA_GCC_UNUSED const char *path, pa_modinfo *i) { - assert(name && i); + pa_assert(name); + pa_assert(i); + printf("%-40s%s\n", name, i->description ? i->description : "n/a"); } static void long_info(const char *name, const char *path, pa_modinfo *i) { static int nl = 0; - assert(name && i); + pa_assert(name); + pa_assert(i); if (nl) printf("\n"); @@ -77,6 +80,8 @@ static void long_info(const char *name, const char *path, pa_modinfo *i) { static void show_info(const char *name, const char *path, void (*info)(const char *name, const char *path, pa_modinfo*i)) { pa_modinfo *i; + pa_assert(name); + if ((i = pa_modinfo_get_by_name(path ? path : name))) { info(name, path, i); pa_modinfo_free(i); @@ -122,6 +127,8 @@ static int callback(const char *path, lt_ptr data) { } void pa_dump_modules(pa_daemon_conf *c, int argc, char * const argv[]) { + pa_assert(c); + if (argc > 0) { int i; for (i = 0; i < argc; i++) diff --git a/src/daemon/main.c b/src/daemon/main.c index ed5aa440..87f3f01d 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -287,7 +286,7 @@ static int create_runtime_dir(void) { static void set_one_rlimit(const pa_rlimit *r, int resource, const char *name) { struct rlimit rl; - assert(r); + pa_assert(r); if (!r->is_set) return; @@ -498,7 +497,7 @@ int main(int argc, char *argv[]) { goto finish; default: - assert(conf->cmd == PA_CMD_DAEMON); + pa_assert(conf->cmd == PA_CMD_DAEMON); } if (real_root && !conf->system_instance) { @@ -630,8 +629,7 @@ int main(int argc, char *argv[]) { pa_rtsig_configure(SIGRTMIN+10, SIGRTMAX); - mainloop = pa_mainloop_new(); - assert(mainloop); + pa_assert_se(mainloop = pa_mainloop_new()); if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm))) { pa_log("pa_core_new() failed."); @@ -664,9 +662,7 @@ int main(int argc, char *argv[]) { #endif #ifdef OS_IS_WIN32 - timer = pa_mainloop_get_api(mainloop)->time_new( - pa_mainloop_get_api(mainloop), pa_gettimeofday(&tv), message_cb, NULL); - assert(timer); + pa_assert_se(timer = pa_mainloop_get_api(mainloop)->time_new(pa_mainloop_get_api(mainloop), pa_gettimeofday(&tv), message_cb, NULL)); #endif if (conf->daemonize) @@ -674,10 +670,8 @@ int main(int argc, char *argv[]) { oil_init(); - if (!conf->no_cpu_limit) { - r = pa_cpu_limit_init(pa_mainloop_get_api(mainloop)); - assert(r == 0); - } + if (!conf->no_cpu_limit) + pa_assert_se(pa_cpu_limit_init(pa_mainloop_get_api(mainloop)) == 0); buf = pa_strbuf_new(); if (conf->default_script_file) diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c index 5d49a3c4..ee2dfdb8 100644 --- a/src/modules/alsa-util.c +++ b/src/modules/alsa-util.c @@ -88,7 +88,7 @@ static void io_cb(pa_mainloop_api*a, pa_io_event* e, PA_GCC_UNUSED int fd, pa_io } } - assert(i != fdl->num_fds); + pa_assert(i != fdl->num_fds); if ((err = snd_mixer_poll_descriptors_revents(fdl->mixer, fdl->work_fds, fdl->num_fds, &revents)) < 0) { pa_log_error("Unable to get poll revent: %s", snd_strerror(err)); diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index fef7b01e..e4a6ed0e 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -26,7 +26,6 @@ #include #endif -#include #include #include @@ -817,7 +816,7 @@ int pa__init(pa_module*m) { pa_log_info("Using %u fragments of size %lu bytes.", nfrags, (long unsigned) u->fragment_size); if (u->mixer_handle) { - assert(u->mixer_elem); + pa_assert(u->mixer_elem); if (snd_mixer_selem_has_capture_volume(u->mixer_elem)) { int i; diff --git a/src/modules/module-cli.c b/src/modules/module-cli.c index fd180bc7..84125214 100644 --- a/src/modules/module-cli.c +++ b/src/modules/module-cli.c @@ -26,7 +26,6 @@ #endif #include -#include #include #include @@ -35,6 +34,7 @@ #include #include #include +#include #include "module-cli-symdef.h" @@ -51,8 +51,8 @@ static const char* const valid_modargs[] = { static void eof_and_unload_cb(pa_cli*c, void *userdata) { pa_module *m = userdata; - assert(c); - assert(m); + pa_assert(c); + pa_assert(m); pa_module_unload_request(m); } @@ -60,8 +60,8 @@ static void eof_and_unload_cb(pa_cli*c, void *userdata) { static void eof_and_exit_cb(pa_cli*c, void *userdata) { pa_module *m = userdata; - assert(c); - assert(m); + pa_assert(c); + pa_assert(m); m->core->mainloop->quit(m->core->mainloop, 0); } @@ -71,7 +71,7 @@ int pa__init(pa_module*m) { pa_modargs *ma; int exit_on_eof = 0; - assert(m); + pa_assert(m); if (m->core->running_as_daemon) { pa_log_info("Running as daemon, refusing to load this module."); @@ -113,7 +113,7 @@ fail: } void pa__done(pa_module*m) { - assert(m); + pa_assert(m); if (m->core->running_as_daemon == 0) { pa_cli_free(m->userdata); diff --git a/src/modules/module-detect.c b/src/modules/module-detect.c index 858147e3..7dc25243 100644 --- a/src/modules/module-detect.c +++ b/src/modules/module-detect.c @@ -28,7 +28,6 @@ #endif #include -#include #include #include #include @@ -44,6 +43,7 @@ #include #include #include +#include #include "module-detect-symdef.h" diff --git a/src/modules/module-lirc.c b/src/modules/module-lirc.c index 6f4e98dc..401763b7 100644 --- a/src/modules/module-lirc.c +++ b/src/modules/module-lirc.c @@ -26,12 +26,12 @@ #endif #include -#include #include #include -#include #include +#include + #include #include @@ -39,6 +39,7 @@ #include #include #include +#include #include "module-lirc-symdef.h" diff --git a/src/modules/module-sine.c b/src/modules/module-sine.c index 94036f6c..f48cb09e 100644 --- a/src/modules/module-sine.c +++ b/src/modules/module-sine.c @@ -26,7 +26,6 @@ #endif #include -#include #include #include diff --git a/src/modules/module-zeroconf-publish.c b/src/modules/module-zeroconf-publish.c index 1cdde84c..8b62ffbd 100644 --- a/src/modules/module-zeroconf-publish.c +++ b/src/modules/module-zeroconf-publish.c @@ -26,7 +26,6 @@ #endif #include -#include #include #include #include diff --git a/src/pulse/glib-mainloop.c b/src/pulse/glib-mainloop.c index 5b399aa2..b7a7537a 100644 --- a/src/pulse/glib-mainloop.c +++ b/src/pulse/glib-mainloop.c @@ -25,8 +25,6 @@ #include #endif -#include - #include #include diff --git a/src/pulse/subscribe.c b/src/pulse/subscribe.c index 31b76369..580038cc 100644 --- a/src/pulse/subscribe.c +++ b/src/pulse/subscribe.c @@ -25,7 +25,6 @@ #include #endif -#include #include #include diff --git a/src/pulse/util.c b/src/pulse/util.c index 32f4137f..a5f0e8e2 100644 --- a/src/pulse/util.c +++ b/src/pulse/util.c @@ -26,7 +26,6 @@ #include #endif -#include #include #include #include diff --git a/src/pulsecore/authkey-prop.c b/src/pulsecore/authkey-prop.c index 35b62d45..179c16ca 100644 --- a/src/pulsecore/authkey-prop.c +++ b/src/pulsecore/authkey-prop.c @@ -38,7 +38,6 @@ struct authkey_data { PA_REFCNT_DECLARE; - int ref; size_t length; }; diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c index 3a1ce5a8..2e674cc2 100644 --- a/src/pulsecore/cli-command.c +++ b/src/pulsecore/cli-command.c @@ -28,7 +28,6 @@ #include #include -#include #include #include #include diff --git a/src/pulsecore/cli.c b/src/pulsecore/cli.c index bb80e908..9fff7347 100644 --- a/src/pulsecore/cli.c +++ b/src/pulsecore/cli.c @@ -27,7 +27,6 @@ #include #include -#include #include #include diff --git a/src/pulsecore/core-scache.c b/src/pulsecore/core-scache.c index 6176dcbd..1cd24aa2 100644 --- a/src/pulsecore/core-scache.c +++ b/src/pulsecore/core-scache.c @@ -26,7 +26,6 @@ #include #endif -#include #include #include #include @@ -60,6 +59,7 @@ #include #include #include +#include #include "core-scache.h" @@ -68,7 +68,10 @@ static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { pa_core *c = userdata; struct timeval ntv; - assert(c && c->mainloop == m && c->scache_auto_unload_event == e); + + pa_assert(c); + pa_assert(c->mainloop == m); + pa_assert(c->scache_auto_unload_event == e); pa_scache_unload_unused(c); @@ -78,7 +81,8 @@ static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, PA_GCC_UNUSED } static void free_entry(pa_scache_entry *e) { - assert(e); + pa_assert(e); + pa_namereg_unregister(e->core, e->name); pa_subscription_post(e->core, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_REMOVE, e->index); pa_xfree(e->name); @@ -90,7 +94,9 @@ static void free_entry(pa_scache_entry *e) { static pa_scache_entry* scache_add_item(pa_core *c, const char *name) { pa_scache_entry *e; - assert(c && name); + + pa_assert(c); + pa_assert(name); if ((e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 0))) { if (e->memchunk.memblock) @@ -98,11 +104,11 @@ static pa_scache_entry* scache_add_item(pa_core *c, const char *name) { pa_xfree(e->filename); - assert(e->core == c); + pa_assert(e->core == c); pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index); } else { - e = pa_xmalloc(sizeof(pa_scache_entry)); + e = pa_xnew(pa_scache_entry, 1); if (!pa_namereg_register(c, name, PA_NAMEREG_SAMPLE, e, 1)) { pa_xfree(e); @@ -114,7 +120,7 @@ static pa_scache_entry* scache_add_item(pa_core *c, const char *name) { if (!c->scache) { c->scache = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - assert(c->scache); + pa_assert(c->scache); } pa_idxset_put(c->scache, e, &e->index); @@ -139,7 +145,9 @@ static pa_scache_entry* scache_add_item(pa_core *c, const char *name) { int pa_scache_add_item(pa_core *c, const char *name, const pa_sample_spec *ss, const pa_channel_map *map, const pa_memchunk *chunk, uint32_t *idx) { pa_scache_entry *e; char st[PA_SAMPLE_SPEC_SNPRINT_MAX]; - assert(c && name); + + pa_assert(c); + pa_assert(name); if (chunk && chunk->length > PA_SCACHE_ENTRY_SIZE_MAX) return -1; @@ -164,9 +172,9 @@ int pa_scache_add_item(pa_core *c, const char *name, const pa_sample_spec *ss, c if (idx) *idx = e->index; - pa_log_debug("created sample \"%s\" (#%d), %lu bytes with sample spec %s", + pa_log_debug("Created sample \"%s\" (#%d), %lu bytes with sample spec %s", name, e->index, (unsigned long) e->memchunk.length, - pa_sample_spec_snprint(st, sizeof(st), &e->sample_spec)); + pa_sample_spec_snprint(st, sizeof(st), &e->sample_spec)); return 0; } @@ -184,6 +192,10 @@ int pa_scache_add_file(pa_core *c, const char *name, const char *filename, uint3 filename = buf; #endif + pa_assert(c); + pa_assert(name); + pa_assert(filename); + if (pa_sound_file_load(c->mempool, filename, &ss, &map, &chunk) < 0) return -1; @@ -203,7 +215,9 @@ int pa_scache_add_file_lazy(pa_core *c, const char *name, const char *filename, filename = buf; #endif - assert(c && name); + pa_assert(c); + pa_assert(name); + pa_assert(filename); if (!(e = scache_add_item(c, name))) return -1; @@ -226,15 +240,17 @@ int pa_scache_add_file_lazy(pa_core *c, const char *name, const char *filename, int pa_scache_remove_item(pa_core *c, const char *name) { pa_scache_entry *e; - assert(c && name); + + pa_assert(c); + pa_assert(name); if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 0))) return -1; if (pa_idxset_remove_by_data(c->scache, e, NULL) != e) - assert(0); + pa_assert(0); - pa_log_debug("removed sample \"%s\"", name); + pa_log_debug("Removed sample \"%s\"", name); free_entry(e); @@ -243,12 +259,13 @@ int pa_scache_remove_item(pa_core *c, const char *name) { static void free_cb(void *p, PA_GCC_UNUSED void *userdata) { pa_scache_entry *e = p; - assert(e); + pa_assert(e); + free_entry(e); } void pa_scache_free(pa_core *c) { - assert(c); + pa_assert(c); if (c->scache) { pa_idxset_free(c->scache, free_cb, NULL); @@ -264,9 +281,9 @@ int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t char *t; pa_cvolume r; - assert(c); - assert(name); - assert(sink); + pa_assert(c); + pa_assert(name); + pa_assert(sink); if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 1))) return -1; @@ -284,7 +301,7 @@ int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t if (!e->memchunk.memblock) return -1; - pa_log_debug("playing sample \"%s\" on \"%s\"", name, sink->name); + pa_log_debug("Playing sample \"%s\" on \"%s\"", name, sink->name); t = pa_sprintf_malloc("sample:%s", name); @@ -318,7 +335,9 @@ int pa_scache_play_item_by_name(pa_core *c, const char *name, const char*sink_na const char * pa_scache_get_name_by_id(pa_core *c, uint32_t id) { pa_scache_entry *e; - assert(c && id != PA_IDXSET_INVALID); + + pa_assert(c); + pa_assert(id != PA_IDXSET_INVALID); if (!c->scache || !(e = pa_idxset_get_by_index(c->scache, id))) return NULL; @@ -328,7 +347,9 @@ const char * pa_scache_get_name_by_id(pa_core *c, uint32_t id) { uint32_t pa_scache_get_id_by_name(pa_core *c, const char *name) { pa_scache_entry *e; - assert(c && name); + + pa_assert(c); + pa_assert(name); if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 0))) return PA_IDXSET_INVALID; @@ -339,7 +360,8 @@ uint32_t pa_scache_get_id_by_name(pa_core *c, const char *name) { uint32_t pa_scache_total_size(pa_core *c) { pa_scache_entry *e; uint32_t idx, sum = 0; - assert(c); + + pa_assert(c); if (!c->scache || !pa_idxset_size(c->scache)) return 0; @@ -355,7 +377,8 @@ void pa_scache_unload_unused(pa_core *c) { pa_scache_entry *e; time_t now; uint32_t idx; - assert(c); + + pa_assert(c); if (!c->scache || !pa_idxset_size(c->scache)) return; @@ -382,6 +405,9 @@ static void add_file(pa_core *c, const char *pathname) { struct stat st; const char *e; + pa_core_assert_ref(c); + pa_assert(pathname); + e = pa_path_get_filename(pathname); if (stat(pathname, &st) < 0) { @@ -397,7 +423,9 @@ static void add_file(pa_core *c, const char *pathname) { int pa_scache_add_directory_lazy(pa_core *c, const char *pathname) { DIR *dir; - assert(c && pathname); + + pa_core_assert_ref(c); + pa_assert(pathname); /* First try to open this as directory */ if (!(dir = opendir(pathname))) { diff --git a/src/pulsecore/core-subscribe.c b/src/pulsecore/core-subscribe.c index 288d1078..06c5a4ad 100644 --- a/src/pulsecore/core-subscribe.c +++ b/src/pulsecore/core-subscribe.c @@ -26,12 +26,12 @@ #endif #include -#include #include #include #include +#include #include "core-subscribe.h" @@ -68,9 +68,9 @@ static void sched_event(pa_core *c); pa_subscription* pa_subscription_new(pa_core *c, pa_subscription_mask_t m, pa_subscription_cb_t callback, void *userdata) { pa_subscription *s; - assert(c); - assert(m); - assert(callback); + pa_assert(c); + pa_assert(m); + pa_assert(callback); s = pa_xnew(pa_subscription, 1); s->core = c; @@ -85,24 +85,24 @@ pa_subscription* pa_subscription_new(pa_core *c, pa_subscription_mask_t m, pa_su /* Free a subscription object, effectively marking it for deletion */ void pa_subscription_free(pa_subscription*s) { - assert(s); - assert(!s->dead); + pa_assert(s); + pa_assert(!s->dead); s->dead = 1; sched_event(s->core); } static void free_subscription(pa_subscription *s) { - assert(s); - assert(s->core); + pa_assert(s); + pa_assert(s->core); PA_LLIST_REMOVE(pa_subscription, s->core->subscriptions, s); pa_xfree(s); } static void free_event(pa_subscription_event *s) { - assert(s); - assert(s->core); + pa_assert(s); + pa_assert(s->core); if (!s->next) s->core->subscription_event_last = s->prev; @@ -113,7 +113,7 @@ static void free_event(pa_subscription_event *s) { /* Free all subscription objects */ void pa_subscription_free_all(pa_core *c) { - assert(c); + pa_assert(c); while (c->subscriptions) free_subscription(c->subscriptions); @@ -160,9 +160,9 @@ static void defer_cb(pa_mainloop_api *m, pa_defer_event *de, void *userdata) { pa_core *c = userdata; pa_subscription *s; - assert(c->mainloop == m); - assert(c); - assert(c->subscription_defer_event == de); + pa_assert(c->mainloop == m); + pa_assert(c); + pa_assert(c->subscription_defer_event == de); c->mainloop->defer_enable(c->subscription_defer_event, 0); @@ -196,11 +196,11 @@ static void defer_cb(pa_mainloop_api *m, pa_defer_event *de, void *userdata) { /* Schedule an mainloop event so that a pending subscription event is dispatched */ static void sched_event(pa_core *c) { - assert(c); + pa_assert(c); if (!c->subscription_defer_event) { c->subscription_defer_event = c->mainloop->defer_new(c->mainloop, defer_cb, c); - assert(c->subscription_defer_event); + pa_assert(c->subscription_defer_event); } c->mainloop->defer_enable(c->subscription_defer_event, 1); @@ -209,7 +209,7 @@ static void sched_event(pa_core *c) { /* Append a new subscription event to the subscription event queue and schedule a main loop event */ void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t idx) { pa_subscription_event *e; - assert(c); + pa_assert(c); /* No need for queuing subscriptions of noone is listening */ if (!c->subscriptions) diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index d37a11cc..c0dd0d68 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -132,7 +132,7 @@ int pa_set_root(HANDLE handle) { void pa_make_nonblock_fd(int fd) { #ifdef O_NONBLOCK int v; - assert(fd >= 0); + pa_assert(fd >= 0); if ((v = fcntl(fd, F_GETFL)) >= 0) if (!(v & O_NONBLOCK)) @@ -153,7 +153,7 @@ int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) { struct stat st; int r; - assert(dir); + pa_assert(dir); #ifdef OS_IS_WIN32 r = mkdir(dir); @@ -300,9 +300,9 @@ ssize_t pa_loop_read(int fd, void*data, size_t size, int *type) { ssize_t ret = 0; int _type; - assert(fd >= 0); - assert(data); - assert(size); + pa_assert(fd >= 0); + pa_assert(data); + pa_assert(size); if (!type) { _type = 0; @@ -331,9 +331,9 @@ ssize_t pa_loop_write(int fd, const void*data, size_t size, int *type) { ssize_t ret = 0; int _type; - assert(fd >= 0); - assert(data); - assert(size); + pa_assert(fd >= 0); + pa_assert(data); + pa_assert(size); if (!type) { _type = 0; @@ -423,7 +423,7 @@ char *pa_sprintf_malloc(const char *format, ...) { int size = 100; char *c = NULL; - assert(format); + pa_assert(format); for(;;) { int r; @@ -453,7 +453,7 @@ char *pa_vsprintf_malloc(const char *format, va_list ap) { int size = 100; char *c = NULL; - assert(format); + pa_assert(format); for(;;) { int r; @@ -479,7 +479,9 @@ char *pa_vsprintf_malloc(const char *format, va_list ap) { /* Similar to OpenBSD's strlcpy() function */ char *pa_strlcpy(char *b, const char *s, size_t l) { - assert(b && s && l > 0); + pa_assert(b); + pa_assert(s); + pa_assert(l > 0); strncpy(b, s, l); b[l-1] = 0; @@ -550,7 +552,7 @@ int pa_fd_set_cloexec(int fd, int b) { #ifdef FD_CLOEXEC int v; - assert(fd >= 0); + pa_assert(fd >= 0); if ((v = fcntl(fd, F_GETFD, 0)) < 0) return -1; @@ -690,7 +692,7 @@ int pa_own_uid_in_group(const char *name, gid_t *gid) { int n = sysconf(_SC_NGROUPS_MAX); int r = -1, i; - assert(n > 0); + pa_assert(n > 0); gids = pa_xmalloc(sizeof(GETGROUPS_T)*n); @@ -856,7 +858,7 @@ int pa_lock_fd(int fd, int b) { /* Remove trailing newlines from a string */ char* pa_strip_nl(char *s) { - assert(s); + pa_assert(s); s[strcspn(s, "\r\n")] = 0; return s; @@ -865,7 +867,7 @@ char* pa_strip_nl(char *s) { /* Create a temporary lock file and lock it. */ int pa_lock_lockfile(const char *fn) { int fd = -1; - assert(fn); + pa_assert(fn); for (;;) { struct stat st; @@ -916,7 +918,8 @@ fail: /* Unlock a temporary lcok file */ int pa_unlock_lockfile(const char *fn, int fd) { int r = 0; - assert(fn && fd >= 0); + pa_assert(fn); + pa_assert(fd >= 0); if (unlink(fn) < 0) { pa_log_warn("WARNING: unable to remove lock file '%s': %s", @@ -1026,7 +1029,10 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env char *pa_hexstr(const uint8_t* d, size_t dlength, char *s, size_t slength) { size_t i = 0, j = 0; const char hex[] = "0123456789abcdef"; - assert(d && s && slength > 0); + + pa_assert(d); + pa_assert(s); + pa_assert(slength > 0); while (i < dlength && j+3 <= slength) { s[j++] = hex[*d >> 4]; @@ -1057,7 +1063,9 @@ static int hexc(char c) { /* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */ size_t pa_parsehex(const char *p, uint8_t *d, size_t dlength) { size_t j = 0; - assert(p && d); + + pa_assert(p); + pa_assert(d); while (j < dlength && *p) { int b; @@ -1084,8 +1092,8 @@ size_t pa_parsehex(const char *p, uint8_t *d, size_t dlength) { int pa_startswith(const char *s, const char *pfx) { size_t l; - assert(s); - assert(pfx); + pa_assert(s); + pa_assert(pfx); l = strlen(pfx); @@ -1096,8 +1104,8 @@ int pa_startswith(const char *s, const char *pfx) { int pa_endswith(const char *s, const char *sfx) { size_t l1, l2; - assert(s); - assert(sfx); + pa_assert(s); + pa_assert(sfx); l1 = strlen(s); l2 = strlen(sfx); @@ -1150,7 +1158,9 @@ char *pa_runtime_path(const char *fn, char *s, size_t l) { int pa_atoi(const char *s, int32_t *ret_i) { char *x = NULL; long l; - assert(s && ret_i); + + pa_assert(s); + pa_assert(ret_i); l = strtol(s, &x, 0); @@ -1166,7 +1176,9 @@ int pa_atoi(const char *s, int32_t *ret_i) { int pa_atou(const char *s, uint32_t *ret_u) { char *x = NULL; unsigned long l; - assert(s && ret_u); + + pa_assert(s); + pa_assert(ret_u); l = strtoul(s, &x, 0); diff --git a/src/pulsecore/dynarray.c b/src/pulsecore/dynarray.c index 944e3570..f5e73ed0 100644 --- a/src/pulsecore/dynarray.c +++ b/src/pulsecore/dynarray.c @@ -26,10 +26,10 @@ #endif #include -#include #include #include +#include #include "dynarray.h" @@ -52,7 +52,7 @@ pa_dynarray* pa_dynarray_new(void) { void pa_dynarray_free(pa_dynarray* a, void (*func)(void *p, void *userdata), void *userdata) { unsigned i; - assert(a); + pa_assert(a); if (func) for (i = 0; i < a->n_entries; i++) @@ -64,7 +64,7 @@ void pa_dynarray_free(pa_dynarray* a, void (*func)(void *p, void *userdata), voi } void pa_dynarray_put(pa_dynarray*a, unsigned i, void *p) { - assert(a); + pa_assert(a); if (i >= a->n_allocated) { unsigned n; @@ -85,21 +85,27 @@ void pa_dynarray_put(pa_dynarray*a, unsigned i, void *p) { } unsigned pa_dynarray_append(pa_dynarray*a, void *p) { - unsigned i = a->n_entries; + unsigned i; + + pa_assert(a); + + i = a->n_entries; pa_dynarray_put(a, i, p); return i; } void *pa_dynarray_get(pa_dynarray*a, unsigned i) { - assert(a); + pa_assert(a); + if (i >= a->n_entries) return NULL; - assert(a->data); + pa_assert(a->data); return a->data[i]; } unsigned pa_dynarray_size(pa_dynarray*a) { - assert(a); + pa_assert(a); + return a->n_entries; } diff --git a/src/pulsecore/flist.c b/src/pulsecore/flist.c index ada0d571..680a9f76 100644 --- a/src/pulsecore/flist.c +++ b/src/pulsecore/flist.c @@ -25,14 +25,14 @@ #include #endif -#include +#include #include #include #include #include #include -#include +#include #include "flist.h" @@ -111,7 +111,7 @@ pa_flist *pa_flist_new(unsigned size) { if (!size) size = FLIST_SIZE; - assert(pa_is_power_of_two(size)); + pa_assert(pa_is_power_of_two(size)); l = pa_xmalloc0(PA_ALIGN(sizeof(pa_flist)) + (sizeof(struct cell) * size)); @@ -129,7 +129,7 @@ static int reduce(pa_flist *l, int value) { } void pa_flist_free(pa_flist *l, pa_free_cb_t free_cb) { - assert(l); + pa_assert(l); if (free_cb) { struct cell *cells; @@ -156,8 +156,8 @@ int pa_flist_push(pa_flist*l, void *p) { int idx, len, n; struct cell *cells; - assert(l); - assert(p); + pa_assert(l); + pa_assert(p); cells = PA_FLIST_CELLS(l); @@ -196,7 +196,7 @@ void* pa_flist_pop(pa_flist*l) { int idx, len, n; struct cell *cells; - assert(l); + pa_assert(l); cells = PA_FLIST_CELLS(l); diff --git a/src/pulsecore/hashmap.c b/src/pulsecore/hashmap.c index 57be8180..8366181c 100644 --- a/src/pulsecore/hashmap.c +++ b/src/pulsecore/hashmap.c @@ -26,7 +26,6 @@ #endif #include -#include #include #include @@ -34,6 +33,7 @@ #include #include #include +#include #include "hashmap.h" @@ -72,8 +72,8 @@ pa_hashmap *pa_hashmap_new(pa_hash_func_t hash_func, pa_compare_func_t compare_f } static void remove(pa_hashmap *h, struct hashmap_entry *e) { - assert(h); - assert(e); + pa_assert(h); + pa_assert(e); if (e->next) e->next->previous = e->previous; @@ -87,7 +87,7 @@ static void remove(pa_hashmap *h, struct hashmap_entry *e) { if (e->bucket_previous) e->bucket_previous->bucket_next = e->bucket_next; else { - assert(e->hash < h->size); + pa_assert(e->hash < h->size); h->data[e->hash] = e->bucket_next; } @@ -98,7 +98,7 @@ static void remove(pa_hashmap *h, struct hashmap_entry *e) { } void pa_hashmap_free(pa_hashmap*h, void (*free_func)(void *p, void *userdata), void *userdata) { - assert(h); + pa_assert(h); while (h->first_entry) { if (free_func) @@ -112,8 +112,8 @@ void pa_hashmap_free(pa_hashmap*h, void (*free_func)(void *p, void *userdata), v static struct hashmap_entry *get(pa_hashmap *h, unsigned hash, const void *key) { struct hashmap_entry *e; - assert(h); - assert(hash < h->size); + pa_assert(h); + pa_assert(hash < h->size); for (e = h->data[hash]; e; e = e->bucket_next) if (h->compare_func(e->key, key) == 0) @@ -125,7 +125,7 @@ static struct hashmap_entry *get(pa_hashmap *h, unsigned hash, const void *key) int pa_hashmap_put(pa_hashmap *h, const void *key, void *value) { struct hashmap_entry *e; unsigned hash; - assert(h); + pa_assert(h); hash = h->hash_func(key) % h->size; @@ -159,7 +159,7 @@ void* pa_hashmap_get(pa_hashmap *h, const void *key) { unsigned hash; struct hashmap_entry *e; - assert(h); + pa_assert(h); hash = h->hash_func(key) % h->size; @@ -174,7 +174,7 @@ void* pa_hashmap_remove(pa_hashmap *h, const void *key) { unsigned hash; void *data; - assert(h); + pa_assert(h); hash = h->hash_func(key) % h->size; @@ -191,8 +191,8 @@ unsigned pa_hashmap_size(pa_hashmap *h) { } void *pa_hashmap_iterate(pa_hashmap *h, void **state, const void **key) { - assert(h); - assert(state); + pa_assert(h); + pa_assert(state); if (!*state) *state = h->first_entry; @@ -214,7 +214,7 @@ void *pa_hashmap_iterate(pa_hashmap *h, void **state, const void **key) { void* pa_hashmap_steal_first(pa_hashmap *h) { void *data; - assert(h); + pa_assert(h); if (!h->first_entry) return NULL; @@ -225,7 +225,7 @@ void* pa_hashmap_steal_first(pa_hashmap *h) { } void *pa_hashmap_get_first(pa_hashmap *h) { - assert(h); + pa_assert(h); if (!h->first_entry) return NULL; diff --git a/src/pulsecore/hook-list.c b/src/pulsecore/hook-list.c index 4f884187..3a6874c4 100644 --- a/src/pulsecore/hook-list.c +++ b/src/pulsecore/hook-list.c @@ -21,10 +21,16 @@ USA. ***/ -#include +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "hook-list.h" void pa_hook_init(pa_hook *hook, void *data) { - assert(hook); + pa_assert(hook); PA_LLIST_HEAD_INIT(pa_hook_slot, hook->slots); hook->last = NULL; @@ -33,8 +39,8 @@ void pa_hook_init(pa_hook *hook, void *data) { } static void slot_free(pa_hook *hook, pa_hook_slot *slot) { - assert(hook); - assert(slot); + pa_assert(hook); + pa_assert(slot); if (hook->last == slot) hook->last = slot->prev; @@ -45,8 +51,8 @@ static void slot_free(pa_hook *hook, pa_hook_slot *slot) { } void pa_hook_free(pa_hook *hook) { - assert(hook); - assert(!hook->firing); + pa_assert(hook); + pa_assert(!hook->firing); while (hook->slots) slot_free(hook, hook->slots); @@ -57,7 +63,7 @@ void pa_hook_free(pa_hook *hook) { pa_hook_slot* pa_hook_connect(pa_hook *hook, pa_hook_cb_t cb, void *data) { pa_hook_slot *slot; - assert(cb); + pa_assert(cb); slot = pa_xnew(pa_hook_slot, 1); slot->hook = hook; @@ -72,8 +78,8 @@ pa_hook_slot* pa_hook_connect(pa_hook *hook, pa_hook_cb_t cb, void *data) { } void pa_hook_slot_free(pa_hook_slot *slot) { - assert(slot); - assert(!slot->dead); + pa_assert(slot); + pa_assert(!slot->dead); if (slot->hook->firing > 0) { slot->dead = 1; @@ -86,7 +92,7 @@ pa_hook_result_t pa_hook_fire(pa_hook *hook, void *data) { pa_hook_slot *slot, *next; pa_hook_result_t result = PA_HOOK_OK; - assert(hook); + pa_assert(hook); hook->firing ++; diff --git a/src/pulsecore/iochannel.c b/src/pulsecore/iochannel.c index 6f58ae75..2f586cbf 100644 --- a/src/pulsecore/iochannel.c +++ b/src/pulsecore/iochannel.c @@ -27,7 +27,6 @@ #endif #include -#include #include #include #include @@ -47,6 +46,7 @@ #include #include #include +#include #include "iochannel.h" @@ -68,11 +68,11 @@ struct pa_iochannel { }; static void enable_mainloop_sources(pa_iochannel *io) { - assert(io); + pa_assert(io); if (io->input_event == io->output_event && io->input_event) { pa_io_event_flags_t f = PA_IO_EVENT_NULL; - assert(io->input_event); + pa_assert(io->input_event); if (!io->readable) f |= PA_IO_EVENT_INPUT; @@ -92,10 +92,10 @@ static void callback(pa_mainloop_api* m, pa_io_event *e, int fd, pa_io_event_fla pa_iochannel *io = userdata; int changed = 0; - assert(m); - assert(e); - assert(fd >= 0); - assert(userdata); + pa_assert(m); + pa_assert(e); + pa_assert(fd >= 0); + pa_assert(userdata); if ((f & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) && !io->hungup) { io->hungup = 1; @@ -105,13 +105,13 @@ static void callback(pa_mainloop_api* m, pa_io_event *e, int fd, pa_io_event_fla if ((f & PA_IO_EVENT_INPUT) && !io->readable) { io->readable = 1; changed = 1; - assert(e == io->input_event); + pa_assert(e == io->input_event); } if ((f & PA_IO_EVENT_OUTPUT) && !io->writable) { io->writable = 1; changed = 1; - assert(e == io->output_event); + pa_assert(e == io->output_event); } if (changed) { @@ -125,8 +125,8 @@ static void callback(pa_mainloop_api* m, pa_io_event *e, int fd, pa_io_event_fla pa_iochannel* pa_iochannel_new(pa_mainloop_api*m, int ifd, int ofd) { pa_iochannel *io; - assert(m); - assert(ifd >= 0 || ofd >= 0); + pa_assert(m); + pa_assert(ifd >= 0 || ofd >= 0); io = pa_xnew(pa_iochannel, 1); io->ifd = ifd; @@ -144,7 +144,7 @@ pa_iochannel* pa_iochannel_new(pa_mainloop_api*m, int ifd, int ofd) { io->input_event = io->output_event = NULL; if (ifd == ofd) { - assert(ifd >= 0); + pa_assert(ifd >= 0); pa_make_nonblock_fd(io->ifd); io->input_event = io->output_event = m->io_new(m, ifd, PA_IO_EVENT_INPUT|PA_IO_EVENT_OUTPUT, callback, io); } else { @@ -164,7 +164,7 @@ pa_iochannel* pa_iochannel_new(pa_mainloop_api*m, int ifd, int ofd) { } void pa_iochannel_free(pa_iochannel*io) { - assert(io); + pa_assert(io); if (io->input_event) io->mainloop->io_free(io->input_event); @@ -183,19 +183,19 @@ void pa_iochannel_free(pa_iochannel*io) { } int pa_iochannel_is_readable(pa_iochannel*io) { - assert(io); + pa_assert(io); return io->readable || io->hungup; } int pa_iochannel_is_writable(pa_iochannel*io) { - assert(io); + pa_assert(io); return io->writable && !io->hungup; } int pa_iochannel_is_hungup(pa_iochannel*io) { - assert(io); + pa_assert(io); return io->hungup; } @@ -203,10 +203,10 @@ int pa_iochannel_is_hungup(pa_iochannel*io) { ssize_t pa_iochannel_write(pa_iochannel*io, const void*data, size_t l) { ssize_t r; - assert(io); - assert(data); - assert(l); - assert(io->ofd >= 0); + pa_assert(io); + pa_assert(data); + pa_assert(l); + pa_assert(io->ofd >= 0); r = pa_write(io->ofd, data, l, &io->ofd_type); if (r >= 0) { @@ -220,9 +220,9 @@ ssize_t pa_iochannel_write(pa_iochannel*io, const void*data, size_t l) { ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l) { ssize_t r; - assert(io); - assert(data); - assert(io->ifd >= 0); + pa_assert(io); + pa_assert(data); + pa_assert(io->ifd >= 0); r = pa_read(io->ifd, data, l, &io->ifd_type); if (r >= 0) { @@ -239,9 +239,9 @@ int pa_iochannel_creds_supported(pa_iochannel *io) { struct sockaddr_un sa; socklen_t l; - assert(io); - assert(io->ifd >= 0); - assert(io->ofd == io->ifd); + pa_assert(io); + pa_assert(io->ifd >= 0); + pa_assert(io->ofd == io->ifd); l = sizeof(sa); @@ -254,8 +254,8 @@ int pa_iochannel_creds_supported(pa_iochannel *io) { int pa_iochannel_creds_enable(pa_iochannel *io) { int t = 1; - assert(io); - assert(io->ifd >= 0); + pa_assert(io); + pa_assert(io->ifd >= 0); if (setsockopt(io->ifd, SOL_SOCKET, SO_PASSCRED, &t, sizeof(t)) < 0) { pa_log_error("setsockopt(SOL_SOCKET, SO_PASSCRED): %s", pa_cstrerror(errno)); @@ -273,10 +273,10 @@ ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l struct ucred *u; struct cmsghdr *cmsg; - assert(io); - assert(data); - assert(l); - assert(io->ofd >= 0); + pa_assert(io); + pa_assert(data); + pa_assert(l); + pa_assert(io->ofd >= 0); memset(&iov, 0, sizeof(iov)); iov.iov_base = (void*) data; @@ -322,12 +322,12 @@ ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, pa_cr struct iovec iov; uint8_t cmsg_data[CMSG_SPACE(sizeof(struct ucred))]; - assert(io); - assert(data); - assert(l); - assert(io->ifd >= 0); - assert(creds); - assert(creds_valid); + pa_assert(io); + pa_assert(data); + pa_assert(l); + pa_assert(io->ifd >= 0); + pa_assert(creds); + pa_assert(creds_valid); memset(&iov, 0, sizeof(iov)); iov.iov_base = data; @@ -353,7 +353,7 @@ ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, pa_cr if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) { struct ucred u; - assert(cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))); + pa_assert(cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))); memcpy(&u, CMSG_DATA(cmsg), sizeof(struct ucred)); creds->gid = u.gid; @@ -373,46 +373,46 @@ ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, pa_cr #endif /* HAVE_CREDS */ void pa_iochannel_set_callback(pa_iochannel*io, pa_iochannel_cb_t _callback, void *userdata) { - assert(io); + pa_assert(io); io->callback = _callback; io->userdata = userdata; } void pa_iochannel_set_noclose(pa_iochannel*io, int b) { - assert(io); + pa_assert(io); io->no_close = b; } void pa_iochannel_socket_peer_to_string(pa_iochannel*io, char*s, size_t l) { - assert(io); - assert(s); - assert(l); + pa_assert(io); + pa_assert(s); + pa_assert(l); pa_socket_peer_to_string(io->ifd, s, l); } int pa_iochannel_socket_set_rcvbuf(pa_iochannel *io, size_t l) { - assert(io); + pa_assert(io); return pa_socket_set_rcvbuf(io->ifd, l); } int pa_iochannel_socket_set_sndbuf(pa_iochannel *io, size_t l) { - assert(io); + pa_assert(io); return pa_socket_set_sndbuf(io->ofd, l); } pa_mainloop_api* pa_iochannel_get_mainloop_api(pa_iochannel *io) { - assert(io); + pa_assert(io); return io->mainloop; } int pa_iochannel_get_recv_fd(pa_iochannel *io) { - assert(io); + pa_assert(io); return io->ifd; } diff --git a/src/pulsecore/iochannel.h b/src/pulsecore/iochannel.h index c22fefd3..90eb963c 100644 --- a/src/pulsecore/iochannel.h +++ b/src/pulsecore/iochannel.h @@ -25,6 +25,10 @@ USA. ***/ +#ifndef PACKAGE +#error "Please include config.h before including this file!" +#endif + #include #include diff --git a/src/pulsecore/ioline.c b/src/pulsecore/ioline.c index 23a90a78..a3627003 100644 --- a/src/pulsecore/ioline.c +++ b/src/pulsecore/ioline.c @@ -27,7 +27,6 @@ #include #include -#include #include #include @@ -35,6 +34,8 @@ #include #include +#include +#include #include "ioline.h" @@ -42,10 +43,11 @@ #define READ_SIZE (1024) struct pa_ioline { + PA_REFCNT_DECLARE; + pa_iochannel *io; pa_defer_event *defer_event; pa_mainloop_api *mainloop; - int ref; int dead; char *wbuf; @@ -65,9 +67,10 @@ static void defer_callback(pa_mainloop_api*m, pa_defer_event*e, void *userdata); pa_ioline* pa_ioline_new(pa_iochannel *io) { pa_ioline *l; - assert(io); + pa_assert(io); l = pa_xnew(pa_ioline, 1); + PA_REFCNT_INIT(l); l->io = io; l->dead = 0; @@ -79,7 +82,6 @@ pa_ioline* pa_ioline_new(pa_iochannel *io) { l->callback = NULL; l->userdata = NULL; - l->ref = 1; l->mainloop = pa_iochannel_get_mainloop_api(io); @@ -94,7 +96,7 @@ pa_ioline* pa_ioline_new(pa_iochannel *io) { } static void ioline_free(pa_ioline *l) { - assert(l); + pa_assert(l); if (l->io) pa_iochannel_free(l->io); @@ -108,24 +110,24 @@ static void ioline_free(pa_ioline *l) { } void pa_ioline_unref(pa_ioline *l) { - assert(l); - assert(l->ref >= 1); + pa_assert(l); + pa_assert(PA_REFCNT_VALUE(l) >= 1); - if ((--l->ref) <= 0) + if (PA_REFCNT_DEC(l) <= 0) ioline_free(l); } pa_ioline* pa_ioline_ref(pa_ioline *l) { - assert(l); - assert(l->ref >= 1); + pa_assert(l); + pa_assert(PA_REFCNT_VALUE(l) >= 1); - l->ref++; + PA_REFCNT_INC(l); return l; } void pa_ioline_close(pa_ioline *l) { - assert(l); - assert(l->ref >= 1); + pa_assert(l); + pa_assert(PA_REFCNT_VALUE(l) >= 1); l->dead = 1; @@ -146,9 +148,9 @@ void pa_ioline_close(pa_ioline *l) { void pa_ioline_puts(pa_ioline *l, const char *c) { size_t len; - assert(l); - assert(l->ref >= 1); - assert(c); + pa_assert(l); + pa_assert(PA_REFCNT_VALUE(l) >= 1); + pa_assert(c); if (l->dead) return; @@ -158,7 +160,7 @@ void pa_ioline_puts(pa_ioline *l, const char *c) { len = BUFFER_LIMIT - l->wbuf_valid_length; if (len) { - assert(l->wbuf_length >= l->wbuf_valid_length); + pa_assert(l->wbuf_length >= l->wbuf_valid_length); /* In case the allocated buffer is too small, enlarge it. */ if (l->wbuf_valid_length + len > l->wbuf_length) { @@ -178,7 +180,7 @@ void pa_ioline_puts(pa_ioline *l, const char *c) { l->wbuf_index = 0; } - assert(l->wbuf_index + l->wbuf_valid_length + len <= l->wbuf_length); + pa_assert(l->wbuf_index + l->wbuf_valid_length + len <= l->wbuf_length); /* Append the new string */ memcpy(l->wbuf + l->wbuf_index + l->wbuf_valid_length, c, len); @@ -189,17 +191,17 @@ void pa_ioline_puts(pa_ioline *l, const char *c) { } void pa_ioline_set_callback(pa_ioline*l, void (*callback)(pa_ioline*io, const char *s, void *userdata), void *userdata) { - assert(l); - assert(l->ref >= 1); + pa_assert(l); + pa_assert(PA_REFCNT_VALUE(l) >= 1); l->callback = callback; l->userdata = userdata; } static void failure(pa_ioline *l, int process_leftover) { - assert(l); - assert(l->ref >= 1); - assert(!l->dead); + pa_assert(l); + pa_assert(PA_REFCNT_VALUE(l) >= 1); + pa_assert(!l->dead); if (process_leftover && l->rbuf_valid_length > 0) { /* Pass the last missing bit to the client */ @@ -220,7 +222,9 @@ static void failure(pa_ioline *l, int process_leftover) { } static void scan_for_lines(pa_ioline *l, size_t skip) { - assert(l && l->ref >= 1 && skip < l->rbuf_valid_length); + pa_assert(l); + pa_assert(PA_REFCNT_VALUE(l) >= 1); + pa_assert(skip < l->rbuf_valid_length); while (!l->dead && l->rbuf_valid_length > skip) { char *e, *p; @@ -255,7 +259,8 @@ static void scan_for_lines(pa_ioline *l, size_t skip) { static int do_write(pa_ioline *l); static int do_read(pa_ioline *l) { - assert(l && l->ref >= 1); + pa_assert(l); + pa_assert(PA_REFCNT_VALUE(l) >= 1); while (!l->dead && pa_iochannel_is_readable(l->io)) { ssize_t r; @@ -289,7 +294,7 @@ static int do_read(pa_ioline *l) { len = l->rbuf_length - l->rbuf_index - l->rbuf_valid_length; - assert(len >= READ_SIZE); + pa_assert(len >= READ_SIZE); /* Read some data */ if ((r = pa_iochannel_read(l->io, l->rbuf+l->rbuf_index+l->rbuf_valid_length, len)) <= 0) { @@ -314,7 +319,9 @@ static int do_read(pa_ioline *l) { /* Try to flush the buffer */ static int do_write(pa_ioline *l) { ssize_t r; - assert(l && l->ref >= 1); + + pa_assert(l); + pa_assert(PA_REFCNT_VALUE(l) >= 1); while (!l->dead && pa_iochannel_is_writable(l->io) && l->wbuf_valid_length) { @@ -341,8 +348,8 @@ static int do_write(pa_ioline *l) { /* Try to flush read/write data */ static void do_work(pa_ioline *l) { - assert(l); - assert(l->ref >= 1); + pa_assert(l); + pa_assert(PA_REFCNT_VALUE(l) >= 1); pa_ioline_ref(l); @@ -362,21 +369,28 @@ static void do_work(pa_ioline *l) { static void io_callback(pa_iochannel*io, void *userdata) { pa_ioline *l = userdata; - assert(io && l && l->ref >= 1); + + pa_assert(io); + pa_assert(l); + pa_assert(PA_REFCNT_VALUE(l) >= 1); do_work(l); } static void defer_callback(pa_mainloop_api*m, pa_defer_event*e, void *userdata) { pa_ioline *l = userdata; - assert(l && l->ref >= 1 && l->mainloop == m && l->defer_event == e); + + pa_assert(l); + pa_assert(PA_REFCNT_VALUE(l) >= 1); + pa_assert(l->mainloop == m); + pa_assert(l->defer_event == e); do_work(l); } void pa_ioline_defer_close(pa_ioline *l) { - assert(l); - assert(l->ref >= 1); + pa_assert(l); + pa_assert(PA_REFCNT_VALUE(l) >= 1); l->defer_close = 1; @@ -388,8 +402,8 @@ void pa_ioline_printf(pa_ioline *l, const char *format, ...) { char *t; va_list ap; - assert(l); - assert(l->ref >= 1); + pa_assert(l); + pa_assert(PA_REFCNT_VALUE(l) >= 1); va_start(ap, format); t = pa_vsprintf_malloc(format, ap); diff --git a/src/pulsecore/ipacl.c b/src/pulsecore/ipacl.c index a240d2a0..8a8eac78 100644 --- a/src/pulsecore/ipacl.c +++ b/src/pulsecore/ipacl.c @@ -46,13 +46,13 @@ #include #endif -#include "winsock.h" - #include #include #include #include +#include +#include #ifndef HAVE_INET_PTON #include "inet_pton.h" @@ -77,7 +77,7 @@ pa_ip_acl* pa_ip_acl_new(const char *s) { char *a; pa_ip_acl *acl; - assert(s); + pa_assert(s); acl = pa_xnew(pa_ip_acl, 1); PA_LLIST_HEAD_INIT(struct acl_entry, acl->entries); @@ -91,7 +91,7 @@ pa_ip_acl* pa_ip_acl_new(const char *s) { *slash = 0; slash++; if (pa_atou(slash, &bits) < 0) { - pa_log("failed to parse number of bits: %s", slash); + pa_log_warn("Failed to parse number of bits: %s", slash); goto fail; } } else @@ -102,7 +102,7 @@ pa_ip_acl* pa_ip_acl_new(const char *s) { e.bits = bits == (uint32_t) -1 ? 32 : (int) bits; if (e.bits > 32) { - pa_log("number of bits out of range: %i", e.bits); + pa_log_warn("Number of bits out of range: %i", e.bits); goto fail; } @@ -116,7 +116,7 @@ pa_ip_acl* pa_ip_acl_new(const char *s) { e.bits = bits == (uint32_t) -1 ? 128 : (int) bits; if (e.bits > 128) { - pa_log("number of bits out of range: %i", e.bits); + pa_log_warn("Number of bits out of range: %i", e.bits); goto fail; } e.family = AF_INET6; @@ -142,7 +142,7 @@ pa_ip_acl* pa_ip_acl_new(const char *s) { } } else { - pa_log("failed to parse address: %s", a); + pa_log_warn("Failed to parse address: %s", a); goto fail; } @@ -162,7 +162,7 @@ fail: } void pa_ip_acl_free(pa_ip_acl *acl) { - assert(acl); + pa_assert(acl); while (acl->entries) { struct acl_entry *e = acl->entries; @@ -178,8 +178,8 @@ int pa_ip_acl_check(pa_ip_acl *acl, int fd) { struct acl_entry *e; socklen_t salen; - assert(acl); - assert(fd >= 0); + pa_assert(acl); + pa_assert(fd >= 0); salen = sizeof(sa); if (getpeername(fd, (struct sockaddr*) &sa, &salen) < 0) diff --git a/src/pulsecore/mcalign.c b/src/pulsecore/mcalign.c index 97616437..8ca7c962 100644 --- a/src/pulsecore/mcalign.c +++ b/src/pulsecore/mcalign.c @@ -27,10 +27,10 @@ #include #include -#include #include #include +#include #include "mcalign.h" @@ -41,7 +41,7 @@ struct pa_mcalign { pa_mcalign *pa_mcalign_new(size_t base) { pa_mcalign *m; - assert(base); + pa_assert(base); m = pa_xnew(pa_mcalign, 1); @@ -53,7 +53,7 @@ pa_mcalign *pa_mcalign_new(size_t base) { } void pa_mcalign_free(pa_mcalign *m) { - assert(m); + pa_assert(m); if (m->leftover.memblock) pa_memblock_unref(m->leftover.memblock); @@ -65,13 +65,13 @@ void pa_mcalign_free(pa_mcalign *m) { } void pa_mcalign_push(pa_mcalign *m, const pa_memchunk *c) { - assert(m); - assert(c); + pa_assert(m); + pa_assert(c); - assert(c->memblock); - assert(c->length > 0); + pa_assert(c->memblock); + pa_assert(c->length > 0); - assert(!m->current.memblock); + pa_assert(!m->current.memblock); /* Append to the leftover memory block */ if (m->leftover.memblock) { @@ -94,7 +94,7 @@ void pa_mcalign_push(pa_mcalign *m, const pa_memchunk *c) { void *lo_data, *m_data; /* We have to copy */ - assert(m->leftover.length < m->base); + pa_assert(m->leftover.length < m->base); l = m->base - m->leftover.length; if (l > c->length) @@ -110,8 +110,8 @@ void pa_mcalign_push(pa_mcalign *m, const pa_memchunk *c) { pa_memblock_release(c->memblock); m->leftover.length += l; - assert(m->leftover.length <= m->base); - assert(m->leftover.length <= pa_memblock_get_length(m->leftover.memblock)); + pa_assert(m->leftover.length <= m->base); + pa_assert(m->leftover.length <= pa_memblock_get_length(m->leftover.memblock)); if (c->length > l) { /* Save the remainder of the memory block */ @@ -134,12 +134,13 @@ void pa_mcalign_push(pa_mcalign *m, const pa_memchunk *c) { } int pa_mcalign_pop(pa_mcalign *m, pa_memchunk *c) { - assert(m); - assert(c); + pa_assert(m); + pa_assert(c); /* First test if there's a leftover memory block available */ if (m->leftover.memblock) { - assert(m->leftover.length > 0 && m->leftover.length <= m->base); + pa_assert(m->leftover.length > 0); + pa_assert(m->leftover.length <= m->base); /* The leftover memory block is not yet complete */ if (m->leftover.length < m->base) @@ -161,13 +162,13 @@ int pa_mcalign_pop(pa_mcalign *m, pa_memchunk *c) { /* Now let's see if there is other data available */ if (m->current.memblock) { size_t l; - assert(m->current.length >= m->base); + pa_assert(m->current.length >= m->base); /* The length of the returned memory block */ l = m->current.length; l /= m->base; l *= m->base; - assert(l > 0); + pa_assert(l > 0); /* Prepare the returned block */ *c = m->current; @@ -175,7 +176,7 @@ int pa_mcalign_pop(pa_mcalign *m, pa_memchunk *c) { c->length = l; /* Drop that from the current memory block */ - assert(l <= m->current.length); + pa_assert(l <= m->current.length); m->current.index += l; m->current.length -= l; @@ -184,7 +185,7 @@ int pa_mcalign_pop(pa_mcalign *m, pa_memchunk *c) { pa_memblock_unref(m->current.memblock); else { /* Move the raimainder to leftover */ - assert(m->current.length < m->base && !m->leftover.memblock); + pa_assert(m->current.length < m->base && !m->leftover.memblock); m->leftover = m->current; } @@ -200,10 +201,10 @@ int pa_mcalign_pop(pa_mcalign *m, pa_memchunk *c) { } size_t pa_mcalign_csize(pa_mcalign *m, size_t l) { - assert(m); - assert(l > 0); + pa_assert(m); + pa_assert(l > 0); - assert(!m->current.memblock); + pa_assert(!m->current.memblock); if (m->leftover.memblock) l += m->leftover.length; diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index 53c60878..cded2dfc 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -28,7 +28,6 @@ #include #include -#include #include #include #include diff --git a/src/pulsecore/memchunk.c b/src/pulsecore/memchunk.c index 36df9f6b..4e73b636 100644 --- a/src/pulsecore/memchunk.c +++ b/src/pulsecore/memchunk.c @@ -27,7 +27,6 @@ #include #include -#include #include #include @@ -42,8 +41,8 @@ pa_memchunk* pa_memchunk_make_writable(pa_memchunk *c, size_t min) { size_t l; void *tdata, *sdata; - assert(c); - assert(c->memblock); + pa_assert(c); + pa_assert(c->memblock); if (pa_memblock_ref_is_one(c->memblock) && !pa_memblock_is_read_only(c->memblock) && @@ -68,7 +67,7 @@ pa_memchunk* pa_memchunk_make_writable(pa_memchunk *c, size_t min) { } pa_memchunk* pa_memchunk_reset(pa_memchunk *c) { - assert(c); + pa_assert(c); c->memblock = NULL; c->length = c->index = 0; diff --git a/src/pulsecore/modargs.c b/src/pulsecore/modargs.c index 3733f655..41e80084 100644 --- a/src/pulsecore/modargs.c +++ b/src/pulsecore/modargs.c @@ -26,7 +26,6 @@ #endif #include -#include #include #include @@ -39,6 +38,7 @@ #include #include #include +#include #include "modargs.h" @@ -48,7 +48,10 @@ struct entry { static int add_key_value(pa_hashmap *map, char *key, char *value, const char* const valid_keys[]) { struct entry *e; - assert(map && key && value); + + pa_assert(map); + pa_assert(key); + pa_assert(value); if (valid_keys) { const char*const* v; @@ -63,10 +66,11 @@ static int add_key_value(pa_hashmap *map, char *key, char *value, const char* co } } - e = pa_xmalloc(sizeof(struct entry)); + e = pa_xnew(struct entry, 1); e->key = key; e->value = value; pa_hashmap_put(map, key, e); + return 0; } @@ -74,7 +78,6 @@ pa_modargs *pa_modargs_new(const char *args, const char* const* valid_keys) { pa_hashmap *map = NULL; map = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - assert(map); if (args) { enum { WHITESPACE, KEY, VALUE_START, VALUE_SIMPLE, VALUE_DOUBLE_QUOTES, VALUE_TICKS } state; @@ -166,10 +169,10 @@ fail: return NULL; } - static void free_func(void *p, PA_GCC_UNUSED void*userdata) { struct entry *e = p; - assert(e); + pa_assert(e); + pa_xfree(e->key); pa_xfree(e->value); pa_xfree(e); @@ -192,7 +195,10 @@ const char *pa_modargs_get_value(pa_modargs *ma, const char *key, const char *de int pa_modargs_get_value_u32(pa_modargs *ma, const char *key, uint32_t *value) { const char *v; - assert(ma && key && value); + + pa_assert(ma); + pa_assert(key); + pa_assert(value); if (!(v = pa_modargs_get_value(ma, key, NULL))) return 0; @@ -205,7 +211,10 @@ int pa_modargs_get_value_u32(pa_modargs *ma, const char *key, uint32_t *value) { int pa_modargs_get_value_s32(pa_modargs *ma, const char *key, int32_t *value) { const char *v; - assert(ma && key && value); + + pa_assert(ma); + pa_assert(key); + pa_assert(value); if (!(v = pa_modargs_get_value(ma, key, NULL))) return 0; @@ -219,7 +228,10 @@ int pa_modargs_get_value_s32(pa_modargs *ma, const char *key, int32_t *value) { int pa_modargs_get_value_boolean(pa_modargs *ma, const char *key, int *value) { const char *v; int r; - assert(ma && key && value); + + pa_assert(ma); + pa_assert(key); + pa_assert(value); if (!(v = pa_modargs_get_value(ma, key, NULL))) return 0; @@ -238,9 +250,9 @@ int pa_modargs_get_sample_spec(pa_modargs *ma, pa_sample_spec *rss) { const char *format; uint32_t channels; pa_sample_spec ss; - assert(ma && rss); - -/* DEBUG_TRAP;*/ + + pa_assert(ma); + pa_assert(rss); ss = *rss; if ((pa_modargs_get_value_u32(ma, "rate", &ss.rate)) < 0) @@ -267,8 +279,8 @@ int pa_modargs_get_channel_map(pa_modargs *ma, pa_channel_map *rmap) { pa_channel_map map; const char *cm; - assert(ma); - assert(rmap); + pa_assert(ma); + pa_assert(rmap); map = *rmap; @@ -287,9 +299,9 @@ int pa_modargs_get_sample_spec_and_channel_map(pa_modargs *ma, pa_sample_spec *r pa_sample_spec ss; pa_channel_map map; - assert(ma); - assert(rss); - assert(rmap); + pa_assert(ma); + pa_assert(rss); + pa_assert(rmap); ss = *rss; diff --git a/src/pulsecore/modinfo.c b/src/pulsecore/modinfo.c index 79baef84..9f53887b 100644 --- a/src/pulsecore/modinfo.c +++ b/src/pulsecore/modinfo.c @@ -82,7 +82,7 @@ pa_modinfo *pa_modinfo_get_by_name(const char *name) { } void pa_modinfo_free(pa_modinfo *i) { - assert(i); + pa_assert(i); pa_xfree(i->author); pa_xfree(i->description); diff --git a/src/pulsecore/module.c b/src/pulsecore/module.c index bd565546..e6d7fcaf 100644 --- a/src/pulsecore/module.c +++ b/src/pulsecore/module.c @@ -157,7 +157,8 @@ static void pa_module_free(pa_module *m) { } void pa_module_unload(pa_core *c, pa_module *m) { - pa_assert(c && m); + pa_assert(c); + pa_assert(m); pa_assert(c->modules); if (!(m = pa_idxset_remove_by_data(c->modules, m, NULL))) diff --git a/src/pulsecore/mutex-posix.c b/src/pulsecore/mutex-posix.c index a66950eb..64f466d9 100644 --- a/src/pulsecore/mutex-posix.c +++ b/src/pulsecore/mutex-posix.c @@ -25,18 +25,13 @@ #include #endif -#include #include #include +#include #include "mutex.h" -#define ASSERT_SUCCESS(x) do { \ - int _r = (x); \ - assert(_r == 0); \ -} while(0) - struct pa_mutex { pthread_mutex_t mutex; }; @@ -52,61 +47,59 @@ pa_mutex* pa_mutex_new(int recursive) { pthread_mutexattr_init(&attr); if (recursive) - ASSERT_SUCCESS(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)); + pa_assert_se(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) == 0); m = pa_xnew(pa_mutex, 1); - - ASSERT_SUCCESS(pthread_mutex_init(&m->mutex, &attr)); + pa_assert_se(pthread_mutex_init(&m->mutex, &attr) == 0); return m; } void pa_mutex_free(pa_mutex *m) { - assert(m); + pa_assert(m); - ASSERT_SUCCESS(pthread_mutex_destroy(&m->mutex)); + pa_assert_se(pthread_mutex_destroy(&m->mutex) == 0); pa_xfree(m); } void pa_mutex_lock(pa_mutex *m) { - assert(m); + pa_assert(m); - ASSERT_SUCCESS(pthread_mutex_lock(&m->mutex)); + pa_assert_se(pthread_mutex_lock(&m->mutex) == 0); } void pa_mutex_unlock(pa_mutex *m) { - assert(m); + pa_assert(m); - ASSERT_SUCCESS(pthread_mutex_unlock(&m->mutex)); + pa_assert_se(pthread_mutex_unlock(&m->mutex) == 0); } pa_cond *pa_cond_new(void) { pa_cond *c; c = pa_xnew(pa_cond, 1); - - ASSERT_SUCCESS(pthread_cond_init(&c->cond, NULL)); + pa_assert_se(pthread_cond_init(&c->cond, NULL) == 0); return c; } void pa_cond_free(pa_cond *c) { - assert(c); + pa_assert(c); - ASSERT_SUCCESS(pthread_cond_destroy(&c->cond)); + pa_assert_se(pthread_cond_destroy(&c->cond) == 0); pa_xfree(c); } void pa_cond_signal(pa_cond *c, int broadcast) { - assert(c); + pa_assert(c); if (broadcast) - ASSERT_SUCCESS(pthread_cond_broadcast(&c->cond)); + pa_assert_se(pthread_cond_broadcast(&c->cond) == 0); else - ASSERT_SUCCESS(pthread_cond_signal(&c->cond)); + pa_assert_se(pthread_cond_signal(&c->cond) == 0); } int pa_cond_wait(pa_cond *c, pa_mutex *m) { - assert(c); - assert(m); + pa_assert(c); + pa_assert(m); return pthread_cond_wait(&c->cond, &m->mutex); } diff --git a/src/pulsecore/namereg.c b/src/pulsecore/namereg.c index 5fae3fc3..fe2be467 100644 --- a/src/pulsecore/namereg.c +++ b/src/pulsecore/namereg.c @@ -27,7 +27,6 @@ #include #include -#include #include #include @@ -38,6 +37,7 @@ #include #include #include +#include #include "namereg.h" @@ -90,23 +90,22 @@ static char* cleanup_name(const char *name) { } void pa_namereg_free(pa_core *c) { - assert(c); + pa_assert(c); if (!c->namereg) return; - assert(pa_hashmap_size(c->namereg) == 0); + pa_assert(pa_hashmap_size(c->namereg) == 0); pa_hashmap_free(c->namereg, NULL, NULL); } const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t type, void *data, int fail) { struct namereg_entry *e; char *n = NULL; - int r; - assert(c); - assert(name); - assert(data); + pa_assert(c); + pa_assert(name); + pa_assert(data); if (!*name) return NULL; @@ -163,8 +162,7 @@ const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t e->name = n ? n : pa_xstrdup(name); e->data = data; - r = pa_hashmap_put(c->namereg, e->name, e); - assert (r >= 0); + pa_assert_se(pa_hashmap_put(c->namereg, e->name, e) >= 0); return e->name; } @@ -172,11 +170,10 @@ const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t void pa_namereg_unregister(pa_core *c, const char *name) { struct namereg_entry *e; - assert(c); - assert(name); + pa_assert(c); + pa_assert(name); - e = pa_hashmap_remove(c->namereg, name); - assert(e); + pa_assert_se(e = pa_hashmap_remove(c->namereg, name)); pa_xfree(e->name); pa_xfree(e); @@ -185,7 +182,7 @@ void pa_namereg_unregister(pa_core *c, const char *name) { void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type, int autoload) { struct namereg_entry *e; uint32_t idx; - assert(c); + pa_assert(c); if (!name) { @@ -245,8 +242,8 @@ void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type, int a int pa_namereg_set_default(pa_core*c, const char *name, pa_namereg_type_t type) { char **s; - assert(c); - assert(type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE); + pa_assert(c); + pa_assert(type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE); s = type == PA_NAMEREG_SINK ? &c->default_sink_name : &c->default_source_name; @@ -269,7 +266,7 @@ int pa_namereg_set_default(pa_core*c, const char *name, pa_namereg_type_t type) const char *pa_namereg_get_default_sink_name(pa_core *c) { pa_sink *s; - assert(c); + pa_assert(c); if (c->default_sink_name) return c->default_sink_name; @@ -284,7 +281,7 @@ const char *pa_namereg_get_default_source_name(pa_core *c) { pa_source *s; uint32_t idx; - assert(c); + pa_assert(c); if (c->default_source_name) return c->default_source_name; diff --git a/src/pulsecore/packet.c b/src/pulsecore/packet.c index ce57cb3e..2706efea 100644 --- a/src/pulsecore/packet.c +++ b/src/pulsecore/packet.c @@ -25,22 +25,22 @@ #include #endif -#include #include #include +#include #include "packet.h" pa_packet* pa_packet_new(size_t length) { pa_packet *p; - assert(length); + pa_assert(length > 0); - p = pa_xmalloc(sizeof(pa_packet)+length); - p->ref = 1; + p = pa_xmalloc(PA_ALIGN(sizeof(pa_packet)) + length); + PA_REFCNT_INIT(p); p->length = length; - p->data = (uint8_t*) (p+1); + p->data = (uint8_t*) p + PA_ALIGN(sizeof(pa_packet)); p->type = PA_PACKET_APPENDED; return p; @@ -49,11 +49,11 @@ pa_packet* pa_packet_new(size_t length) { pa_packet* pa_packet_new_dynamic(void* data, size_t length) { pa_packet *p; - assert(data); - assert(length); + pa_assert(data); + pa_assert(length > 0); p = pa_xnew(pa_packet, 1); - p->ref = 1; + PA_REFCNT_INIT(p); p->length = length; p->data = data; p->type = PA_PACKET_DYNAMIC; @@ -62,18 +62,18 @@ pa_packet* pa_packet_new_dynamic(void* data, size_t length) { } pa_packet* pa_packet_ref(pa_packet *p) { - assert(p); - assert(p->ref >= 1); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) >= 1); - p->ref++; + PA_REFCNT_INC(p); return p; } void pa_packet_unref(pa_packet *p) { - assert(p); - assert(p->ref >= 1); + pa_assert(p); + pa_assert(PA_REFCNT_VALUE(p) >= 1); - if (--p->ref == 0) { + if (PA_REFCNT_DEC(p) <= 0) { if (p->type == PA_PACKET_DYNAMIC) pa_xfree(p->data); pa_xfree(p); diff --git a/src/pulsecore/packet.h b/src/pulsecore/packet.h index 842582c8..bcac4a7f 100644 --- a/src/pulsecore/packet.h +++ b/src/pulsecore/packet.h @@ -27,9 +27,11 @@ #include #include +#include + typedef struct pa_packet { + PA_REFCNT_DECLARE; enum { PA_PACKET_APPENDED, PA_PACKET_DYNAMIC } type; - unsigned ref; size_t length; uint8_t *data; } pa_packet; diff --git a/src/pulsecore/parseaddr.c b/src/pulsecore/parseaddr.c index a49a09ed..0df37f4e 100644 --- a/src/pulsecore/parseaddr.c +++ b/src/pulsecore/parseaddr.c @@ -26,13 +26,13 @@ #endif #include -#include #include #include - #include + #include +#include #include "parseaddr.h" @@ -45,7 +45,9 @@ * Return a newly allocated string of the hostname and fill in *ret_port if specified */ static char *parse_host(const char *s, uint16_t *ret_port) { - assert(s && ret_port); + pa_assert(s); + pa_assert(ret_port); + if (*s == '[') { char *e; if (!(e = strchr(s+1, ']'))) @@ -70,7 +72,10 @@ static char *parse_host(const char *s, uint16_t *ret_port) { int pa_parse_address(const char *name, pa_parsed_address *ret_p) { const char *p; - assert(name && ret_p); + + pa_assert(name); + pa_assert(ret_p); + memset(ret_p, 0, sizeof(pa_parsed_address)); ret_p->type = PA_PARSED_ADDRESS_TCP_AUTO; @@ -112,6 +117,5 @@ int pa_parse_address(const char *name, pa_parsed_address *ret_p) { if (!(ret_p->path_or_host = parse_host(p, &ret_p->port))) return -1; - return 0; } diff --git a/src/pulsecore/pdispatch.c b/src/pulsecore/pdispatch.c index f5ec1c09..737b1b98 100644 --- a/src/pulsecore/pdispatch.c +++ b/src/pulsecore/pdispatch.c @@ -28,7 +28,6 @@ #include #include -#include #include #include @@ -37,6 +36,8 @@ #include #include #include +#include +#include #include "pdispatch.h" @@ -108,7 +109,7 @@ struct reply_info { }; struct pa_pdispatch { - int ref; + PA_REFCNT_DECLARE; pa_mainloop_api *mainloop; const pa_pdispatch_cb_t *callback_table; unsigned n_commands; @@ -119,7 +120,9 @@ struct pa_pdispatch { }; static void reply_info_free(struct reply_info *r) { - assert(r && r->pdispatch && r->pdispatch->mainloop); + pa_assert(r); + pa_assert(r->pdispatch); + pa_assert(r->pdispatch->mainloop); if (r->time_event) r->pdispatch->mainloop->time_free(r->time_event); @@ -131,12 +134,12 @@ static void reply_info_free(struct reply_info *r) { pa_pdispatch* pa_pdispatch_new(pa_mainloop_api *mainloop, const pa_pdispatch_cb_t*table, unsigned entries) { pa_pdispatch *pd; - assert(mainloop); + pa_assert(mainloop); - assert((entries && table) || (!entries && !table)); + pa_assert((entries && table) || (!entries && !table)); - pd = pa_xmalloc(sizeof(pa_pdispatch)); - pd->ref = 1; + pd = pa_xnew(pa_pdispatch, 1); + PA_REFCNT_INIT(pd); pd->mainloop = mainloop; pd->callback_table = table; pd->n_commands = entries; @@ -149,7 +152,7 @@ pa_pdispatch* pa_pdispatch_new(pa_mainloop_api *mainloop, const pa_pdispatch_cb_ } static void pdispatch_free(pa_pdispatch *pd) { - assert(pd); + pa_assert(pd); while (pd->replies) { if (pd->replies->free_cb) @@ -165,7 +168,7 @@ static void run_action(pa_pdispatch *pd, struct reply_info *r, uint32_t command, pa_pdispatch_cb_t callback; void *userdata; uint32_t tag; - assert(r); + pa_assert(r); pa_pdispatch_ref(pd); @@ -187,7 +190,12 @@ int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*packet, const pa_creds *creds, uint32_t tag, command; pa_tagstruct *ts = NULL; int ret = -1; - assert(pd && packet && packet->data); + + pa_assert(pd); + pa_assert(PA_REFCNT_VALUE(pd) >= 1); + pa_assert(packet); + pa_assert(PA_REFCNT_VALUE(packet) >= 1); + pa_assert(packet->data); pa_pdispatch_ref(pd); @@ -195,7 +203,6 @@ int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*packet, const pa_creds *creds, goto finish; ts = pa_tagstruct_new(packet->data, packet->length); - assert(ts); if (pa_tagstruct_getu32(ts, &command) < 0 || pa_tagstruct_getu32(ts, &tag) < 0) @@ -248,7 +255,12 @@ finish: static void timeout_callback(pa_mainloop_api*m, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { struct reply_info*r = userdata; - assert(r && r->time_event == e && r->pdispatch && r->pdispatch->mainloop == m && r->callback); + + pa_assert(r); + pa_assert(r->time_event == e); + pa_assert(r->pdispatch); + pa_assert(r->pdispatch->mainloop == m); + pa_assert(r->callback); run_action(r->pdispatch, r, PA_COMMAND_TIMEOUT, NULL); } @@ -256,7 +268,10 @@ static void timeout_callback(pa_mainloop_api*m, pa_time_event*e, PA_GCC_UNUSED c void pa_pdispatch_register_reply(pa_pdispatch *pd, uint32_t tag, int timeout, pa_pdispatch_cb_t cb, void *userdata, pa_free_cb_t free_cb) { struct reply_info *r; struct timeval tv; - assert(pd && pd->ref >= 1 && cb); + + pa_assert(pd); + pa_assert(PA_REFCNT_VALUE(pd) >= 1); + pa_assert(cb); r = pa_xnew(struct reply_info, 1); r->pdispatch = pd; @@ -268,21 +283,22 @@ void pa_pdispatch_register_reply(pa_pdispatch *pd, uint32_t tag, int timeout, pa pa_gettimeofday(&tv); tv.tv_sec += timeout; - r->time_event = pd->mainloop->time_new(pd->mainloop, &tv, timeout_callback, r); - assert(r->time_event); + pa_assert_se(r->time_event = pd->mainloop->time_new(pd->mainloop, &tv, timeout_callback, r)); PA_LLIST_PREPEND(struct reply_info, pd->replies, r); } int pa_pdispatch_is_pending(pa_pdispatch *pd) { - assert(pd); + pa_assert(pd); + pa_assert(PA_REFCNT_VALUE(pd) >= 1); return !!pd->replies; } void pa_pdispatch_set_drain_callback(pa_pdispatch *pd, void (*cb)(pa_pdispatch *pd, void *userdata), void *userdata) { - assert(pd); - assert(!cb || pa_pdispatch_is_pending(pd)); + pa_assert(pd); + pa_assert(PA_REFCNT_VALUE(pd) >= 1); + pa_assert(!cb || pa_pdispatch_is_pending(pd)); pd->drain_callback = cb; pd->drain_userdata = userdata; @@ -290,7 +306,9 @@ void pa_pdispatch_set_drain_callback(pa_pdispatch *pd, void (*cb)(pa_pdispatch * void pa_pdispatch_unregister_reply(pa_pdispatch *pd, void *userdata) { struct reply_info *r, *n; - assert(pd); + + pa_assert(pd); + pa_assert(PA_REFCNT_VALUE(pd) >= 1); for (r = pd->replies; r; r = n) { n = r->next; @@ -301,21 +319,24 @@ void pa_pdispatch_unregister_reply(pa_pdispatch *pd, void *userdata) { } void pa_pdispatch_unref(pa_pdispatch *pd) { - assert(pd && pd->ref >= 1); + pa_assert(pd); + pa_assert(PA_REFCNT_VALUE(pd) >= 1); - if (!(--(pd->ref))) + if (PA_REFCNT_DEC(pd) <= 0) pdispatch_free(pd); } pa_pdispatch* pa_pdispatch_ref(pa_pdispatch *pd) { - assert(pd && pd->ref >= 1); - pd->ref++; + pa_assert(pd); + pa_assert(PA_REFCNT_VALUE(pd) >= 1); + + PA_REFCNT_INC(pd); return pd; } const pa_creds * pa_pdispatch_creds(pa_pdispatch *pd) { - assert(pd); - assert(pd->ref >= 1); + pa_assert(pd); + pa_assert(PA_REFCNT_VALUE(pd) >= 1); return pd->creds; } diff --git a/src/pulsecore/pid.c b/src/pulsecore/pid.c index efb6e64e..22ceae89 100644 --- a/src/pulsecore/pid.c +++ b/src/pulsecore/pid.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -47,6 +46,7 @@ #include #include #include +#include #include "pid.h" @@ -57,7 +57,8 @@ static pid_t read_pid(const char *fn, int fd) { char t[20], *e; uint32_t pid; - assert(fn && fd >= 0); + pa_assert(fn); + pa_assert(fd >= 0); if ((r = pa_loop_read(fd, t, sizeof(t)-1, NULL)) < 0) { pa_log_warn("WARNING: failed to read PID file '%s': %s", @@ -73,7 +74,7 @@ static pid_t read_pid(const char *fn, int fd) { *e = 0; if (pa_atou(t, &pid) < 0) { - pa_log("WARNING: failed to parse PID file '%s'", fn); + pa_log_warn("WARNING: failed to parse PID file '%s'", fn); return (pid_t) -1; } @@ -83,6 +84,8 @@ static pid_t read_pid(const char *fn, int fd) { static int open_pid_file(const char *fn, int mode) { int fd = -1; + pa_assert(fn); + for (;;) { struct stat st; @@ -238,7 +241,7 @@ fail: if (fd >= 0) { pa_lock_fd(fd, 0); - close(fd); + pa_assert_se(close(fd) == 0); } return ret; @@ -280,7 +283,7 @@ fail: if (fd >= 0) { pa_lock_fd(fd, 0); - close(fd); + pa_assert_se(close(fd) == 0); } return ret; diff --git a/src/pulsecore/props.c b/src/pulsecore/props.c index 37e74194..fc3dce9e 100644 --- a/src/pulsecore/props.c +++ b/src/pulsecore/props.c @@ -25,11 +25,9 @@ #include #endif -#include - #include - #include +#include #include "props.h" @@ -41,9 +39,11 @@ typedef struct pa_property { /* Allocate a new property object */ static pa_property* property_new(const char *name, void *data) { pa_property* p; - assert(name && data); + + pa_assert(name); + pa_assert(data); - p = pa_xmalloc(sizeof(pa_property)); + p = pa_xnew(pa_property, 1); p->name = pa_xstrdup(name); p->data = data; @@ -52,7 +52,7 @@ static pa_property* property_new(const char *name, void *data) { /* Free a property object */ static void property_free(pa_property *p) { - assert(p); + pa_assert(p); pa_xfree(p->name); pa_xfree(p); @@ -60,7 +60,10 @@ static void property_free(pa_property *p) { void* pa_property_get(pa_core *c, const char *name) { pa_property *p; - assert(c && name && c->properties); + + pa_assert(c); + pa_assert(name); + pa_assert(c->properties); if (!(p = pa_hashmap_get(c->properties, name))) return NULL; @@ -70,7 +73,11 @@ void* pa_property_get(pa_core *c, const char *name) { int pa_property_set(pa_core *c, const char *name, void *data) { pa_property *p; - assert(c && name && data && c->properties); + + pa_assert(c); + pa_assert(name); + pa_assert(data); + pa_assert(c->properties); if (pa_hashmap_get(c->properties, name)) return -1; @@ -82,7 +89,10 @@ int pa_property_set(pa_core *c, const char *name, void *data) { int pa_property_remove(pa_core *c, const char *name) { pa_property *p; - assert(c && name && c->properties); + + pa_assert(c); + pa_assert(name); + pa_assert(c->properties); if (!(p = pa_hashmap_remove(c->properties, name))) return -1; @@ -92,18 +102,18 @@ int pa_property_remove(pa_core *c, const char *name) { } void pa_property_init(pa_core *c) { - assert(c); + pa_assert(c); c->properties = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); } void pa_property_cleanup(pa_core *c) { - assert(c); + pa_assert(c); if (!c->properties) return; - assert(!pa_hashmap_size(c->properties)); + pa_assert(!pa_hashmap_size(c->properties)); pa_hashmap_free(c->properties, NULL, NULL); c->properties = NULL; @@ -113,14 +123,17 @@ void pa_property_cleanup(pa_core *c) { void pa_property_dump(pa_core *c, pa_strbuf *s) { void *state = NULL; pa_property *p; - assert(c && s); + + pa_assert(c); + pa_assert(s); while ((p = pa_hashmap_iterate(c->properties, &state, NULL))) pa_strbuf_printf(s, "[%s] -> [%p]\n", p->name, p->data); } int pa_property_replace(pa_core *c, const char *name, void *data) { - assert(c && name); + pa_assert(c); + pa_assert(name); pa_property_remove(c, name); return pa_property_set(c, name, data); diff --git a/src/pulsecore/protocol-cli.c b/src/pulsecore/protocol-cli.c index 1d543ae5..d9d00734 100644 --- a/src/pulsecore/protocol-cli.c +++ b/src/pulsecore/protocol-cli.c @@ -25,13 +25,13 @@ #include #endif -#include #include #include #include #include +#include #include "protocol-cli.h" @@ -47,7 +47,8 @@ struct pa_protocol_cli { static void cli_eof_cb(pa_cli*c, void*userdata) { pa_protocol_cli *p = userdata; - assert(p); + pa_assert(p); + pa_idxset_remove_by_data(p->connections, c, NULL); pa_cli_free(c); } @@ -55,7 +56,10 @@ static void cli_eof_cb(pa_cli*c, void*userdata) { static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) { pa_protocol_cli *p = userdata; pa_cli *c; - assert(s && io && p); + + pa_assert(s); + pa_assert(io); + pa_assert(p); if (pa_idxset_size(p->connections)+1 > MAX_CONNECTIONS) { pa_log("Warning! Too many connections (%u), dropping incoming connection.", MAX_CONNECTIONS); @@ -64,7 +68,6 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) } c = pa_cli_new(p->core, io, p->module); - assert(c); pa_cli_set_eof_callback(c, cli_eof_cb, p); pa_idxset_put(p->connections, c, NULL); @@ -72,9 +75,11 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) pa_protocol_cli* pa_protocol_cli_new(pa_core *core, pa_socket_server *server, pa_module *m, PA_GCC_UNUSED pa_modargs *ma) { pa_protocol_cli* p; - assert(core && server); - p = pa_xmalloc(sizeof(pa_protocol_cli)); + pa_core_assert_ref(core); + pa_assert(server); + + p = pa_xnew(pa_protocol_cli, 1); p->module = m; p->core = core; p->server = server; @@ -86,12 +91,13 @@ pa_protocol_cli* pa_protocol_cli_new(pa_core *core, pa_socket_server *server, pa } static void free_connection(void *p, PA_GCC_UNUSED void *userdata) { - assert(p); + pa_assert(p); + pa_cli_free(p); } void pa_protocol_cli_free(pa_protocol_cli *p) { - assert(p); + pa_assert(p); pa_idxset_free(p->connections, free_connection, NULL); pa_socket_server_unref(p->server); diff --git a/src/pulsecore/protocol-http.c b/src/pulsecore/protocol-http.c index eb5bda0d..4a2836e7 100644 --- a/src/pulsecore/protocol-http.c +++ b/src/pulsecore/protocol-http.c @@ -25,7 +25,6 @@ #include #endif -#include #include #include #include @@ -34,6 +33,7 @@ #include #include +#include #include #include #include @@ -65,9 +65,10 @@ struct pa_protocol_http { static void http_response(struct connection *c, int code, const char *msg, const char *mime) { char s[256]; - assert(c); - assert(msg); - assert(mime); + + pa_assert(c); + pa_assert(msg); + pa_assert(mime); pa_snprintf(s, sizeof(s), "HTTP/1.0 %i %s\n" @@ -83,7 +84,7 @@ static void http_response(struct connection *c, int code, const char *msg, const static void http_message(struct connection *c, int code, const char *msg, const char *text) { char s[256]; - assert(c); + pa_assert(c); http_response(c, code, msg, "text/html"); @@ -103,21 +104,22 @@ static void http_message(struct connection *c, int code, const char *msg, const static void connection_free(struct connection *c, int del) { - assert(c); + pa_assert(c); if (c->url) pa_xfree(c->url); if (del) pa_idxset_remove_by_data(c->protocol->connections, c, NULL); + pa_ioline_unref(c->line); pa_xfree(c); } static void line_callback(pa_ioline *line, const char *s, void *userdata) { struct connection *c = userdata; - assert(line); - assert(c); + pa_assert(line); + pa_assert(c); if (!s) { /* EOF */ @@ -223,7 +225,10 @@ fail: static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) { pa_protocol_http *p = userdata; struct connection *c; - assert(s && io && p); + + pa_assert(s); + pa_assert(io); + pa_assert(p); if (pa_idxset_size(p->connections)+1 > MAX_CONNECTIONS) { pa_log_warn("Warning! Too many connections (%u), dropping incoming connection.", MAX_CONNECTIONS); @@ -231,7 +236,7 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) return; } - c = pa_xmalloc(sizeof(struct connection)); + c = pa_xnew(struct connection, 1); c->protocol = p; c->line = pa_ioline_new(io); c->state = REQUEST_LINE; @@ -243,9 +248,11 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) pa_protocol_http* pa_protocol_http_new(pa_core *core, pa_socket_server *server, pa_module *m, PA_GCC_UNUSED pa_modargs *ma) { pa_protocol_http* p; - assert(core && server); + + pa_core_assert_ref(core); + pa_assert(server); - p = pa_xmalloc(sizeof(pa_protocol_http)); + p = pa_xnew(pa_protocol_http, 1); p->module = m; p->core = core; p->server = server; @@ -257,12 +264,12 @@ pa_protocol_http* pa_protocol_http_new(pa_core *core, pa_socket_server *server, } static void free_connection(void *p, PA_GCC_UNUSED void *userdata) { - assert(p); + pa_assert(p); connection_free(p, 0); } void pa_protocol_http_free(pa_protocol_http *p) { - assert(p); + pa_assert(p); pa_idxset_free(p->connections, free_connection, NULL); pa_socket_server_unref(p->server); diff --git a/src/pulsecore/pstream-util.c b/src/pulsecore/pstream-util.c index fae1e49b..1b513782 100644 --- a/src/pulsecore/pstream-util.c +++ b/src/pulsecore/pstream-util.c @@ -25,9 +25,8 @@ #include #endif -#include - #include +#include #include "pstream-util.h" @@ -35,20 +34,20 @@ void pa_pstream_send_tagstruct_with_creds(pa_pstream *p, pa_tagstruct *t, const size_t length; uint8_t *data; pa_packet *packet; - assert(p); - assert(t); - data = pa_tagstruct_free_data(t, &length); - assert(data && length); - packet = pa_packet_new_dynamic(data, length); - assert(packet); + pa_assert(p); + pa_assert(t); + + pa_assert_se(data = pa_tagstruct_free_data(t, &length)); + pa_assert_se(packet = pa_packet_new_dynamic(data, length)); pa_pstream_send_packet(p, packet, creds); pa_packet_unref(packet); } void pa_pstream_send_error(pa_pstream *p, uint32_t tag, uint32_t error) { - pa_tagstruct *t = pa_tagstruct_new(NULL, 0); - assert(t); + pa_tagstruct *t; + + pa_assert_se(t = pa_tagstruct_new(NULL, 0)); pa_tagstruct_putu32(t, PA_COMMAND_ERROR); pa_tagstruct_putu32(t, tag); pa_tagstruct_putu32(t, error); @@ -56,8 +55,9 @@ void pa_pstream_send_error(pa_pstream *p, uint32_t tag, uint32_t error) { } void pa_pstream_send_simple_ack(pa_pstream *p, uint32_t tag) { - pa_tagstruct *t = pa_tagstruct_new(NULL, 0); - assert(t); + pa_tagstruct *t; + + pa_assert_se(t = pa_tagstruct_new(NULL, 0)); pa_tagstruct_putu32(t, PA_COMMAND_REPLY); pa_tagstruct_putu32(t, tag); pa_pstream_send_tagstruct(p, t); diff --git a/src/pulsecore/queue.c b/src/pulsecore/queue.c index b095481a..a88876f6 100644 --- a/src/pulsecore/queue.c +++ b/src/pulsecore/queue.c @@ -72,6 +72,9 @@ void pa_queue_free(pa_queue* q, void (*destroy)(void *p, void *userdata), void * void pa_queue_push(pa_queue *q, void *p) { struct queue_entry *e; + pa_assert(q); + pa_assert(p); + if (!(e = pa_flist_pop(PA_STATIC_FLIST_GET(entries)))) e = pa_xnew(struct queue_entry, 1); diff --git a/src/pulsecore/random.c b/src/pulsecore/random.c index 3f591917..b0b4926c 100644 --- a/src/pulsecore/random.c +++ b/src/pulsecore/random.c @@ -31,21 +31,22 @@ #include #include #include -#include #include #include #include +#include #include "random.h" static int has_whined = 0; -static const char *devices[] = { "/dev/urandom", "/dev/random", NULL }; +static const char * const devices[] = { "/dev/urandom", "/dev/random", NULL }; static int random_proper(void *ret_data, size_t length) { #ifdef OS_IS_WIN32 - assert(ret_data && length); + pa_assert(ret_data); + pa_assert(length > 0); return -1; @@ -53,9 +54,10 @@ static int random_proper(void *ret_data, size_t length) { int fd, ret = -1; ssize_t r = 0; - const char **device; + const char *const * device; - assert(ret_data && length); + pa_assert(ret_data); + pa_assert(length > 0); device = devices; @@ -84,7 +86,7 @@ void pa_random_seed(void) { if (random_proper(&seed, sizeof(unsigned int)) < 0) { if (!has_whined) - pa_log_warn("failed to get proper entropy. Falling back to seeding with current time."); + pa_log_warn("Failed to get proper entropy. Falling back to seeding with current time."); has_whined = 1; seed = (unsigned int) time(NULL); @@ -97,13 +99,14 @@ void pa_random(void *ret_data, size_t length) { uint8_t *p; size_t l; - assert(ret_data && length); + pa_assert(ret_data); + pa_assert(length > 0); if (random_proper(ret_data, length) >= 0) return; if (!has_whined) - pa_log_warn("failed to get proper entropy. Falling back to unsecure pseudo RNG."); + pa_log_warn("Failed to get proper entropy. Falling back to unsecure pseudo RNG."); has_whined = 1; for (p = ret_data, l = length; l > 0; p++, l--) diff --git a/src/pulsecore/shm.c b/src/pulsecore/shm.c index 38187dd2..78b968e2 100644 --- a/src/pulsecore/shm.c +++ b/src/pulsecore/shm.c @@ -1,32 +1,31 @@ /* $Id$ */ /*** - This file is part of PulseAudio. + This file is part of PulseAudio. - Copyright 2006 Lennart Poettering - Copyright 2006 Pierre Ossman for Cendio AB + Copyright 2006 Lennart Poettering + Copyright 2006 Pierre Ossman for Cendio AB - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. ***/ #ifdef HAVE_CONFIG_H #include #endif -#include #include #include #include @@ -63,10 +62,10 @@ int pa_shm_create_rw(pa_shm *m, size_t size, int shared, mode_t mode) { char fn[32]; int fd = -1; - assert(m); - assert(size > 0); - assert(size < MAX_SHM_SIZE); - assert(mode >= 0600); + pa_assert(m); + pa_assert(size > 0); + pa_assert(size < MAX_SHM_SIZE); + pa_assert(mode >= 0600); if (!shared) { m->id = 0; @@ -115,7 +114,7 @@ int pa_shm_create_rw(pa_shm *m, size_t size, int shared, mode_t mode) { close(fd); m->do_unlink = 1; #else - return -1; + return -1; #endif } @@ -128,7 +127,7 @@ fail: #ifdef HAVE_SHM_OPEN if (fd >= 0) { shm_unlink(fn); - close(fd); + pa_assert_se(close(fd) >= 0); } #endif @@ -136,12 +135,12 @@ fail: } void pa_shm_free(pa_shm *m) { - assert(m); - assert(m->ptr); - assert(m->size > 0); + pa_assert(m); + pa_assert(m->ptr); + pa_assert(m->size > 0); #ifdef MAP_FAILED - assert(m->ptr != MAP_FAILED); + pa_assert(m->ptr != MAP_FAILED); #endif if (!m->shared) { @@ -179,13 +178,13 @@ void pa_shm_punch(pa_shm *m, size_t offset, size_t size) { void *ptr; size_t o, ps; - assert(m); - assert(m->ptr); - assert(m->size > 0); - assert(offset+size <= m->size); + pa_assert(m); + pa_assert(m->ptr); + pa_assert(m->size > 0); + pa_assert(offset+size <= m->size); #ifdef MAP_FAILED - assert(m->ptr != MAP_FAILED); + pa_assert(m->ptr != MAP_FAILED); #endif /* You're welcome to implement this as NOOP on systems that don't @@ -225,7 +224,7 @@ int pa_shm_attach_ro(pa_shm *m, unsigned id) { int fd = -1; struct stat st; - assert(m); + pa_assert(m); segment_name(fn, sizeof(fn), m->id = id); @@ -254,13 +253,13 @@ int pa_shm_attach_ro(pa_shm *m, unsigned id) { m->do_unlink = 0; m->shared = 1; - close(fd); + pa_assert_se(close(fd) >= 0); return 0; fail: if (fd >= 0) - close(fd); + pa_assert_se(close(fd) >= 0); return -1; } @@ -268,7 +267,7 @@ fail: #else /* HAVE_SHM_OPEN */ int pa_shm_attach_ro(pa_shm *m, unsigned id) { - return -1; + return -1; } #endif /* HAVE_SHM_OPEN */ diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index b61a8507..aac4a2f6 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -27,7 +27,6 @@ #endif #include -#include #include #include @@ -64,7 +63,6 @@ pa_sink* pa_sink_new( pa_sink *s; char *n = NULL; char st[256]; - int r; pa_channel_map tmap; pa_assert(core); @@ -120,8 +118,7 @@ pa_sink* pa_sink_new( s->rtpoll = NULL; s->silence = NULL; - r = pa_idxset_put(core->sinks, s, &s->index); - pa_assert(s->index != PA_IDXSET_INVALID && r >= 0); + pa_assert_se(pa_idxset_put(core->sinks, s, &s->index) >= 0); pa_sample_spec_snprint(st, sizeof(st), spec); pa_log_info("Created sink %u \"%s\" with sample spec \"%s\"", s->index, s->name, st); diff --git a/src/pulsecore/sioman.c b/src/pulsecore/sioman.c index d3d7538e..8d4c6fa7 100644 --- a/src/pulsecore/sioman.c +++ b/src/pulsecore/sioman.c @@ -25,21 +25,17 @@ #include #endif -#include +#include +#include #include "sioman.h" -static int stdio_inuse = 0; +static pa_atomic_t stdio_inuse = PA_ATOMIC_INIT(0); int pa_stdio_acquire(void) { - if (stdio_inuse) - return -1; - - stdio_inuse = 1; - return 0; + return pa_atomic_cmpxchg(&stdio_inuse, 0, 1) ? 0 : -1; } void pa_stdio_release(void) { - assert(stdio_inuse); - stdio_inuse = 0; + pa_assert_se(pa_atomic_cmpxchg(&stdio_inuse, 1, 0)); } diff --git a/src/pulsecore/socket-client.c b/src/pulsecore/socket-client.c index 9e7280dd..0922a947 100644 --- a/src/pulsecore/socket-client.c +++ b/src/pulsecore/socket-client.c @@ -1,25 +1,25 @@ /* $Id$ */ /*** - This file is part of PulseAudio. + This file is part of PulseAudio. - Copyright 2004-2006 Lennart Poettering - Copyright 2006-2007 Pierre Ossman for Cendio AB + Copyright 2004-2006 Lennart Poettering + Copyright 2006-2007 Pierre Ossman for Cendio AB - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. ***/ #ifdef HAVE_CONFIG_H @@ -32,7 +32,6 @@ #include #include #include -#include #include #ifdef HAVE_SYS_SOCKET_H @@ -55,23 +54,24 @@ #include #endif -#include "winsock.h" - #include #include +#include #include #include #include #include #include +#include +#include #include "socket-client.h" #define CONNECT_TIMEOUT 5 struct pa_socket_client { - int ref; + PA_REFCNT_DECLARE; pa_mainloop_api *mainloop; int fd; pa_io_event *io_event; @@ -89,10 +89,10 @@ struct pa_socket_client { static pa_socket_client*pa_socket_client_new(pa_mainloop_api *m) { pa_socket_client *c; - assert(m); + pa_assert(m); - c = pa_xmalloc(sizeof(pa_socket_client)); - c->ref = 1; + c = pa_xnew(pa_socket_client, 1); + PA_REFCNT_INIT(c); c->mainloop = m; c->fd = -1; c->io_event = NULL; @@ -112,7 +112,7 @@ static pa_socket_client*pa_socket_client_new(pa_mainloop_api *m) { } static void free_events(pa_socket_client *c) { - assert(c); + pa_assert(c); if (c->io_event) { c->mainloop->io_free(c->io_event); @@ -134,7 +134,10 @@ static void do_call(pa_socket_client *c) { pa_iochannel *io = NULL; int error; socklen_t lerror; - assert(c && c->callback); + + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c->callback); pa_socket_client_ref(c); @@ -159,7 +162,7 @@ static void do_call(pa_socket_client *c) { } io = pa_iochannel_new(c->mainloop, c->fd, c->fd); - assert(io); + pa_assert(io); finish: if (!io && c->fd >= 0) @@ -168,7 +171,7 @@ finish: free_events(c); - assert(c->callback); + pa_assert(c->callback); c->callback(c, io, c->userdata); pa_socket_client_unref(c); @@ -176,19 +179,34 @@ finish: static void connect_fixed_cb(pa_mainloop_api *m, pa_defer_event *e, void *userdata) { pa_socket_client *c = userdata; - assert(m && c && c->defer_event == e); + + pa_assert(m); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c->defer_event == e); + do_call(c); } static void connect_io_cb(pa_mainloop_api*m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) { pa_socket_client *c = userdata; - assert(m && c && c->io_event == e && fd >= 0); + + pa_assert(m); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c->io_event == e); + pa_assert(fd >= 0); + do_call(c); } static int do_connect(pa_socket_client *c, const struct sockaddr *sa, socklen_t len) { int r; - assert(c && sa && len); + + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(sa); + pa_assert(len > 0); pa_make_nonblock_fd(c->fd); @@ -203,25 +221,24 @@ static int do_connect(pa_socket_client *c, const struct sockaddr *sa, socklen_t return -1; } - c->io_event = c->mainloop->io_new(c->mainloop, c->fd, PA_IO_EVENT_OUTPUT, connect_io_cb, c); - assert(c->io_event); - } else { - c->defer_event = c->mainloop->defer_new(c->mainloop, connect_fixed_cb, c); - assert(c->defer_event); - } + pa_assert_se(c->io_event = c->mainloop->io_new(c->mainloop, c->fd, PA_IO_EVENT_OUTPUT, connect_io_cb, c)); + } else + pa_assert_se(c->defer_event = c->mainloop->defer_new(c->mainloop, connect_fixed_cb, c)); return 0; } pa_socket_client* pa_socket_client_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port) { struct sockaddr_in sa; - assert(m && port > 0); - + + pa_assert(m); + pa_assert(port > 0); + memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = htons(port); sa.sin_addr.s_addr = htonl(address); - + return pa_socket_client_new_sockaddr(m, (struct sockaddr*) &sa, sizeof(sa)); } @@ -229,7 +246,9 @@ pa_socket_client* pa_socket_client_new_ipv4(pa_mainloop_api *m, uint32_t address pa_socket_client* pa_socket_client_new_unix(pa_mainloop_api *m, const char *filename) { struct sockaddr_un sa; - assert(m && filename); + + pa_assert(m); + pa_assert(filename); memset(&sa, 0, sizeof(sa)); sa.sun_family = AF_UNIX; @@ -248,9 +267,9 @@ pa_socket_client* pa_socket_client_new_unix(pa_mainloop_api *m, const char *file #endif /* HAVE_SYS_UN_H */ static int sockaddr_prepare(pa_socket_client *c, const struct sockaddr *sa, size_t salen) { - assert(c); - assert(sa); - assert(salen); + pa_assert(c); + pa_assert(sa); + pa_assert(salen); switch (sa->sa_family) { case AF_UNIX: @@ -288,9 +307,12 @@ static int sockaddr_prepare(pa_socket_client *c, const struct sockaddr *sa, size pa_socket_client* pa_socket_client_new_sockaddr(pa_mainloop_api *m, const struct sockaddr *sa, size_t salen) { pa_socket_client *c; - assert(m && sa); - c = pa_socket_client_new(m); - assert(c); + + pa_assert(m); + pa_assert(sa); + pa_assert(salen > 0); + + pa_assert_se(c = pa_socket_client_new(m)); if (sockaddr_prepare(c, sa, salen) < 0) goto fail; @@ -300,12 +322,11 @@ pa_socket_client* pa_socket_client_new_sockaddr(pa_mainloop_api *m, const struct fail: pa_socket_client_unref(c); return NULL; - } static void socket_client_free(pa_socket_client *c) { - assert(c && c->mainloop); - + pa_assert(c); + pa_assert(c->mainloop); free_events(c); @@ -325,20 +346,25 @@ static void socket_client_free(pa_socket_client *c) { } void pa_socket_client_unref(pa_socket_client *c) { - assert(c && c->ref >= 1); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); - if (!(--(c->ref))) + if (PA_REFCNT_DEC(c) < 0) socket_client_free(c); } pa_socket_client* pa_socket_client_ref(pa_socket_client *c) { - assert(c && c->ref >= 1); - c->ref++; + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + + PA_REFCNT_INC(c); return c; } void pa_socket_client_set_callback(pa_socket_client *c, void (*on_connection)(pa_socket_client *c, pa_iochannel*io, void *userdata), void *userdata) { - assert(c); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + c->callback = on_connection; c->userdata = userdata; } @@ -346,6 +372,10 @@ void pa_socket_client_set_callback(pa_socket_client *c, void (*on_connection)(pa pa_socket_client* pa_socket_client_new_ipv6(pa_mainloop_api *m, uint8_t address[16], uint16_t port) { struct sockaddr_in6 sa; + pa_assert(m); + pa_assert(address); + pa_assert(port > 0); + memset(&sa, 0, sizeof(sa)); sa.sin6_family = AF_INET6; sa.sin6_port = htons(port); @@ -360,7 +390,12 @@ static void asyncns_cb(pa_mainloop_api*m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_socket_client *c = userdata; struct addrinfo *res = NULL; int ret; - assert(m && c && c->asyncns_io_event == e && fd >= 0); + + pa_assert(m); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + pa_assert(c->asyncns_io_event == e); + pa_assert(fd >= 0); if (asyncns_wait(c->asyncns, 0) < 0) goto fail; @@ -397,10 +432,11 @@ fail: static void timeout_cb(pa_mainloop_api *m, pa_time_event *e, const struct timeval *tv, void *userdata) { pa_socket_client *c = userdata; - assert(m); - assert(e); - assert(tv); - assert(c); + + pa_assert(m); + pa_assert(e); + pa_assert(tv); + pa_assert(c); if (c->fd >= 0) { pa_close(c->fd); @@ -413,8 +449,8 @@ static void timeout_cb(pa_mainloop_api *m, pa_time_event *e, const struct timeva static void start_timeout(pa_socket_client *c) { struct timeval tv; - assert(c); - assert(!c->timeout_event); + pa_assert(c); + pa_assert(!c->timeout_event); pa_gettimeofday(&tv); pa_timeval_add(&tv, CONNECT_TIMEOUT * 1000000); @@ -424,7 +460,9 @@ static void start_timeout(pa_socket_client *c) { pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, const char*name, uint16_t default_port) { pa_socket_client *c = NULL; pa_parsed_address a; - assert(m && name); + + pa_assert(m); + pa_assert(name); if (pa_parse_address(name, &a) < 0) return NULL; @@ -435,7 +473,7 @@ pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, const char*nam switch (a.type) { case PA_PARSED_ADDRESS_UNIX: if ((c = pa_socket_client_new_unix(m, a.path_or_host))) - start_timeout(c); + start_timeout(c); break; case PA_PARSED_ADDRESS_TCP4: /* Fallthrough */ @@ -462,7 +500,7 @@ pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, const char*nam c->asyncns = asyncns; c->asyncns_io_event = m->io_new(m, asyncns_fd(c->asyncns), PA_IO_EVENT_INPUT, asyncns_cb, c); c->asyncns_query = asyncns_getaddrinfo(c->asyncns, a.path_or_host, port, &hints); - assert(c->asyncns_query); + pa_assert(c->asyncns_query); start_timeout(c); } #else /* HAVE_LIBASYNCNS */ @@ -479,7 +517,7 @@ pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, const char*nam if (res->ai_addr) { if ((c = pa_socket_client_new_sockaddr(m, res->ai_addr, res->ai_addrlen))) start_timeout(c); - } + } freeaddrinfo(res); #else /* HAVE_GETADDRINFO */ @@ -507,7 +545,7 @@ pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, const char*nam s.sin_port = htons(a.port); if ((c = pa_socket_client_new_sockaddr(m, (struct sockaddr*)&s, sizeof(s)))) - start_timeout(c); + start_timeout(c); #endif /* HAVE_GETADDRINFO */ } #endif /* HAVE_LIBASYNCNS */ @@ -524,6 +562,8 @@ finish: local. "local" means UNIX socket or TCP socket on localhost. Other local IP addresses are not considered local. */ int pa_socket_client_is_local(pa_socket_client *c) { - assert(c); + pa_assert(c); + pa_assert(PA_REFCNT_VALUE(c) >= 1); + return c->local; } diff --git a/src/pulsecore/socket-server.c b/src/pulsecore/socket-server.c index c900ff32..21c51151 100644 --- a/src/pulsecore/socket-server.c +++ b/src/pulsecore/socket-server.c @@ -27,7 +27,6 @@ #endif #include -#include #include #include #include @@ -72,12 +71,14 @@ #include #include #include +#include #include +#include #include "socket-server.h" struct pa_socket_server { - int ref; + PA_REFCNT_DECLARE; int fd; char *filename; char *tcpwrap_service; @@ -94,7 +95,14 @@ static void callback(pa_mainloop_api *mainloop, pa_io_event *e, int fd, PA_GCC_U pa_socket_server *s = userdata; pa_iochannel *io; int nfd; - assert(s && s->mainloop == mainloop && s->io_event == e && e && fd >= 0 && fd == s->fd); + + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(s->mainloop == mainloop); + pa_assert(s->io_event == e); + pa_assert(e); + pa_assert(fd >= 0); + pa_assert(fd == s->fd); pa_socket_server_ref(s); @@ -133,8 +141,7 @@ static void callback(pa_mainloop_api *mainloop, pa_io_event *e, int fd, PA_GCC_U else pa_socket_low_delay(fd); - io = pa_iochannel_new(s->mainloop, nfd, nfd); - assert(io); + pa_assert_se(io = pa_iochannel_new(s->mainloop, nfd, nfd)); s->on_connection(s, io, s->userdata); finish: @@ -143,10 +150,12 @@ finish: pa_socket_server* pa_socket_server_new(pa_mainloop_api *m, int fd) { pa_socket_server *s; - assert(m && fd >= 0); + + pa_assert(m); + pa_assert(fd >= 0); - s = pa_xmalloc(sizeof(pa_socket_server)); - s->ref = 1; + s = pa_xnew(pa_socket_server, 1); + PA_REFCNT_INIT(s); s->fd = fd; s->filename = NULL; s->on_connection = NULL; @@ -154,8 +163,7 @@ pa_socket_server* pa_socket_server_new(pa_mainloop_api *m, int fd) { s->tcpwrap_service = NULL; s->mainloop = m; - s->io_event = m->io_new(m, fd, PA_IO_EVENT_INPUT, callback, s); - assert(s->io_event); + pa_assert_se(s->io_event = m->io_new(m, fd, PA_IO_EVENT_INPUT, callback, s)); s->type = SOCKET_SERVER_GENERIC; @@ -163,8 +171,10 @@ pa_socket_server* pa_socket_server_new(pa_mainloop_api *m, int fd) { } pa_socket_server* pa_socket_server_ref(pa_socket_server *s) { - assert(s && s->ref >= 1); - s->ref++; + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); + + PA_REFCNT_INC(s); return s; } @@ -175,7 +185,8 @@ pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *file struct sockaddr_un sa; pa_socket_server *s; - assert(m && filename); + pa_assert(m); + pa_assert(filename); if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { pa_log("socket(): %s", pa_cstrerror(errno)); @@ -206,8 +217,7 @@ pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *file goto fail; } - s = pa_socket_server_new(m, fd); - assert(s); + pa_assert_se(s = pa_socket_server_new(m, fd)); s->filename = pa_xstrdup(filename); s->type = SOCKET_SERVER_UNIX; @@ -235,7 +245,8 @@ pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address struct sockaddr_in sa; int on = 1; - assert(m && port); + pa_assert(m); + pa_assert(port); if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { pa_log("socket(PF_INET): %s", pa_cstrerror(errno)); @@ -286,7 +297,8 @@ pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t ad struct sockaddr_in6 sa; int on = 1; - assert(m && port); + pa_assert(m); + pa_assert(port > 0); if ((fd = socket(PF_INET6, SOCK_STREAM, 0)) < 0) { pa_log("socket(PF_INET6): %s", pa_cstrerror(errno)); @@ -337,29 +349,29 @@ fail: } pa_socket_server* pa_socket_server_new_ipv4_loopback(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) { - assert(m); - assert(port > 0); + pa_assert(m); + pa_assert(port > 0); return pa_socket_server_new_ipv4(m, INADDR_LOOPBACK, port, tcpwrap_service); } pa_socket_server* pa_socket_server_new_ipv6_loopback(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) { - assert(m); - assert(port > 0); + pa_assert(m); + pa_assert(port > 0); return pa_socket_server_new_ipv6(m, in6addr_loopback.s6_addr, port, tcpwrap_service); } pa_socket_server* pa_socket_server_new_ipv4_any(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) { - assert(m); - assert(port > 0); + pa_assert(m); + pa_assert(port > 0); return pa_socket_server_new_ipv4(m, INADDR_ANY, port, tcpwrap_service); } pa_socket_server* pa_socket_server_new_ipv6_any(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) { - assert(m); - assert(port > 0); + pa_assert(m); + pa_assert(port > 0); return pa_socket_server_new_ipv6(m, in6addr_any.s6_addr, port, tcpwrap_service); } @@ -367,9 +379,9 @@ pa_socket_server* pa_socket_server_new_ipv6_any(pa_mainloop_api *m, uint16_t por pa_socket_server* pa_socket_server_new_ipv4_string(pa_mainloop_api *m, const char *name, uint16_t port, const char *tcpwrap_service) { struct in_addr ipv4; - assert(m); - assert(name); - assert(port > 0); + pa_assert(m); + pa_assert(name); + pa_assert(port > 0); if (inet_pton(AF_INET, name, &ipv4) > 0) return pa_socket_server_new_ipv4(m, ntohl(ipv4.s_addr), port, tcpwrap_service); @@ -380,9 +392,9 @@ pa_socket_server* pa_socket_server_new_ipv4_string(pa_mainloop_api *m, const cha pa_socket_server* pa_socket_server_new_ipv6_string(pa_mainloop_api *m, const char *name, uint16_t port, const char *tcpwrap_service) { struct in6_addr ipv6; - assert(m); - assert(name); - assert(port > 0); + pa_assert(m); + pa_assert(name); + pa_assert(port > 0); if (inet_pton(AF_INET6, name, &ipv6) > 0) return pa_socket_server_new_ipv6(m, ipv6.s6_addr, port, tcpwrap_service); @@ -391,7 +403,7 @@ pa_socket_server* pa_socket_server_new_ipv6_string(pa_mainloop_api *m, const cha } static void socket_server_free(pa_socket_server*s) { - assert(s); + pa_assert(s); if (s->filename) { unlink(s->filename); @@ -407,21 +419,26 @@ static void socket_server_free(pa_socket_server*s) { } void pa_socket_server_unref(pa_socket_server *s) { - assert(s && s->ref >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); - if (!(--(s->ref))) + if (PA_REFCNT_DEC(s)) socket_server_free(s); } void pa_socket_server_set_callback(pa_socket_server*s, void (*on_connection)(pa_socket_server*s, pa_iochannel *io, void *userdata), void *userdata) { - assert(s && s->ref >= 1); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); s->on_connection = on_connection; s->userdata = userdata; } char *pa_socket_server_get_address(pa_socket_server *s, char *c, size_t l) { - assert(s && c && l > 0); + pa_assert(s); + pa_assert(PA_REFCNT_VALUE(s) >= 1); + pa_assert(c); + pa_assert(l > 0); switch (s->type) { case SOCKET_SERVER_IPV6: { diff --git a/src/pulsecore/socket-util.c b/src/pulsecore/socket-util.c index 511f12ef..4026b9b1 100644 --- a/src/pulsecore/socket-util.c +++ b/src/pulsecore/socket-util.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -75,19 +74,19 @@ #include #include #include +#include #include "socket-util.h" void pa_socket_peer_to_string(int fd, char *c, size_t l) { struct stat st; - assert(c && l && fd >= 0); + pa_assert(fd >= 0); + pa_assert(c); + pa_assert(l > 0); #ifndef OS_IS_WIN32 - if (fstat(fd, &st) < 0) { - pa_snprintf(c, l, "Invalid client fd"); - return; - } + pa_assert_se(fstat(fd, &st) == 0); #endif #ifndef OS_IS_WIN32 @@ -109,11 +108,11 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) { uint32_t ip = ntohl(sa.in.sin_addr.s_addr); pa_snprintf(c, l, "TCP/IP client from %i.%i.%i.%i:%u", - ip >> 24, - (ip >> 16) & 0xFF, - (ip >> 8) & 0xFF, - ip & 0xFF, - ntohs(sa.in.sin_port)); + ip >> 24, + (ip >> 16) & 0xFF, + (ip >> 8) & 0xFF, + ip & 0xFF, + ntohs(sa.in.sin_port)); return; } else if (sa.sa.sa_family == AF_INET6) { char buf[INET6_ADDRSTRLEN]; @@ -147,7 +146,7 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) { int pa_socket_low_delay(int fd) { #ifdef SO_PRIORITY int priority; - assert(fd >= 0); + pa_assert(fd >= 0); priority = 7; if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (void*)&priority, sizeof(priority)) < 0) @@ -160,7 +159,7 @@ int pa_socket_low_delay(int fd) { int pa_socket_tcp_low_delay(int fd) { int ret, tos, on; - assert(fd >= 0); + pa_assert(fd >= 0); ret = pa_socket_low_delay(fd); @@ -176,8 +175,7 @@ int pa_socket_tcp_low_delay(int fd) { ret = -1; #endif -#if defined(IPTOS_LOWDELAY) && defined(IP_TOS) && (defined(SOL_IP) || \ - defined(IPPROTO_IP)) +#if defined(IPTOS_LOWDELAY) && defined(IP_TOS) && (defined(SOL_IP) || defined(IPPROTO_IP)) tos = IPTOS_LOWDELAY; #ifdef SOL_IP if (setsockopt(fd, SOL_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) @@ -188,27 +186,26 @@ int pa_socket_tcp_low_delay(int fd) { #endif return ret; - } int pa_socket_set_rcvbuf(int fd, size_t l) { - assert(fd >= 0); + pa_assert(fd >= 0); -/* if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void*)&l, sizeof(l)) < 0) { */ -/* pa_log("SO_RCVBUF: %s", strerror(errno)); */ -/* return -1; */ -/* } */ + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void*)&l, sizeof(l)) < 0) { + pa_log_warn("SO_RCVBUF: %s", pa_cstrerror(errno)); + return -1; + } return 0; } int pa_socket_set_sndbuf(int fd, size_t l) { - assert(fd >= 0); + pa_assert(fd >= 0); -/* if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void*)&l, sizeof(l)) < 0) { */ -/* pa_log("SO_SNDBUF: %s", strerror(errno)); */ -/* return -1; */ -/* } */ + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void*)&l, sizeof(l)) < 0) { + pa_log("SO_SNDBUF: %s", pa_cstrerror(errno)); + return -1; + } return 0; } @@ -219,6 +216,8 @@ int pa_unix_socket_is_stale(const char *fn) { struct sockaddr_un sa; int fd = -1, ret = -1; + pa_assert(fn); + if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { pa_log("socket(): %s", pa_cstrerror(errno)); goto finish; @@ -244,6 +243,8 @@ finish: int pa_unix_socket_remove_stale(const char *fn) { int r; + pa_assert(fn); + if ((r = pa_unix_socket_is_stale(fn)) < 0) return errno != ENOENT ? -1 : 0; diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index f33240ec..2f1a5a5f 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -27,7 +27,6 @@ #endif #include -#include #include #include @@ -56,12 +55,11 @@ pa_source* pa_source_new( pa_source *s; char st[256]; - int r; pa_channel_map tmap; - assert(core); - assert(name); - assert(spec); + pa_assert(core); + pa_assert(name); + pa_assert(spec); pa_return_null_if_fail(pa_sample_spec_valid(spec)); @@ -112,8 +110,7 @@ pa_source* pa_source_new( s->asyncmsgq = NULL; s->rtpoll = NULL; - r = pa_idxset_put(core->sources, s, &s->index); - assert(s->index != PA_IDXSET_INVALID && r >= 0); + pa_assert_se(pa_idxset_put(core->sources, s, &s->index) >= 0); pa_sample_spec_snprint(st, sizeof(st), spec); pa_log_info("Created source %u \"%s\" with sample spec \"%s\"", s->index, s->name, st); diff --git a/src/pulsecore/strbuf.c b/src/pulsecore/strbuf.c index 122343f4..ea8389f5 100644 --- a/src/pulsecore/strbuf.c +++ b/src/pulsecore/strbuf.c @@ -82,7 +82,7 @@ char *pa_strbuf_tostring(pa_strbuf *sb) { e = t = pa_xnew(char, sb->length+1); for (c = sb->head; c; c = c->next) { - assert((size_t) (e-t) <= sb->length); + pa_assert((size_t) (e-t) <= sb->length); memcpy(e, CHUNK_TO_TEXT(c), c->length); e += c->length; } @@ -90,7 +90,7 @@ char *pa_strbuf_tostring(pa_strbuf *sb) { /* Trailing NUL */ *e = 0; - assert(e == t+sb->length); + pa_assert(e == t+sb->length); return t; } diff --git a/src/pulsecore/tagstruct.c b/src/pulsecore/tagstruct.c index ac7ae1ab..8cf542b6 100644 --- a/src/pulsecore/tagstruct.c +++ b/src/pulsecore/tagstruct.c @@ -29,19 +29,18 @@ #include #include #include -#include #include #ifdef HAVE_NETINET_IN_H #include #endif -#include "winsock.h" - #include -#include "tagstruct.h" +#include +#include +#include "tagstruct.h" struct pa_tagstruct { uint8_t *data; @@ -54,18 +53,20 @@ struct pa_tagstruct { pa_tagstruct *pa_tagstruct_new(const uint8_t* data, size_t length) { pa_tagstruct*t; - assert(!data || (data && length)); + pa_assert(!data || (data && length)); - t = pa_xmalloc(sizeof(pa_tagstruct)); + t = pa_xnew(pa_tagstruct, 1); t->data = (uint8_t*) data; t->allocated = t->length = data ? length : 0; t->rindex = 0; t->dynamic = !data; + return t; } void pa_tagstruct_free(pa_tagstruct*t) { - assert(t); + pa_assert(t); + if (t->dynamic) pa_xfree(t->data); pa_xfree(t); @@ -73,7 +74,11 @@ void pa_tagstruct_free(pa_tagstruct*t) { uint8_t* pa_tagstruct_free_data(pa_tagstruct*t, size_t *l) { uint8_t *p; - assert(t && t->dynamic && l); + + pa_assert(t); + pa_assert(t->dynamic); + pa_assert(l); + p = t->data; *l = t->length; pa_xfree(t); @@ -81,8 +86,8 @@ uint8_t* pa_tagstruct_free_data(pa_tagstruct*t, size_t *l) { } static void extend(pa_tagstruct*t, size_t l) { - assert(t); - assert(t->dynamic); + pa_assert(t); + pa_assert(t->dynamic); if (t->length+l <= t->allocated) return; @@ -92,7 +97,8 @@ static void extend(pa_tagstruct*t, size_t l) { void pa_tagstruct_puts(pa_tagstruct*t, const char *s) { size_t l; - assert(t); + pa_assert(t); + if (s) { l = strlen(s)+2; extend(t, l); @@ -107,7 +113,8 @@ void pa_tagstruct_puts(pa_tagstruct*t, const char *s) { } void pa_tagstruct_putu32(pa_tagstruct*t, uint32_t i) { - assert(t); + pa_assert(t); + extend(t, 5); t->data[t->length] = PA_TAG_U32; i = htonl(i); @@ -116,7 +123,8 @@ void pa_tagstruct_putu32(pa_tagstruct*t, uint32_t i) { } void pa_tagstruct_putu8(pa_tagstruct*t, uint8_t c) { - assert(t); + pa_assert(t); + extend(t, 2); t->data[t->length] = PA_TAG_U8; *(t->data+t->length+1) = c; @@ -125,7 +133,10 @@ void pa_tagstruct_putu8(pa_tagstruct*t, uint8_t c) { void pa_tagstruct_put_sample_spec(pa_tagstruct *t, const pa_sample_spec *ss) { uint32_t rate; - assert(t && ss); + + pa_assert(t); + pa_assert(ss); + extend(t, 7); t->data[t->length] = PA_TAG_SAMPLE_SPEC; t->data[t->length+1] = (uint8_t) ss->format; @@ -137,7 +148,9 @@ void pa_tagstruct_put_sample_spec(pa_tagstruct *t, const pa_sample_spec *ss) { void pa_tagstruct_put_arbitrary(pa_tagstruct *t, const void *p, size_t length) { uint32_t tmp; - assert(t && p); + + pa_assert(t); + pa_assert(p); extend(t, 5+length); t->data[t->length] = PA_TAG_ARBITRARY; @@ -149,7 +162,8 @@ void pa_tagstruct_put_arbitrary(pa_tagstruct *t, const void *p, size_t length) { } void pa_tagstruct_put_boolean(pa_tagstruct*t, int b) { - assert(t); + pa_assert(t); + extend(t, 1); t->data[t->length] = b ? PA_TAG_BOOLEAN_TRUE : PA_TAG_BOOLEAN_FALSE; t->length += 1; @@ -157,7 +171,8 @@ void pa_tagstruct_put_boolean(pa_tagstruct*t, int b) { void pa_tagstruct_put_timeval(pa_tagstruct*t, const struct timeval *tv) { uint32_t tmp; - assert(t); + pa_assert(t); + extend(t, 9); t->data[t->length] = PA_TAG_TIMEVAL; tmp = htonl(tv->tv_sec); @@ -169,7 +184,9 @@ void pa_tagstruct_put_timeval(pa_tagstruct*t, const struct timeval *tv) { void pa_tagstruct_put_usec(pa_tagstruct*t, pa_usec_t u) { uint32_t tmp; - assert(t); + + pa_assert(t); + extend(t, 9); t->data[t->length] = PA_TAG_USEC; tmp = htonl((uint32_t) (u >> 32)); @@ -181,7 +198,9 @@ void pa_tagstruct_put_usec(pa_tagstruct*t, pa_usec_t u) { void pa_tagstruct_putu64(pa_tagstruct*t, uint64_t u) { uint32_t tmp; - assert(t); + + pa_assert(t); + extend(t, 9); t->data[t->length] = PA_TAG_U64; tmp = htonl((uint32_t) (u >> 32)); @@ -193,7 +212,9 @@ void pa_tagstruct_putu64(pa_tagstruct*t, uint64_t u) { void pa_tagstruct_puts64(pa_tagstruct*t, int64_t u) { uint32_t tmp; - assert(t); + + pa_assert(t); + extend(t, 9); t->data[t->length] = PA_TAG_S64; tmp = htonl((uint32_t) ((uint64_t) u >> 32)); @@ -206,7 +227,7 @@ void pa_tagstruct_puts64(pa_tagstruct*t, int64_t u) { void pa_tagstruct_put_channel_map(pa_tagstruct *t, const pa_channel_map *map) { unsigned i; - assert(t); + pa_assert(t); extend(t, 2 + map->channels); t->data[t->length++] = PA_TAG_CHANNEL_MAP; @@ -220,7 +241,7 @@ void pa_tagstruct_put_cvolume(pa_tagstruct *t, const pa_cvolume *cvolume) { unsigned i; pa_volume_t vol; - assert(t); + pa_assert(t); extend(t, 2 + cvolume->channels * sizeof(pa_volume_t)); t->data[t->length++] = PA_TAG_CVOLUME; @@ -237,7 +258,9 @@ int pa_tagstruct_gets(pa_tagstruct*t, const char **s) { int error = 0; size_t n; char *c; - assert(t && s); + + pa_assert(t); + pa_assert(s); if (t->rindex+1 > t->length) return -1; @@ -271,7 +294,8 @@ int pa_tagstruct_gets(pa_tagstruct*t, const char **s) { } int pa_tagstruct_getu32(pa_tagstruct*t, uint32_t *i) { - assert(t && i); + pa_assert(t); + pa_assert(i); if (t->rindex+5 > t->length) return -1; @@ -286,7 +310,8 @@ int pa_tagstruct_getu32(pa_tagstruct*t, uint32_t *i) { } int pa_tagstruct_getu8(pa_tagstruct*t, uint8_t *c) { - assert(t && c); + pa_assert(t); + pa_assert(c); if (t->rindex+2 > t->length) return -1; @@ -300,7 +325,8 @@ int pa_tagstruct_getu8(pa_tagstruct*t, uint8_t *c) { } int pa_tagstruct_get_sample_spec(pa_tagstruct *t, pa_sample_spec *ss) { - assert(t && ss); + pa_assert(t); + pa_assert(ss); if (t->rindex+7 > t->length) return -1; @@ -319,7 +345,9 @@ int pa_tagstruct_get_sample_spec(pa_tagstruct *t, pa_sample_spec *ss) { int pa_tagstruct_get_arbitrary(pa_tagstruct *t, const void **p, size_t length) { uint32_t len; - assert(t && p); + + pa_assert(t); + pa_assert(p); if (t->rindex+5+length > t->length) return -1; @@ -337,19 +365,24 @@ int pa_tagstruct_get_arbitrary(pa_tagstruct *t, const void **p, size_t length) { } int pa_tagstruct_eof(pa_tagstruct*t) { - assert(t); + pa_assert(t); + return t->rindex >= t->length; } const uint8_t* pa_tagstruct_data(pa_tagstruct*t, size_t *l) { - assert(t && t->dynamic && l); + pa_assert(t); + pa_assert(t->dynamic); + pa_assert(l); + *l = t->length; return t->data; } int pa_tagstruct_get_boolean(pa_tagstruct*t, int *b) { - assert(t && b); - + pa_assert(t); + pa_assert(b); + if (t->rindex+1 > t->length) return -1; @@ -366,6 +399,9 @@ int pa_tagstruct_get_boolean(pa_tagstruct*t, int *b) { int pa_tagstruct_get_timeval(pa_tagstruct*t, struct timeval *tv) { + pa_assert(t); + pa_assert(tv); + if (t->rindex+9 > t->length) return -1; @@ -382,7 +418,9 @@ int pa_tagstruct_get_timeval(pa_tagstruct*t, struct timeval *tv) { int pa_tagstruct_get_usec(pa_tagstruct*t, pa_usec_t *u) { uint32_t tmp; - assert(t && u); + + pa_assert(t); + pa_assert(u); if (t->rindex+9 > t->length) return -1; @@ -400,7 +438,9 @@ int pa_tagstruct_get_usec(pa_tagstruct*t, pa_usec_t *u) { int pa_tagstruct_getu64(pa_tagstruct*t, uint64_t *u) { uint32_t tmp; - assert(t && u); + + pa_assert(t); + pa_assert(u); if (t->rindex+9 > t->length) return -1; @@ -418,7 +458,9 @@ int pa_tagstruct_getu64(pa_tagstruct*t, uint64_t *u) { int pa_tagstruct_gets64(pa_tagstruct*t, int64_t *u) { uint32_t tmp; - assert(t && u); + + pa_assert(t); + pa_assert(u); if (t->rindex+9 > t->length) return -1; @@ -437,8 +479,8 @@ int pa_tagstruct_gets64(pa_tagstruct*t, int64_t *u) { int pa_tagstruct_get_channel_map(pa_tagstruct *t, pa_channel_map *map) { unsigned i; - assert(t); - assert(map); + pa_assert(t); + pa_assert(map); if (t->rindex+2 > t->length) return -1; @@ -463,8 +505,8 @@ int pa_tagstruct_get_cvolume(pa_tagstruct *t, pa_cvolume *cvolume) { unsigned i; pa_volume_t vol; - assert(t); - assert(cvolume); + pa_assert(t); + pa_assert(cvolume); if (t->rindex+2 > t->length) return -1; @@ -489,7 +531,7 @@ int pa_tagstruct_get_cvolume(pa_tagstruct *t, pa_cvolume *cvolume) { void pa_tagstruct_put(pa_tagstruct *t, ...) { va_list va; - assert(t); + pa_assert(t); va_start(va, t); @@ -550,7 +592,7 @@ void pa_tagstruct_put(pa_tagstruct *t, ...) { break; default: - abort(); + pa_assert_not_reached(); } } @@ -561,7 +603,7 @@ int pa_tagstruct_get(pa_tagstruct *t, ...) { va_list va; int ret = 0; - assert(t); + pa_assert(t); va_start(va, t); while (ret == 0) { @@ -620,9 +662,8 @@ int pa_tagstruct_get(pa_tagstruct *t, ...) { ret = pa_tagstruct_get_cvolume(t, va_arg(va, pa_cvolume *)); break; - default: - abort(); + pa_assert_not_reached(); } } diff --git a/src/pulsecore/tokenizer.c b/src/pulsecore/tokenizer.c index 117c7f88..ed54a86e 100644 --- a/src/pulsecore/tokenizer.c +++ b/src/pulsecore/tokenizer.c @@ -26,20 +26,16 @@ #endif #include -#include #include #include #include #include +#include #include "tokenizer.h" -struct pa_tokenizer { - pa_dynarray *dynarray; -}; - static void token_free(void *p, PA_GCC_UNUSED void *userdata) { pa_xfree(p); } @@ -48,7 +44,9 @@ static void parse(pa_dynarray*a, const char *s, unsigned args) { int infty = 0; const char delimiter[] = " \t\n\r"; const char *p; - assert(a && s); + + pa_assert(a); + pa_assert(s); if (args == 0) infty = 1; @@ -70,23 +68,23 @@ static void parse(pa_dynarray*a, const char *s, unsigned args) { } pa_tokenizer* pa_tokenizer_new(const char *s, unsigned args) { - pa_tokenizer *t; - - t = pa_xmalloc(sizeof(pa_tokenizer)); - t->dynarray = pa_dynarray_new(); - assert(t->dynarray); + pa_dynarray *a; - parse(t->dynarray, s, args); - return t; + a = pa_dynarray_new(); + parse(a, s, args); + return (pa_tokenizer*) a; } void pa_tokenizer_free(pa_tokenizer *t) { - assert(t); - pa_dynarray_free(t->dynarray, token_free, NULL); - pa_xfree(t); + pa_dynarray *a = (pa_dynarray*) t; + + pa_assert(a); + pa_dynarray_free(a, token_free, NULL); } const char *pa_tokenizer_get(pa_tokenizer *t, unsigned i) { - assert(t); - return pa_dynarray_get(t->dynarray, i); + pa_dynarray *a = (pa_dynarray*) t; + + pa_assert(a); + return pa_dynarray_get(a, i); } diff --git a/src/pulsecore/x11prop.c b/src/pulsecore/x11prop.c index 5b85ea42..a740e39b 100644 --- a/src/pulsecore/x11prop.c +++ b/src/pulsecore/x11prop.c @@ -32,7 +32,6 @@ #include "x11prop.h" - void pa_x11_set_prop(Display *d, const char *name, const char *data) { Atom a = XInternAtom(d, name, False); XChangeProperty(d, RootWindow(d, 0), a, XA_STRING, 8, PropModeReplace, (const unsigned char*) data, strlen(data)+1); diff --git a/src/pulsecore/x11wrap.c b/src/pulsecore/x11wrap.c index 1bcbcd48..1cb1ce84 100644 --- a/src/pulsecore/x11wrap.c +++ b/src/pulsecore/x11wrap.c @@ -25,7 +25,6 @@ #include #endif -#include #include #include @@ -34,6 +33,7 @@ #include #include #include +#include #include "x11wrap.h" @@ -47,8 +47,8 @@ struct pa_x11_internal { }; struct pa_x11_wrapper { + PA_REFCNT_DECLARE; pa_core *core; - int ref; char *property_name; Display *display; @@ -69,7 +69,8 @@ struct pa_x11_client { /* Dispatch all pending X11 events */ static void work(pa_x11_wrapper *w) { - assert(w && w->ref >= 1); + pa_assert(w); + pa_assert(PA_REFCNT_VALUE(w) >= 1); while (XPending(w->display)) { pa_x11_client *c; @@ -77,7 +78,7 @@ static void work(pa_x11_wrapper *w) { XNextEvent(w->display, &e); for (c = w->clients; c; c = c->next) { - assert(c->callback); + pa_assert(c->callback); if (c->callback(w, &e, c->userdata) != 0) break; } @@ -87,14 +88,24 @@ static void work(pa_x11_wrapper *w) { /* IO notification event for the X11 display connection */ static void display_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) { pa_x11_wrapper *w = userdata; - assert(m && e && fd >= 0 && w && w->ref >= 1); + + pa_assert(m); + pa_assert(e); + pa_assert(fd >= 0); + pa_assert(w); + pa_assert(PA_REFCNT_VALUE(w) >= 1); + work(w); } /* Deferred notification event. Called once each main loop iteration */ static void defer_event(pa_mainloop_api *m, pa_defer_event *e, void *userdata) { pa_x11_wrapper *w = userdata; - assert(m && e && w && w->ref >= 1); + + pa_assert(m); + pa_assert(e); + pa_assert(w); + pa_assert(PA_REFCNT_VALUE(w) >= 1); m->defer_enable(e, 0); @@ -104,7 +115,12 @@ static void defer_event(pa_mainloop_api *m, pa_defer_event *e, void *userdata) { /* IO notification event for X11 internal connections */ static void internal_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) { pa_x11_wrapper *w = userdata; - assert(m && e && fd >= 0 && w && w->ref >= 1); + + pa_assert(m); + pa_assert(e); + pa_assert(fd >= 0); + pa_assert(w); + pa_assert(PA_REFCNT_VALUE(w) >= 1); XProcessInternalConnection(w->display, fd); @@ -114,10 +130,9 @@ static void internal_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, PA_GCC /* Add a new IO source for the specified X11 internal connection */ static pa_x11_internal* x11_internal_add(pa_x11_wrapper *w, int fd) { pa_x11_internal *i; - assert(fd >= 0); + pa_assert(fd >= 0); - i = pa_xmalloc(sizeof(pa_x11_internal)); - assert(i); + i = pa_xnew(pa_x11_internal, 1); i->wrapper = w; i->io_event = w->core->mainloop->io_new(w->core->mainloop, fd, PA_IO_EVENT_INPUT, internal_io_event, w); i->fd = fd; @@ -128,7 +143,7 @@ static pa_x11_internal* x11_internal_add(pa_x11_wrapper *w, int fd) { /* Remove an IO source for an X11 internal connection */ static void x11_internal_remove(pa_x11_wrapper *w, pa_x11_internal *i) { - assert(i); + pa_assert(i); PA_LLIST_REMOVE(pa_x11_internal, w->internals, i); w->core->mainloop->io_free(i->io_event); @@ -138,7 +153,10 @@ static void x11_internal_remove(pa_x11_wrapper *w, pa_x11_internal *i) { /* Implementation of XConnectionWatchProc */ static void x11_watch(Display *display, XPointer userdata, int fd, Bool opening, XPointer *watch_data) { pa_x11_wrapper *w = (pa_x11_wrapper*) userdata; - assert(display && w && fd >= 0); + + pa_assert(display); + pa_assert(w); + pa_assert(fd >= 0); if (opening) *watch_data = (XPointer) x11_internal_add(w, fd); @@ -149,16 +167,15 @@ static void x11_watch(Display *display, XPointer userdata, int fd, Bool opening, static pa_x11_wrapper* x11_wrapper_new(pa_core *c, const char *name, const char *t) { pa_x11_wrapper*w; Display *d; - int r; if (!(d = XOpenDisplay(name))) { pa_log("XOpenDisplay() failed"); return NULL; } - w = pa_xmalloc(sizeof(pa_x11_wrapper)); + w = pa_xnew(pa_x11_wrapper, 1); + PA_REFCNT_INIT(w); w->core = c; - w->ref = 1; w->property_name = pa_xstrdup(t); w->display = d; @@ -170,20 +187,17 @@ static pa_x11_wrapper* x11_wrapper_new(pa_core *c, const char *name, const char XAddConnectionWatch(d, x11_watch, (XPointer) w); - r = pa_property_set(c, w->property_name, w); - assert(r >= 0); + pa_assert_se(pa_property_set(c, w->property_name, w) >= 0); return w; } static void x11_wrapper_free(pa_x11_wrapper*w) { - int r; - assert(w); + pa_assert(w); - r = pa_property_remove(w->core, w->property_name); - assert(r >= 0); + pa_assert_se(pa_property_remove(w->core, w->property_name) >= 0); - assert(!w->clients); + pa_assert(!w->clients); XRemoveConnectionWatch(w->display, x11_watch, (XPointer) w); XCloseDisplay(w->display); @@ -201,7 +215,8 @@ static void x11_wrapper_free(pa_x11_wrapper*w) { pa_x11_wrapper* pa_x11_wrapper_get(pa_core *c, const char *name) { char t[256]; pa_x11_wrapper *w; - assert(c); + + pa_core_assert_ref(c); pa_snprintf(t, sizeof(t), "x11-wrapper%s%s", name ? "-" : "", name ? name : ""); if ((w = pa_property_get(c, t))) @@ -211,20 +226,24 @@ pa_x11_wrapper* pa_x11_wrapper_get(pa_core *c, const char *name) { } pa_x11_wrapper* pa_x11_wrapper_ref(pa_x11_wrapper *w) { - assert(w && w->ref >= 1); - w->ref++; + pa_assert(w); + pa_assert(PA_REFCNT_VALUE(w) >= 1); + + PA_REFCNT_INC(w); return w; } void pa_x11_wrapper_unref(pa_x11_wrapper* w) { - assert(w && w->ref >= 1); + pa_assert(w); + pa_assert(PA_REFCNT_VALUE(w) >= 1); - if (!(--w->ref)) + if (PA_REFCNT_DEC(w) <= 0) x11_wrapper_free(w); } Display *pa_x11_wrapper_get_display(pa_x11_wrapper *w) { - assert(w && w->ref >= 1); + pa_assert(w); + pa_assert(PA_REFCNT_VALUE(w) >= 1); /* Somebody is using us, schedule a output buffer flush */ w->core->mainloop->defer_enable(w->defer_event, 1); @@ -234,9 +253,11 @@ Display *pa_x11_wrapper_get_display(pa_x11_wrapper *w) { pa_x11_client* pa_x11_client_new(pa_x11_wrapper *w, int (*cb)(pa_x11_wrapper *w, XEvent *e, void *userdata), void *userdata) { pa_x11_client *c; - assert(w && w->ref >= 1); + + pa_assert(w); + pa_assert(PA_REFCNT_VALUE(w) >= 1); - c = pa_xmalloc(sizeof(pa_x11_client)); + c = pa_xnew(pa_x11_client, 1); c->wrapper = w; c->callback = cb; c->userdata = userdata; @@ -247,8 +268,10 @@ pa_x11_client* pa_x11_client_new(pa_x11_wrapper *w, int (*cb)(pa_x11_wrapper *w, } void pa_x11_client_free(pa_x11_client *c) { - assert(c && c->wrapper && c->wrapper->ref >= 1); - + pa_assert(c); + pa_assert(c->wrapper); + pa_assert(PA_REFCNT_VALUE(c->wrapper) >= 1); + PA_LLIST_REMOVE(pa_x11_client, c->wrapper->clients, c); pa_xfree(c); } -- cgit From 54506ab44a9ac61e79b3a5c632db56bde41beded Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Sep 2007 23:12:24 +0000 Subject: on systems where we know that POSIX shm is mapped to /dev/shm, add the ability to cleanup stale SHM segments. (Right now only Linux) git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1810 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/cmdline.c | 9 +++- src/daemon/daemon-conf.h | 3 +- src/daemon/main.c | 11 ++++- src/pulsecore/shm.c | 118 +++++++++++++++++++++++++++++++++++++++++++++-- src/pulsecore/shm.h | 2 + 5 files changed, 134 insertions(+), 9 deletions(-) diff --git a/src/daemon/cmdline.c b/src/daemon/cmdline.c index a3f1ff03..d14002f6 100644 --- a/src/daemon/cmdline.c +++ b/src/daemon/cmdline.c @@ -64,7 +64,8 @@ enum { ARG_NO_CPU_LIMIT, ARG_DISABLE_SHM, ARG_DUMP_RESAMPLE_METHODS, - ARG_SYSTEM + ARG_SYSTEM, + ARG_CLEANUP_SHM }; /* Tabel for getopt_long() */ @@ -94,6 +95,7 @@ static struct option long_options[] = { {"no-cpu-limit", 2, 0, ARG_NO_CPU_LIMIT}, {"disable-shm", 2, 0, ARG_DISABLE_SHM}, {"dump-resample-methods", 2, 0, ARG_DUMP_RESAMPLE_METHODS}, + {"cleanup-shm", 2, 0, ARG_CLEANUP_SHM}, {NULL, 0, 0, 0} }; @@ -114,6 +116,7 @@ void pa_cmdline_help(const char *argv0) { " --dump-conf Dump default configuration\n" " --dump-modules Dump list of available modules\n" " --dump-resample-methods Dump available resample methods\n" + " --cleanup-shm Cleanup stale shared memory segments\n" " -k --kill Kill a running daemon\n" " --check Check for a running daemon\n\n" @@ -188,6 +191,10 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d case ARG_DUMP_RESAMPLE_METHODS: conf->cmd = PA_CMD_DUMP_RESAMPLE_METHODS; break; + + case ARG_CLEANUP_SHM: + conf->cmd = PA_CMD_CLEANUP_SHM; + break; case 'k': case ARG_KILL: diff --git a/src/daemon/daemon-conf.h b/src/daemon/daemon-conf.h index 76334271..4d37861d 100644 --- a/src/daemon/daemon-conf.h +++ b/src/daemon/daemon-conf.h @@ -41,7 +41,8 @@ typedef enum pa_daemon_conf_cmd { PA_CMD_DUMP_MODULES, PA_CMD_KILL, PA_CMD_CHECK, - PA_CMD_DUMP_RESAMPLE_METHODS + PA_CMD_DUMP_RESAMPLE_METHODS, + PA_CMD_CLEANUP_SHM } pa_daemon_conf_cmd_t; #ifdef HAVE_SYS_RESOURCE_H diff --git a/src/daemon/main.c b/src/daemon/main.c index 87f3f01d..4509e7f9 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -58,13 +58,12 @@ #include #endif -#include "../pulsecore/winsock.h" - #include #include #include #include +#include #include #include #include @@ -83,6 +82,7 @@ #include #include #include +#include #include "cmdline.h" #include "cpulimit.h" @@ -496,6 +496,13 @@ int main(int argc, char *argv[]) { goto finish; + case PA_CMD_CLEANUP_SHM: + + if (pa_shm_cleanup() >= 0) + retval = 0; + + goto finish; + default: pa_assert(conf->cmd == PA_CMD_DAEMON); } diff --git a/src/pulsecore/shm.c b/src/pulsecore/shm.c index 78b968e2..f17d9460 100644 --- a/src/pulsecore/shm.c +++ b/src/pulsecore/shm.c @@ -33,17 +33,22 @@ #include #include #include +#include +#include +#include #ifdef HAVE_SYS_MMAN_H #include #endif +#include + #include #include #include #include #include -#include +#include #include "shm.h" @@ -51,8 +56,29 @@ #define MADV_REMOVE 9 #endif -#define MAX_SHM_SIZE (1024*1024*20) +#define MAX_SHM_SIZE (PA_ALIGN(1024*1024*20)) + +#ifdef __linux__ +/* On Linux we know that the shared memory blocks are files in + * /dev/shm. We can use that information to list all blocks and + * cleanup unused ones */ +#define SHM_PATH "/dev/shm/" +#else +#undef SHM_PATH +#endif +#define SHM_MARKER ((int) 0xbeefcafe) + +/* We now put this SHM marker at the end of each segment. It's optional to not require a reboot when upgrading, though */ +struct shm_marker { + pa_atomic_t marker; /* 0xbeefcafe */ + pa_atomic_t pid; + void *_reserverd1; + void *_reserverd2; + void *_reserverd3; + void *_reserverd4; +}; + static char *segment_name(char *fn, size_t l, unsigned id) { pa_snprintf(fn, l, "/pulse-shm-%u", id); return fn; @@ -67,6 +93,13 @@ int pa_shm_create_rw(pa_shm *m, size_t size, int shared, mode_t mode) { pa_assert(size < MAX_SHM_SIZE); pa_assert(mode >= 0600); + /* Each time we create a new SHM area, let's first drop all stale + * ones */ + pa_shm_cleanup(); + + /* Round up to make it aligned */ + size = PA_ALIGN(size); + if (!shared) { m->id = 0; m->size = size; @@ -93,6 +126,8 @@ int pa_shm_create_rw(pa_shm *m, size_t size, int shared, mode_t mode) { } else { #ifdef HAVE_SHM_OPEN + struct shm_marker *marker; + pa_random(&m->id, sizeof(m->id)); segment_name(fn, sizeof(fn), m->id); @@ -101,7 +136,9 @@ int pa_shm_create_rw(pa_shm *m, size_t size, int shared, mode_t mode) { goto fail; } - if (ftruncate(fd, m->size = size) < 0) { + m->size = size + PA_ALIGN(sizeof(struct shm_marker)); + + if (ftruncate(fd, m->size) < 0) { pa_log("ftruncate() failed: %s", pa_cstrerror(errno)); goto fail; } @@ -111,6 +148,12 @@ int pa_shm_create_rw(pa_shm *m, size_t size, int shared, mode_t mode) { goto fail; } + /* We store our PID at the end of the shm block, so that we + * can check for dead shm segments later */ + marker = (struct shm_marker*) ((uint8_t*) m->ptr + m->size - PA_ALIGN(sizeof(struct shm_marker))); + pa_atomic_store(&marker->pid, (int) getpid()); + pa_atomic_store(&marker->marker, SHM_MARKER); + close(fd); m->do_unlink = 1; #else @@ -229,7 +272,8 @@ int pa_shm_attach_ro(pa_shm *m, unsigned id) { segment_name(fn, sizeof(fn), m->id = id); if ((fd = shm_open(fn, O_RDONLY, 0)) < 0) { - pa_log("shm_open() failed: %s", pa_cstrerror(errno)); + if (errno != EACCES) + pa_log("shm_open() failed: %s", pa_cstrerror(errno)); goto fail; } @@ -238,7 +282,7 @@ int pa_shm_attach_ro(pa_shm *m, unsigned id) { goto fail; } - if (st.st_size <= 0 || st.st_size > MAX_SHM_SIZE) { + if (st.st_size <= 0 || st.st_size > MAX_SHM_SIZE+PA_ALIGN(sizeof(struct shm_marker)) || PA_ALIGN(st.st_size) != st.st_size) { pa_log("Invalid shared memory segment size"); goto fail; } @@ -271,3 +315,67 @@ int pa_shm_attach_ro(pa_shm *m, unsigned id) { } #endif /* HAVE_SHM_OPEN */ + +int pa_shm_cleanup(void) { + +#ifdef SHM_PATH + DIR *d; + struct dirent *de; + + if (!(d = opendir(SHM_PATH))) { + pa_log_warn("Failed to read "SHM_PATH": %s", pa_cstrerror(errno)); + return -1; + } + + while ((de = readdir(d))) { + pa_shm seg; + unsigned id; + pid_t pid; + char fn[128]; + struct shm_marker *m; + + if (strncmp(de->d_name, "pulse-shm-", 10)) + continue; + + if (pa_atou(de->d_name + 10, &id) < 0) + continue; + + if (pa_shm_attach_ro(&seg, id) < 0) + continue; + + if (seg.size < PA_ALIGN(sizeof(struct shm_marker))) { + pa_shm_free(&seg); + continue; + } + + m = (struct shm_marker*) ((uint8_t*) seg.ptr + seg.size - PA_ALIGN(sizeof(struct shm_marker))); + + if (pa_atomic_load(&m->marker) != SHM_MARKER) { + pa_shm_free(&seg); + continue; + } + + if (!(pid = (pid_t) pa_atomic_load(&m->pid))) { + pa_shm_free(&seg); + continue; + } + + if (kill(pid, 0) == 0 || errno != ESRCH) { + pa_shm_free(&seg); + continue; + } + + pa_shm_free(&seg); + + /* Ok, the owner of this shms segment is dead, so, let's remove the segment */ + segment_name(fn, sizeof(fn), id); + + if (shm_unlink(fn) < 0 && errno != EACCES) + pa_log_warn("Failed to remove SHM segment %s: %s\n", fn, pa_cstrerror(errno)); + } + + closedir(d); +#endif + + return 0; +} diff --git a/src/pulsecore/shm.h b/src/pulsecore/shm.h index e695a2a1..270591de 100644 --- a/src/pulsecore/shm.h +++ b/src/pulsecore/shm.h @@ -41,4 +41,6 @@ void pa_shm_punch(pa_shm *m, size_t offset, size_t size); void pa_shm_free(pa_shm *m); +int pa_shm_cleanup(void); + #endif -- cgit From 7f92542420ef6085b6f090954052266cc70af8a1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 12 Sep 2007 00:04:21 +0000 Subject: consolidate close() calls to pa_close(), and make sure on every occasion that we handle failures of close() sensibly git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1811 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/cpulimit.c | 4 +-- src/daemon/main.c | 16 ++++----- src/modules/module-esound-compat-spawnfd.c | 2 +- src/modules/module-mmkbd-evdev.c | 2 +- src/modules/module-oss.c | 8 ++--- src/modules/module-pipe-sink.c | 2 +- src/modules/module-pipe-source.c | 2 +- src/modules/oss-util.c | 4 +-- src/pulse/context.c | 8 ++--- src/pulse/mainloop.c | 4 +-- src/pulsecore/authkey.c | 10 ++++-- src/pulsecore/core-util.c | 36 ++++++++++----------- src/pulsecore/fdsem.c | 4 +-- src/pulsecore/pid.c | 52 ++++++++++++++++-------------- src/pulsecore/random.c | 2 +- src/pulsecore/shm.c | 8 ++--- src/pulsecore/sound-file-stream.c | 3 +- src/pulsecore/sound-file.c | 3 +- 18 files changed, 89 insertions(+), 81 deletions(-) diff --git a/src/daemon/cpulimit.c b/src/daemon/cpulimit.c index 37f7976b..4f0adc06 100644 --- a/src/daemon/cpulimit.c +++ b/src/daemon/cpulimit.c @@ -223,9 +223,9 @@ void pa_cpu_limit_done(void) { } if (the_pipe[0] >= 0) - close(the_pipe[0]); + pa_assert_se(pa_close(the_pipe[0]) == 0); if (the_pipe[1] >= 0) - close(the_pipe[1]); + pa_assert_se(pa_close(the_pipe[1]) == 0); the_pipe[0] = the_pipe[1] = -1; if (installed) { diff --git a/src/daemon/main.c b/src/daemon/main.c index 4509e7f9..0bbddffa 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -160,9 +160,9 @@ static void signal_callback(pa_mainloop_api*m, PA_GCC_UNUSED pa_signal_event *e, static void close_pipe(int p[2]) { if (p[0] != -1) - close(p[0]); + pa_assert_se(pa_close(p[0]) == 0); if (p[1] != -1) - close(p[1]); + pa_assert_se(pa_close(p[1]) == 0); p[0] = p[1] = -1; } @@ -537,7 +537,7 @@ int main(int argc, char *argv[]) { if (child != 0) { /* Father */ - close(daemon_pipe[1]); + pa_assert_se(pa_close(daemon_pipe[1]) == 0); daemon_pipe[1] = -1; if (pa_loop_read(daemon_pipe[0], &retval, sizeof(retval), NULL) != sizeof(retval)) { @@ -553,7 +553,7 @@ int main(int argc, char *argv[]) { goto finish; } - close(daemon_pipe[0]); + pa_assert_se(pa_close(daemon_pipe[0]) == 0); daemon_pipe[0] = -1; #endif @@ -568,9 +568,9 @@ int main(int argc, char *argv[]) { #endif #ifndef OS_IS_WIN32 - close(0); - close(1); - close(2); + pa_close(0); + pa_close(1); + pa_close(2); open("/dev/null", O_RDONLY); open("/dev/null", O_WRONLY); @@ -592,7 +592,7 @@ int main(int argc, char *argv[]) { #ifdef TIOCNOTTY if ((tty_fd = open("/dev/tty", O_RDWR)) >= 0) { ioctl(tty_fd, TIOCNOTTY, (char*) 0); - close(tty_fd); + pa_assert_se(pa_close(tty_fd) == 0); } #endif } diff --git a/src/modules/module-esound-compat-spawnfd.c b/src/modules/module-esound-compat-spawnfd.c index 890ebb16..46235c09 100644 --- a/src/modules/module-esound-compat-spawnfd.c +++ b/src/modules/module-esound-compat-spawnfd.c @@ -65,7 +65,7 @@ int pa__init(pa_module*m) { if (pa_loop_write(fd, &x, sizeof(x), NULL) != sizeof(x)) pa_log_warn("WARNING: write(%u, 1, 1) failed: %s", fd, pa_cstrerror(errno)); - close(fd); + pa_assert_se(pa_close(fd) == 0); pa_module_unload_request(m); diff --git a/src/modules/module-mmkbd-evdev.c b/src/modules/module-mmkbd-evdev.c index 03394c0a..dc0b1c1a 100644 --- a/src/modules/module-mmkbd-evdev.c +++ b/src/modules/module-mmkbd-evdev.c @@ -254,7 +254,7 @@ void pa__done(pa_module*m) { m->core->mainloop->io_free(u->io); if (u->fd >= 0) - close(u->fd); + pa_assert_se(pa_close(u->fd) == 0); pa_xfree(u->sink_name); pa_xfree(u); diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 9273a393..ffecd394 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -476,7 +476,7 @@ static int suspend(struct userdata *u) { /* Let's suspend */ ioctl(u->fd, SNDCTL_DSP_SYNC, NULL); - close(u->fd); + pa_close(u->fd); u->fd = -1; if (u->rtpoll_item) { @@ -588,7 +588,7 @@ static int unsuspend(struct userdata *u) { return 0; fail: - close(u->fd); + pa_close(u->fd); u->fd = -1; return -1; } @@ -1324,7 +1324,7 @@ fail: if (u) pa__done(m); else if (fd >= 0) - close(fd); + pa_close(fd); if (ma) pa_modargs_free(ma); @@ -1391,7 +1391,7 @@ void pa__done(pa_module*m) { munmap(u->out_mmap, u->out_hwbuf_size); if (u->fd >= 0) - close(u->fd); + pa_close(u->fd); pa_xfree(u->device_name); diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index 5cafaada..61454261 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -335,7 +335,7 @@ void pa__done(pa_module*m) { } if (u->fd >= 0) - close(u->fd); + pa_assert_se(pa_close(u->fd) == 0); pa_xfree(u); } diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index 291010e1..68c89a0d 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -313,7 +313,7 @@ void pa__done(pa_module*m) { } if (u->fd >= 0) - close(u->fd); + pa_assert_se(pa_close(u->fd) == 0); pa_xfree(u); } diff --git a/src/modules/oss-util.c b/src/modules/oss-util.c index 5a939cf8..36498809 100644 --- a/src/modules/oss-util.c +++ b/src/modules/oss-util.c @@ -68,7 +68,7 @@ int pa_oss_open(const char *device, int *mode, int* pcaps) { pa_log_warn("'%s' doesn't support full duplex", device); - close(fd); + pa_close(fd); } if ((fd = open(device, (*mode = O_WRONLY)|O_NDELAY|O_NOCTTY)) < 0) { @@ -147,7 +147,7 @@ success: fail: if (fd >= 0) - close(fd); + pa_close(fd); return -1; } diff --git a/src/pulse/context.c b/src/pulse/context.c index ab06aeb9..1ed250f9 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -524,7 +524,7 @@ static int context_connect_spawn(pa_context *c) { int n; /* Not required, since fds[0] has CLOEXEC enabled anyway */ - close(fds[0]); + pa_assert_se(pa_close(fds[0]) == 0); if (c->spawn_api.atfork) c->spawn_api.atfork(); @@ -571,7 +571,7 @@ static int context_connect_spawn(pa_context *c) { goto fail; } - close(fds[1]); + pa_assert_se(pa_close(fds[1]) == 0); c->is_local = 1; @@ -586,9 +586,9 @@ static int context_connect_spawn(pa_context *c) { fail: if (fds[0] != -1) - close(fds[0]); + pa_assert_se(pa_close(fds[0]) == 0); if (fds[1] != -1) - close(fds[1]); + pa_assert_se(pa_close(fds[1]) == 0); unlock_autospawn_lock_file(c); diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index 419b74d6..fc373d97 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -606,9 +606,9 @@ void pa_mainloop_free(pa_mainloop* m) { pa_xfree(m->pollfds); if (m->wakeup_pipe[0] >= 0) - close(m->wakeup_pipe[0]); + pa_assert_se(pa_close(m->wakeup_pipe[0]) == 0); if (m->wakeup_pipe[1] >= 0) - close(m->wakeup_pipe[1]); + pa_assert_se(pa_close(m->wakeup_pipe[1]) == 0); pa_xfree(m); } diff --git a/src/pulsecore/authkey.c b/src/pulsecore/authkey.c index d8056247..4d9bfd3a 100644 --- a/src/pulsecore/authkey.c +++ b/src/pulsecore/authkey.c @@ -120,7 +120,10 @@ finish: if (unlock) pa_lock_fd(fd, 0); - close(fd); + if (pa_close(fd) < 0) { + pa_log_warn("Failed to close cookie file: %s", pa_cstrerror(errno)); + ret = -1; + } } return ret; @@ -221,7 +224,10 @@ finish: if (unlock) pa_lock_fd(fd, 0); - close(fd); + if (pa_close(fd) < 0) { + pa_log_warn("Failed to close cookie file: %s", pa_cstrerror(errno)); + ret = -1; + } } return ret; diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index c0dd0d68..62a63761 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -360,11 +360,11 @@ ssize_t pa_loop_write(int fd, const void*data, size_t size, int *type) { /** Platform independent read function. Necessary since not all * systems treat all file descriptors equal. */ int pa_close(int fd) { + #ifdef OS_IS_WIN32 int ret; - ret = closesocket(fd); - if (ret == 0) + if ((ret = closesocket(fd)) == 0) return 0; if (WSAGetLastError() != WSAENOTSOCK) { @@ -838,8 +838,7 @@ int pa_lock_fd(int fd, int b) { return 0; } - pa_log("%slock: %s", !b? "un" : "", - pa_cstrerror(errno)); + pa_log("%slock: %s", !b? "un" : "", pa_cstrerror(errno)); #endif #ifdef OS_IS_WIN32 @@ -873,32 +872,33 @@ int pa_lock_lockfile(const char *fn) { struct stat st; if ((fd = open(fn, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)) < 0) { - pa_log("failed to create lock file '%s': %s", fn, - pa_cstrerror(errno)); + pa_log_warn("Failed to create lock file '%s': %s", fn, pa_cstrerror(errno)); goto fail; } if (pa_lock_fd(fd, 1) < 0) { - pa_log("failed to lock file '%s'.", fn); + pa_log_warn("Failed to lock file '%s'.", fn); goto fail; } if (fstat(fd, &st) < 0) { - pa_log("failed to fstat() file '%s'.", fn); + pa_log_warn("Failed to fstat() file '%s': %s", fn, pa_cstrerror(errno)); goto fail; } - /* Check wheter the file has been removed meanwhile. When yes, restart this loop, otherwise, we're done */ + /* Check wheter the file has been removed meanwhile. When yes, + * restart this loop, otherwise, we're done */ if (st.st_nlink >= 1) break; if (pa_lock_fd(fd, 0) < 0) { - pa_log("failed to unlock file '%s'.", fn); + pa_log_warn("Failed to unlock file '%s'.", fn); goto fail; } - if (close(fd) < 0) { - pa_log("failed to close file '%s'.", fn); + if (pa_close(fd) < 0) { + pa_log_warn("Failed to close file '%s': %s", fn, pa_cstrerror(errno)); + fd = -1; goto fail; } @@ -910,7 +910,7 @@ int pa_lock_lockfile(const char *fn) { fail: if (fd >= 0) - close(fd); + pa_close(fd); return -1; } @@ -922,19 +922,17 @@ int pa_unlock_lockfile(const char *fn, int fd) { pa_assert(fd >= 0); if (unlink(fn) < 0) { - pa_log_warn("WARNING: unable to remove lock file '%s': %s", - fn, pa_cstrerror(errno)); + pa_log_warn("Unable to remove lock file '%s': %s", fn, pa_cstrerror(errno)); r = -1; } if (pa_lock_fd(fd, 0) < 0) { - pa_log_warn("WARNING: failed to unlock file '%s'.", fn); + pa_log_warn("Failed to unlock file '%s'.", fn); r = -1; } - if (close(fd) < 0) { - pa_log_warn("WARNING: failed to close lock file '%s': %s", - fn, pa_cstrerror(errno)); + if (pa_close(fd) < 0) { + pa_log_warn("Failed to close '%s': %s", fn, pa_cstrerror(errno)); r = -1; } diff --git a/src/pulsecore/fdsem.c b/src/pulsecore/fdsem.c index 5a358e2b..710a74f5 100644 --- a/src/pulsecore/fdsem.c +++ b/src/pulsecore/fdsem.c @@ -67,8 +67,8 @@ pa_fdsem *pa_fdsem_new(void) { void pa_fdsem_free(pa_fdsem *f) { pa_assert(f); - close(f->fds[0]); - close(f->fds[1]); + pa_assert_se(pa_close(f->fds[0]) == 0); + pa_assert_se(pa_close(f->fds[1]) == 0); pa_xfree(f); } diff --git a/src/pulsecore/pid.c b/src/pulsecore/pid.c index 22ceae89..6bc9f06a 100644 --- a/src/pulsecore/pid.c +++ b/src/pulsecore/pid.c @@ -61,8 +61,7 @@ static pid_t read_pid(const char *fn, int fd) { pa_assert(fd >= 0); if ((r = pa_loop_read(fd, t, sizeof(t)-1, NULL)) < 0) { - pa_log_warn("WARNING: failed to read PID file '%s': %s", - fn, pa_cstrerror(errno)); + pa_log_warn("Failed to read PID file '%s': %s", fn, pa_cstrerror(errno)); return (pid_t) -1; } @@ -74,7 +73,7 @@ static pid_t read_pid(const char *fn, int fd) { *e = 0; if (pa_atou(t, &pid) < 0) { - pa_log_warn("WARNING: failed to parse PID file '%s'", fn); + pa_log_warn("Failed to parse PID file '%s'", fn); return (pid_t) -1; } @@ -91,8 +90,7 @@ static int open_pid_file(const char *fn, int mode) { if ((fd = open(fn, mode, S_IRUSR|S_IWUSR)) < 0) { if (mode != O_RDONLY || errno != ENOENT) - pa_log_warn("WARNING: failed to open PID file '%s': %s", - fn, pa_cstrerror(errno)); + pa_log_warn("WARNING: failed to open PID file '%s': %s", fn, pa_cstrerror(errno)); goto fail; } @@ -101,8 +99,7 @@ static int open_pid_file(const char *fn, int mode) { goto fail; if (fstat(fd, &st) < 0) { - pa_log_warn("WARNING: failed to fstat() PID file '%s': %s", - fn, pa_cstrerror(errno)); + pa_log_warn("Failed to fstat() PID file '%s': %s", fn, pa_cstrerror(errno)); goto fail; } @@ -113,9 +110,9 @@ static int open_pid_file(const char *fn, int mode) { if (pa_lock_fd(fd, 0) < 0) goto fail; - if (close(fd) < 0) { - pa_log_warn("WARNING: failed to close file '%s': %s", - fn, pa_cstrerror(errno)); + if (pa_close(fd) < 0) { + pa_log_warn("Failed to close file '%s': %s", fn, pa_cstrerror(errno)); + fd = -1; goto fail; } @@ -128,7 +125,7 @@ fail: if (fd >= 0) { pa_lock_fd(fd, 0); - close(fd); + pa_close(fd); } return -1; @@ -153,7 +150,7 @@ int pa_pid_file_create(void) { goto fail; if ((pid = read_pid(fn, fd)) == (pid_t) -1) - pa_log("corrupt PID file, overwriting."); + pa_log_warn("Corrupt PID file, overwriting."); else if (pid > 0) { #ifdef OS_IS_WIN32 if ((process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid)) != NULL) { @@ -161,17 +158,16 @@ int pa_pid_file_create(void) { #else if (kill(pid, 0) >= 0 || errno != ESRCH) { #endif - pa_log("daemon already running."); + pa_log("Daemon already running."); goto fail; } - pa_log("stale PID file, overwriting."); + pa_log_warn("Stale PID file, overwriting."); } /* Overwrite the current PID file */ if (lseek(fd, 0, SEEK_SET) == (off_t) -1 || ftruncate(fd, 0) < 0) { - pa_log("failed to truncate PID file '%s': %s", - fn, pa_cstrerror(errno)); + pa_log("Failed to truncate PID file '%s': %s", fn, pa_cstrerror(errno)); goto fail; } @@ -179,7 +175,7 @@ int pa_pid_file_create(void) { l = strlen(t); if (pa_loop_write(fd, t, l, NULL) != (ssize_t) l) { - pa_log("failed to write PID file."); + pa_log("Failed to write PID file."); goto fail; } @@ -188,7 +184,11 @@ int pa_pid_file_create(void) { fail: if (fd >= 0) { pa_lock_fd(fd, 0); - close(fd); + + if (pa_close(fd) < 0) { + pa_log("Failed to close PID file '%s': %s", fn, pa_cstrerror(errno)); + ret = -1; + } } return ret; @@ -213,13 +213,12 @@ int pa_pid_file_remove(void) { goto fail; if (pid != getpid()) { - pa_log("WARNING: PID file '%s' not mine!", fn); + pa_log("PID file '%s' not mine!", fn); goto fail; } if (ftruncate(fd, 0) < 0) { - pa_log_warn("WARNING: failed to truncate PID file '%s': %s", - fn, pa_cstrerror(errno)); + pa_log_warn("Failed to truncate PID file '%s': %s", fn, pa_cstrerror(errno)); goto fail; } @@ -230,8 +229,7 @@ int pa_pid_file_remove(void) { #endif if (unlink(fn) < 0) { - pa_log_warn("WARNING: failed to remove PID file '%s': %s", - fn, pa_cstrerror(errno)); + pa_log_warn("Failed to remove PID file '%s': %s", fn, pa_cstrerror(errno)); goto fail; } @@ -241,7 +239,11 @@ fail: if (fd >= 0) { pa_lock_fd(fd, 0); - pa_assert_se(close(fd) == 0); + + if (pa_close(fd) < 0) { + pa_log_warn("Failed to close PID file '%s': %s", fn, pa_cstrerror(errno)); + ret = -1; + } } return ret; @@ -283,7 +285,7 @@ fail: if (fd >= 0) { pa_lock_fd(fd, 0); - pa_assert_se(close(fd) == 0); + pa_close(fd); } return ret; diff --git a/src/pulsecore/random.c b/src/pulsecore/random.c index b0b4926c..87afebfa 100644 --- a/src/pulsecore/random.c +++ b/src/pulsecore/random.c @@ -69,7 +69,7 @@ static int random_proper(void *ret_data, size_t length) { if ((r = pa_loop_read(fd, ret_data, length, NULL)) < 0 || (size_t) r != length) ret = -1; - close(fd); + pa_close(fd); } else ret = -1; diff --git a/src/pulsecore/shm.c b/src/pulsecore/shm.c index f17d9460..02f6a7bd 100644 --- a/src/pulsecore/shm.c +++ b/src/pulsecore/shm.c @@ -154,7 +154,7 @@ int pa_shm_create_rw(pa_shm *m, size_t size, int shared, mode_t mode) { pa_atomic_store(&marker->pid, (int) getpid()); pa_atomic_store(&marker->marker, SHM_MARKER); - close(fd); + pa_assert_se(close(fd) == 0); m->do_unlink = 1; #else return -1; @@ -170,7 +170,7 @@ fail: #ifdef HAVE_SHM_OPEN if (fd >= 0) { shm_unlink(fn); - pa_assert_se(close(fd) >= 0); + pa_close(fd); } #endif @@ -297,13 +297,13 @@ int pa_shm_attach_ro(pa_shm *m, unsigned id) { m->do_unlink = 0; m->shared = 1; - pa_assert_se(close(fd) >= 0); + pa_assert_se(pa_close(fd) == 0); return 0; fail: if (fd >= 0) - pa_assert_se(close(fd) >= 0); + pa_close(fd); return -1; } diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index d5523a64..8a04b821 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "sound-file-stream.h" @@ -271,7 +272,7 @@ int pa_play_file( if (!(u->sndfile = sf_open_fd(fd, SFM_READ, &sfinfo, 1))) { pa_log("Failed to open file %s", fname); - close(fd); + pa_close(fd); goto fail; } diff --git a/src/pulsecore/sound-file.c b/src/pulsecore/sound-file.c index 8727ba15..b1c509f2 100644 --- a/src/pulsecore/sound-file.c +++ b/src/pulsecore/sound-file.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "sound-file.h" #include "core-scache.h" @@ -77,7 +78,7 @@ int pa_sound_file_load( if (!(sf = sf_open_fd(fd, SFM_READ, &sfinfo, 1))) { pa_log("Failed to open file %s", fname); - close(fd); + pa_close(fd); goto finish; } -- cgit From d9c4c9509d34ba89db06ff1252f3da18c6fd623b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 12 Sep 2007 00:17:51 +0000 Subject: add new pa_pipe_close() API to close two fds at the same time git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1812 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/cpulimit.c | 6 +----- src/daemon/main.c | 10 +--------- src/pulse/context.c | 5 +---- src/pulse/mainloop-signal.c | 4 +--- src/pulse/mainloop.c | 5 +---- src/pulsecore/core-util.c | 13 +++++++++++++ src/pulsecore/core-util.h | 2 ++ src/pulsecore/fdsem.c | 3 +-- 8 files changed, 21 insertions(+), 27 deletions(-) diff --git a/src/daemon/cpulimit.c b/src/daemon/cpulimit.c index 4f0adc06..0fe11ea6 100644 --- a/src/daemon/cpulimit.c +++ b/src/daemon/cpulimit.c @@ -222,11 +222,7 @@ void pa_cpu_limit_done(void) { api = NULL; } - if (the_pipe[0] >= 0) - pa_assert_se(pa_close(the_pipe[0]) == 0); - if (the_pipe[1] >= 0) - pa_assert_se(pa_close(the_pipe[1]) == 0); - the_pipe[0] = the_pipe[1] = -1; + pa_close_pipe(the_pipe); if (installed) { pa_assert_se(sigaction(SIGXCPU, &sigaction_prev, NULL) >= 0); diff --git a/src/daemon/main.c b/src/daemon/main.c index 0bbddffa..93d4eb6b 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -158,14 +158,6 @@ static void signal_callback(pa_mainloop_api*m, PA_GCC_UNUSED pa_signal_event *e, } } -static void close_pipe(int p[2]) { - if (p[0] != -1) - pa_assert_se(pa_close(p[0]) == 0); - if (p[1] != -1) - pa_assert_se(pa_close(p[1]) == 0); - p[0] = p[1] = -1; -} - #define set_env(key, value) putenv(pa_sprintf_malloc("%s=%s", (key), (value))) #if defined(HAVE_PWD_H) && defined(HAVE_GRP_H) @@ -745,7 +737,7 @@ finish: if (valid_pid_file) pa_pid_file_remove(); - close_pipe(daemon_pipe); + pa_close_pipe(daemon_pipe); #ifdef OS_IS_WIN32 WSACleanup(); diff --git a/src/pulse/context.c b/src/pulse/context.c index 1ed250f9..a39646d3 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -585,10 +585,7 @@ static int context_connect_spawn(pa_context *c) { return 0; fail: - if (fds[0] != -1) - pa_assert_se(pa_close(fds[0]) == 0); - if (fds[1] != -1) - pa_assert_se(pa_close(fds[1]) == 0); + pa_close_pipe(fds); unlock_autospawn_lock_file(c); diff --git a/src/pulse/mainloop-signal.c b/src/pulse/mainloop-signal.c index d2d42d99..b6414c4e 100644 --- a/src/pulse/mainloop-signal.c +++ b/src/pulse/mainloop-signal.c @@ -147,9 +147,7 @@ void pa_signal_done(void) { api->io_free(io_event); io_event = NULL; - pa_assert_se(close(signal_pipe[0]) == 0); - pa_assert_se(close(signal_pipe[1]) == 0); - signal_pipe[0] = signal_pipe[1] = -1; + pa_close_pipe(signal_pipe); api = NULL; } diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index fc373d97..641eded4 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -605,10 +605,7 @@ void pa_mainloop_free(pa_mainloop* m) { pa_xfree(m->pollfds); - if (m->wakeup_pipe[0] >= 0) - pa_assert_se(pa_close(m->wakeup_pipe[0]) == 0); - if (m->wakeup_pipe[1] >= 0) - pa_assert_se(pa_close(m->wakeup_pipe[1]) == 0); + pa_close_pipe(m->wakeup_pipe); pa_xfree(m); } diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 62a63761..5becdef0 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -1323,3 +1323,16 @@ void *pa_will_need(const void *p, size_t l) { return (void*) p; } + +void pa_close_pipe(int fds[2]) { + pa_assert(fds); + + if (fds[0] >= 0) + pa_assert_se(pa_close(fds[0]) == 0); + + if (fds[1] >= 0) + pa_assert_se(pa_close(fds[1]) == 0); + + fds[0] = fds[1] = -1; +} + diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index fcafe63d..efd19f45 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -120,4 +120,6 @@ static inline unsigned pa_make_power_of_two(unsigned n) { return n + 1; } +void pa_close_pipe(int fds[2]); + #endif diff --git a/src/pulsecore/fdsem.c b/src/pulsecore/fdsem.c index 710a74f5..68207a76 100644 --- a/src/pulsecore/fdsem.c +++ b/src/pulsecore/fdsem.c @@ -67,8 +67,7 @@ pa_fdsem *pa_fdsem_new(void) { void pa_fdsem_free(pa_fdsem *f) { pa_assert(f); - pa_assert_se(pa_close(f->fds[0]) == 0); - pa_assert_se(pa_close(f->fds[1]) == 0); + pa_close_pipe(f->fds); pa_xfree(f); } -- cgit From 41378658153585c82eebca83d280b25f684e90c4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 12 Sep 2007 20:12:13 +0000 Subject: change pa_modargs_get_channel_map() to take an extra argument for specifying the name of the modargs attribute to parse git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1813 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-combine.c | 4 ++-- src/pulsecore/modargs.c | 6 +++--- src/pulsecore/modargs.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 390b6e5c..dcdc954e 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -233,7 +233,7 @@ static void thread_func(void *userdata) { pa_rtclock_get(&u->timestamp); - /* This is only run when were are in NULL mode, to make sure that + /* This is only run when we are in NULL mode, to make sure that * playback doesn't stop. In all other cases we hook our stuff * into the master sink. */ @@ -1029,7 +1029,7 @@ int pa__init(pa_module*m) { else pa_channel_map_init_auto(&map, ss.channels, PA_CHANNEL_MAP_DEFAULT); - if ((pa_modargs_get_channel_map(ma, &map) < 0)) { + if ((pa_modargs_get_channel_map(ma, NULL, &map) < 0)) { pa_log("Invalid channel map."); goto fail; } diff --git a/src/pulsecore/modargs.c b/src/pulsecore/modargs.c index 41e80084..7ce3dd08 100644 --- a/src/pulsecore/modargs.c +++ b/src/pulsecore/modargs.c @@ -275,7 +275,7 @@ int pa_modargs_get_sample_spec(pa_modargs *ma, pa_sample_spec *rss) { return 0; } -int pa_modargs_get_channel_map(pa_modargs *ma, pa_channel_map *rmap) { +int pa_modargs_get_channel_map(pa_modargs *ma, const char *name, pa_channel_map *rmap) { pa_channel_map map; const char *cm; @@ -284,7 +284,7 @@ int pa_modargs_get_channel_map(pa_modargs *ma, pa_channel_map *rmap) { map = *rmap; - if ((cm = pa_modargs_get_value(ma, "channel_map", NULL))) + if ((cm = pa_modargs_get_value(ma, name ? name : "channel_map", NULL))) if (!pa_channel_map_parse(&map, cm)) return -1; @@ -311,7 +311,7 @@ int pa_modargs_get_sample_spec_and_channel_map(pa_modargs *ma, pa_sample_spec *r if (!pa_channel_map_init_auto(&map, ss.channels, def)) map.channels = 0; - if (pa_modargs_get_channel_map(ma, &map) < 0) + if (pa_modargs_get_channel_map(ma, NULL, &map) < 0) return -1; if (map.channels != ss.channels) diff --git a/src/pulsecore/modargs.h b/src/pulsecore/modargs.h index 77262e1e..aa175885 100644 --- a/src/pulsecore/modargs.h +++ b/src/pulsecore/modargs.h @@ -49,8 +49,8 @@ int pa_modargs_get_value_boolean(pa_modargs *ma, const char *key, int *value); /* Return sample spec data from the three arguments "rate", "format" and "channels" */ int pa_modargs_get_sample_spec(pa_modargs *ma, pa_sample_spec *ss); -/* Return channel map data from the argument "channel_map" */ -int pa_modargs_get_channel_map(pa_modargs *ma, pa_channel_map *map); +/* Return channel map data from the argument "channel_map" if name is NULL, otherwise read from the specified argument */ +int pa_modargs_get_channel_map(pa_modargs *ma, const char *name, pa_channel_map *map); /* Combination of pa_modargs_get_sample_spec() and pa_modargs_get_channel_map(). Not always suitable, since this routine -- cgit From 03f311a464fcf7cb295b996a4cda48e90941bef0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 12 Sep 2007 22:50:44 +0000 Subject: reindent, and s/assert/pa_assert/g git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1814 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/llist.h | 123 +++++++++++++++++++++++++++----------------------- 1 file changed, 66 insertions(+), 57 deletions(-) diff --git a/src/pulsecore/llist.h b/src/pulsecore/llist.h index 8fc8e22b..e62f15b4 100644 --- a/src/pulsecore/llist.h +++ b/src/pulsecore/llist.h @@ -24,77 +24,86 @@ USA. ***/ -#include +#include /* Some macros for maintaining doubly linked lists */ /* The head of the linked list. Use this in the structure that shall * contain the head of the linked list */ -#define PA_LLIST_HEAD(t,name) t *name +#define PA_LLIST_HEAD(t,name) \ + t *name /* The pointers in the linked list's items. Use this in the item structure */ -#define PA_LLIST_FIELDS(t) t *next, *prev +#define PA_LLIST_FIELDS(t) \ + t *next, *prev /* Initialize the list's head */ -#define PA_LLIST_HEAD_INIT(t,item) do { (item) = (t*) NULL; } while(0) +#define PA_LLIST_HEAD_INIT(t,item) \ + do { \ + (item) = (t*) NULL; } \ + while(0) /* Initialize a list item */ -#define PA_LLIST_INIT(t,item) do { \ - t *_item = (item); \ - assert(_item); \ - _item->prev = _item->next = NULL; \ - } while(0) +#define PA_LLIST_INIT(t,item) \ + do { \ + t *_item = (item); \ + pa_assert(_item); \ + _item->prev = _item->next = NULL; \ + } while(0) /* Prepend an item to the list */ -#define PA_LLIST_PREPEND(t,head,item) do { \ - t **_head = &(head), *_item = (item); \ - assert(_item); \ - if ((_item->next = *_head)) \ - _item->next->prev = _item; \ - _item->prev = NULL; \ - *_head = _item; \ - } while (0) +#define PA_LLIST_PREPEND(t,head,item) \ + do { \ + t **_head = &(head), *_item = (item); \ + pa_assert(_item); \ + if ((_item->next = *_head)) \ + _item->next->prev = _item; \ + _item->prev = NULL; \ + *_head = _item; \ + } while (0) /* Remove an item from the list */ -#define PA_LLIST_REMOVE(t,head,item) do { \ - t **_head = &(head), *_item = (item); \ - assert(_item); \ - if (_item->next) \ - _item->next->prev = _item->prev; \ - if (_item->prev) \ - _item->prev->next = _item->next; \ - else {\ - assert(*_head == _item); \ - *_head = _item->next; \ - } \ - _item->next = _item->prev = NULL; \ - } while(0) - -#define PA_LLIST_FIND_HEAD(t,item,head) \ -do { \ - t **_head = (head), *_item = (item); \ - *_head = _item; \ - assert(_head); \ - while ((*_head)->prev) \ - *_head = (*_head)->prev; \ -} while (0) - -#define PA_LLIST_INSERT_AFTER(t,head,a,b) \ -do { \ - t **_head = &(head), *_a = (a), *_b = (b); \ - assert(_b); \ - if (!_a) { \ - if ((_b->next = *_head)) \ - _b->next->prev = _b; \ - _b->prev = NULL; \ - *_head = _b; \ - } else { \ - if ((_b->next = _a->next)) \ - _b->next->prev = _b; \ - _b->prev = _a; \ - _a->next = _b; \ - } \ -} while (0) - +#define PA_LLIST_REMOVE(t,head,item) \ + do { \ + t **_head = &(head), *_item = (item); \ + pa_assert(_item); \ + if (_item->next) \ + _item->next->prev = _item->prev; \ + if (_item->prev) \ + _item->prev->next = _item->next; \ + else { \ + pa_assert(*_head == _item); \ + *_head = _item->next; \ + } \ + _item->next = _item->prev = NULL; \ + } while(0) + +/* Find the head of the list */ +#define PA_LLIST_FIND_HEAD(t,item,head) \ + do { \ + t **_head = (head), *_item = (item); \ + *_head = _item; \ + pa_assert(_head); \ + while ((*_head)->prev) \ + *_head = (*_head)->prev; \ + } while (0) + +/* Insert an item after another one (a = where, b = what) */ +#define PA_LLIST_INSERT_AFTER(t,head,a,b) \ + do { \ + t **_head = &(head), *_a = (a), *_b = (b); \ + pa_assert(_b); \ + if (!_a) { \ + if ((_b->next = *_head)) \ + _b->next->prev = _b; \ + _b->prev = NULL; \ + *_head = _b; \ + } else { \ + if ((_b->next = _a->next)) \ + _b->next->prev = _b; \ + _b->prev = _a; \ + _a->next = _b; \ + } \ + } while (0) #endif -- cgit From cf3e9da9dd8c2d69ffdbfcaafa354e9e85a9f871 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 12 Sep 2007 22:54:22 +0000 Subject: add missing config.h inclusion git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1815 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/tests/hook-list-test.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tests/hook-list-test.c b/src/tests/hook-list-test.c index 6879eae5..8628f521 100644 --- a/src/tests/hook-list-test.c +++ b/src/tests/hook-list-test.c @@ -1,5 +1,9 @@ /* $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include -- cgit From ef83a195251271f59feda68dba20b53d1634402f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 12 Sep 2007 22:57:29 +0000 Subject: extend rtpoll API to allow registration of arbitray functions to be executed in the event loop. Add priority system for specifying the order of these functions. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1816 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 4 +- src/modules/module-alsa-source.c | 4 +- src/modules/module-combine.c | 4 +- src/modules/module-null-sink.c | 2 +- src/modules/module-oss.c | 6 +- src/modules/module-pipe-sink.c | 4 +- src/modules/module-pipe-source.c | 4 +- src/pulsecore/rtpoll.c | 132 +++++++++++++++++++++++++++------------ src/pulsecore/rtpoll.h | 22 ++++++- src/pulsecore/sink.c | 2 +- src/tests/rtpoll-test.c | 16 ++++- 11 files changed, 139 insertions(+), 61 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index bb7392d8..26c24c87 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -322,7 +322,7 @@ static int build_pollfd(struct userdata *u) { if (u->alsa_rtpoll_item) pa_rtpoll_item_free(u->alsa_rtpoll_item); - u->alsa_rtpoll_item = pa_rtpoll_item_new(u->rtpoll, n); + u->alsa_rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, n); pollfd = pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, NULL); if ((err = snd_pcm_poll_descriptors(u->pcm_handle, pollfd, n)) < 0) { @@ -745,7 +745,7 @@ int pa__init(pa_module*m) { pa_thread_mq_init(&u->thread_mq, m->core->mainloop); u->rtpoll = pa_rtpoll_new(); u->alsa_rtpoll_item = NULL; - pa_rtpoll_item_new_asyncmsgq(u->rtpoll, u->thread_mq.inq); + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); snd_config_update_free_global(); if ((err = snd_pcm_open(&u->pcm_handle, dev = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index e4a6ed0e..9e03729a 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -310,7 +310,7 @@ static int build_pollfd(struct userdata *u) { if (u->alsa_rtpoll_item) pa_rtpoll_item_free(u->alsa_rtpoll_item); - u->alsa_rtpoll_item = pa_rtpoll_item_new(u->rtpoll, n); + u->alsa_rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, n); pollfd = pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, NULL); if ((err = snd_pcm_poll_descriptors(u->pcm_handle, pollfd, n)) < 0) { @@ -726,7 +726,7 @@ int pa__init(pa_module*m) { pa_thread_mq_init(&u->thread_mq, m->core->mainloop); u->rtpoll = pa_rtpoll_new(); u->alsa_rtpoll_item = NULL; - pa_rtpoll_item_new_asyncmsgq(u->rtpoll, u->thread_mq.inq); + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); snd_config_update_free_global(); if ((err = snd_pcm_open(&u->pcm_handle, dev = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) { diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index dcdc954e..11707b19 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -401,7 +401,7 @@ static void sink_input_attach_cb(pa_sink_input *i) { pa_assert(o); pa_assert(!o->rtpoll_item); - o->rtpoll_item = pa_rtpoll_item_new_asyncmsgq(i->sink->rtpoll, o->asyncmsgq); + o->rtpoll_item = pa_rtpoll_item_new_asyncmsgq(i->sink->rtpoll, PA_RTPOLL_NORMAL, o->asyncmsgq); } /* Called from I/O thread context */ @@ -721,7 +721,7 @@ static int update_master(struct userdata *u, struct output *o) { pa_assert(!u->rtpoll); u->rtpoll = pa_rtpoll_new(); - pa_rtpoll_item_new_asyncmsgq(u->rtpoll, u->thread_mq.inq); + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); pa_sink_set_rtpoll(u->sink, u->rtpoll); diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index 2fe541fc..ba2ae6f0 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -199,7 +199,7 @@ int pa__init(pa_module*m) { m->userdata = u; pa_thread_mq_init(&u->thread_mq, m->core->mainloop); u->rtpoll = pa_rtpoll_new(); - pa_rtpoll_item_new_asyncmsgq(u->rtpoll, u->thread_mq.inq); + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); if (!(u->sink = pa_sink_new(m->core, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map))) { pa_log("Failed to create sink."); diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index ffecd394..1fd8d2e5 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -577,7 +577,7 @@ static int unsuspend(struct userdata *u) { pa_assert(!u->rtpoll_item); - u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, 1); + u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1); pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); pollfd->fd = u->fd; pollfd->events = 0; @@ -1167,8 +1167,8 @@ int pa__init(pa_module*m) { u->use_mmap = use_mmap; pa_thread_mq_init(&u->thread_mq, m->core->mainloop); u->rtpoll = pa_rtpoll_new(); - pa_rtpoll_item_new_asyncmsgq(u->rtpoll, u->thread_mq.inq); - u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, 1); + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); + u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1); pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); pollfd->fd = fd; pollfd->events = 0; diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index 61454261..9594a685 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -236,7 +236,7 @@ int pa__init(pa_module*m) { pa_memchunk_reset(&u->memchunk); pa_thread_mq_init(&u->thread_mq, m->core->mainloop); u->rtpoll = pa_rtpoll_new(); - pa_rtpoll_item_new_asyncmsgq(u->rtpoll, u->thread_mq.inq); + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); u->filename = pa_xstrdup(pa_modargs_get_value(ma, "file", DEFAULT_FILE_NAME)); @@ -274,7 +274,7 @@ int pa__init(pa_module*m) { pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Unix FIFO sink '%s'", u->filename)); pa_xfree(t); - u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, 1); + u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1); pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); pollfd->fd = u->fd; pollfd->events = pollfd->revents = 0; diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index 68c89a0d..1b42fcfa 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -215,7 +215,7 @@ int pa__init(pa_module*m) { pa_memchunk_reset(&u->memchunk); pa_thread_mq_init(&u->thread_mq, m->core->mainloop); u->rtpoll = pa_rtpoll_new(); - pa_rtpoll_item_new_asyncmsgq(u->rtpoll, u->thread_mq.inq); + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); u->filename = pa_xstrdup(pa_modargs_get_value(ma, "file", DEFAULT_FILE_NAME)); @@ -252,7 +252,7 @@ int pa__init(pa_module*m) { pa_source_set_description(u->source, t = pa_sprintf_malloc("Unix FIFO source '%s'", u->filename)); pa_xfree(t); - u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, 1); + u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1); pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); pollfd->fd = u->fd; pollfd->events = pollfd->revents = 0; diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c index be1c83c0..659e5381 100644 --- a/src/pulsecore/rtpoll.c +++ b/src/pulsecore/rtpoll.c @@ -45,7 +45,6 @@ #include "rtpoll.h" struct pa_rtpoll { - struct pollfd *pollfd, *pollfd2; unsigned n_pollfd_alloc, n_pollfd_used; @@ -72,6 +71,8 @@ struct pa_rtpoll_item { pa_rtpoll *rtpoll; int dead; + pa_rtpoll_priority_t priority; + struct pollfd *pollfd; unsigned n_pollfd; @@ -245,7 +246,7 @@ void pa_rtpoll_free(pa_rtpoll *p) { while (p->items) rtpoll_item_destroy(p->items); - + pa_xfree(p->pollfd); pa_xfree(p->pollfd2); @@ -257,11 +258,37 @@ void pa_rtpoll_free(pa_rtpoll *p) { pa_xfree(p); } +static void reset_revents(pa_rtpoll_item *i) { + struct pollfd *f; + unsigned n; + + pa_assert(i); + + if (!(f = pa_rtpoll_item_get_pollfd(i, &n))) + return; + + for (; n > 0; n--) + f[n-1].revents = 0; +} + +static void reset_all_revents(pa_rtpoll *p) { + pa_rtpoll_item *i; + + pa_assert(p); + + for (i = p->items; i; i = i->next) { + + if (i->dead) + continue; + + reset_revents(i); + } +} + int pa_rtpoll_run(pa_rtpoll *p, int wait) { pa_rtpoll_item *i; int r = 0; - int no_events = 0; - int saved_errno; + int saved_errno = 0; struct timespec timeout; pa_assert(p); @@ -270,20 +297,23 @@ int pa_rtpoll_run(pa_rtpoll *p, int wait) { p->running = 1; - for (i = p->items; i; i = i->next) { - + for (i = p->items; i && i->priority < PA_RTPOLL_NEVER; i = i->next) { + int k; + if (i->dead) continue; if (!i->before_cb) continue; - if (i->before_cb(i) < 0) { + if ((k = i->before_cb(i)) != 0) { /* Hmm, this one doesn't let us enter the poll, so rewind everything */ + reset_all_revents(p); + for (i = i->prev; i; i = i->prev) { - + if (i->dead) continue; @@ -292,6 +322,9 @@ int pa_rtpoll_run(pa_rtpoll *p, int wait) { i->after_cb(i); } + + if (k < 0) + r = k; goto finish; } @@ -329,7 +362,13 @@ int pa_rtpoll_run(pa_rtpoll *p, int wait) { r = poll(p->pollfd, p->n_pollfd_used, p->timer_enabled > 0 ? (timeout.tv_sec*1000) + (timeout.tv_nsec / 1000000) : -1); #endif - saved_errno = errno; + if (r < 0) + reset_all_revents(p); + + if (r < 0 && (errno == EAGAIN || errno == EINTR)) + r = 0; + + saved_errno = r < 0 ? errno : 0; if (p->timer_enabled) { if (p->period > 0) { @@ -340,18 +379,13 @@ int pa_rtpoll_run(pa_rtpoll *p, int wait) { /* Guarantee that the next timeout will happen in the future */ if (pa_timespec_cmp(&p->next_elapse, &now) < 0) - pa_timespec_add(&p->next_elapse, (pa_timespec_diff(&now, &p->next_elapse) / p->period + 1) * p->period); + pa_timespec_add(&p->next_elapse, (pa_timespec_diff(&now, &p->next_elapse) / p->period + 1) * p->period); } else p->timer_enabled = 0; } - - if (r == 0 || (r < 0 && (errno == EAGAIN || errno == EINTR))) { - r = 0; - no_events = 1; - } - for (i = p->items; i; i = i->next) { + for (i = p->items; i && i->priority < PA_RTPOLL_NEVER; i = i->next) { if (i->dead) continue; @@ -359,13 +393,6 @@ int pa_rtpoll_run(pa_rtpoll *p, int wait) { if (!i->after_cb) continue; - if (no_events) { - unsigned j; - - for (j = 0; j < i->n_pollfd; j++) - i->pollfd[j].revents = 0; - } - i->after_cb(i); } @@ -386,7 +413,7 @@ finish: } } - if (r < 0) + if (saved_errno != 0) errno = saved_errno; return r; @@ -484,11 +511,10 @@ void pa_rtpoll_set_timer_disabled(pa_rtpoll *p) { update_timer(p); } -pa_rtpoll_item *pa_rtpoll_item_new(pa_rtpoll *p, unsigned n_fds) { - pa_rtpoll_item *i; +pa_rtpoll_item *pa_rtpoll_item_new(pa_rtpoll *p, pa_rtpoll_priority_t prio, unsigned n_fds) { + pa_rtpoll_item *i, *j, *l = NULL; pa_assert(p); - pa_assert(n_fds > 0); if (!(i = pa_flist_pop(PA_STATIC_FLIST_GET(items)))) i = pa_xnew(pa_rtpoll_item, 1); @@ -497,15 +523,25 @@ pa_rtpoll_item *pa_rtpoll_item_new(pa_rtpoll *p, unsigned n_fds) { i->dead = 0; i->n_pollfd = n_fds; i->pollfd = NULL; + i->priority = prio; i->userdata = NULL; i->before_cb = NULL; i->after_cb = NULL; - - PA_LLIST_PREPEND(pa_rtpoll_item, p->items, i); - p->rebuild_needed = 1; - p->n_pollfd_used += n_fds; + for (j = p->items; j; j = j->next) { + if (prio <= j->priority) + break; + + l = j; + } + + PA_LLIST_INSERT_AFTER(pa_rtpoll_item, p->items, j ? j->prev : l, i); + + if (n_fds > 0) { + p->rebuild_needed = 1; + p->n_pollfd_used += n_fds; + } return i; } @@ -525,8 +561,9 @@ void pa_rtpoll_item_free(pa_rtpoll_item *i) { struct pollfd *pa_rtpoll_item_get_pollfd(pa_rtpoll_item *i, unsigned *n_fds) { pa_assert(i); - if (i->rtpoll->rebuild_needed) - rtpoll_rebuild(i->rtpoll); + if (i->n_pollfd > 0) + if (i->rtpoll->rebuild_needed) + rtpoll_rebuild(i->rtpoll); if (n_fds) *n_fds = i->n_pollfd; @@ -536,12 +573,14 @@ struct pollfd *pa_rtpoll_item_get_pollfd(pa_rtpoll_item *i, unsigned *n_fds) { void pa_rtpoll_item_set_before_callback(pa_rtpoll_item *i, int (*before_cb)(pa_rtpoll_item *i)) { pa_assert(i); - + pa_assert(i->priority < PA_RTPOLL_NEVER); + i->before_cb = before_cb; } void pa_rtpoll_item_set_after_callback(pa_rtpoll_item *i, void (*after_cb)(pa_rtpoll_item *i)) { pa_assert(i); + pa_assert(i->priority < PA_RTPOLL_NEVER); i->after_cb = after_cb; } @@ -559,22 +598,28 @@ void* pa_rtpoll_item_get_userdata(pa_rtpoll_item *i) { } static int fdsem_before(pa_rtpoll_item *i) { - return pa_fdsem_before_poll(i->userdata); + + if (pa_fdsem_before_poll(i->userdata) < 0) + return 1; /* 1 means immediate restart of the loop */ + + return 0; } static void fdsem_after(pa_rtpoll_item *i) { + pa_assert(i); + pa_assert((i->pollfd[0].revents & ~POLLIN) == 0); pa_fdsem_after_poll(i->userdata); } -pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_fdsem *f) { +pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_fdsem *f) { pa_rtpoll_item *i; struct pollfd *pollfd; pa_assert(p); pa_assert(f); - i = pa_rtpoll_item_new(p, 1); + i = pa_rtpoll_item_new(p, prio, 1); pollfd = pa_rtpoll_item_get_pollfd(i, NULL); @@ -589,22 +634,29 @@ pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_fdsem *f) { } static int asyncmsgq_before(pa_rtpoll_item *i) { - return pa_asyncmsgq_before_poll(i->userdata); + pa_assert(i); + + if (pa_asyncmsgq_before_poll(i->userdata) < 0) + return 1; /* 1 means immediate restart of the loop */ + + return 0; } static void asyncmsgq_after(pa_rtpoll_item *i) { + pa_assert(i); + pa_assert((i->pollfd[0].revents & ~POLLIN) == 0); pa_asyncmsgq_after_poll(i->userdata); } -pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq(pa_rtpoll *p, pa_asyncmsgq *q) { +pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_asyncmsgq *q) { pa_rtpoll_item *i; struct pollfd *pollfd; pa_assert(p); pa_assert(q); - i = pa_rtpoll_item_new(p, 1); + i = pa_rtpoll_item_new(p, prio, 1); pollfd = pa_rtpoll_item_get_pollfd(i, NULL); pollfd->fd = pa_asyncmsgq_get_fd(q); diff --git a/src/pulsecore/rtpoll.h b/src/pulsecore/rtpoll.h index f393f918..bef9eedb 100644 --- a/src/pulsecore/rtpoll.h +++ b/src/pulsecore/rtpoll.h @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -53,9 +54,17 @@ typedef struct pa_rtpoll pa_rtpoll; typedef struct pa_rtpoll_item pa_rtpoll_item; +typedef enum pa_rtpoll_priority { + PA_RTPOLL_EARLY = -100, /* For veeery important stuff, like handling control messages */ + PA_RTPOLL_NORMAL = 0, /* For normal stuff */ + PA_RTPOLL_LATE = +100, /* For housekeeping */ + PA_RTPOLL_NEVER = INT_MAX, /* For stuff that doesn't register any callbacks, but only fds to listen on */ +} pa_rtpoll_priority_t; + pa_rtpoll *pa_rtpoll_new(void); void pa_rtpoll_free(pa_rtpoll *p); +/* Install the rtpoll in the current thread */ void pa_rtpoll_install(pa_rtpoll *p); /* Sleep on the rtpoll until the time event, or any of the fd events @@ -68,7 +77,8 @@ void pa_rtpoll_set_timer_periodic(pa_rtpoll *p, pa_usec_t usec); void pa_rtpoll_set_timer_relative(pa_rtpoll *p, pa_usec_t usec); void pa_rtpoll_set_timer_disabled(pa_rtpoll *p); -pa_rtpoll_item *pa_rtpoll_item_new(pa_rtpoll *p, unsigned n_fds); +/* A new fd wakeup item for pa_rtpoll */ +pa_rtpoll_item *pa_rtpoll_item_new(pa_rtpoll *p, pa_rtpoll_priority_t prio, unsigned n_fds); void pa_rtpoll_item_free(pa_rtpoll_item *i); /* Please note that this pointer might change on every call and when @@ -76,12 +86,18 @@ void pa_rtpoll_item_free(pa_rtpoll_item *i); * using the pointer and don't save the result anywhere */ struct pollfd *pa_rtpoll_item_get_pollfd(pa_rtpoll_item *i, unsigned *n_fds); +/* Set the callback that shall be called immediately before entering + * the sleeping poll: If the callback returns a negative value, the + * poll is skipped. */ void pa_rtpoll_item_set_before_callback(pa_rtpoll_item *i, int (*before_cb)(pa_rtpoll_item *i)); + +/* Set the callback that shall be called immediately after having + * entered the sleeping poll */ void pa_rtpoll_item_set_after_callback(pa_rtpoll_item *i, void (*after_cb)(pa_rtpoll_item *i)); void pa_rtpoll_item_set_userdata(pa_rtpoll_item *i, void *userdata); void* pa_rtpoll_item_get_userdata(pa_rtpoll_item *i); -pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_fdsem *s); -pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq(pa_rtpoll *p, pa_asyncmsgq *q); +pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_fdsem *s); +pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_asyncmsgq *q); #endif diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index aac4a2f6..b009bc77 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -126,7 +126,7 @@ pa_sink* pa_sink_new( n = pa_sprintf_malloc("%s.monitor", name); if (!(s->monitor_source = pa_source_new(core, driver, n, 0, spec, map))) - pa_log_warn("failed to create monitor source."); + pa_log_warn("Failed to create monitor source."); else { char *d; s->monitor_source->monitor_of = s; diff --git a/src/tests/rtpoll-test.c b/src/tests/rtpoll-test.c index 20913e7f..bad8e7d7 100644 --- a/src/tests/rtpoll-test.c +++ b/src/tests/rtpoll-test.c @@ -38,16 +38,21 @@ static void after(pa_rtpoll_item *i) { pa_log("after"); } +static int worker(pa_rtpoll_item *w) { + pa_log("worker"); + return 0; +} + int main(int argc, char *argv[]) { pa_rtpoll *p; - pa_rtpoll_item *i; + pa_rtpoll_item *i, *w; struct pollfd *pollfd; pa_rtsig_configure(SIGRTMIN+10, SIGRTMAX); p = pa_rtpoll_new(); - i = pa_rtpoll_item_new(p, 1); + i = pa_rtpoll_item_new(p, PA_RTPOLL_EARLY, 1); pa_rtpoll_item_set_before_callback(i, before); pa_rtpoll_item_set_after_callback(i, after); @@ -55,6 +60,9 @@ int main(int argc, char *argv[]) { pollfd->fd = 0; pollfd->events = POLLIN; + w = pa_rtpoll_item_new(p, PA_RTPOLL_NORMAL, 0); + pa_rtpoll_item_set_before_callback(w, worker); + pa_rtpoll_install(p); pa_rtpoll_set_timer_periodic(p, 10000000); /* 10 s */ @@ -62,7 +70,7 @@ int main(int argc, char *argv[]) { pa_rtpoll_item_free(i); - i = pa_rtpoll_item_new(p, 1); + i = pa_rtpoll_item_new(p, PA_RTPOLL_EARLY, 1); pa_rtpoll_item_set_before_callback(i, before); pa_rtpoll_item_set_after_callback(i, after); @@ -73,6 +81,8 @@ int main(int argc, char *argv[]) { pa_rtpoll_run(p, 1); pa_rtpoll_item_free(i); + + pa_rtpoll_item_free(w); pa_rtpoll_free(p); -- cgit From 9be0d70ea7fa2cc63e4995b57706a41714033cb9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 14 Sep 2007 17:12:25 +0000 Subject: make newer gcc shut up git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1817 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/object.c | 2 +- src/pulsecore/object.h | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pulsecore/object.c b/src/pulsecore/object.c index 23a45754..6680d078 100644 --- a/src/pulsecore/object.c +++ b/src/pulsecore/object.c @@ -68,5 +68,5 @@ void pa_object_unref(pa_object *o) { int pa_object_check_type(const char *type_name) { pa_assert(type_name); - return type_name == "pa_object" || strcmp(type_name, "pa_object") == 0; + return strcmp(type_name, "pa_object") == 0; } diff --git a/src/pulsecore/object.h b/src/pulsecore/object.h index 9c62f74a..562fd113 100644 --- a/src/pulsecore/object.h +++ b/src/pulsecore/object.h @@ -96,8 +96,7 @@ static inline pa_object* pa_object_cast(void *o) { #define PA_DEFINE_CHECK_TYPE(c, parent) \ int c##_check_type(const char *type) { \ pa_assert(type); \ - if (type == #c || \ - strcmp(type, #c) == 0) \ + if (strcmp(type, #c) == 0) \ return 1; \ return parent##_check_type(type); \ } \ -- cgit From 87753092340fc099dee86f94633da97104fbf5dc Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 14 Sep 2007 21:01:00 +0000 Subject: fix two typos in reference count handling git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1818 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/socket-client.c | 2 +- src/pulsecore/socket-server.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/socket-client.c b/src/pulsecore/socket-client.c index 0922a947..360a0b48 100644 --- a/src/pulsecore/socket-client.c +++ b/src/pulsecore/socket-client.c @@ -349,7 +349,7 @@ void pa_socket_client_unref(pa_socket_client *c) { pa_assert(c); pa_assert(PA_REFCNT_VALUE(c) >= 1); - if (PA_REFCNT_DEC(c) < 0) + if (PA_REFCNT_DEC(c) <= 0) socket_client_free(c); } diff --git a/src/pulsecore/socket-server.c b/src/pulsecore/socket-server.c index 21c51151..502005d2 100644 --- a/src/pulsecore/socket-server.c +++ b/src/pulsecore/socket-server.c @@ -422,7 +422,7 @@ void pa_socket_server_unref(pa_socket_server *s) { pa_assert(s); pa_assert(PA_REFCNT_VALUE(s) >= 1); - if (PA_REFCNT_DEC(s)) + if (PA_REFCNT_DEC(s) <= 0) socket_server_free(s); } -- cgit From 04ed0f9536f8b211d68d7df381f0fb4dd04dc0ff Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 14 Sep 2007 21:02:18 +0000 Subject: call dbus_shutdown() before exiting, to make valgrind output more useful git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1819 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 2 +- src/Makefile.am | 5 ++--- src/daemon/main.c | 8 ++++++++ src/modules/dbus-util.c | 4 ++-- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 7c8f3888..cb68f57b 100644 --- a/configure.ac +++ b/configure.ac @@ -769,7 +769,7 @@ if test "x${dbus}" != xno ; then LIBS="$LIBS $DBUS_LIBS" AC_CHECK_FUNCS(dbus_watch_get_unix_fd) LIBS="$saved_LIBS" - + AC_DEFINE([HAVE_DBUS], 1, [Have D-Bus.]) ], [ HAVE_DBUS=0 diff --git a/src/Makefile.am b/src/Makefile.am index 52fa4b84..a04a91a8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -135,10 +135,9 @@ pulseaudio_SOURCES = \ daemon/main.c \ pulsecore/gccmacro.h -pulseaudio_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS) +pulseaudio_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS) $(LIBSAMPLERATE_CFLAGS) $(LIBSNDFILE_CFLAGS) $(CAP_CFLAGS) $(LIBOIL_CFLAGS) $(DBUS_CFLAGS) pulseaudio_CPPFLAGS = $(AM_CPPFLAGS) -pulseaudio_LDADD = $(AM_LDADD) libpulsecore.la $(LIBLTDL) \ - $(LIBSAMPLERATE_LIBS) $(LIBSNDFILE_LIBS) $(CAP_LIBS) $(LIBOIL_LIBS) +pulseaudio_LDADD = $(AM_LDADD) libpulsecore.la $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSNDFILE_LIBS) $(CAP_LIBS) $(LIBOIL_LIBS) $(DBUS_LIBS) # This is needed because automake doesn't properly expand the foreach below pulseaudio_DEPENDENCIES = libpulsecore.la $(PREOPEN_LIBS) diff --git a/src/daemon/main.c b/src/daemon/main.c index 93d4eb6b..e01bb231 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -58,6 +58,10 @@ #include #endif +#ifdef HAVE_DBUS +#include +#endif + #include #include #include @@ -745,5 +749,9 @@ finish: libtool_done(); +#ifdef HAVE_DBUS + dbus_shutdown(); +#endif + return retval; } diff --git a/src/modules/dbus-util.c b/src/modules/dbus-util.c index 9078ec72..ccc658b7 100644 --- a/src/modules/dbus-util.c +++ b/src/modules/dbus-util.c @@ -26,10 +26,10 @@ #include #endif -#include -#include #include #include +#include +#include #include "dbus-util.h" -- cgit From bf274cb617d92e55d18fa7e2f6b1cf139b96a413 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 14 Sep 2007 21:04:08 +0000 Subject: add two new macros PA_ONCE_BEGIN and PA_ONCE_END which allow usage of pa_once without declaring a function to be called git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1820 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/once-posix.c | 51 ++++++++++++++++++++++++++++++---------------- src/pulsecore/once.h | 32 ++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 19 deletions(-) diff --git a/src/pulsecore/once-posix.c b/src/pulsecore/once-posix.c index fd6288fe..fba0ddf1 100644 --- a/src/pulsecore/once-posix.c +++ b/src/pulsecore/once-posix.c @@ -32,18 +32,20 @@ #include "once.h" -/* Not reentrant -- how could it be? */ -void pa_run_once(pa_once *control, pa_once_func_t func) { +int pa_once_begin(pa_once *control) { pa_mutex *m; pa_assert(control); - pa_assert(func); if (pa_atomic_load(&control->done)) - return; + return 0; pa_atomic_inc(&control->ref); + /* Caveat: We have to make sure that the once func has completed + * before returning, even if the once func is not actually + * executed by us. Hence the awkward locking. */ + for (;;) { if ((m = pa_atomic_ptr_load(&control->mutex))) { @@ -51,33 +53,46 @@ void pa_run_once(pa_once *control, pa_once_func_t func) { /* The mutex is stored in locked state, hence let's just * wait until it is unlocked */ pa_mutex_lock(m); - pa_mutex_unlock(m); - break; + + pa_once_end(control); + return 0; } pa_assert_se(m = pa_mutex_new(0)); pa_mutex_lock(m); - if (pa_atomic_ptr_cmpxchg(&control->mutex, NULL, m)) { - func(); - pa_atomic_store(&control->done, 1); - pa_mutex_unlock(m); - - break; - } + if (pa_atomic_ptr_cmpxchg(&control->mutex, NULL, m)) + return 1; pa_mutex_unlock(m); pa_mutex_free(m); } +} + +void pa_once_end(pa_once *control) { + pa_mutex *m; + + pa_assert(control); - pa_assert(pa_atomic_load(&control->done)); + pa_atomic_store(&control->done, 1); + + pa_assert_se(m = pa_atomic_ptr_load(&control->mutex)); + pa_mutex_unlock(m); if (pa_atomic_dec(&control->ref) <= 1) { - pa_assert(pa_atomic_ptr_cmpxchg(&control->mutex, m, NULL)); + pa_assert_se(pa_atomic_ptr_cmpxchg(&control->mutex, m, NULL)); pa_mutex_free(m); } +} - /* Caveat: We have to make sure that the once func has completed - * before returning, even if the once func is not actually - * executed by us. Hence the awkward locking. */ +/* Not reentrant -- how could it be? */ +void pa_run_once(pa_once *control, pa_once_func_t func) { + pa_assert(control); + pa_assert(func); + + if (pa_once_begin(control)) { + func(); + pa_once_end(control); + } } + diff --git a/src/pulsecore/once.h b/src/pulsecore/once.h index d9372d86..a4a0b239 100644 --- a/src/pulsecore/once.h +++ b/src/pulsecore/once.h @@ -39,8 +39,38 @@ typedef struct pa_once { .done = PA_ATOMIC_INIT(0) \ } -typedef void (*pa_once_func_t) (void); +/* Not to be called directly, use the macros defined below instead */ +int pa_once_begin(pa_once *o); +void pa_once_end(pa_once *o); + +#define PA_ONCE_BEGIN \ + do { \ + static pa_once _once = PA_ONCE_INIT; \ + if (pa_once_begin(&_once)) {{ + +#define PA_ONCE_END \ + } \ + pa_once_end(&_once); \ + } \ + } while(0) +/* + + Usage of these macros is like this: + + void foo() { + + PA_ONCE_BEGIN { + + ... stuff to be called just once ... + + } PA_ONCE_END; + } + +*/ + +/* Same API but calls a function */ +typedef void (*pa_once_func_t) (void); void pa_run_once(pa_once *o, pa_once_func_t f); #endif -- cgit From f0b9dce32e4c5d77f57364ccdc7795f828f7f6a0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 14 Sep 2007 21:05:47 +0000 Subject: explicitly destory TLS data before destroying TLS git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1821 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/thread.h b/src/pulsecore/thread.h index 4a2b1bb8..0c6c859d 100644 --- a/src/pulsecore/thread.h +++ b/src/pulsecore/thread.h @@ -70,8 +70,14 @@ void *pa_tls_set(pa_tls *t, void *userdata); } \ static void name##_tls_destructor(void) PA_GCC_DESTRUCTOR; \ static void name##_tls_destructor(void) { \ - if (name##_tls.tls) \ - pa_tls_free(name##_tls.tls); \ + if (!name##_tls.tls) \ + return; \ + if (free_cb) { \ + void *p; \ + if ((p = pa_tls_get(name##_tls.tls))) \ + free_cb(p); \ + } \ + pa_tls_free(name##_tls.tls); \ } \ static inline void* name##_tls_get(void) { \ return pa_tls_get(name##_tls_obj()); \ -- cgit From 3396b65f15a06ff312e318bc05e502ba402c564e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 14 Sep 2007 21:51:05 +0000 Subject: simplify rt loops a bit by moving more code into pa_rtpoll. It is now possible to attach "work" functions to a pa_rtpoll_item, which will be called in each loop iteration. This allows us to hide the message processing in the RT loops and to drop the seperate sink_input->process hooks. Basically, only the driver-specific code remains in the RT loops. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1822 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 21 +++------- src/modules/module-alsa-source.c | 23 +++------- src/modules/module-combine.c | 85 ++++++++++++------------------------- src/modules/module-null-sink.c | 23 +++------- src/modules/module-oss.c | 33 +++------------ src/modules/module-pipe-sink.c | 28 ++++--------- src/modules/module-pipe-source.c | 23 +++------- src/pulsecore/asyncmsgq.c | 21 ++++++++++ src/pulsecore/asyncmsgq.h | 1 + src/pulsecore/rtpoll.c | 91 +++++++++++++++++++++++++++++++++------- src/pulsecore/rtpoll.h | 20 +++++++-- src/pulsecore/sink-input.c | 2 - src/pulsecore/sink-input.h | 7 ---- src/pulsecore/sink.c | 17 -------- src/pulsecore/source-output.c | 2 - src/pulsecore/source-output.h | 7 ---- src/pulsecore/source.c | 18 -------- src/pulsecore/thread-mq.c | 25 ----------- src/pulsecore/thread-mq.h | 3 -- 19 files changed, 180 insertions(+), 270 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 26c24c87..1bcb30c0 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -630,24 +630,13 @@ static void thread_func(void *userdata) { } } - /* Now give the sink inputs some to time to process their data */ - if ((ret = pa_sink_process_inputs(u->sink)) < 0) + /* Hmm, nothing to do. Let's sleep */ + if ((ret = pa_rtpoll_run(u->rtpoll, 1)) < 0) goto fail; - if (ret > 0) - continue; - /* Check whether there is a message for us to process */ - if ((ret = pa_thread_mq_process(&u->thread_mq) < 0)) + if (ret == 0) goto finish; - if (ret > 0) - continue; - /* Hmm, nothing to do. Let's sleep */ - if (pa_rtpoll_run(u->rtpoll, 1) < 0) { - pa_log("poll() failed: %s", pa_cstrerror(errno)); - goto fail; - } - /* Tell ALSA about this and process its response */ if (PA_SINK_OPENED(u->sink->thread_info.state)) { struct pollfd *pollfd; @@ -676,8 +665,8 @@ static void thread_func(void *userdata) { } fail: - /* We have to continue processing messages until we receive the - * SHUTDOWN message */ + /* If this was no regular exit from the loop we have to continue + * processing messages until we received PA_MESSAGE_SHUTDOWN */ pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 9e03729a..870f204d 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -612,24 +612,13 @@ static void thread_func(void *userdata) { } } - /* Now give the source outputs some to time to process their data */ - if ((ret = pa_source_process_outputs(u->source)) < 0) - goto fail; - if (ret > 0) - continue; - - /* Check whether there is a message for us to process */ - if ((ret = pa_thread_mq_process(&u->thread_mq) < 0)) - goto finish; - if (ret > 0) - continue; - /* Hmm, nothing to do. Let's sleep */ - if (pa_rtpoll_run(u->rtpoll, 1) < 0) { - pa_log("poll() failed: %s", pa_cstrerror(errno)); + if ((ret = pa_rtpoll_run(u->rtpoll, 1)) < 0) goto fail; - } + if (ret == 0) + goto finish; + /* Tell ALSA about this and process its response */ if (PA_SOURCE_OPENED(u->source->thread_info.state)) { struct pollfd *pollfd; @@ -658,8 +647,8 @@ static void thread_func(void *userdata) { } fail: - /* We have to continue processing messages until we receive the - * SHUTDOWN message */ + /* If this was no regular exit from the loop we have to continue + * processing messages until we received PA_MESSAGE_SHUTDOWN */ pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 11707b19..7df04ec5 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -139,6 +139,10 @@ enum { SINK_MESSAGE_REMOVE_OUTPUT }; +enum { + SINK_INPUT_MESSAGE_POST = PA_SINK_INPUT_MESSAGE_MAX +}; + static void output_free(struct output *o); static int output_create_sink_input(struct userdata *u, struct output *o); static int update_master(struct userdata *u, struct output *o); @@ -255,28 +259,17 @@ static void thread_func(void *userdata) { } else pa_rtpoll_set_timer_disabled(u->rtpoll); - /* Now give the sink inputs some to time to process their data */ - if ((ret = pa_sink_process_inputs(u->sink)) < 0) + /* Hmm, nothing to do. Let's sleep */ + if ((ret = pa_rtpoll_run(u->rtpoll, 1)) < 0) goto fail; - if (ret > 0) - continue; - /* Check whether there is a message for us to process */ - if ((ret = pa_thread_mq_process(&u->thread_mq) < 0)) + if (ret == 0) goto finish; - if (ret > 0) - continue; - - /* Hmm, nothing to do. Let's sleep */ - if (pa_rtpoll_run(u->rtpoll, 1) < 0) { - pa_log("poll() failed: %s", pa_cstrerror(errno)); - goto fail; - } } fail: - /* We have to continue processing messages until we receive the - * SHUTDOWN message */ + /* If this was no regular exit from the loop we have to continue + * processing messages until we received PA_MESSAGE_SHUTDOWN */ pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); @@ -294,10 +287,8 @@ static void request_memblock(struct output *o) { /* If another thread already prepared some data we received * the data over the asyncmsgq, hence let's first process * it. */ - while (pa_asyncmsgq_get(o->asyncmsgq, NULL, NULL, NULL, NULL, &chunk, 0) == 0) { - pa_memblockq_push_align(o->memblockq, &chunk); - pa_asyncmsgq_done(o->asyncmsgq, 0); - } + while (pa_asyncmsgq_process_one(o->asyncmsgq) > 0) + ; /* Check whether we're now readable */ if (pa_memblockq_is_readable(o->memblockq)) @@ -309,10 +300,8 @@ static void request_memblock(struct output *o) { if (PA_SINK_OPENED(o->userdata->sink->thread_info.state)) { /* Maybe there's some data now? */ - while (pa_asyncmsgq_get(o->asyncmsgq, NULL, NULL, NULL, NULL, &chunk, 0) == 0) { - pa_memblockq_push_align(o->memblockq, &chunk); - pa_asyncmsgq_done(o->asyncmsgq, 0); - } + while (pa_asyncmsgq_process_one(o->asyncmsgq) > 0) + ; /* Ok, now let's prepare some data if we really have to */ while (!pa_memblockq_is_readable(o->memblockq)) { @@ -324,7 +313,7 @@ static void request_memblock(struct output *o) { /* OK, let's send this data to the other threads */ for (j = o->userdata->thread_info.outputs; j; j = j->next) if (j != o && j->sink_input) - pa_asyncmsgq_post(j->asyncmsgq, NULL, 0, NULL, 0, &chunk, NULL); + pa_asyncmsgq_post(j->asyncmsgq, PA_MSGOBJECT(j->sink_input), SINK_INPUT_MESSAGE_POST, NULL, 0, &chunk, NULL); /* And push it into our own queue */ pa_memblockq_push_align(o->memblockq, &chunk); @@ -361,37 +350,6 @@ static void sink_input_drop_cb(pa_sink_input *i, size_t length) { pa_memblockq_drop(o->memblockq, length); } -/* Called from I/O thread context */ -static int sink_input_process_cb(pa_sink_input *i) { - struct output *o; - pa_memchunk chunk; - int r = 0; - - pa_sink_input_assert_ref(i); - o = i->userdata; - pa_assert(o); - - /* Move all data in the asyncmsgq into our memblockq */ - - while (pa_asyncmsgq_get(o->asyncmsgq, NULL, NULL, NULL, NULL, &chunk, 0) == 0) { - if (PA_SINK_OPENED(i->sink->thread_info.state)) - pa_memblockq_push_align(o->memblockq, &chunk); - pa_asyncmsgq_done(o->asyncmsgq, 0); - } - - /* If the sink is suspended, flush our queue */ - if (!PA_SINK_OPENED(i->sink->thread_info.state)) - pa_memblockq_flush(o->memblockq); - - if (o == o->userdata->thread_info.master) { - pa_mutex_lock(o->userdata->mutex); - r = pa_sink_process_inputs(o->userdata->sink); - pa_mutex_unlock(o->userdata->mutex); - } - - return r; -} - /* Called from I/O thread context */ static void sink_input_attach_cb(pa_sink_input *i) { struct output *o; @@ -401,7 +359,10 @@ static void sink_input_attach_cb(pa_sink_input *i) { pa_assert(o); pa_assert(!o->rtpoll_item); - o->rtpoll_item = pa_rtpoll_item_new_asyncmsgq(i->sink->rtpoll, PA_RTPOLL_NORMAL, o->asyncmsgq); + o->rtpoll_item = pa_rtpoll_item_new_asyncmsgq( + i->sink->rtpoll, + PA_RTPOLL_NORMAL, /* This one has a lower priority than the normal message handling */ + o->asyncmsgq); } /* Called from I/O thread context */ @@ -448,6 +409,15 @@ static int sink_input_process_msg(pa_msgobject *obj, int code, void *data, int64 break; } + case SINK_INPUT_MESSAGE_POST: { + + if (PA_SINK_OPENED(o->sink_input->sink->thread_info.state)) + pa_memblockq_push_align(o->memblockq, chunk); + else + pa_memblockq_flush(o->memblockq); + + break; + } } return pa_sink_input_process_msg(obj, code, data, offset, chunk); @@ -784,7 +754,6 @@ static int output_create_sink_input(struct userdata *u, struct output *o) { o->sink_input->parent.process_msg = sink_input_process_msg; o->sink_input->peek = sink_input_peek_cb; o->sink_input->drop = sink_input_drop_cb; - o->sink_input->process = sink_input_process_cb; o->sink_input->attach = sink_input_attach_cb; o->sink_input->detach = sink_input_detach_cb; o->sink_input->kill = sink_input_kill_cb; diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index ba2ae6f0..04df239d 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -145,28 +145,17 @@ static void thread_func(void *userdata) { } else pa_rtpoll_set_timer_disabled(u->rtpoll); - /* Now give the sink inputs some to time to process their data */ - if ((ret = pa_sink_process_inputs(u->sink)) < 0) - goto fail; - if (ret > 0) - continue; - - /* Check whether there is a message for us to process */ - if ((ret = pa_thread_mq_process(&u->thread_mq) < 0)) - goto finish; - if (ret > 0) - continue; - /* Hmm, nothing to do. Let's sleep */ - if (pa_rtpoll_run(u->rtpoll, 1) < 0) { - pa_log("poll() failed: %s", pa_cstrerror(errno)); + if ((ret = pa_rtpoll_run(u->rtpoll, 1)) < 0) goto fail; - } + + if (ret == 0) + goto finish; } fail: - /* We have to continue processing messages until we receive the - * SHUTDOWN message */ + /* If this was no regular exit from the loop we have to continue + * processing messages until we received PA_MESSAGE_SHUTDOWN */ pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 1fd8d2e5..037c4017 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -999,28 +999,6 @@ static void thread_func(void *userdata) { /* pa_log("loop2"); */ - /* Now give the sink inputs some to time to process their data */ - if (u->sink) { - if ((ret = pa_sink_process_inputs(u->sink)) < 0) - goto fail; - if (ret > 0) - continue; - } - - /* Now give the source outputs some to time to process their data */ - if (u->source) { - if ((ret = pa_source_process_outputs(u->source)) < 0) - goto fail; - if (ret > 0) - continue; - } - - /* Check whether there is a message for us to process */ - if ((ret = pa_thread_mq_process(&u->thread_mq) < 0)) - goto finish; - if (ret > 0) - continue; - if (u->fd >= 0) { struct pollfd *pollfd; @@ -1031,11 +1009,12 @@ static void thread_func(void *userdata) { } /* Hmm, nothing to do. Let's sleep */ - if (pa_rtpoll_run(u->rtpoll, 1) < 0) { - pa_log("poll() failed: %s", pa_cstrerror(errno)); + if ((ret = pa_rtpoll_run(u->rtpoll, 1)) < 0) goto fail; - } + if (ret == 0) + goto finish; + if (u->fd >= 0) { struct pollfd *pollfd; @@ -1052,8 +1031,8 @@ static void thread_func(void *userdata) { } fail: - /* We have to continue processing messages until we receive the - * SHUTDOWN message */ + /* If this was no regular exit from the loop we have to continue + * processing messages until we received PA_MESSAGE_SHUTDOWN */ pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index 9594a685..a1bdc8fb 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -126,8 +126,8 @@ static void thread_func(void *userdata) { pa_rtpoll_install(u->rtpoll); for (;;) { - int ret; struct pollfd *pollfd; + int ret; pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); @@ -170,36 +170,26 @@ static void thread_func(void *userdata) { } } - /* Now give the sink inputs some to time to process their data */ - if ((ret = pa_sink_process_inputs(u->sink)) < 0) - goto fail; - if (ret > 0) - continue; - - /* Check whether there is a message for us to process */ - if ((ret = pa_thread_mq_process(&u->thread_mq) < 0)) - goto finish; - if (ret > 0) - continue; - /* Hmm, nothing to do. Let's sleep */ pollfd->events = u->sink->thread_info.state == PA_SINK_RUNNING ? POLLOUT : 0; - if (pa_rtpoll_run(u->rtpoll, 1) < 0) { - pa_log("poll() failed: %s", pa_cstrerror(errno)); + if ((ret = pa_rtpoll_run(u->rtpoll, 1)) < 0) goto fail; - } + + if (ret == 0) + goto finish; pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + if (pollfd->revents & ~POLLOUT) { pa_log("FIFO shutdown."); goto fail; } - } + } fail: - /* We have to continue processing messages until we receive the - * SHUTDOWN message */ + /* If this was no regular exit from the loop we have to continue + * processing messages until we received PA_MESSAGE_SHUTDOWN */ pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index 1b42fcfa..382da8f9 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -149,26 +149,15 @@ static void thread_func(void *userdata) { } } - /* Now give the source outputs some to time to process their data */ - if ((ret = pa_source_process_outputs(u->source)) < 0) - goto fail; - if (ret > 0) - continue; - - /* Check whether there is a message for us to process */ - if ((ret = pa_thread_mq_process(&u->thread_mq) < 0)) - goto finish; - if (ret > 0) - continue; - /* Hmm, nothing to do. Let's sleep */ pollfd->events = u->source->thread_info.state == PA_SOURCE_RUNNING ? POLLIN : 0; - if (pa_rtpoll_run(u->rtpoll, 1) < 0) { - pa_log("poll() failed: %s", pa_cstrerror(errno)); + if ((ret = pa_rtpoll_run(u->rtpoll, 1)) < 0) goto fail; - } + if (ret == 0) + goto finish; + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); if (pollfd->revents & ~POLLIN) { pa_log("FIFO shutdown."); @@ -177,8 +166,8 @@ static void thread_func(void *userdata) { } fail: - /* We have to continue processing messages until we receive the - * SHUTDOWN message */ + /* If this was no regular exit from the loop we have to continue + * processing messages until we received PA_MESSAGE_SHUTDOWN */ pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); diff --git a/src/pulsecore/asyncmsgq.c b/src/pulsecore/asyncmsgq.c index e3a1ba91..b3654460 100644 --- a/src/pulsecore/asyncmsgq.c +++ b/src/pulsecore/asyncmsgq.c @@ -248,6 +248,27 @@ int pa_asyncmsgq_wait_for(pa_asyncmsgq *a, int code) { return 0; } +int pa_asyncmsgq_process_one(pa_asyncmsgq *a) { + pa_msgobject *object; + int code; + void *data; + pa_memchunk chunk; + int64_t offset; + int ret; + + pa_assert(PA_REFCNT_VALUE(a) > 0); + + if (pa_asyncmsgq_get(a, &object, &code, &data, &offset, &chunk, 0) < 0) + return 0; + + pa_asyncmsgq_ref(a); + ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); + pa_asyncmsgq_done(a, ret); + pa_asyncmsgq_unref(a); + + return 1; +} + int pa_asyncmsgq_get_fd(pa_asyncmsgq *a) { pa_assert(PA_REFCNT_VALUE(a) > 0); diff --git a/src/pulsecore/asyncmsgq.h b/src/pulsecore/asyncmsgq.h index 55812c6f..393bb0b1 100644 --- a/src/pulsecore/asyncmsgq.h +++ b/src/pulsecore/asyncmsgq.h @@ -65,6 +65,7 @@ int pa_asyncmsgq_get(pa_asyncmsgq *q, pa_msgobject **object, int *code, void **u int pa_asyncmsgq_dispatch(pa_msgobject *object, int code, void *userdata, int64_t offset, pa_memchunk *memchunk); void pa_asyncmsgq_done(pa_asyncmsgq *q, int ret); int pa_asyncmsgq_wait_for(pa_asyncmsgq *a, int code); +int pa_asyncmsgq_process_one(pa_asyncmsgq *a); /* Just for the reading side */ int pa_asyncmsgq_get_fd(pa_asyncmsgq *q); diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c index 659e5381..0de8d0ce 100644 --- a/src/pulsecore/rtpoll.c +++ b/src/pulsecore/rtpoll.c @@ -53,7 +53,7 @@ struct pa_rtpoll { pa_usec_t period; int scan_for_dead; - int running, installed, rebuild_needed; + int running, installed, rebuild_needed, quit; #ifdef HAVE_PPOLL int rtsig; @@ -76,6 +76,7 @@ struct pa_rtpoll_item { struct pollfd *pollfd; unsigned n_pollfd; + int (*work_cb)(pa_rtpoll_item *i); int (*before_cb)(pa_rtpoll_item *i); void (*after_cb)(pa_rtpoll_item *i); void *userdata; @@ -134,6 +135,7 @@ pa_rtpoll *pa_rtpoll_new(void) { p->installed = 0; p->scan_for_dead = 0; p->rebuild_needed = 0; + p->quit = 0; PA_LLIST_HEAD_INIT(pa_rtpoll_item, p->items); @@ -288,7 +290,6 @@ static void reset_all_revents(pa_rtpoll *p) { int pa_rtpoll_run(pa_rtpoll *p, int wait) { pa_rtpoll_item *i; int r = 0; - int saved_errno = 0; struct timespec timeout; pa_assert(p); @@ -297,6 +298,7 @@ int pa_rtpoll_run(pa_rtpoll *p, int wait) { p->running = 1; + /* First, let's do some work */ for (i = p->items; i && i->priority < PA_RTPOLL_NEVER; i = i->next) { int k; @@ -306,12 +308,31 @@ int pa_rtpoll_run(pa_rtpoll *p, int wait) { if (!i->before_cb) continue; - if ((k = i->before_cb(i)) != 0) { + if (p->quit) + goto finish; + + if ((k = i->work_cb(i)) != 0) { + if (k < 0) + r = k; + + goto finish; + } + } + + /* Now let's prepare for entering the sleep */ + for (i = p->items; i && i->priority < PA_RTPOLL_NEVER; i = i->next) { + int k = 0; + + if (i->dead) + continue; + + if (!i->before_cb) + continue; + + if (p->quit || (k = i->before_cb(i)) != 0) { /* Hmm, this one doesn't let us enter the poll, so rewind everything */ - reset_all_revents(p); - for (i = i->prev; i; i = i->prev) { if (i->dead) @@ -334,7 +355,7 @@ int pa_rtpoll_run(pa_rtpoll *p, int wait) { rtpoll_rebuild(p); /* Calculate timeout */ - if (!wait) { + if (!wait || p->quit) { timeout.tv_sec = 0; timeout.tv_nsec = 0; } else if (p->timer_enabled) { @@ -362,13 +383,14 @@ int pa_rtpoll_run(pa_rtpoll *p, int wait) { r = poll(p->pollfd, p->n_pollfd_used, p->timer_enabled > 0 ? (timeout.tv_sec*1000) + (timeout.tv_nsec / 1000000) : -1); #endif - if (r < 0) + if (r < 0) { reset_all_revents(p); - if (r < 0 && (errno == EAGAIN || errno == EINTR)) - r = 0; - - saved_errno = r < 0 ? errno : 0; + if (errno == EAGAIN || errno == EINTR) + r = 0; + else + pa_log_error("poll(): %s", pa_cstrerror(errno)); + } if (p->timer_enabled) { if (p->period > 0) { @@ -385,6 +407,7 @@ int pa_rtpoll_run(pa_rtpoll *p, int wait) { p->timer_enabled = 0; } + /* Let's tell everyone that we left the sleep */ for (i = p->items; i && i->priority < PA_RTPOLL_NEVER; i = i->next) { if (i->dead) @@ -413,10 +436,7 @@ finish: } } - if (saved_errno != 0) - errno = saved_errno; - - return r; + return r < 0 ? r : !p->quit; } static void update_timer(pa_rtpoll *p) { @@ -528,6 +548,7 @@ pa_rtpoll_item *pa_rtpoll_item_new(pa_rtpoll *p, pa_rtpoll_priority_t prio, unsi i->userdata = NULL; i->before_cb = NULL; i->after_cb = NULL; + i->work_cb = NULL; for (j = p->items; j; j = j->next) { if (prio <= j->priority) @@ -585,6 +606,13 @@ void pa_rtpoll_item_set_after_callback(pa_rtpoll_item *i, void (*after_cb)(pa_rt i->after_cb = after_cb; } +void pa_rtpoll_item_set_work_callback(pa_rtpoll_item *i, int (*work_cb)(pa_rtpoll_item *i)) { + pa_assert(i); + pa_assert(i->priority < PA_RTPOLL_NEVER); + + i->work_cb = work_cb; +} + void pa_rtpoll_item_set_userdata(pa_rtpoll_item *i, void *userdata) { pa_assert(i); @@ -649,6 +677,32 @@ static void asyncmsgq_after(pa_rtpoll_item *i) { pa_asyncmsgq_after_poll(i->userdata); } +static int asyncmsgq_work(pa_rtpoll_item *i) { + pa_msgobject *object; + int code; + void *data; + pa_memchunk chunk; + int64_t offset; + + pa_assert(i); + + if (pa_asyncmsgq_get(i->userdata, &object, &code, &data, &offset, &chunk, 0) == 0) { + int ret; + + if (!object && code == PA_MESSAGE_SHUTDOWN) { + pa_asyncmsgq_done(i->userdata, 0); + pa_rtpoll_quit(i->rtpoll); + return 1; + } + + ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); + pa_asyncmsgq_done(i->userdata, ret); + return 1; + } + + return 0; +} + pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_asyncmsgq *q) { pa_rtpoll_item *i; struct pollfd *pollfd; @@ -664,7 +718,14 @@ pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq(pa_rtpoll *p, pa_rtpoll_priority_t i->before_cb = asyncmsgq_before; i->after_cb = asyncmsgq_after; + i->work_cb = asyncmsgq_work; i->userdata = q; return i; } + +void pa_rtpoll_quit(pa_rtpoll *p) { + pa_assert(p); + + p->quit = 1; +} diff --git a/src/pulsecore/rtpoll.h b/src/pulsecore/rtpoll.h index bef9eedb..9a368d36 100644 --- a/src/pulsecore/rtpoll.h +++ b/src/pulsecore/rtpoll.h @@ -69,7 +69,9 @@ void pa_rtpoll_install(pa_rtpoll *p); /* Sleep on the rtpoll until the time event, or any of the fd events * is triggered. If "wait" is 0 we don't sleep but only update the - * struct pollfd. */ + * struct pollfd. Returns negative on error, positive if the loop + * should continue to run, 0 when the loop should be terminated + * cleanly. */ int pa_rtpoll_run(pa_rtpoll *f, int wait); void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timespec *ts); @@ -86,18 +88,30 @@ void pa_rtpoll_item_free(pa_rtpoll_item *i); * using the pointer and don't save the result anywhere */ struct pollfd *pa_rtpoll_item_get_pollfd(pa_rtpoll_item *i, unsigned *n_fds); +/* Set the callback that shall be called when there's time to do some work: If the + * callback returns a value > 0, the poll is skipped and the next + * iteraton of the loop will start immediately. */ +void pa_rtpoll_item_set_work_callback(pa_rtpoll_item *i, int (*work_cb)(pa_rtpoll_item *i)); + /* Set the callback that shall be called immediately before entering - * the sleeping poll: If the callback returns a negative value, the - * poll is skipped. */ + * the sleeping poll: If the callback returns a value > 0, the poll is + * skipped and the next iteraton of the loop will start + * immediately.. */ void pa_rtpoll_item_set_before_callback(pa_rtpoll_item *i, int (*before_cb)(pa_rtpoll_item *i)); /* Set the callback that shall be called immediately after having * entered the sleeping poll */ void pa_rtpoll_item_set_after_callback(pa_rtpoll_item *i, void (*after_cb)(pa_rtpoll_item *i)); + + void pa_rtpoll_item_set_userdata(pa_rtpoll_item *i, void *userdata); void* pa_rtpoll_item_get_userdata(pa_rtpoll_item *i); pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_fdsem *s); pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_asyncmsgq *q); +/* Requests the loop to exit. Will cause the next iteration of + * pa_rtpoll_run() to return 0 */ +void pa_rtpoll_quit(pa_rtpoll *p); + #endif diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index c33d8e70..2687cfaa 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -194,7 +194,6 @@ pa_sink_input* pa_sink_input_new( i->peek = NULL; i->drop = NULL; - i->process = NULL; i->kill = NULL; i->get_latency = NULL; i->attach = NULL; @@ -272,7 +271,6 @@ void pa_sink_input_unlink(pa_sink_input *i) { i->peek = NULL; i->drop = NULL; - i->process = NULL; i->kill = NULL; i->get_latency = NULL; i->attach = NULL; diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index e1d89ffb..c4e65b50 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -90,13 +90,6 @@ struct pa_sink_input { * peek(), but not necessarily. Called from IO thread context. */ void (*drop) (pa_sink_input *i, size_t length); - /* If non-NULL this function is called in each IO event loop and - * can be used to do additional processing even when the device is - * suspended and peek() is never called. Should return 1 when - * "some work" has been done and the IO event loop should be - * reiterated immediately. Called from IO thread context. */ - int (*process) (pa_sink_input *i); /* may be NULL */ - /* If non-NULL this function is called when the input is first * connected to a sink. Called from IO thread context */ void (*attach) (pa_sink_input *i); /* may be NULL */ diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index b009bc77..a7ed5a40 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -922,20 +922,3 @@ int pa_sink_suspend_all(pa_core *c, int suspend) { return ret; } -int pa_sink_process_inputs(pa_sink *s) { - pa_sink_input *i; - void *state = NULL; - int r; - - pa_sink_assert_ref(s); - - if (!PA_SINK_LINKED(s->thread_info.state)) - return 0; - - while ((i = PA_SINK_INPUT(pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))) - if (i->process) - if ((r = i->process(i))) - return r; - - return 0; -} diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 42672341..b77a4ae3 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -148,7 +148,6 @@ pa_source_output* pa_source_output_new( o->channel_map = data->channel_map; o->push = NULL; - o->process = NULL; o->kill = NULL; o->get_latency = NULL; o->detach = NULL; @@ -204,7 +203,6 @@ void pa_source_output_unlink(pa_source_output*o) { pa_source_update_status(o->source); o->push = NULL; - o->process = NULL; o->kill = NULL; o->get_latency = NULL; o->attach = NULL; diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h index 2027e37a..5059c465 100644 --- a/src/pulsecore/source-output.h +++ b/src/pulsecore/source-output.h @@ -73,13 +73,6 @@ struct pa_source_output { * context. */ void (*push)(pa_source_output *o, const pa_memchunk *chunk); - /* If non-NULL this function is called in each IO event loop and - * can be used to do additional processing even when the device is - * suspended and peek() is never called. Should return 1 when - * "some work" has been done and the IO event loop should be - * reiterated immediately. Called from IO thread context. */ - int (*process) (pa_source_output *o); /* may be NULL */ - /* If non-NULL this function is called when the output is first * connected to a source. Called from IO thread context */ void (*attach) (pa_source_output *o); /* may be NULL */ diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 2f1a5a5f..34e023de 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -504,21 +504,3 @@ int pa_source_suspend_all(pa_core *c, int suspend) { return ret; } - -int pa_source_process_outputs(pa_source *s) { - pa_source_output *o; - void *state = NULL; - int r; - - pa_source_assert_ref(s); - - if (!PA_SOURCE_LINKED(s->state)) - return 0; - - while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) - if (o->process) - if ((r = o->process(o))) - return r; - - return 0; -} diff --git a/src/pulsecore/thread-mq.c b/src/pulsecore/thread-mq.c index 3000246a..d572f6e0 100644 --- a/src/pulsecore/thread-mq.c +++ b/src/pulsecore/thread-mq.c @@ -110,28 +110,3 @@ void pa_thread_mq_install(pa_thread_mq *q) { pa_thread_mq *pa_thread_mq_get(void) { return PA_STATIC_TLS_GET(thread_mq); } - -int pa_thread_mq_process(pa_thread_mq *q) { - pa_msgobject *object; - int code; - void *data; - pa_memchunk chunk; - int64_t offset; - - pa_assert(q); - - if (pa_asyncmsgq_get(q->inq, &object, &code, &data, &offset, &chunk, 0) == 0) { - int ret; - - if (!object && code == PA_MESSAGE_SHUTDOWN) { - pa_asyncmsgq_done(q->inq, 0); - return -1; - } - - ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); - pa_asyncmsgq_done(q->inq, ret); - return 1; - } - - return 0; -} diff --git a/src/pulsecore/thread-mq.h b/src/pulsecore/thread-mq.h index 2b1fd687..13b6e01f 100644 --- a/src/pulsecore/thread-mq.h +++ b/src/pulsecore/thread-mq.h @@ -43,9 +43,6 @@ void pa_thread_mq_done(pa_thread_mq *q); /* Install the specified pa_thread_mq object for the current thread */ void pa_thread_mq_install(pa_thread_mq *q); -/* Dispatched queued events on the thread side. */ -int pa_thread_mq_process(pa_thread_mq *q); - /* Return the pa_thread_mq object that is set for the current thread */ pa_thread_mq *pa_thread_mq_get(void); -- cgit From 5ae4eed52e911fb3e9712e1cd7d6095427515cd1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 14 Sep 2007 23:26:17 +0000 Subject: Move attaching/detaching from a pa_rtpoll into pa_sink proper, remove it from module-combine git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1823 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-combine.c | 44 +++++++++++++++------------------ src/pulsecore/sink-input.h | 5 +++- src/pulsecore/sink.c | 58 ++++++++++++++++++++++++++++++++++++++++++++ src/pulsecore/sink.h | 10 ++++++-- src/pulsecore/source.c | 53 ++++++++++++++++++++++++++++++++++++++++ src/pulsecore/source.h | 10 ++++++-- 6 files changed, 150 insertions(+), 30 deletions(-) diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 7df04ec5..91561ee7 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -133,9 +133,7 @@ struct userdata { }; enum { - SINK_MESSAGE_DETACH = PA_SINK_MESSAGE_MAX, - SINK_MESSAGE_ATTACH, - SINK_MESSAGE_ADD_OUTPUT, + SINK_MESSAGE_ADD_OUTPUT = PA_SINK_MESSAGE_MAX, SINK_MESSAGE_REMOVE_OUTPUT }; @@ -358,6 +356,15 @@ static void sink_input_attach_cb(pa_sink_input *i) { o = i->userdata; pa_assert(o); + if (o->userdata->master == o) { + /* Calling these two functions here is safe, because both + * threads that might access this sink input are known to be + * waiting for us. */ + pa_sink_set_asyncmsgq(o->userdata->sink, i->sink->asyncmsgq); + pa_sink_set_rtpoll(o->userdata->sink, i->sink->rtpoll); + pa_sink_attach_within_thread(o->userdata->sink); + } + pa_assert(!o->rtpoll_item); o->rtpoll_item = pa_rtpoll_item_new_asyncmsgq( i->sink->rtpoll, @@ -376,6 +383,9 @@ static void sink_input_detach_cb(pa_sink_input *i) { pa_assert(o->rtpoll_item); pa_rtpoll_item_free(o->rtpoll_item); o->rtpoll_item = NULL; + + if (o->userdata->master == o) + pa_sink_detach_from_thread(o->userdata->sink); } /* Called from main context */ @@ -543,36 +553,20 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse break; } - case SINK_MESSAGE_DETACH: { - pa_sink_input *i; - void *state = NULL; + case PA_SINK_MESSAGE_DETACH: /* We're detaching all our input streams artificially, so - * that we can driver our sink from a different sink */ - - while ((i = pa_hashmap_iterate(u->sink->thread_info.inputs, &state, NULL))) - if (i->detach) - i->detach(i); + * that we can drive our sink from a different sink */ u->thread_info.master = NULL; - break; - } - case SINK_MESSAGE_ATTACH: { - pa_sink_input *i; - void *state = NULL; + case PA_SINK_MESSAGE_ATTACH: /* We're attached all our input streams artificially again */ - - while ((i = pa_hashmap_iterate(u->sink->thread_info.inputs, &state, NULL))) - if (i->attach) - i->attach(i); - - u->thread_info.master = data; + u->thread_info.master = data; break; - } case SINK_MESSAGE_ADD_OUTPUT: PA_LLIST_PREPEND(struct output, u->thread_info.outputs, (struct output*) data); @@ -655,7 +649,7 @@ static int update_master(struct userdata *u, struct output *o) { /* Make sure everything is detached from the old thread before we move our stuff to a new thread */ if (u->sink && PA_SINK_LINKED(pa_sink_get_state(u->sink))) - pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_DETACH, NULL, 0, NULL); + pa_sink_detach(u->sink); if (o) { /* If we have a master sink we run our own sink in its thread */ @@ -706,7 +700,7 @@ static int update_master(struct userdata *u, struct output *o) { /* Now attach everything again */ if (u->sink && PA_SINK_LINKED(pa_sink_get_state(u->sink))) - pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_ATTACH, u->master, 0, NULL); + pa_sink_attach(u->sink); return 0; } diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index c4e65b50..a101828f 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -91,7 +91,10 @@ struct pa_sink_input { void (*drop) (pa_sink_input *i, size_t length); /* If non-NULL this function is called when the input is first - * connected to a sink. Called from IO thread context */ + * connected to a sink or when the rtpoll/asyncmsgq fields + * change. You usually don't need to implement this function + * unless you rewrite a sink that is piggy-backed onto + * another. Called from IO thread context */ void (*attach) (pa_sink_input *i); /* may be NULL */ /* If non-NULL this function is called when the output is diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index a7ed5a40..9b191886 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -901,6 +901,20 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse s->thread_info.state = PA_PTR_TO_UINT(userdata); return 0; + case PA_SINK_MESSAGE_DETACH: + + /* We're detaching all our input streams so that the + * asyncmsgq and rtpoll fields can be changed without + * problems */ + pa_sink_detach_within_thread(s); + break; + + case PA_SINK_MESSAGE_ATTACH: + + /* Reattach all streams */ + pa_sink_attach_within_thread(s); + break; + case PA_SINK_MESSAGE_GET_LATENCY: case PA_SINK_MESSAGE_MAX: ; @@ -922,3 +936,47 @@ int pa_sink_suspend_all(pa_core *c, int suspend) { return ret; } +void pa_sink_detach(pa_sink *s) { + pa_sink_assert_ref(s); + pa_assert(PA_SINK_LINKED(s->state)); + + pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_DETACH, NULL, 0, NULL); +} + +void pa_sink_attach(pa_sink *s) { + pa_sink_assert_ref(s); + pa_assert(PA_SINK_LINKED(s->state)); + + pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_ATTACH, NULL, 0, NULL); +} + +void pa_sink_detach_within_thread(pa_sink *s) { + pa_sink_input *i; + void *state = NULL; + + pa_sink_assert_ref(s); + pa_assert(PA_SINK_LINKED(s->thread_info.state)); + + while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL))) + if (i->detach) + i->detach(i); + + if (s->monitor_source) + pa_source_detach_within_thread(s->monitor_source); +} + +void pa_sink_attach_within_thread(pa_sink *s) { + pa_sink_input *i; + void *state = NULL; + + pa_sink_assert_ref(s); + pa_assert(PA_SINK_LINKED(s->thread_info.state)); + + while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL))) + if (i->attach) + i->attach(i); + + if (s->monitor_source) + pa_source_attach_within_thread(s->monitor_source); +} + diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index b3fcff49..be883ed6 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -122,6 +122,8 @@ typedef enum pa_sink_message { PA_SINK_MESSAGE_SET_STATE, PA_SINK_MESSAGE_PING, PA_SINK_MESSAGE_REMOVE_INPUT_AND_BUFFER, + PA_SINK_MESSAGE_ATTACH, + PA_SINK_MESSAGE_DETACH, PA_SINK_MESSAGE_MAX } pa_sink_message_t; @@ -143,6 +145,9 @@ void pa_sink_set_description(pa_sink *s, const char *description); void pa_sink_set_asyncmsgq(pa_sink *s, pa_asyncmsgq *q); void pa_sink_set_rtpoll(pa_sink *s, pa_rtpoll *p); +void pa_sink_detach(pa_sink *s); +void pa_sink_attach(pa_sink *s); + /* May be called by everyone, from main context */ pa_usec_t pa_sink_get_latency(pa_sink *s); @@ -173,8 +178,9 @@ void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target); void pa_sink_skip(pa_sink *s, size_t length); -int pa_sink_process_inputs(pa_sink *s); - int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk); +void pa_sink_attach_within_thread(pa_sink *s); +void pa_sink_detach_within_thread(pa_sink *s); + #endif diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 34e023de..63ff9d7d 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -483,6 +483,20 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_ case PA_SOURCE_MESSAGE_SET_STATE: s->thread_info.state = PA_PTR_TO_UINT(userdata); return 0; + + case PA_SOURCE_MESSAGE_DETACH: + + /* We're detaching all our output streams so that the + * asyncmsgq and rtpoll fields can be changed without + * problems */ + pa_source_detach_within_thread(s); + break; + + case PA_SOURCE_MESSAGE_ATTACH: + + /* Reattach all streams */ + pa_source_attach_within_thread(s); + break; case PA_SOURCE_MESSAGE_GET_LATENCY: case PA_SOURCE_MESSAGE_MAX: @@ -504,3 +518,42 @@ int pa_source_suspend_all(pa_core *c, int suspend) { return ret; } + +void pa_source_detach(pa_source *s) { + pa_source_assert_ref(s); + pa_assert(PA_SOURCE_LINKED(s->state)); + + pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_DETACH, NULL, 0, NULL); +} + +void pa_source_attach(pa_source *s) { + pa_source_assert_ref(s); + pa_assert(PA_SOURCE_LINKED(s->state)); + + pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_ATTACH, NULL, 0, NULL); +} + +void pa_source_detach_within_thread(pa_source *s) { + pa_source_output *o; + void *state = NULL; + + pa_source_assert_ref(s); + pa_assert(PA_SOURCE_LINKED(s->thread_info.state)); + + while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) + if (o->detach) + o->detach(o); +} + +void pa_source_attach_within_thread(pa_source *s) { + pa_source_output *o; + void *state = NULL; + + pa_source_assert_ref(s); + pa_assert(PA_SOURCE_LINKED(s->thread_info.state)); + + while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL))) + if (o->attach) + o->attach(o); + +} diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index ddc66156..0fd14860 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -121,6 +121,8 @@ typedef enum pa_source_message { PA_SOURCE_MESSAGE_GET_LATENCY, PA_SOURCE_MESSAGE_SET_STATE, PA_SOURCE_MESSAGE_PING, + PA_SOURCE_MESSAGE_ATTACH, + PA_SOURCE_MESSAGE_DETACH, PA_SOURCE_MESSAGE_MAX } pa_source_message_t; @@ -142,6 +144,9 @@ void pa_source_set_description(pa_source *s, const char *description); void pa_source_set_asyncmsgq(pa_source *s, pa_asyncmsgq *q); void pa_source_set_rtpoll(pa_source *s, pa_rtpoll *p); +void pa_source_detach(pa_source *s); +void pa_source_attach(pa_source *s); + /* May be called by everyone, from main context */ pa_usec_t pa_source_get_latency(pa_source *s); @@ -164,8 +169,9 @@ unsigned pa_source_used_by(pa_source *s); void pa_source_post(pa_source*s, const pa_memchunk *b); -int pa_source_process_outputs(pa_source *o); - int pa_source_process_msg(pa_msgobject *o, int code, void *userdata, int64_t, pa_memchunk *chunk); +void pa_source_attach_within_thread(pa_source *s); +void pa_source_detach_within_thread(pa_source *s); + #endif -- cgit From 8389264d6560d32b3912c60474497742807efbde Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 15 Sep 2007 14:21:05 +0000 Subject: count corked streams per sink/source and make pa_sink_used_by() return only the number of streams that are not corked. Introduce pa_sink_linked_by() returning the number of streams connected at all. This will allow suspending of sinks/sources when all streams connected to a sink are corked. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1824 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-combine.c | 2 +- src/pulsecore/sink-input.c | 19 +++++++++++++++++-- src/pulsecore/sink.c | 19 +++++++++++++++++++ src/pulsecore/sink.h | 6 ++++-- src/pulsecore/source-output.c | 6 ++++++ src/pulsecore/source.c | 15 ++++++++++++++- src/pulsecore/source.h | 4 +++- 7 files changed, 64 insertions(+), 7 deletions(-) diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 91561ee7..86ae0b1e 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -385,7 +385,7 @@ static void sink_input_detach_cb(pa_sink_input *i) { o->rtpoll_item = NULL; if (o->userdata->master == o) - pa_sink_detach_from_thread(o->userdata->sink); + pa_sink_detach_within_thread(o->userdata->sink); } /* Called from main context */ diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 2687cfaa..009000e3 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -225,6 +225,15 @@ pa_sink_input* pa_sink_input_new( return i; } +static void update_n_corked(pa_sink_input *i, pa_sink_input_state_t state) { + pa_assert(i); + + if (i->state == PA_SINK_INPUT_CORKED && state != PA_SINK_INPUT_CORKED) + pa_assert_se(i->sink->n_corked -- >= 1); + else if (i->state != PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_CORKED) + i->sink->n_corked++; +} + static int sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) { pa_sink_input *ssync; pa_assert(i); @@ -238,11 +247,17 @@ static int sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) { if (pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) < 0) return -1; + update_n_corked(i, state); i->state = state; - for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev) + + for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev) { + update_n_corked(ssync, state); ssync->state = state; - for (ssync = i->sync_next; ssync; ssync = ssync->sync_next) + } + for (ssync = i->sync_next; ssync; ssync = ssync->sync_next) { + update_n_corked(ssync, state); ssync->state = state; + } return 0; } diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 9b191886..318b191a 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -101,6 +101,7 @@ pa_sink* pa_sink_new( s->channel_map = *map; s->inputs = pa_idxset_new(NULL, NULL); + s->n_corked = 0; pa_cvolume_reset(&s->volume, spec->channels); s->muted = 0; @@ -735,6 +736,20 @@ void pa_sink_set_description(pa_sink *s, const char *description) { pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); } +unsigned pa_sink_linked_by(pa_sink *s) { + unsigned ret; + + pa_sink_assert_ref(s); + pa_assert(PA_SINK_LINKED(s->state)); + + ret = pa_idxset_size(s->inputs); + + if (s->monitor_source) + ret += pa_source_used_by(s->monitor_source); + + return ret; +} + unsigned pa_sink_used_by(pa_sink *s) { unsigned ret; @@ -743,6 +758,10 @@ unsigned pa_sink_used_by(pa_sink *s) { ret = pa_idxset_size(s->inputs); + pa_assert(ret >= s->n_corked); + + ret -= s->n_corked; + if (s->monitor_source) ret += pa_source_used_by(s->monitor_source); diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index be883ed6..537e9cb6 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -77,7 +77,8 @@ struct pa_sink { pa_channel_map channel_map; pa_idxset *inputs; - pa_source *monitor_source; + unsigned n_corked; + pa_source *monitor_source; pa_cvolume volume; int muted; @@ -166,7 +167,8 @@ const pa_cvolume *pa_sink_get_volume(pa_sink *sink); void pa_sink_set_mute(pa_sink *sink, int mute); int pa_sink_get_mute(pa_sink *sink); -unsigned pa_sink_used_by(pa_sink *s); +unsigned pa_sink_linked_by(pa_sink *s); /* Number of connected streams */ +unsigned pa_sink_used_by(pa_sink *s); /* Number of connected streams which are not corked */ #define pa_sink_get_state(s) ((s)->state) /* To be called exclusively by the sink driver, from IO context */ diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index b77a4ae3..8650e532 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -182,7 +182,13 @@ static int source_output_set_state(pa_source_output *o, pa_source_output_state_t if (pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_STATE, PA_UINT_TO_PTR(state), 0, NULL) < 0) return -1; + if (o->state == PA_SOURCE_OUTPUT_CORKED && state != PA_SOURCE_OUTPUT_CORKED) + pa_assert_se(o->source->n_corked -- >= 1); + else if (o->state != PA_SOURCE_OUTPUT_CORKED && state == PA_SOURCE_OUTPUT_CORKED) + o->source->n_corked++; + o->state = state; + return 0; } diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 63ff9d7d..d72349f8 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -93,6 +93,7 @@ pa_source* pa_source_new( s->channel_map = *map; s->outputs = pa_idxset_new(NULL, NULL); + s->n_corked = 0; s->monitor_of = NULL; pa_cvolume_reset(&s->volume, spec->channels); @@ -426,13 +427,25 @@ void pa_source_set_rtpoll(pa_source *s, pa_rtpoll *p) { s->rtpoll = p; } -unsigned pa_source_used_by(pa_source *s) { +unsigned pa_source_linked_by(pa_source *s) { pa_source_assert_ref(s); pa_assert(PA_SOURCE_LINKED(s->state)); return pa_idxset_size(s->outputs); } +unsigned pa_source_used_by(pa_source *s) { + unsigned ret; + + pa_source_assert_ref(s); + pa_assert(PA_SOURCE_LINKED(s->state)); + + ret = pa_idxset_size(s->outputs); + pa_assert(ret >= s->n_corked); + + return ret - s->n_corked; +} + int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_t offset, pa_memchunk *chunk) { pa_source *s = PA_SOURCE(object); pa_source_assert_ref(s); diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index 0fd14860..4e488a74 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -79,6 +79,7 @@ struct pa_source { pa_channel_map channel_map; pa_idxset *outputs; + unsigned n_corked; pa_sink *monitor_of; /* may be NULL */ pa_cvolume volume; @@ -162,7 +163,8 @@ const pa_cvolume *pa_source_get_volume(pa_source *source); void pa_source_set_mute(pa_source *source, int mute); int pa_source_get_mute(pa_source *source); -unsigned pa_source_used_by(pa_source *s); +unsigned pa_source_linked_by(pa_source *s); /* Number of connected streams */ +unsigned pa_source_used_by(pa_source *s); /* Number of connected streams that are not corked */ #define pa_source_get_state(s) ((pa_source_state_t) (s)->state) /* To be called exclusively by the source driver, from IO context */ -- cgit From 298d2392f9b5e586977ddb7e31b45ec322998602 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 15 Sep 2007 14:57:18 +0000 Subject: trivial typo git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1825 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-combine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 86ae0b1e..f2633ab4 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -322,7 +322,7 @@ static void request_memblock(struct output *o) { pa_mutex_unlock(o->userdata->mutex); } -/* Called from I/O trhead context */ +/* Called from I/O thread context */ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { struct output *o; -- cgit From 0469c8436655cb4cc422216ab8a13849080f14c0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 16 Sep 2007 15:05:26 +0000 Subject: add frame alignment APIs; don't require memory to be writable when silencing it (required of the mmap modes drivers where the hw data needs to be silenced, although it is not writable to others) git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1826 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sample-util.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c index a1361f4e..add6608d 100644 --- a/src/pulsecore/sample-util.c +++ b/src/pulsecore/sample-util.c @@ -38,7 +38,7 @@ #include "sample-util.h" #include "endianmacros.h" -#define PA_SILENCE_MAX (1024*1024*1) +#define PA_SILENCE_MAX (PA_PAGE_SIZE*16) pa_memblock *pa_silence_memblock_new(pa_mempool *pool, const pa_sample_spec *spec, size_t length) { size_t fs; @@ -82,7 +82,6 @@ void pa_silence_memchunk(pa_memchunk *c, const pa_sample_spec *spec) { pa_assert(c->memblock); pa_assert(spec); - pa_memchunk_make_writable(c, 0); data = pa_memblock_acquire(c->memblock); pa_silence_memory((uint8_t*) data+c->index, c->length, spec); pa_memblock_release(c->memblock); @@ -474,3 +473,23 @@ void pa_volume_memchunk( pa_memblock_release(c->memblock); } +size_t pa_frame_align(size_t l, const pa_sample_spec *ss) { + size_t fs; + + pa_assert(ss); + + fs = pa_frame_size(ss); + + return (l/fs) * fs; +} + +int pa_frame_aligned(size_t l, const pa_sample_spec *ss) { + size_t fs; + + pa_assert(ss); + + fs = pa_frame_size(ss); + + return l % fs == 0; +} + -- cgit From e17fbf0606200c4fa08bda5d00c9706503dde313 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 16 Sep 2007 15:09:45 +0000 Subject: be a little bit more elaborate on the reason why we drop to software volume control if hw is not featureful enough for us git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1827 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 1bcb30c0..70685e40 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -234,7 +234,7 @@ static int unix_write(struct userdata *u) { l = snd_pcm_status_get_avail(status) * u->frame_size; -/* pa_log("%u bytes to write", l); */ +/* pa_log("%u bytes to write", l); */ if (l <= 0) return work_done; @@ -248,7 +248,7 @@ static int unix_write(struct userdata *u) { t = snd_pcm_writei(u->pcm_handle, (const uint8_t*) p + u->memchunk.index, u->memchunk.length / u->frame_size); pa_memblock_release(u->memchunk.memblock); -/* pa_log("wrote %i bytes of %u (%u)", t*u->frame_size, u->memchunk.length, l); */ +/* pa_log("wrote %i bytes of %u (%u)", t*u->frame_size, u->memchunk.length, l); */ pa_assert(t != 0); @@ -834,16 +834,17 @@ int pa__init(pa_module*m) { if (snd_mixer_selem_has_playback_volume(u->mixer_elem)) { int i; - for (i = 0;i < ss.channels; i++) { + for (i = 0; i < ss.channels; i++) if (!snd_mixer_selem_has_playback_channel(u->mixer_elem, i)) break; - } if (i == ss.channels) { + pa_log_debug("ALSA device has separate volumes controls for all %u channels.", ss.channels); u->sink->get_volume = sink_get_volume_cb; u->sink->set_volume = sink_set_volume_cb; snd_mixer_selem_get_playback_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max); - } + } else + pa_log_info("ALSA device lacks separate volumes controls for all %u channels (%u available), falling back to software volume control.", ss.channels, i+1); } if (snd_mixer_selem_has_playback_switch(u->mixer_elem)) { -- cgit From 87795b09737c0428bec4d1fcec23bfa1df5f92be Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 16 Sep 2007 15:10:16 +0000 Subject: add missing header file changes for frame alignment apis git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1828 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sample-util.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pulsecore/sample-util.h b/src/pulsecore/sample-util.h index 2b11ad3c..0d4924b1 100644 --- a/src/pulsecore/sample-util.h +++ b/src/pulsecore/sample-util.h @@ -56,4 +56,8 @@ void pa_volume_memchunk( const pa_sample_spec *spec, const pa_cvolume *volume); +size_t pa_frame_align(size_t l, const pa_sample_spec *ss); + +int pa_frame_aligned(size_t l, const pa_sample_spec *ss); + #endif -- cgit From d079b4863b2e0c758e81d117df4cdc967c342c22 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 16 Sep 2007 21:54:12 +0000 Subject: properly define MAX/MIN macros git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1829 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/macro.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/macro.h b/src/pulsecore/macro.h index c46ae524..ec451547 100644 --- a/src/pulsecore/macro.h +++ b/src/pulsecore/macro.h @@ -64,8 +64,13 @@ static inline size_t pa_page_align(size_t l) { #define PA_ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0])) -#define SA_MAX(a, b) ((a) > (b) ? (a) : (b)) -#define SA_MIN(a, b) ((a) < (b) ? (a) : (b)) +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif #ifdef __GNUC__ #define PA_PRETTY_FUNCTION __PRETTY_FUNCTION__ -- cgit From fce85071796577ceb59fc0ff413c5188c2e385c1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 16 Sep 2007 21:56:38 +0000 Subject: * add a new resampler "copy" which is does not change sample rates but copies data unmodified from input to output. * add a new API pa_resampler_max_block_size() which can be used to determine the maximum input buffer size for the resampler so that the bounce buffers don't grow larger then the mempool tile size git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1830 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/resampler.c | 66 ++++++++++++++++++++++++++++++++++++++++++++--- src/pulsecore/resampler.h | 4 +++ 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index 7493eef0..c4b8179d 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -45,6 +45,9 @@ #include "resampler.h" +/* Number of samples of extra space we allow the resamplers to return */ +#define EXTRA_SAMPLES 128 + struct pa_resampler { pa_resample_method_t resample_method; pa_sample_spec i_ss, o_ss; @@ -88,6 +91,7 @@ struct pa_resampler { } ffmpeg; }; +static int copy_init(pa_resampler *r); static int trivial_init(pa_resampler*r); static int speex_init(pa_resampler*r); static int ffmpeg_init(pa_resampler*r); @@ -136,6 +140,7 @@ static int (* const init_table[])(pa_resampler*r) = { [PA_RESAMPLER_SPEEX_FIXED_BASE+10] = speex_init, [PA_RESAMPLER_FFMPEG] = ffmpeg_init, [PA_RESAMPLER_AUTO] = NULL, + [PA_RESAMPLER_COPY] = copy_init }; static inline size_t sample_size(pa_sample_format_t f) { @@ -169,13 +174,23 @@ pa_resampler* pa_resampler_new( /* Fix method */ + if (!variable_rate && a->rate == b->rate) { + pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates."); + resample_method = PA_RESAMPLER_COPY; + } + if (!pa_resample_method_supported(resample_method)) { pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(resample_method)); resample_method = PA_RESAMPLER_AUTO; } if (resample_method == PA_RESAMPLER_FFMPEG && variable_rate) { - pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'." ); + pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'."); + resample_method = PA_RESAMPLER_AUTO; + } + + if (resample_method == PA_RESAMPLER_COPY && (variable_rate || a->rate != b->rate)) { + pa_log_info("Resampler 'copy' cannot change sampling rate, reverting to resampler 'auto'."); resample_method = PA_RESAMPLER_AUTO; } @@ -321,6 +336,35 @@ size_t pa_resampler_request(pa_resampler *r, size_t out_length) { return (((out_length / r->o_fz)*r->i_ss.rate)/r->o_ss.rate) * r->i_fz; } +size_t pa_resampler_max_block_size(pa_resampler *r) { + size_t block_size_max; + pa_sample_spec ss; + size_t fs; + + pa_assert(r); + + block_size_max = pa_mempool_block_size_max(r->mempool); + + /* We deduce the "largest" sample spec we're using during the + * conversion */ + ss = r->i_ss; + if (r->o_ss.channels > ss.channels) + ss.channels = r->o_ss.channels; + + /* We silently assume that the format enum is ordered by size */ + if (r->o_ss.format > ss.format) + ss.format = r->o_ss.format; + if (r->work_format > ss.format) + ss.format = r->work_format; + + if (r->o_ss.rate > ss.rate) + ss.rate = r->o_ss.rate; + + fs = pa_frame_size(&ss); + + return (((block_size_max/fs + EXTRA_SAMPLES)*r->i_ss.rate)/ss.rate)*r->i_fz; +} + pa_resample_method_t pa_resampler_get_method(pa_resampler *r) { pa_assert(r); @@ -357,7 +401,8 @@ static const char * const resample_methods[] = { "speex-fixed-9", "speex-fixed-10", "ffmpeg", - "auto" + "auto", + "copy" }; const char *pa_resample_method_to_string(pa_resample_method_t m) { @@ -568,7 +613,7 @@ static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) { in_n_samples = input->length / r->w_sz; in_n_frames = in_n_samples / r->o_ss.channels; - out_n_frames = ((in_n_frames*r->o_ss.rate)/r->i_ss.rate)+1024; + out_n_frames = ((in_n_frames*r->o_ss.rate)/r->i_ss.rate)+EXTRA_SAMPLES; out_n_samples = out_n_frames * r->o_ss.channels; r->buf3.index = 0; @@ -875,6 +920,7 @@ static int trivial_init(pa_resampler*r) { r->impl_resample = trivial_resample; r->impl_update_rates = trivial_update_rates; + r->impl_free = NULL; return 0; } @@ -994,3 +1040,17 @@ static int ffmpeg_init(pa_resampler *r) { return 0; } + +/*** copy (noop) implementation ***/ + +static int copy_init(pa_resampler *r) { + pa_assert(r); + + pa_assert(r->o_ss.rate == r->i_ss.rate); + + r->impl_free = NULL; + r->impl_resample = NULL; + r->impl_update_rates = NULL; + + return 0; +} diff --git a/src/pulsecore/resampler.h b/src/pulsecore/resampler.h index fed4d897..8de8ad71 100644 --- a/src/pulsecore/resampler.h +++ b/src/pulsecore/resampler.h @@ -45,6 +45,7 @@ typedef enum pa_resample_method { PA_RESAMPLER_SPEEX_FIXED_MAX = PA_RESAMPLER_SPEEX_FIXED_BASE + 10, PA_RESAMPLER_FFMPEG, PA_RESAMPLER_AUTO, /* automatic select based on sample format */ + PA_RESAMPLER_COPY, PA_RESAMPLER_MAX } pa_resample_method_t; @@ -62,6 +63,9 @@ void pa_resampler_free(pa_resampler *r); /* Returns the size of an input memory block which is required to return the specified amount of output data */ size_t pa_resampler_request(pa_resampler *r, size_t out_length); +/* Requires the maximum size of input blocks we can process without needing bounce buffers larger than the mempool tile size. */ +size_t pa_resampler_max_block_size(pa_resampler *r); + /* Pass the specified memory chunk to the resampler and return the newly resampled data */ void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out); -- cgit From ac1ee4e6754f3aa287bb4e3ede03c59d1369cd50 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 16 Sep 2007 21:57:15 +0000 Subject: add new API pa_mempool_block_size_max() to query the maximum tile size git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1831 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/memblock.c | 9 ++++++++- src/pulsecore/memblock.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index cded2dfc..05fc34d9 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -300,7 +300,7 @@ pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) { * take the largest size that fits in one of our slots. */ if (length == (size_t) -1) - length = p->block_size - PA_ALIGN(sizeof(struct mempool_slot)) - PA_ALIGN(sizeof(pa_memblock)); + length = pa_mempool_block_size_max(p); if (p->block_size - PA_ALIGN(sizeof(struct mempool_slot)) >= PA_ALIGN(sizeof(pa_memblock)) + length) { @@ -722,6 +722,13 @@ const pa_mempool_stat* pa_mempool_get_stat(pa_mempool *p) { return &p->stat; } +/* No lock necessary */ +size_t pa_mempool_block_size_max(pa_mempool *p) { + pa_assert(p); + + return p->block_size - PA_ALIGN(sizeof(struct mempool_slot)) - PA_ALIGN(sizeof(pa_memblock)); +} + /* No lock necessary */ void pa_mempool_vacuum(pa_mempool *p) { struct mempool_slot *slot; diff --git a/src/pulsecore/memblock.h b/src/pulsecore/memblock.h index 9bf7d8a5..c704014a 100644 --- a/src/pulsecore/memblock.h +++ b/src/pulsecore/memblock.h @@ -122,6 +122,7 @@ const pa_mempool_stat* pa_mempool_get_stat(pa_mempool *p); void pa_mempool_vacuum(pa_mempool *p); int pa_mempool_get_shm_id(pa_mempool *p, uint32_t *id); int pa_mempool_is_shared(pa_mempool *p); +size_t pa_mempool_block_size_max(pa_mempool *p); /* For recieving blocks from other nodes */ pa_memimport* pa_memimport_new(pa_mempool *p, pa_memimport_release_cb_t cb, void *userdata); -- cgit From 5df7a85473f1c06a8baf6a4d81433bde18f86714 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 16 Sep 2007 21:58:04 +0000 Subject: split memblocks into multiples of the mempool tile size git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1832 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/pstream.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c index 33bc520c..333012c0 100644 --- a/src/pulsecore/pstream.c +++ b/src/pulsecore/pstream.c @@ -40,16 +40,17 @@ #include #endif -#include "winsock.h" #include +#include #include #include #include #include #include #include +#include #include "pstream.h" @@ -83,7 +84,6 @@ typedef uint32_t pa_pstream_descriptor[PA_PSTREAM_DESCRIPTOR_MAX]; #define PA_PSTREAM_DESCRIPTOR_SIZE (PA_PSTREAM_DESCRIPTOR_MAX*sizeof(uint32_t)) #define FRAME_SIZE_MAX_ALLOW PA_SCACHE_ENTRY_SIZE_MAX /* allow uploading a single sample in one frame at max */ -#define FRAME_SIZE_MAX_USE (1024*64) PA_STATIC_FLIST_DECLARE(items, 0, pa_xfree); @@ -351,6 +351,7 @@ void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const pa_creds *cre void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa_seek_mode_t seek_mode, const pa_memchunk *chunk) { size_t length, idx; + size_t bsm; pa_assert(p); pa_assert(PA_REFCNT_VALUE(p) > 0); @@ -362,6 +363,8 @@ void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa idx = 0; length = chunk->length; + + bsm = pa_mempool_block_size_max(p->mempool); while (length > 0) { struct item_info *i; @@ -371,7 +374,7 @@ void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa i = pa_xnew(struct item_info, 1); i->type = PA_PSTREAM_ITEM_MEMBLOCK; - n = length < FRAME_SIZE_MAX_USE ? length : FRAME_SIZE_MAX_USE; + n = MIN(length, bsm); i->chunk.index = chunk->index + idx; i->chunk.length = n; i->chunk.memblock = pa_memblock_ref(chunk->memblock); -- cgit From 1d1eda60595622a79e598e7c986cc3c23e6a5c34 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 16 Sep 2007 22:00:38 +0000 Subject: add a "length" argument to the seek functions, as an optimization to request a certain block size if any data needs to be generated. this is merely a hint. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1833 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-combine.c | 8 +++--- src/modules/module-sine.c | 2 +- src/pulsecore/play-memblockq.c | 2 +- src/pulsecore/play-memchunk.c | 2 +- src/pulsecore/protocol-esound.c | 4 +-- src/pulsecore/protocol-native.c | 4 +-- src/pulsecore/protocol-simple.c | 2 +- src/pulsecore/sink-input.c | 56 ++++++++++++++++++++++++++++----------- src/pulsecore/sink-input.h | 10 ++++--- src/pulsecore/sink.c | 44 +++++++++++++++++++++--------- src/pulsecore/sound-file-stream.c | 10 +++---- 11 files changed, 94 insertions(+), 50 deletions(-) diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index f2633ab4..235e04e6 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -275,7 +275,7 @@ finish: pa_log_debug("Thread shutting down"); } -static void request_memblock(struct output *o) { +static void request_memblock(struct output *o, size_t length) { pa_memchunk chunk; pa_assert(o); @@ -306,7 +306,7 @@ static void request_memblock(struct output *o) { struct output *j; /* Do it! */ - pa_sink_render(o->userdata->sink, o->userdata->block_size, &chunk); + pa_sink_render(o->userdata->sink, length, &chunk); /* OK, let's send this data to the other threads */ for (j = o->userdata->thread_info.outputs; j; j = j->next) @@ -323,7 +323,7 @@ static void request_memblock(struct output *o) { } /* Called from I/O thread context */ -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { +static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) { struct output *o; pa_sink_input_assert_ref(i); @@ -331,7 +331,7 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { pa_assert(o); /* If necessary, get some new data */ - request_memblock(o); + request_memblock(o, length); return pa_memblockq_peek(o->memblockq, chunk); } diff --git a/src/modules/module-sine.c b/src/modules/module-sine.c index f48cb09e..5684f94c 100644 --- a/src/modules/module-sine.c +++ b/src/modules/module-sine.c @@ -58,7 +58,7 @@ static const char* const valid_modargs[] = { NULL, }; -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { +static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) { struct userdata *u; pa_assert(i); diff --git a/src/pulsecore/play-memblockq.c b/src/pulsecore/play-memblockq.c index 68ce21b1..5652ac2b 100644 --- a/src/pulsecore/play-memblockq.c +++ b/src/pulsecore/play-memblockq.c @@ -97,7 +97,7 @@ static void sink_input_kill_cb(pa_sink_input *i) { memblockq_stream_unlink(MEMBLOCKQ_STREAM(i->userdata)); } -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { +static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) { memblockq_stream *u; pa_assert(i); diff --git a/src/pulsecore/play-memchunk.c b/src/pulsecore/play-memchunk.c index f60f706e..fd931a24 100644 --- a/src/pulsecore/play-memchunk.c +++ b/src/pulsecore/play-memchunk.c @@ -97,7 +97,7 @@ static void sink_input_kill_cb(pa_sink_input *i) { memchunk_stream_unlink(MEMCHUNK_STREAM(i->userdata)); } -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { +static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) { memchunk_stream *u; pa_assert(i); diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c index fc881c81..b6943634 100644 --- a/src/pulsecore/protocol-esound.c +++ b/src/pulsecore/protocol-esound.c @@ -150,7 +150,7 @@ typedef struct proto_handler { } esd_proto_handler_info_t; static void sink_input_drop_cb(pa_sink_input *i, size_t length); -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk); +static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk); static void sink_input_kill_cb(pa_sink_input *i); static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk); static pa_usec_t source_output_get_latency_cb(pa_source_output *o); @@ -1237,7 +1237,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int } /* Called from thread context */ -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { +static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) { connection*c; int r; diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 52cec097..24f5997e 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -199,7 +199,7 @@ enum { CONNECTION_MESSAGE_REVOKE }; -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk); +static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk); static void sink_input_drop_cb(pa_sink_input *i, size_t length); static void sink_input_kill_cb(pa_sink_input *i); @@ -973,7 +973,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int } /* Called from thread context */ -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { +static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) { playback_stream *s; pa_sink_input_assert_ref(i); diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index db7c9a69..da5f24e7 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -343,7 +343,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int } /* Called from thread context */ -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { +static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) { connection *c; int r; diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 009000e3..f2855fc9 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -41,9 +41,9 @@ #include "sink-input.h" -#define CONVERT_BUFFER_LENGTH 4096 -#define MOVE_BUFFER_LENGTH (1024*1024) -#define SILENCE_BUFFER_LENGTH (64*1024) +#define CONVERT_BUFFER_LENGTH (PA_PAGE_SIZE) +#define SILENCE_BUFFER_LENGTH (PA_PAGE_SIZE*12) +#define MOVE_BUFFER_LENGTH (PA_PAGE_SIZE*256) static PA_DEFINE_CHECK_TYPE(pa_sink_input, pa_msgobject); @@ -368,13 +368,15 @@ pa_usec_t pa_sink_input_get_latency(pa_sink_input *i) { } /* Called from thread context */ -int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) { +int pa_sink_input_peek(pa_sink_input *i, size_t length, pa_memchunk *chunk, pa_cvolume *volume) { int ret = -1; int do_volume_adj_here; int volume_is_norm; + size_t block_size_max; pa_sink_input_assert_ref(i); pa_assert(PA_SINK_INPUT_LINKED(i->thread_info.state)); + pa_assert(pa_frame_aligned(length, &i->sink->sample_spec)); pa_assert(chunk); pa_assert(volume); @@ -383,6 +385,15 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) pa_assert(i->thread_info.state == PA_SINK_INPUT_RUNNING || i->thread_info.state == PA_SINK_INPUT_DRAINED); + /* Default buffer size */ + if (length <= 0) + length = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sink->sample_spec); + + /* Make sure the buffer fits in the mempool tile */ + block_size_max = pa_mempool_block_size_max(i->sink->core->mempool); + if (length > block_size_max) + length = pa_frame_align(block_size_max, &i->sink->sample_spec); + if (i->thread_info.move_silence > 0) { size_t l; @@ -390,7 +401,10 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) * while until the old sink has drained its playback buffer */ if (!i->thread_info.silence_memblock) - i->thread_info.silence_memblock = pa_silence_memblock_new(i->sink->core->mempool, &i->sink->sample_spec, SILENCE_BUFFER_LENGTH); + i->thread_info.silence_memblock = pa_silence_memblock_new( + i->sink->core->mempool, + &i->sink->sample_spec, + pa_frame_align(SILENCE_BUFFER_LENGTH, &i->sink->sample_spec)); chunk->memblock = pa_memblock_ref(i->thread_info.silence_memblock); chunk->index = 0; @@ -404,7 +418,7 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) if (!i->thread_info.resampler) { do_volume_adj_here = 0; /* FIXME??? */ - ret = i->peek(i, chunk); + ret = i->peek(i, length, chunk); goto finish; } @@ -413,15 +427,22 @@ int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) while (!i->thread_info.resampled_chunk.memblock) { pa_memchunk tchunk; - size_t l; + size_t l, rmbs; - if ((ret = i->peek(i, &tchunk)) < 0) + l = pa_resampler_request(i->thread_info.resampler, length); + + if (l <= 0) + l = pa_frame_align(CONVERT_BUFFER_LENGTH, &i->sample_spec); + + rmbs = pa_resampler_max_block_size(i->thread_info.resampler); + if (l > rmbs) + l = rmbs; + + if ((ret = i->peek(i, l, &tchunk)) < 0) goto finish; pa_assert(tchunk.length > 0); - l = pa_resampler_request(i->thread_info.resampler, CONVERT_BUFFER_LENGTH); - if (tchunk.length > l) tchunk.length = l; @@ -477,6 +498,7 @@ finish: void pa_sink_input_drop(pa_sink_input *i, size_t length) { pa_sink_input_assert_ref(i); pa_assert(PA_SINK_INPUT_LINKED(i->thread_info.state)); + pa_assert(pa_frame_aligned(length, &i->sink->sample_spec)); pa_assert(length > 0); if (i->thread_info.move_silence > 0) { @@ -527,9 +549,9 @@ void pa_sink_input_drop(pa_sink_input *i, size_t length) { pa_memchunk chunk; pa_cvolume volume; - if (pa_sink_input_peek(i, &chunk, &volume) >= 0) { + if (pa_sink_input_peek(i, length, &chunk, &volume) >= 0) { size_t l; - + pa_memblock_unref(chunk.memblock); l = chunk.length; @@ -541,11 +563,13 @@ void pa_sink_input_drop(pa_sink_input *i, size_t length) { } else { size_t l; - + + l = pa_resampler_request(i->thread_info.resampler, length); + /* Hmmm, peeking failed, so let's at least drop * the right amount of data */ - if ((l = pa_resampler_request(i->thread_info.resampler, length)) > 0) + if (l > 0) if (i->drop) i->drop(i, l); @@ -798,9 +822,9 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { i->thread_info.move_silence = 0; else i->thread_info.move_silence = pa_usec_to_bytes( - pa_bytes_to_usec(i->thread_info.move_silence, &i->sample_spec) + + pa_bytes_to_usec(i->thread_info.move_silence, &origin->sample_spec) + silence_usec, - &i->sample_spec); + &dest->sample_spec); pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, i, 0, NULL); diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index a101828f..7d405640 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -83,8 +83,12 @@ struct pa_sink_input { int muted; /* Returns the chunk of audio data (but doesn't drop it - * yet!). Returns -1 on failure. Called from IO thread context. */ - int (*peek) (pa_sink_input *i, pa_memchunk *chunk); + * yet!). Returns -1 on failure. Called from IO thread context. If + * data needs to be generated from scratch then please in the + * specified length. This is an optimization only. If less data is + * available, it's fine to return a smaller block. If more data is + * already ready, it is better to return the full block.*/ + int (*peek) (pa_sink_input *i, size_t length, pa_memchunk *chunk); /* Drops the specified number of bytes, usually called right after * peek(), but not necessarily. Called from IO thread context. */ @@ -217,7 +221,7 @@ pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i); /* To be used exclusively by the sink driver thread */ -int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume); +int pa_sink_input_peek(pa_sink_input *i, size_t length, pa_memchunk *chunk, pa_cvolume *volume); void pa_sink_input_drop(pa_sink_input *i, size_t length); int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk); diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 318b191a..45cc96bf 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -46,7 +46,8 @@ #include "sink.h" #define MAX_MIX_CHANNELS 32 -#define SILENCE_BUFFER_LENGTH (64*1024) +#define MIX_BUFFER_LENGTH (PA_PAGE_SIZE) +#define SILENCE_BUFFER_LENGTH (PA_PAGE_SIZE*12) static PA_DEFINE_CHECK_TYPE(pa_sink, pa_msgobject); @@ -311,7 +312,7 @@ void pa_sink_ping(pa_sink *s) { pa_asyncmsgq_post(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_PING, NULL, 0, NULL, NULL); } -static unsigned fill_mix_info(pa_sink *s, pa_mix_info *info, unsigned maxinfo) { +static unsigned fill_mix_info(pa_sink *s, size_t length, pa_mix_info *info, unsigned maxinfo) { pa_sink_input *i; unsigned n = 0; void *state = NULL; @@ -322,7 +323,7 @@ static unsigned fill_mix_info(pa_sink *s, pa_mix_info *info, unsigned maxinfo) { while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)) && maxinfo > 0) { pa_sink_input_assert_ref(i); - if (pa_sink_input_peek(i, &info->chunk, &info->volume) < 0) + if (pa_sink_input_peek(i, length, &info->chunk, &info->volume) < 0) continue; info->userdata = pa_sink_input_ref(i); @@ -399,20 +400,32 @@ static void inputs_drop(pa_sink *s, pa_mix_info *info, unsigned n, size_t length void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) { pa_mix_info info[MAX_MIX_CHANNELS]; unsigned n; - + size_t block_size_max; + pa_sink_assert_ref(s); pa_assert(PA_SINK_OPENED(s->thread_info.state)); - pa_assert(length); + pa_assert(pa_frame_aligned(length, &s->sample_spec)); pa_assert(result); pa_sink_ref(s); - n = s->thread_info.state == PA_SINK_RUNNING ? fill_mix_info(s, info, MAX_MIX_CHANNELS) : 0; + if (length <= 0) + length = pa_frame_align(MIX_BUFFER_LENGTH, &s->sample_spec); + + block_size_max = pa_mempool_block_size_max(s->core->mempool); + if (length > block_size_max) + length = pa_frame_align(block_size_max, &s->sample_spec); + + pa_assert(length > 0); + + n = s->thread_info.state == PA_SINK_RUNNING ? fill_mix_info(s, length, info, MAX_MIX_CHANNELS) : 0; if (n == 0) { if (length > SILENCE_BUFFER_LENGTH) - length = SILENCE_BUFFER_LENGTH; + length = pa_frame_align(SILENCE_BUFFER_LENGTH, &s->sample_spec); + + pa_assert(length > 0); if (!s->silence || pa_memblock_get_length(s->silence) < length) { if (s->silence) @@ -470,11 +483,12 @@ void pa_sink_render_into(pa_sink*s, pa_memchunk *target) { pa_assert(PA_SINK_OPENED(s->thread_info.state)); pa_assert(target); pa_assert(target->memblock); - pa_assert(target->length); + pa_assert(target->length > 0); + pa_assert(pa_frame_aligned(target->length, &s->sample_spec)); pa_sink_ref(s); - n = s->thread_info.state == PA_SINK_RUNNING ? fill_mix_info(s, info, MAX_MIX_CHANNELS) : 0; + n = s->thread_info.state == PA_SINK_RUNNING ? fill_mix_info(s, target->length, info, MAX_MIX_CHANNELS) : 0; if (n == 0) { pa_silence_memchunk(target, &s->sample_spec); @@ -536,7 +550,8 @@ void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) { pa_assert(PA_SINK_OPENED(s->thread_info.state)); pa_assert(target); pa_assert(target->memblock); - pa_assert(target->length); + pa_assert(target->length > 0); + pa_assert(pa_frame_aligned(target->length, &s->sample_spec)); pa_sink_ref(s); @@ -559,13 +574,15 @@ void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) { void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) { pa_sink_assert_ref(s); pa_assert(PA_SINK_OPENED(s->thread_info.state)); - pa_assert(length); + pa_assert(length > 0); + pa_assert(pa_frame_aligned(length, &s->sample_spec)); pa_assert(result); /*** This needs optimization ***/ - result->memblock = pa_memblock_new(s->core->mempool, result->length = length); result->index = 0; + result->length = length; + result->memblock = pa_memblock_new(s->core->mempool, length); pa_sink_render_into_full(s, result); } @@ -577,6 +594,7 @@ void pa_sink_skip(pa_sink *s, size_t length) { pa_sink_assert_ref(s); pa_assert(PA_SINK_OPENED(s->thread_info.state)); pa_assert(length > 0); + pa_assert(pa_frame_aligned(length, &s->sample_spec)); if (pa_source_used_by(s->monitor_source)) { pa_memchunk chunk; @@ -853,7 +871,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse pa_cvolume volume; size_t n; - if (pa_sink_input_peek(info->sink_input, &memchunk, &volume) < 0) + if (pa_sink_input_peek(info->sink_input, info->buffer_bytes, &memchunk, &volume) < 0) break; n = memchunk.length > info->buffer_bytes ? info->buffer_bytes : memchunk.length; diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index 8a04b821..6c70c4f1 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -44,8 +44,6 @@ #include "sound-file-stream.h" -#define BUF_SIZE (1024*16) - typedef struct file_stream { pa_msgobject parent; pa_core *core; @@ -113,7 +111,7 @@ static void sink_input_kill_cb(pa_sink_input *i) { file_stream_unlink(FILE_STREAM(i->userdata)); } -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { +static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) { file_stream *u; pa_assert(i); @@ -128,7 +126,7 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { if (!u->memchunk.memblock) { - u->memchunk.memblock = pa_memblock_new(i->sink->core->mempool, BUF_SIZE); + u->memchunk.memblock = pa_memblock_new(i->sink->core->mempool, length); u->memchunk.index = 0; if (u->readf_function) { @@ -137,7 +135,7 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { size_t fs = pa_frame_size(&i->sample_spec); p = pa_memblock_acquire(u->memchunk.memblock); - n = u->readf_function(u->sndfile, p, BUF_SIZE/fs); + n = u->readf_function(u->sndfile, p, length/fs); pa_memblock_release(u->memchunk.memblock); if (n <= 0) @@ -149,7 +147,7 @@ static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { void *p; p = pa_memblock_acquire(u->memchunk.memblock); - n = sf_read_raw(u->sndfile, p, BUF_SIZE); + n = sf_read_raw(u->sndfile, p, length); pa_memblock_release(u->memchunk.memblock); if (n <= 0) -- cgit From 35483eeab7d08bc3e7ab2cd7a91e3d7453dca605 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 16 Sep 2007 22:03:19 +0000 Subject: add a new module module-remap-sink which can be used to remap the channel maps of an already existant sink. one use case is to create a virtual sink that redirects stereo data to the rear speakers of a surround card. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1834 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 8 +- src/modules/module-remap-sink.c | 330 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 337 insertions(+), 1 deletion(-) create mode 100644 src/modules/module-remap-sink.c diff --git a/src/Makefile.am b/src/Makefile.am index a04a91a8..9914c193 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -934,7 +934,8 @@ modlibexec_LTLIBRARIES += \ module-native-protocol-tcp.la \ module-native-protocol-fd.la \ module-esound-protocol-tcp.la \ - module-combine.la + module-combine.la \ + module-remap-sink.la # module-tunnel-sink.la \ # module-tunnel-source.la \ # module-esound-sink.la @@ -1054,6 +1055,7 @@ SYMDEF_FILES = \ modules/module-native-protocol-fd-symdef.h \ modules/module-sine-symdef.h \ modules/module-combine-symdef.h \ + modules/module-remap-sink-symdef.h \ modules/module-esound-compat-spawnfd-symdef.h \ modules/module-esound-compat-spawnpid-symdef.h \ modules/module-match-symdef.h \ @@ -1202,6 +1204,10 @@ module_combine_la_SOURCES = modules/module-combine.c module_combine_la_LDFLAGS = -module -avoid-version module_combine_la_LIBADD = $(AM_LIBADD) libpulsecore.la +module_remap_sink_la_SOURCES = modules/module-remap-sink.c +module_remap_sink_la_LDFLAGS = -module -avoid-version +module_remap_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la + module_match_la_SOURCES = modules/module-match.c module_match_la_LDFLAGS = -module -avoid-version module_match_la_LIBADD = $(AM_LIBADD) libpulsecore.la diff --git a/src/modules/module-remap-sink.c b/src/modules/module-remap-sink.c new file mode 100644 index 00000000..1d272b18 --- /dev/null +++ b/src/modules/module-remap-sink.c @@ -0,0 +1,330 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "module-remap-sink-symdef.h" + +PA_MODULE_AUTHOR("Lennart Poettering") +PA_MODULE_DESCRIPTION("Virtual channel remapping sink") +PA_MODULE_VERSION(PACKAGE_VERSION) +PA_MODULE_USAGE( + "sink_name= " + "master= " + "master_channel_map= " + "format= " + "channels= " + "rate= " + "channel_map=") + +#define DEFAULT_SINK_NAME "remapped" + +struct userdata { + pa_core *core; + pa_module *module; + + pa_sink *sink, *master; + pa_sink_input *sink_input; + + pa_memchunk memchunk; +}; + +static const char* const valid_modargs[] = { + "sink_name", + "master", + "master_channel_map", + "rate", + "format", + "channels", + "channel_map", + NULL +}; + +/* Called from I/O thread context */ +static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { + struct userdata *u = PA_SINK(o)->userdata; + + switch (code) { + + case PA_SINK_MESSAGE_GET_LATENCY: { + pa_usec_t usec = 0; + + if (PA_MSGOBJECT(u->master)->process_msg(PA_MSGOBJECT(u->master), PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0) + usec = 0; + + *((pa_usec_t*) data) = usec + pa_bytes_to_usec(u->memchunk.length, &u->sink->sample_spec); + return 0; + } + } + + return pa_sink_process_msg(o, code, data, offset, chunk); +} + +/* Called from main context */ +static int sink_set_state(pa_sink *s, pa_sink_state_t state) { + struct userdata *u; + + pa_sink_assert_ref(s); + pa_assert_se(u = s->userdata); + + if (PA_SINK_LINKED(state) && u->sink_input) + pa_sink_input_cork(u->sink_input, state == PA_SINK_SUSPENDED); + + return 0; +} + +/* Called from I/O thread context */ +static int sink_input_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { + struct userdata *u = PA_SINK_INPUT(o)->userdata; + + switch (code) { + case PA_SINK_INPUT_MESSAGE_GET_LATENCY: + *((pa_usec_t*) data) = pa_bytes_to_usec(u->memchunk.length, &u->sink_input->sample_spec); + + /* Fall through, the default handler will add in the extra + * latency added by the resampler */ + break; + } + + return pa_sink_input_process_msg(o, code, data, offset, chunk); +} + +/* Called from I/O thread context */ +static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) { + struct userdata *u; + + pa_sink_input_assert_ref(i); + pa_assert_se(u = i->userdata); + + if (!u->memchunk.memblock) + pa_sink_render(u->sink, length, &u->memchunk); + + pa_assert(u->memchunk.memblock); + *chunk = u->memchunk; + pa_memblock_ref(chunk->memblock); + return 0; +} + +/* Called from I/O thread context */ +static void sink_input_drop_cb(pa_sink_input *i, size_t length) { + struct userdata *u; + + pa_sink_input_assert_ref(i); + pa_assert_se(u = i->userdata); + pa_assert(length > 0); + + if (u->memchunk.memblock) { + + if (length < u->memchunk.length) { + u->memchunk.index += length; + u->memchunk.length -= length; + return; + } + + pa_memblock_unref(u->memchunk.memblock); + length -= u->memchunk.length; + pa_memchunk_reset(&u->memchunk); + } + + if (length > 0) + pa_sink_skip(u->sink, length); +} + +/* Called from I/O thread context */ +static void sink_input_detach_cb(pa_sink_input *i) { + struct userdata *u; + + pa_sink_input_assert_ref(i); + pa_assert_se(u = i->userdata); + + pa_sink_detach_within_thread(u->sink); +} + +/* Called from I/O thread context */ +static void sink_input_attach_cb(pa_sink_input *i) { + struct userdata *u; + + pa_sink_input_assert_ref(i); + pa_assert_se(u = i->userdata); + + pa_sink_set_asyncmsgq(u->sink, i->sink->asyncmsgq); + pa_sink_set_rtpoll(u->sink, i->sink->rtpoll); + + pa_sink_attach_within_thread(u->sink); +} + +/* Called from main context */ +static void sink_input_kill_cb(pa_sink_input *i) { + struct userdata *u; + + pa_sink_input_assert_ref(i); + pa_assert_se(u = i->userdata); + + pa_sink_input_unlink(u->sink_input); + pa_sink_input_unref(u->sink_input); + u->sink_input = NULL; + + pa_sink_unlink(u->sink); + pa_sink_unref(u->sink); + u->sink = NULL; + + pa_module_unload_request(u->module); +} + +int pa__init(pa_module*m) { + struct userdata *u; + pa_sample_spec ss; + pa_channel_map sink_map, stream_map; + pa_modargs *ma; + char *t; + pa_sink *master; + pa_sink_input_new_data data; + + pa_assert(m); + + if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { + pa_log("Failed to parse module arguments."); + goto fail; + } + + if (!(master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "master", NULL), PA_NAMEREG_SINK, 1))) { + pa_log("Master sink not found"); + goto fail; + } + + ss = master->sample_spec; + sink_map = master->channel_map; + if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &sink_map, PA_CHANNEL_MAP_DEFAULT) < 0) { + pa_log("Invalid sample format specification or channel map"); + goto fail; + } + + stream_map = sink_map; + if (pa_modargs_get_channel_map(ma, "master_channel_map", &stream_map) < 0) { + pa_log("Invalid master hannel map"); + goto fail; + } + + if (stream_map.channels != ss.channels) { + pa_log("Number of channels doesn't match"); + goto fail; + } + + u = pa_xnew0(struct userdata, 1); + u->core = m->core; + u->module = m; + m->userdata = u; + u->master = master; + pa_memchunk_reset(&u->memchunk); + + /* Create sink */ + if (!(u->sink = pa_sink_new(m->core, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &sink_map))) { + pa_log("Failed to create sink."); + goto fail; + } + + u->sink->parent.process_msg = sink_process_msg; + u->sink->set_state = sink_set_state; + u->sink->userdata = u; + u->sink->flags = PA_SINK_LATENCY|PA_SINK_CAN_SUSPEND; + + pa_sink_set_module(u->sink, m); + pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Remapped sink of '%s'", master->description)); + pa_xfree(t); + pa_sink_set_asyncmsgq(u->sink, master->asyncmsgq); + pa_sink_set_rtpoll(u->sink, master->rtpoll); + + /* Create sink input */ + pa_sink_input_new_data_init(&data); + data.sink = u->master; + data.driver = __FILE__; + data.name = "Remapped stream"; + pa_sink_input_new_data_set_sample_spec(&data, &ss); + pa_sink_input_new_data_set_channel_map(&data, &stream_map); + data.module = m; + + if (!(u->sink_input = pa_sink_input_new(m->core, &data, PA_SINK_INPUT_DONT_MOVE))) + goto fail; + + u->sink_input->parent.process_msg = sink_input_process_msg; + u->sink_input->peek = sink_input_peek_cb; + u->sink_input->drop = sink_input_drop_cb; + u->sink_input->kill = sink_input_kill_cb; + u->sink_input->attach = sink_input_attach_cb; + u->sink_input->detach = sink_input_detach_cb; + u->sink_input->userdata = u; + + pa_sink_put(u->sink); + pa_sink_input_put(u->sink_input); + + pa_modargs_free(ma); + + return 0; + +fail: + if (ma) + pa_modargs_free(ma); + + pa__done(m); + + return -1; +} + +void pa__done(pa_module*m) { + struct userdata *u; + + pa_assert(m); + + if (!(u = m->userdata)) + return; + + if (u->sink_input) { + pa_sink_input_unlink(u->sink_input); + pa_sink_input_unref(u->sink_input); + } + + if (u->sink) { + pa_sink_unlink(u->sink); + pa_sink_unref(u->sink); + } + + if (u->memchunk.memblock) + pa_memblock_unref(u->memchunk.memblock); + + pa_xfree(u); +} -- cgit From 116ddaaae9267d9f89f3d127cba62763246b441c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 16 Sep 2007 22:42:03 +0000 Subject: use gcc const and pure function attributes wherever applicable git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1835 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/cdecl.h | 18 ++++++++++++++++++ src/pulse/channelmap.h | 6 +++--- src/pulse/sample.h | 18 +++++++++--------- src/pulse/timeval.h | 6 +++--- src/pulse/utf8.h | 2 +- src/pulse/volume.h | 20 ++++++++++---------- src/pulsecore/core-util.h | 8 ++++---- src/pulsecore/gccmacro.h | 19 +++++++++++++++++++ src/pulsecore/sample-util.h | 4 ++-- src/pulsecore/sconv.h | 8 ++++---- 10 files changed, 73 insertions(+), 36 deletions(-) diff --git a/src/pulse/cdecl.h b/src/pulse/cdecl.h index 922ad276..e1f23d25 100644 --- a/src/pulse/cdecl.h +++ b/src/pulse/cdecl.h @@ -41,4 +41,22 @@ #endif +#ifndef PA_GCC_PURE +#ifdef __GNUCC__ +#define PA_GCC_PURE __attribute__ ((pure)) +#else +/** This function's return value depends only the arguments list and global state **/ +#define PA_GCC_PURE +#endif +#endif + +#ifndef PA_GCC_CONST +#ifdef __GNUCC__ +#define PA_GCC_CONST __attribute__ ((pure)) +#else +/** This function's return value depends only the arguments list (stricter version of PA_GCC_CONST) **/ +#define PA_GCC_CONST +#endif +#endif + #endif diff --git a/src/pulse/channelmap.h b/src/pulse/channelmap.h index bb8ce952..a05e1911 100644 --- a/src/pulse/channelmap.h +++ b/src/pulse/channelmap.h @@ -172,7 +172,7 @@ pa_channel_map* pa_channel_map_init_stereo(pa_channel_map *m); pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, pa_channel_map_def_t def); /** Return a text label for the specified channel position */ -const char* pa_channel_position_to_string(pa_channel_position_t pos); +const char* pa_channel_position_to_string(pa_channel_position_t pos) PA_GCC_PURE; /** Return a human readable text label for the specified channel position. \since 0.9.7 */ const char* pa_channel_position_to_pretty_string(pa_channel_position_t pos); @@ -187,10 +187,10 @@ char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map); pa_channel_map *pa_channel_map_parse(pa_channel_map *map, const char *s); /** Compare two channel maps. Return 1 if both match. */ -int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b); +int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) PA_GCC_PURE; /** Return non-zero of the specified channel map is considered valid */ -int pa_channel_map_valid(const pa_channel_map *map); +int pa_channel_map_valid(const pa_channel_map *map) PA_GCC_PURE; PA_C_DECL_END diff --git a/src/pulse/sample.h b/src/pulse/sample.h index 683167cc..b307621e 100644 --- a/src/pulse/sample.h +++ b/src/pulse/sample.h @@ -155,31 +155,31 @@ typedef struct pa_sample_spec { typedef uint64_t pa_usec_t; /** Return the amount of bytes playback of a second of audio with the specified sample type takes */ -size_t pa_bytes_per_second(const pa_sample_spec *spec); +size_t pa_bytes_per_second(const pa_sample_spec *spec) PA_GCC_PURE; /** Return the size of a frame with the specific sample type */ -size_t pa_frame_size(const pa_sample_spec *spec); +size_t pa_frame_size(const pa_sample_spec *spec) PA_GCC_PURE; /** Return the size of a sample with the specific sample type */ -size_t pa_sample_size(const pa_sample_spec *spec); +size_t pa_sample_size(const pa_sample_spec *spec) PA_GCC_PURE; /** Calculate the time the specified bytes take to play with the specified sample type */ -pa_usec_t pa_bytes_to_usec(uint64_t length, const pa_sample_spec *spec); +pa_usec_t pa_bytes_to_usec(uint64_t length, const pa_sample_spec *spec) PA_GCC_PURE; /** Calculates the number of bytes that are required for the specified time. \since 0.9 */ -size_t pa_usec_to_bytes(pa_usec_t t, const pa_sample_spec *spec); +size_t pa_usec_to_bytes(pa_usec_t t, const pa_sample_spec *spec) PA_GCC_PURE; /** Return non-zero when the sample type specification is valid */ -int pa_sample_spec_valid(const pa_sample_spec *spec); +int pa_sample_spec_valid(const pa_sample_spec *spec) PA_GCC_PURE; /** Return non-zero when the two sample type specifications match */ -int pa_sample_spec_equal(const pa_sample_spec*a, const pa_sample_spec*b); +int pa_sample_spec_equal(const pa_sample_spec*a, const pa_sample_spec*b) PA_GCC_PURE; /** Return a descriptive string for the specified sample format. \since 0.8 */ -const char *pa_sample_format_to_string(pa_sample_format_t f); +const char *pa_sample_format_to_string(pa_sample_format_t f) PA_GCC_PURE; /** Parse a sample format text. Inverse of pa_sample_format_to_string() */ -pa_sample_format_t pa_parse_sample_format(const char *format); +pa_sample_format_t pa_parse_sample_format(const char *format) PA_GCC_PURE; /** Maximum required string length for pa_sample_spec_snprint() */ #define PA_SAMPLE_SPEC_SNPRINT_MAX 32 diff --git a/src/pulse/timeval.h b/src/pulse/timeval.h index dbf4319c..e90df9f8 100644 --- a/src/pulse/timeval.h +++ b/src/pulse/timeval.h @@ -44,16 +44,16 @@ struct timeval *pa_gettimeofday(struct timeval *tv); /** Calculate the difference between the two specified timeval * structs. */ -pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b); +pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) PA_GCC_PURE; /** Compare the two timeval structs and return 0 when equal, negative when a < b, positive otherwse */ -int pa_timeval_cmp(const struct timeval *a, const struct timeval *b); +int pa_timeval_cmp(const struct timeval *a, const struct timeval *b) PA_GCC_PURE; /** Return the time difference between now and the specified timestamp */ pa_usec_t pa_timeval_age(const struct timeval *tv); /** Add the specified time inmicroseconds to the specified timeval structure */ -struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v); +struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v) PA_GCC_PURE; PA_C_DECL_END diff --git a/src/pulse/utf8.h b/src/pulse/utf8.h index ea08840b..1e08047c 100644 --- a/src/pulse/utf8.h +++ b/src/pulse/utf8.h @@ -34,7 +34,7 @@ PA_C_DECL_BEGIN /** Test if the specified strings qualifies as valid UTF8. Return the string if so, otherwise NULL */ -char *pa_utf8_valid(const char *str); +char *pa_utf8_valid(const char *str) PA_GCC_PURE; /** Filter all invalid UTF8 characters from the specified string, returning a new fully UTF8 valid string. Don't forget to free the returned string with pa_xfree() */ char *pa_utf8_filter(const char *str); diff --git a/src/pulse/volume.h b/src/pulse/volume.h index a928ff71..22e5b8a4 100644 --- a/src/pulse/volume.h +++ b/src/pulse/volume.h @@ -113,7 +113,7 @@ typedef struct pa_cvolume { } pa_cvolume; /** Return non-zero when *a == *b */ -int pa_cvolume_equal(const pa_cvolume *a, const pa_cvolume *b); +int pa_cvolume_equal(const pa_cvolume *a, const pa_cvolume *b) PA_GCC_PURE; /** Set the volume of all channels to PA_VOLUME_NORM */ #define pa_cvolume_reset(a, n) pa_cvolume_set((a), (n), PA_VOLUME_NORM) @@ -131,13 +131,13 @@ pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v); char *pa_cvolume_snprint(char *s, size_t l, const pa_cvolume *c); /** Return the average volume of all channels */ -pa_volume_t pa_cvolume_avg(const pa_cvolume *a); +pa_volume_t pa_cvolume_avg(const pa_cvolume *a) PA_GCC_PURE; /** Return TRUE when the passed cvolume structure is valid, FALSE otherwise */ -int pa_cvolume_valid(const pa_cvolume *v); +int pa_cvolume_valid(const pa_cvolume *v) PA_GCC_PURE; /** Return non-zero if the volume of all channels is equal to the specified value */ -int pa_cvolume_channels_equal_to(const pa_cvolume *a, pa_volume_t v); +int pa_cvolume_channels_equal_to(const pa_cvolume *a, pa_volume_t v) PA_GCC_PURE; /** Return 1 if the specified volume has all channels muted */ #define pa_cvolume_is_muted(a) pa_cvolume_channels_equal_to((a), PA_VOLUME_MUTED) @@ -146,22 +146,22 @@ int pa_cvolume_channels_equal_to(const pa_cvolume *a, pa_volume_t v); #define pa_cvolume_is_norm(a) pa_cvolume_channels_equal_to((a), PA_VOLUME_NORM) /** Multiply two volumes specifications, return the result. This uses PA_VOLUME_NORM as neutral element of multiplication. This is only valid for software volumes! */ -pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b); +pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) PA_GCC_CONST; /** Multiply to per-channel volumes and return the result in *dest. This is only valid for software volumes! */ -pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b); +pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b) PA_GCC_PURE; /** Convert a decibel value to a volume. This is only valid for software volumes! \since 0.4 */ -pa_volume_t pa_sw_volume_from_dB(double f); +pa_volume_t pa_sw_volume_from_dB(double f) PA_GCC_CONST; /** Convert a volume to a decibel value. This is only valid for software volumes! \since 0.4 */ -double pa_sw_volume_to_dB(pa_volume_t v); +double pa_sw_volume_to_dB(pa_volume_t v) PA_GCC_CONST; /** Convert a linear factor to a volume. This is only valid for software volumes! \since 0.8 */ -pa_volume_t pa_sw_volume_from_linear(double v); +pa_volume_t pa_sw_volume_from_linear(double v) PA_GCC_CONST; /** Convert a volume to a linear factor. This is only valid for software volumes! \since 0.8 */ -double pa_sw_volume_to_linear(pa_volume_t v); +double pa_sw_volume_to_linear(pa_volume_t v) PA_GCC_CONST; #ifdef INFINITY #define PA_DECIBEL_MININFTY (-INFINITY) diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index efd19f45..af97e4bf 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -61,14 +61,14 @@ void pa_reset_priority(void); int pa_fd_set_cloexec(int fd, int b); -int pa_parse_boolean(const char *s); +int pa_parse_boolean(const char *s) PA_GCC_PURE; char *pa_split(const char *c, const char*delimiters, const char **state); char *pa_split_spaces(const char *c, const char **state); char *pa_strip_nl(char *s); -const char *pa_strsignal(int sig); +const char *pa_strsignal(int sig) PA_GCC_PURE; int pa_own_uid_in_group(const char *name, gid_t *gid); int pa_uid_in_group(uid_t uid, const char *name); @@ -85,8 +85,8 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env char *pa_hexstr(const uint8_t* d, size_t dlength, char *s, size_t slength); size_t pa_parsehex(const char *p, uint8_t *d, size_t dlength); -int pa_startswith(const char *s, const char *pfx); -int pa_endswith(const char *s, const char *sfx); +int pa_startswith(const char *s, const char *pfx) PA_GCC_PURE; +int pa_endswith(const char *s, const char *sfx) PA_GCC_PURE; char *pa_runtime_path(const char *fn, char *s, size_t l); diff --git a/src/pulsecore/gccmacro.h b/src/pulsecore/gccmacro.h index f3ace593..d211c2e7 100644 --- a/src/pulsecore/gccmacro.h +++ b/src/pulsecore/gccmacro.h @@ -55,7 +55,26 @@ #ifdef __GNUC__ #define PA_GCC_DESTRUCTOR __attribute__ ((destructor)) #else +/** Call this function when process terminates */ #define PA_GCC_DESTRUCTOR #endif +#ifndef PA_GCC_PURE +#ifdef __GNUCC__ +#define PA_GCC_PURE __attribute__ ((pure)) +#else +/** This function's return value depends only the arguments list and global state **/ +#define PA_GCC_PURE +#endif +#endif + +#ifndef PA_GCC_CONST +#ifdef __GNUCC__ +#define PA_GCC_CONST __attribute__ ((pure)) +#else +/** This function's return value depends only the arguments list (stricter version of PA_GCC_CONST) **/ +#define PA_GCC_CONST +#endif +#endif + #endif diff --git a/src/pulsecore/sample-util.h b/src/pulsecore/sample-util.h index 0d4924b1..92c6e9ff 100644 --- a/src/pulsecore/sample-util.h +++ b/src/pulsecore/sample-util.h @@ -56,8 +56,8 @@ void pa_volume_memchunk( const pa_sample_spec *spec, const pa_cvolume *volume); -size_t pa_frame_align(size_t l, const pa_sample_spec *ss); +size_t pa_frame_align(size_t l, const pa_sample_spec *ss) PA_GCC_PURE; -int pa_frame_aligned(size_t l, const pa_sample_spec *ss); +int pa_frame_aligned(size_t l, const pa_sample_spec *ss) PA_GCC_PURE; #endif diff --git a/src/pulsecore/sconv.h b/src/pulsecore/sconv.h index 5e8fa684..901f50a3 100644 --- a/src/pulsecore/sconv.h +++ b/src/pulsecore/sconv.h @@ -29,10 +29,10 @@ typedef void (*pa_convert_func_t)(unsigned n, const void *a, void *b); -pa_convert_func_t pa_get_convert_to_float32ne_function(pa_sample_format_t f); -pa_convert_func_t pa_get_convert_from_float32ne_function(pa_sample_format_t f); +pa_convert_func_t pa_get_convert_to_float32ne_function(pa_sample_format_t f) PA_GCC_PURE; +pa_convert_func_t pa_get_convert_from_float32ne_function(pa_sample_format_t f) PA_GCC_PURE; -pa_convert_func_t pa_get_convert_to_s16ne_function(pa_sample_format_t f); -pa_convert_func_t pa_get_convert_from_s16ne_function(pa_sample_format_t f); +pa_convert_func_t pa_get_convert_to_s16ne_function(pa_sample_format_t f) PA_GCC_PURE; +pa_convert_func_t pa_get_convert_from_s16ne_function(pa_sample_format_t f) PA_GCC_PURE; #endif -- cgit From 61b90a0951ce709bce09cfa44825498224d92120 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 16 Sep 2007 23:28:56 +0000 Subject: add proper boolean type pa_bool_t git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1836 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 12 ++++++++++++ src/pulsecore/macro.h | 15 +++++++++++++++ src/pulsecore/sink-input.c | 8 ++++---- src/pulsecore/sink-input.h | 22 +++++++++++----------- src/pulsecore/sink.c | 16 ++++++++-------- src/pulsecore/sink.h | 20 ++++++++++---------- src/pulsecore/source-output.c | 2 +- src/pulsecore/source-output.h | 8 ++++---- src/pulsecore/source.c | 16 ++++++++-------- src/pulsecore/source.h | 20 ++++++++++---------- 10 files changed, 83 insertions(+), 56 deletions(-) diff --git a/configure.ac b/configure.ac index cb68f57b..f179827f 100644 --- a/configure.ac +++ b/configure.ac @@ -130,6 +130,18 @@ else AC_MSG_RESULT([no]) fi +AC_MSG_CHECKING([whether $CC knows _Bool]) +AC_LANG_CONFTEST([int main() { _Bool b; }]) +$CC conftest.c $CFLAGS -o conftest > /dev/null 2> /dev/null +ret=$? +rm -f conftest.o conftest +if test $ret -eq 0 ; then + AC_DEFINE([HAVE_STD_BOOL], 1, [Have _Bool.]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + #### libtool stuff #### AC_LTDL_ENABLE_INSTALL diff --git a/src/pulsecore/macro.h b/src/pulsecore/macro.h index ec451547..d0dff5e1 100644 --- a/src/pulsecore/macro.h +++ b/src/pulsecore/macro.h @@ -72,6 +72,21 @@ static inline size_t pa_page_align(size_t l) { #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif +/* This type is not intended to be used in exported APIs! Use classic "int" there! */ +#ifdef HAVE_STD_BOOL +typedef _Bool pa_bool_t; +#else +typedef int pa_bool_t; +#endif + +#ifndef FALSE +#define FALSE ((pa_bool_t) 0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + #ifdef __GNUC__ #define PA_PRETTY_FUNCTION __PRETTY_FUNCTION__ #else diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index f2855fc9..b8ca5e1b 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -79,10 +79,10 @@ void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const data->sample_spec = *spec; } -void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, int mute) { +void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute) { pa_assert(data); - data->muted_is_set = 1; + data->muted_is_set = TRUE; data->muted = !!mute; } @@ -607,7 +607,7 @@ const pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i) { return &i->volume; } -void pa_sink_input_set_mute(pa_sink_input *i, int mute) { +void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute) { pa_assert(i); pa_sink_input_assert_ref(i); pa_assert(PA_SINK_INPUT_LINKED(i->state)); @@ -628,7 +628,7 @@ int pa_sink_input_get_mute(pa_sink_input *i) { return !!i->muted; } -void pa_sink_input_cork(pa_sink_input *i, int b) { +void pa_sink_input_cork(pa_sink_input *i, pa_bool_t b) { pa_sink_input_assert_ref(i); pa_assert(PA_SINK_INPUT_LINKED(i->state)); diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index 7d405640..152c24e6 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -46,7 +46,7 @@ typedef enum pa_sink_input_state { PA_SINK_INPUT_UNLINKED /*< The stream is dead */ } pa_sink_input_state_t; -static inline int PA_SINK_INPUT_LINKED(pa_sink_input_state_t x) { +static inline pa_bool_t PA_SINK_INPUT_LINKED(pa_sink_input_state_t x) { return x == PA_SINK_INPUT_DRAINED || x == PA_SINK_INPUT_RUNNING || x == PA_SINK_INPUT_CORKED; } @@ -80,7 +80,7 @@ struct pa_sink_input { pa_sink_input *sync_prev, *sync_next; pa_cvolume volume; - int muted; + pa_bool_t muted; /* Returns the chunk of audio data (but doesn't drop it * yet!). Returns -1 on failure. Called from IO thread context. If @@ -139,7 +139,7 @@ struct pa_sink_input { pa_sink_input *sync_prev, *sync_next; pa_cvolume volume; - int muted; + pa_bool_t muted; } thread_info; void *userdata; @@ -165,14 +165,14 @@ typedef struct pa_sink_input_new_data { pa_sink *sink; pa_sample_spec sample_spec; - int sample_spec_is_set; + pa_bool_t sample_spec_is_set; pa_channel_map channel_map; - int channel_map_is_set; + pa_bool_t channel_map_is_set; pa_cvolume volume; - int volume_is_set; - int muted; - int muted_is_set; + pa_bool_t volume_is_set; + pa_bool_t muted; + pa_bool_t muted_is_set; pa_resample_method_t resample_method; @@ -183,7 +183,7 @@ pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data void pa_sink_input_new_data_set_sample_spec(pa_sink_input_new_data *data, const pa_sample_spec *spec); void pa_sink_input_new_data_set_channel_map(pa_sink_input_new_data *data, const pa_channel_map *map); void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cvolume *volume); -void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, int mute); +void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute); /* To be called by the implementing module only */ @@ -206,10 +206,10 @@ pa_usec_t pa_sink_input_get_latency(pa_sink_input *i); void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume); const pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i); -void pa_sink_input_set_mute(pa_sink_input *i, int mute); +void pa_sink_input_set_mute(pa_sink_input *i, pa_bool_t mute); int pa_sink_input_get_mute(pa_sink_input *i); -void pa_sink_input_cork(pa_sink_input *i, int b); +void pa_sink_input_cork(pa_sink_input *i, pa_bool_t b); int pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate); diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 45cc96bf..98f117cf 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -105,8 +105,8 @@ pa_sink* pa_sink_new( s->n_corked = 0; pa_cvolume_reset(&s->volume, spec->channels); - s->muted = 0; - s->refresh_volume = s->refresh_mute = 0; + s->muted = FALSE; + s->refresh_volume = s->refresh_mute = FALSE; s->get_latency = NULL; s->set_volume = NULL; @@ -295,7 +295,7 @@ int pa_sink_update_status(pa_sink*s) { return sink_set_state(s, pa_sink_used_by(s) ? PA_SINK_RUNNING : PA_SINK_IDLE); } -int pa_sink_suspend(pa_sink *s, int suspend) { +int pa_sink_suspend(pa_sink *s, pa_bool_t suspend) { pa_sink_assert_ref(s); pa_assert(PA_SINK_LINKED(s->state)); @@ -678,7 +678,7 @@ const pa_cvolume *pa_sink_get_volume(pa_sink *s) { return &s->volume; } -void pa_sink_set_mute(pa_sink *s, int mute) { +void pa_sink_set_mute(pa_sink *s, pa_bool_t mute) { int changed; pa_sink_assert_ref(s); @@ -697,8 +697,8 @@ void pa_sink_set_mute(pa_sink *s, int mute) { pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); } -int pa_sink_get_mute(pa_sink *s) { - int old_muted; +pa_bool_t pa_sink_get_mute(pa_sink *s) { + pa_bool_t old_muted; pa_sink_assert_ref(s); pa_assert(PA_SINK_LINKED(s->state)); @@ -927,7 +927,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse return 0; case PA_SINK_MESSAGE_GET_MUTE: - *((int*) userdata) = s->thread_info.soft_muted; + *((pa_bool_t*) userdata) = s->thread_info.soft_muted; return 0; case PA_SINK_MESSAGE_PING: @@ -960,7 +960,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse return -1; } -int pa_sink_suspend_all(pa_core *c, int suspend) { +int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend) { pa_sink *sink; uint32_t idx; int ret = 0; diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index 537e9cb6..ce1d12c3 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -52,11 +52,11 @@ typedef enum pa_sink_state { PA_SINK_UNLINKED } pa_sink_state_t; -static inline int PA_SINK_OPENED(pa_sink_state_t x) { +static inline pa_bool_t PA_SINK_OPENED(pa_sink_state_t x) { return x == PA_SINK_RUNNING || x == PA_SINK_IDLE; } -static inline int PA_SINK_LINKED(pa_sink_state_t x) { +static inline pa_bool_t PA_SINK_LINKED(pa_sink_state_t x) { return x == PA_SINK_RUNNING || x == PA_SINK_IDLE || x == PA_SINK_SUSPENDED; } @@ -81,9 +81,9 @@ struct pa_sink { pa_source *monitor_source; pa_cvolume volume; - int muted; - int refresh_volume; - int refresh_mute; + pa_bool_t muted; + pa_bool_t refresh_volume; + pa_bool_t refresh_mute; int (*set_state)(pa_sink *s, pa_sink_state_t state); /* may be NULL */ int (*set_volume)(pa_sink *s); /* dito */ @@ -101,7 +101,7 @@ struct pa_sink { pa_sink_state_t state; pa_hashmap *inputs; pa_cvolume soft_volume; - int soft_muted; + pa_bool_t soft_muted; } thread_info; pa_memblock *silence; @@ -154,8 +154,8 @@ void pa_sink_attach(pa_sink *s); pa_usec_t pa_sink_get_latency(pa_sink *s); int pa_sink_update_status(pa_sink*s); -int pa_sink_suspend(pa_sink *s, int suspend); -int pa_sink_suspend_all(pa_core *c, int suspend); +int pa_sink_suspend(pa_sink *s, pa_bool_t suspend); +int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend); /* Sends a ping message to the sink thread, to make it wake up and * check for data to process even if there is no real message is @@ -164,8 +164,8 @@ void pa_sink_ping(pa_sink *s); void pa_sink_set_volume(pa_sink *sink, const pa_cvolume *volume); const pa_cvolume *pa_sink_get_volume(pa_sink *sink); -void pa_sink_set_mute(pa_sink *sink, int mute); -int pa_sink_get_mute(pa_sink *sink); +void pa_sink_set_mute(pa_sink *sink, pa_bool_t mute); +pa_bool_t pa_sink_get_mute(pa_sink *sink); unsigned pa_sink_linked_by(pa_sink *s); /* Number of connected streams */ unsigned pa_sink_used_by(pa_sink *s); /* Number of connected streams which are not corked */ diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 8650e532..df5dc8c2 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -306,7 +306,7 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) { pa_memblock_unref(rchunk.memblock); } -void pa_source_output_cork(pa_source_output *o, int b) { +void pa_source_output_cork(pa_source_output *o, pa_bool_t b) { pa_source_output_assert_ref(o); pa_assert(PA_SOURCE_OUTPUT_LINKED(o->state)); diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h index 5059c465..96ded863 100644 --- a/src/pulsecore/source-output.h +++ b/src/pulsecore/source-output.h @@ -42,7 +42,7 @@ typedef enum pa_source_output_state { PA_SOURCE_OUTPUT_UNLINKED } pa_source_output_state_t; -static inline int PA_SOURCE_OUTPUT_LINKED(pa_source_output_state_t x) { +static inline pa_bool_t PA_SOURCE_OUTPUT_LINKED(pa_source_output_state_t x) { return x == PA_SOURCE_OUTPUT_RUNNING || x == PA_SOURCE_OUTPUT_CORKED; } @@ -126,9 +126,9 @@ typedef struct pa_source_output_new_data { pa_source *source; pa_sample_spec sample_spec; - int sample_spec_is_set; + pa_bool_t sample_spec_is_set; pa_channel_map channel_map; - int channel_map_is_set; + pa_bool_t channel_map_is_set; pa_resample_method_t resample_method; } pa_source_output_new_data; @@ -157,7 +157,7 @@ void pa_source_output_kill(pa_source_output*o); pa_usec_t pa_source_output_get_latency(pa_source_output *i); -void pa_source_output_cork(pa_source_output *i, int b); +void pa_source_output_cork(pa_source_output *i, pa_bool_t b); int pa_source_output_set_rate(pa_source_output *o, uint32_t rate); diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index d72349f8..315c2ce5 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -97,8 +97,8 @@ pa_source* pa_source_new( s->monitor_of = NULL; pa_cvolume_reset(&s->volume, spec->channels); - s->muted = 0; - s->refresh_volume = s->refresh_muted = 0; + s->muted = FALSE; + s->refresh_volume = s->refresh_muted = FALSE; s->get_latency = NULL; s->set_volume = NULL; @@ -240,7 +240,7 @@ int pa_source_update_status(pa_source*s) { return source_set_state(s, pa_source_used_by(s) ? PA_SOURCE_RUNNING : PA_SOURCE_IDLE); } -int pa_source_suspend(pa_source *s, int suspend) { +int pa_source_suspend(pa_source *s, pa_bool_t suspend) { pa_source_assert_ref(s); pa_assert(PA_SOURCE_LINKED(s->state)); @@ -348,7 +348,7 @@ const pa_cvolume *pa_source_get_volume(pa_source *s) { return &s->volume; } -void pa_source_set_mute(pa_source *s, int mute) { +void pa_source_set_mute(pa_source *s, pa_bool_t mute) { int changed; pa_source_assert_ref(s); @@ -367,8 +367,8 @@ void pa_source_set_mute(pa_source *s, int mute) { pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); } -int pa_source_get_mute(pa_source *s) { - int old_muted; +pa_bool_t pa_source_get_mute(pa_source *s) { + pa_bool_t old_muted; pa_source_assert_ref(s); pa_assert(PA_SOURCE_LINKED(s->state)); @@ -487,7 +487,7 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_ return 0; case PA_SOURCE_MESSAGE_GET_MUTE: - *((int*) userdata) = s->thread_info.soft_muted; + *((pa_bool_t*) userdata) = s->thread_info.soft_muted; return 0; case PA_SOURCE_MESSAGE_PING: @@ -519,7 +519,7 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_ return -1; } -int pa_source_suspend_all(pa_core *c, int suspend) { +int pa_source_suspend_all(pa_core *c, pa_bool_t suspend) { uint32_t idx; pa_source *source; int ret = 0; diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h index 4e488a74..bd0a9122 100644 --- a/src/pulsecore/source.h +++ b/src/pulsecore/source.h @@ -54,11 +54,11 @@ typedef enum pa_source_state { PA_SOURCE_UNLINKED } pa_source_state_t; -static inline int PA_SOURCE_OPENED(pa_source_state_t x) { +static inline pa_bool_t PA_SOURCE_OPENED(pa_source_state_t x) { return x == PA_SOURCE_RUNNING || x == PA_SOURCE_IDLE; } -static inline int PA_SOURCE_LINKED(pa_source_state_t x) { +static inline pa_bool_t PA_SOURCE_LINKED(pa_source_state_t x) { return x == PA_SOURCE_RUNNING || x == PA_SOURCE_IDLE || x == PA_SOURCE_SUSPENDED; } @@ -83,9 +83,9 @@ struct pa_source { pa_sink *monitor_of; /* may be NULL */ pa_cvolume volume; - int muted; - int refresh_volume; - int refresh_muted; + pa_bool_t muted; + pa_bool_t refresh_volume; + pa_bool_t refresh_muted; int (*set_state)(pa_source*source, pa_source_state_t state); /* may be NULL */ int (*set_volume)(pa_source *s); /* dito */ @@ -103,7 +103,7 @@ struct pa_source { pa_source_state_t state; pa_hashmap *outputs; pa_cvolume soft_volume; - int soft_muted; + pa_bool_t soft_muted; } thread_info; void *userdata; @@ -153,15 +153,15 @@ void pa_source_attach(pa_source *s); pa_usec_t pa_source_get_latency(pa_source *s); int pa_source_update_status(pa_source*s); -int pa_source_suspend(pa_source *s, int suspend); -int pa_source_suspend_all(pa_core *c, int suspend); +int pa_source_suspend(pa_source *s, pa_bool_t suspend); +int pa_source_suspend_all(pa_core *c, pa_bool_t suspend); void pa_source_ping(pa_source *s); void pa_source_set_volume(pa_source *source, const pa_cvolume *volume); const pa_cvolume *pa_source_get_volume(pa_source *source); -void pa_source_set_mute(pa_source *source, int mute); -int pa_source_get_mute(pa_source *source); +void pa_source_set_mute(pa_source *source, pa_bool_t mute); +pa_bool_t pa_source_get_mute(pa_source *source); unsigned pa_source_linked_by(pa_source *s); /* Number of connected streams */ unsigned pa_source_used_by(pa_source *s); /* Number of connected streams that are not corked */ -- cgit From 2741685d3ad4e78c1c155f77cea34c46c259584e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 17 Sep 2007 00:32:51 +0000 Subject: use priority inheritance on mutexes where applicable git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1837 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 16 ++++++++++++++++ src/daemon/main.c | 2 +- src/modules/module-combine.c | 2 +- src/pulse/thread-mainloop.c | 2 +- src/pulsecore/asyncmsgq.c | 2 +- src/pulsecore/memblock.c | 16 ++++++++++------ src/pulsecore/mutex-posix.c | 9 +++++++-- src/pulsecore/mutex.h | 10 +++++++++- src/pulsecore/once-posix.c | 2 +- src/tests/thread-test.c | 2 +- 10 files changed, 48 insertions(+), 15 deletions(-) diff --git a/configure.ac b/configure.ac index f179827f..c12cfc0e 100644 --- a/configure.ac +++ b/configure.ac @@ -297,6 +297,22 @@ AC_CHECK_FUNCS([setresuid setresgid setreuid setregid seteuid setegid ppoll]) ACX_PTHREAD +AC_MSG_CHECKING([for PTHREAD_PRIO_INHERIT]) +AC_LANG_CONFTEST([AC_LANG_SOURCE([[ +#include +int main() { int i = PTHREAD_PRIO_INHERIT; }]])]) +$PTHREAD_CC conftest.c $PTHREAD_CFLAGS $CFLAGS $PTHREAD_LIBS -o conftest > /dev/null 2> /dev/null +ret=$? +rm -f conftest.o conftest + +if test $ret -eq 0 ; then + AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + + #### Large File-Support (LFS) #### AC_SYS_LARGEFILE diff --git a/src/daemon/main.c b/src/daemon/main.c index e01bb231..f34e59e9 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -330,7 +330,7 @@ static const char *libtool_get_error(void) { } static void libtool_init(void) { - pa_assert_se(libtool_mutex = pa_mutex_new(1)); + pa_assert_se(libtool_mutex = pa_mutex_new(TRUE, FALSE)); pa_assert_se(lt_dlmutex_register(libtool_lock, libtool_unlock, libtool_set_error, libtool_get_error) == 0); pa_assert_se(lt_dlinit() == 0); } diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 235e04e6..7ac7b9ab 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -947,7 +947,7 @@ int pa__init(pa_module*m) { u->thread_info.master = u->master = NULL; u->time_event = NULL; u->adjust_time = DEFAULT_ADJUST_TIME; - u->mutex = pa_mutex_new(0); + u->mutex = pa_mutex_new(FALSE, TRUE); pa_thread_mq_init(&u->thread_mq, m->core->mainloop); u->rtpoll = NULL; u->thread = NULL; diff --git a/src/pulse/thread-mainloop.c b/src/pulse/thread-mainloop.c index 29769e2b..30685705 100644 --- a/src/pulse/thread-mainloop.c +++ b/src/pulse/thread-mainloop.c @@ -103,7 +103,7 @@ pa_threaded_mainloop *pa_threaded_mainloop_new(void) { return NULL; } - m->mutex = pa_mutex_new(1); + m->mutex = pa_mutex_new(TRUE, FALSE); m->cond = pa_cond_new(); m->accept_cond = pa_cond_new(); m->thread = NULL; diff --git a/src/pulsecore/asyncmsgq.c b/src/pulsecore/asyncmsgq.c index b3654460..c0917ca6 100644 --- a/src/pulsecore/asyncmsgq.c +++ b/src/pulsecore/asyncmsgq.c @@ -67,7 +67,7 @@ pa_asyncmsgq *pa_asyncmsgq_new(unsigned size) { PA_REFCNT_INIT(a); pa_assert_se(a->asyncq = pa_asyncq_new(size)); - pa_assert_se(a->mutex = pa_mutex_new(0)); + pa_assert_se(a->mutex = pa_mutex_new(FALSE, TRUE)); a->current = NULL; return a; diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index 05fc34d9..3827dc03 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -660,7 +660,7 @@ pa_mempool* pa_mempool_new(int shared) { p = pa_xnew(pa_mempool, 1); - p->mutex = pa_mutex_new(1); + p->mutex = pa_mutex_new(TRUE, TRUE); p->semaphore = pa_semaphore_new(0); p->block_size = PA_PAGE_ALIGN(PA_MEMPOOL_SLOT_SIZE); @@ -781,7 +781,7 @@ pa_memimport* pa_memimport_new(pa_mempool *p, pa_memimport_release_cb_t cb, void pa_assert(cb); i = pa_xnew(pa_memimport, 1); - i->mutex = pa_mutex_new(1); + i->mutex = pa_mutex_new(TRUE, TRUE); i->pool = p; i->segments = pa_hashmap_new(NULL, NULL); i->blocks = pa_hashmap_new(NULL, NULL); @@ -909,18 +909,22 @@ finish: int pa_memimport_process_revoke(pa_memimport *i, uint32_t id) { pa_memblock *b; + int ret = 0; pa_assert(i); pa_mutex_lock(i->mutex); - if (!(b = pa_hashmap_get(i->blocks, PA_UINT32_TO_PTR(id)))) - return -1; + if (!(b = pa_hashmap_get(i->blocks, PA_UINT32_TO_PTR(id)))) { + ret = -1; + goto finish; + } memblock_replace_import(b); +finish: pa_mutex_unlock(i->mutex); - return 0; + return ret; } /* For sending blocks to other nodes */ @@ -934,7 +938,7 @@ pa_memexport* pa_memexport_new(pa_mempool *p, pa_memexport_revoke_cb_t cb, void return NULL; e = pa_xnew(pa_memexport, 1); - e->mutex = pa_mutex_new(1); + e->mutex = pa_mutex_new(TRUE, TRUE); e->pool = p; PA_LLIST_HEAD_INIT(struct memexport_slot, e->free_slots); PA_LLIST_HEAD_INIT(struct memexport_slot, e->used_slots); diff --git a/src/pulsecore/mutex-posix.c b/src/pulsecore/mutex-posix.c index 64f466d9..19e095bb 100644 --- a/src/pulsecore/mutex-posix.c +++ b/src/pulsecore/mutex-posix.c @@ -40,15 +40,20 @@ struct pa_cond { pthread_cond_t cond; }; -pa_mutex* pa_mutex_new(int recursive) { +pa_mutex* pa_mutex_new(pa_bool_t recursive, pa_bool_t inherit_priority) { pa_mutex *m; pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); - + if (recursive) pa_assert_se(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) == 0); +#ifdef HAVE_PTHREAD_PRIO_INHERIT + if (inherit_priority) + pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT); +#endif + m = pa_xnew(pa_mutex, 1); pa_assert_se(pthread_mutex_init(&m->mutex, &attr) == 0); return m; diff --git a/src/pulsecore/mutex.h b/src/pulsecore/mutex.h index b2e34c07..72e88781 100644 --- a/src/pulsecore/mutex.h +++ b/src/pulsecore/mutex.h @@ -24,9 +24,17 @@ USA. ***/ +#include + typedef struct pa_mutex pa_mutex; -pa_mutex* pa_mutex_new(int recursive); +/* Please think twice before enabling priority inheritance. This is no + * magic wand! Use it only when the potentially priorized threads are + * good candidates for it. Don't use this blindly! Also, note that + * only very few operating systems actually implement this, hence this + * is merely a hint. */ +pa_mutex* pa_mutex_new(pa_bool_t recursive, pa_bool_t inherit_priority); + void pa_mutex_free(pa_mutex *m); void pa_mutex_lock(pa_mutex *m); void pa_mutex_unlock(pa_mutex *m); diff --git a/src/pulsecore/once-posix.c b/src/pulsecore/once-posix.c index fba0ddf1..4f6e5b62 100644 --- a/src/pulsecore/once-posix.c +++ b/src/pulsecore/once-posix.c @@ -58,7 +58,7 @@ int pa_once_begin(pa_once *control) { return 0; } - pa_assert_se(m = pa_mutex_new(0)); + pa_assert_se(m = pa_mutex_new(FALSE, FALSE)); pa_mutex_lock(m); if (pa_atomic_ptr_cmpxchg(&control->mutex, NULL, m)) diff --git a/src/tests/thread-test.c b/src/tests/thread-test.c index 0077cde5..72dde6cb 100644 --- a/src/tests/thread-test.c +++ b/src/tests/thread-test.c @@ -98,7 +98,7 @@ int main(int argc, char *argv[]) { assert(pa_thread_is_running(pa_thread_self())); - mutex = pa_mutex_new(0); + mutex = pa_mutex_new(FALSE, FALSE); cond1 = pa_cond_new(); cond2 = pa_cond_new(); tls = pa_tls_new(pa_xfree); -- cgit From 061e8068aab4237b31abc1d8763999db1bcbc57f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 17 Sep 2007 12:31:06 +0000 Subject: Add a special ltdl .so loader that avoids lazy frelocations during runtime git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1838 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 2 +- src/Makefile.am | 1 + src/daemon/ltdl-bind-now.c | 160 +++++++++++++++++++++++++++++++++++++++++++++ src/daemon/ltdl-bind-now.h | 32 +++++++++ src/daemon/main.c | 37 +---------- 5 files changed, 197 insertions(+), 35 deletions(-) create mode 100644 src/daemon/ltdl-bind-now.c create mode 100644 src/daemon/ltdl-bind-now.h diff --git a/configure.ac b/configure.ac index c12cfc0e..869db01a 100644 --- a/configure.ac +++ b/configure.ac @@ -187,7 +187,7 @@ AC_HEADER_STDC AC_CHECK_HEADERS([arpa/inet.h glob.h grp.h netdb.h netinet/in.h \ netinet/in_systm.h netinet/tcp.h pwd.h sched.h \ sys/mman.h sys/resource.h sys/select.h sys/socket.h sys/wait.h \ - syslog.h]) + syslog.h sys/dl.h dlfcn.h]) AC_CHECK_HEADERS([netinet/ip.h], [], [], [#include #if HAVE_NETINET_IN_H diff --git a/src/Makefile.am b/src/Makefile.am index 9914c193..d9933a0b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -132,6 +132,7 @@ pulseaudio_SOURCES = \ daemon/cpulimit.c daemon/cpulimit.h \ daemon/daemon-conf.c daemon/daemon-conf.h \ daemon/dumpmodules.c daemon/dumpmodules.h \ + daemon/ltdl-bind-now.c daemon/ltdl-bind-now.h \ daemon/main.c \ pulsecore/gccmacro.h diff --git a/src/daemon/ltdl-bind-now.c b/src/daemon/ltdl-bind-now.c new file mode 100644 index 00000000..f5347db3 --- /dev/null +++ b/src/daemon/ltdl-bind-now.c @@ -0,0 +1,160 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + Copyright 2006 Pierre Ossman for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if HAVE_DLFCN_H +#include +#endif + +#if HAVE_SYS_DL_H +#include +#endif + +#include + +#include +#include +#include +#include + +#include "ltdl-bind-now.h" + +#ifdef RTLD_NOW +#define PA_BIND_NOW RTLD_NOW +#elif defined(DL_NOW) +#define PA_BIND_NOW DL_NOW +#else +#undef PA_BIND_NOW +#endif + +static pa_mutex *libtool_mutex = NULL; + +PA_STATIC_TLS_DECLARE_NO_FREE(libtool_tls); + +static void libtool_lock(void) { + pa_mutex_lock(libtool_mutex); +} + +static void libtool_unlock(void) { + pa_mutex_unlock(libtool_mutex); +} + +static void libtool_set_error(const char *error) { + PA_STATIC_TLS_SET(libtool_tls, (char*) error); +} + +static const char *libtool_get_error(void) { + return PA_STATIC_TLS_GET(libtool_tls); +} + +#ifdef PA_BIND_NOW + +/* + To avoid lazy relocations during runtime in our RT threads we add + our own shared object loader with uses RTLD_NOW if it is + available. The standard ltdl loader prefers RTLD_LAZY. + + Please note that this loader doesn't have any influence on + relocations on any libraries that are already loaded into our + process, i.e. because the pulseaudio binary links directly to + them. To disable lazy relocations for those libraries it is possible + to set $LT_BIND_NOW before starting the pulsaudio binary. +*/ + +static lt_module bind_now_open(lt_user_data d, const char *fname) { + lt_module m; + + pa_assert(fname); + + if (!(m = dlopen(fname, PA_BIND_NOW))) { + libtool_set_error(dlerror()); + return NULL; + } + + return m; +} + +static int bind_now_close(lt_user_data d, lt_module m) { + + pa_assert(m); + + if (dlclose(m) != 0){ + libtool_set_error(dlerror()); + return 1; + } + + return 0; +} + +static lt_ptr bind_now_find_sym(lt_user_data d, lt_module m, const char *symbol) { + lt_ptr ptr; + + pa_assert(m); + pa_assert(symbol); + + if (!(ptr = dlsym(m, symbol))) { + libtool_set_error(dlerror()); + return NULL; + } + + return ptr; +} + +#endif + +void pa_ltdl_init(void) { + +#ifdef PA_BIND_NOW + lt_dlloader *place; + static const struct lt_user_dlloader loader = { + .module_open = bind_now_open, + .module_close = bind_now_close, + .find_sym = bind_now_find_sym + }; +#endif + + pa_assert_se(lt_dlinit() == 0); + pa_assert_se(libtool_mutex = pa_mutex_new(TRUE, FALSE)); + pa_assert_se(lt_dlmutex_register(libtool_lock, libtool_unlock, libtool_set_error, libtool_get_error) == 0); + +#ifdef PA_BIND_NOW + + if (!(place = lt_dlloader_find("dlopen"))) + place = lt_dlloader_next(NULL); + + /* Add our BIND_NOW loader as the default module loader. */ + if (lt_dlloader_add(place, &loader, "bind-now-loader") != 0) + pa_log_warn("Failed to add bind-now-loader."); +#endif +} + +void pa_ltdl_done(void) { + pa_assert_se(lt_dlexit() == 0); + pa_mutex_free(libtool_mutex); + libtool_mutex = NULL; +} + diff --git a/src/daemon/ltdl-bind-now.h b/src/daemon/ltdl-bind-now.h new file mode 100644 index 00000000..e19c7bc1 --- /dev/null +++ b/src/daemon/ltdl-bind-now.h @@ -0,0 +1,32 @@ +#ifndef foopulsecoreltdlbindnowhfoo +#define foopulsecoreltdlbindnowhfoo + +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + + +void pa_ltdl_init(void); +void pa_ltdl_done(void); + +#endif + diff --git a/src/daemon/main.c b/src/daemon/main.c index f34e59e9..6c7928ee 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -93,6 +93,7 @@ #include "daemon-conf.h" #include "dumpmodules.h" #include "caps.h" +#include "ltdl-bind-now.h" #ifdef HAVE_LIBWRAP /* Only one instance of these variables */ @@ -309,38 +310,6 @@ static void set_all_rlimits(const pa_daemon_conf *conf) { } #endif -static pa_mutex *libtool_mutex = NULL; - -static void libtool_lock(void) { - pa_mutex_lock(libtool_mutex); -} - -static void libtool_unlock(void) { - pa_mutex_unlock(libtool_mutex); -} - -PA_STATIC_TLS_DECLARE_NO_FREE(libtool_tls); - -static void libtool_set_error(const char * error) { - PA_STATIC_TLS_SET(libtool_tls, (char*) error); -} - -static const char *libtool_get_error(void) { - return PA_STATIC_TLS_GET(libtool_tls); -} - -static void libtool_init(void) { - pa_assert_se(libtool_mutex = pa_mutex_new(TRUE, FALSE)); - pa_assert_se(lt_dlmutex_register(libtool_lock, libtool_unlock, libtool_set_error, libtool_get_error) == 0); - pa_assert_se(lt_dlinit() == 0); -} - -static void libtool_done(void) { - pa_assert_se(lt_dlexit() == 0); - pa_mutex_free(libtool_mutex); - libtool_mutex = NULL; -} - int main(int argc, char *argv[]) { pa_core *c = NULL; pa_strbuf *buf = NULL; @@ -396,7 +365,7 @@ int main(int argc, char *argv[]) { LTDL_SET_PRELOADED_SYMBOLS(); - libtool_init(); + pa_ltdl_init(); #ifdef OS_IS_WIN32 { @@ -747,7 +716,7 @@ finish: WSACleanup(); #endif - libtool_done(); + pa_ltdl_done(); #ifdef HAVE_DBUS dbus_shutdown(); -- cgit From a1526f105dfc642aea213cca84f90635878ba4bd Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 17 Sep 2007 13:01:04 +0000 Subject: add missing initialization git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1839 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/daemon/main.c b/src/daemon/main.c index 6c7928ee..43f573e6 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -317,7 +317,7 @@ int main(int argc, char *argv[]) { pa_mainloop *mainloop = NULL; char *s; - int r, retval = 1, d = 0; + int r = 0, retval = 1, d = 0; int daemon_pipe[2] = { -1, -1 }; int suid_root, real_root; int valid_pid_file = 0; -- cgit From 7f9fea74ef4c972ccc7f6cf797f83d1bdbcddde7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 17 Sep 2007 13:32:46 +0000 Subject: on Linu disable lazy binding altogether git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1840 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/main.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/daemon/main.c b/src/daemon/main.c index 43f573e6..c446582e 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -315,7 +315,6 @@ int main(int argc, char *argv[]) { pa_strbuf *buf = NULL; pa_daemon_conf *conf = NULL; pa_mainloop *mainloop = NULL; - char *s; int r = 0, retval = 1, d = 0; int daemon_pipe[2] = { -1, -1 }; @@ -329,6 +328,23 @@ int main(int argc, char *argv[]) { struct timeval tv; #endif + +#if defined(__linux__) && defined(__OPTIMIZE__) + /* + Disable lazy relocations to make usage of external libraries + more deterministic for our RT threads. We abuse __OPTIMIZE__ as + a check whether we are a debug build or not. + */ + + if (!getenv("LD_BIND_NOW")) { + putenv(pa_xstrdup("LD_BIND_NOW=1")); + + /* We have to execute ourselves, because the libc caches the + * value of $LD_BIND_NOW on initialization. */ + pa_assert_se(execv("/proc/self/exe", argv) == 0); + } +#endif + #ifdef HAVE_GETUID real_root = getuid() == 0; suid_root = !real_root && geteuid() == 0; -- cgit From 19eb7ebd4d4b0390b60ecadc57b9aefb3ae94560 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 17 Sep 2007 13:50:13 +0000 Subject: once.c is no longer POSIX specific. Since it is now considerably more advanced than it used to be, use it on windows, too git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1841 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 8 ++-- src/daemon/main.c | 1 - src/pulsecore/once-posix.c | 98 ---------------------------------------------- src/pulsecore/once-win32.c | 69 -------------------------------- src/pulsecore/once.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 101 insertions(+), 173 deletions(-) delete mode 100644 src/pulsecore/once-posix.c delete mode 100644 src/pulsecore/once-win32.c create mode 100644 src/pulsecore/once.c diff --git a/src/Makefile.am b/src/Makefile.am index d9933a0b..95a0e928 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -77,15 +77,11 @@ endif if OS_IS_WIN32 PA_THREAD_OBJS = \ - pulsecore/once-win32.c pulsecore/once.h \ pulsecore/mutex-win32.c pulsecore/mutex.h \ pulsecore/thread-win32.c pulsecore/thread.h \ - pulsecore/semaphore.h -#pulsecore/semaphore-win32.c pulsecore/semaphore.h + pulsecore/semaphore-win32.c pulsecore/semaphore.h else PA_THREAD_OBJS = \ - pulsecore/atomic.h \ - pulsecore/once-posix.c pulsecore/once.h \ pulsecore/mutex-posix.c pulsecore/mutex.h \ pulsecore/thread-posix.c pulsecore/thread.h \ pulsecore/semaphore-posix.c pulsecore/semaphore.h @@ -496,6 +492,7 @@ libpulse_la_SOURCES += \ pulsecore/flist.c pulsecore/flist.h \ pulsecore/object.c pulsecore/object.h \ pulsecore/msgobject.c pulsecore/msgobject.h \ + pulsecore/once.c pulsecore/once.h \ $(PA_THREAD_OBJS) if OS_IS_WIN32 @@ -706,6 +703,7 @@ libpulsecore_la_SOURCES += \ pulsecore/rtpoll.c pulsecore/rtpoll.h \ pulsecore/rtclock.c pulsecore/rtclock.h \ pulsecore/macro.h \ + pulsecore/once.c pulsecore/once.h \ $(PA_THREAD_OBJS) if OS_IS_WIN32 diff --git a/src/daemon/main.c b/src/daemon/main.c index c446582e..ba2a33d5 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -320,7 +320,6 @@ int main(int argc, char *argv[]) { int daemon_pipe[2] = { -1, -1 }; int suid_root, real_root; int valid_pid_file = 0; - gid_t gid = (gid_t) -1; #ifdef OS_IS_WIN32 diff --git a/src/pulsecore/once-posix.c b/src/pulsecore/once-posix.c deleted file mode 100644 index 4f6e5b62..00000000 --- a/src/pulsecore/once-posix.c +++ /dev/null @@ -1,98 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of PulseAudio. - - Copyright 2006 Lennart Poettering - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include -#include - -#include "once.h" - -int pa_once_begin(pa_once *control) { - pa_mutex *m; - - pa_assert(control); - - if (pa_atomic_load(&control->done)) - return 0; - - pa_atomic_inc(&control->ref); - - /* Caveat: We have to make sure that the once func has completed - * before returning, even if the once func is not actually - * executed by us. Hence the awkward locking. */ - - for (;;) { - - if ((m = pa_atomic_ptr_load(&control->mutex))) { - - /* The mutex is stored in locked state, hence let's just - * wait until it is unlocked */ - pa_mutex_lock(m); - - pa_once_end(control); - return 0; - } - - pa_assert_se(m = pa_mutex_new(FALSE, FALSE)); - pa_mutex_lock(m); - - if (pa_atomic_ptr_cmpxchg(&control->mutex, NULL, m)) - return 1; - - pa_mutex_unlock(m); - pa_mutex_free(m); - } -} - -void pa_once_end(pa_once *control) { - pa_mutex *m; - - pa_assert(control); - - pa_atomic_store(&control->done, 1); - - pa_assert_se(m = pa_atomic_ptr_load(&control->mutex)); - pa_mutex_unlock(m); - - if (pa_atomic_dec(&control->ref) <= 1) { - pa_assert_se(pa_atomic_ptr_cmpxchg(&control->mutex, m, NULL)); - pa_mutex_free(m); - } -} - -/* Not reentrant -- how could it be? */ -void pa_run_once(pa_once *control, pa_once_func_t func) { - pa_assert(control); - pa_assert(func); - - if (pa_once_begin(control)) { - func(); - pa_once_end(control); - } -} - diff --git a/src/pulsecore/once-win32.c b/src/pulsecore/once-win32.c deleted file mode 100644 index b30097c8..00000000 --- a/src/pulsecore/once-win32.c +++ /dev/null @@ -1,69 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of PulseAudio. - - Copyright 2006 Pierre Ossman for Cendio AB - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include - -#include - -#include "once.h" - -void pa_once(pa_once_t *control, pa_once_func_t func) { - HANDLE mutex; - char name[64]; - - assert(control); - assert(func); - - /* Create the global mutex */ - sprintf(name, "pulse%d", (int)GetCurrentProcessId()); - - mutex = CreateMutex(NULL, FALSE, name); - assert(mutex); - - /* Create the local mutex */ - WaitForSingleObject(mutex, INFINITE); - if (!control->mutex) - control->mutex = pa_mutex_new(1); - ReleaseMutex(mutex); - - CloseHandle(mutex); - - /* Execute function */ - pa_mutex_lock(control->mutex); - if (!control->once_value) { - control->once_value = 1; - func(); - } - pa_mutex_unlock(control->mutex); - - /* Caveat: We have to make sure that the once func has completed - * before returning, even if the once func is not actually - * executed by us. Hence the awkward locking. */ -} diff --git a/src/pulsecore/once.c b/src/pulsecore/once.c new file mode 100644 index 00000000..4f6e5b62 --- /dev/null +++ b/src/pulsecore/once.c @@ -0,0 +1,98 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include + +#include "once.h" + +int pa_once_begin(pa_once *control) { + pa_mutex *m; + + pa_assert(control); + + if (pa_atomic_load(&control->done)) + return 0; + + pa_atomic_inc(&control->ref); + + /* Caveat: We have to make sure that the once func has completed + * before returning, even if the once func is not actually + * executed by us. Hence the awkward locking. */ + + for (;;) { + + if ((m = pa_atomic_ptr_load(&control->mutex))) { + + /* The mutex is stored in locked state, hence let's just + * wait until it is unlocked */ + pa_mutex_lock(m); + + pa_once_end(control); + return 0; + } + + pa_assert_se(m = pa_mutex_new(FALSE, FALSE)); + pa_mutex_lock(m); + + if (pa_atomic_ptr_cmpxchg(&control->mutex, NULL, m)) + return 1; + + pa_mutex_unlock(m); + pa_mutex_free(m); + } +} + +void pa_once_end(pa_once *control) { + pa_mutex *m; + + pa_assert(control); + + pa_atomic_store(&control->done, 1); + + pa_assert_se(m = pa_atomic_ptr_load(&control->mutex)); + pa_mutex_unlock(m); + + if (pa_atomic_dec(&control->ref) <= 1) { + pa_assert_se(pa_atomic_ptr_cmpxchg(&control->mutex, m, NULL)); + pa_mutex_free(m); + } +} + +/* Not reentrant -- how could it be? */ +void pa_run_once(pa_once *control, pa_once_func_t func) { + pa_assert(control); + pa_assert(func); + + if (pa_once_begin(control)) { + func(); + pa_once_end(control); + } +} + -- cgit From d3b898513c8b289c5cf026493badb1b8865d07a0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 17 Sep 2007 14:03:04 +0000 Subject: drop a couple of WARNING prefixes in log messages, since we have pa_log_warn anyway for marking warnings especially git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1842 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/daemon-conf.c | 2 +- src/modules/module-combine.c | 2 +- src/modules/module-esound-compat-spawnfd.c | 2 +- src/modules/module-esound-compat-spawnpid.c | 2 +- src/modules/module-esound-sink.c | 2 +- src/pulse/client-conf.c | 2 +- src/pulse/mainloop.c | 2 +- src/pulsecore/conf-parser.c | 4 ++-- src/pulsecore/core-util.c | 14 ++++++-------- src/pulsecore/flist.c | 4 ++-- src/pulsecore/ipacl.c | 4 ++-- src/pulsecore/memblock.c | 2 +- src/pulsecore/pid.c | 4 ++-- 13 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c index ff628166..825101c7 100644 --- a/src/daemon/daemon-conf.c +++ b/src/daemon/daemon-conf.c @@ -426,7 +426,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) { pa_open_config_file(DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_FILE_USER, ENV_CONFIG_FILE, &c->config_file, "r"); if (!f && errno != ENOENT) { - pa_log("WARNING: failed to open configuration file '%s': %s", c->config_file, pa_cstrerror(errno)); + pa_log_warn("Failed to open configuration file '%s': %s", c->config_file, pa_cstrerror(errno)); goto finish; } diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 7ac7b9ab..feadf4f9 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -1051,7 +1051,7 @@ int pa__init(pa_module*m) { } if (pa_idxset_size(u->outputs) <= 1) - pa_log_warn("WARNING: No slave sinks specified."); + pa_log_warn("No slave sinks specified."); u->sink_new_slot = NULL; diff --git a/src/modules/module-esound-compat-spawnfd.c b/src/modules/module-esound-compat-spawnfd.c index 46235c09..49dcf3be 100644 --- a/src/modules/module-esound-compat-spawnfd.c +++ b/src/modules/module-esound-compat-spawnfd.c @@ -63,7 +63,7 @@ int pa__init(pa_module*m) { } if (pa_loop_write(fd, &x, sizeof(x), NULL) != sizeof(x)) - pa_log_warn("WARNING: write(%u, 1, 1) failed: %s", fd, pa_cstrerror(errno)); + pa_log_warn("write(%u, 1, 1) failed: %s", fd, pa_cstrerror(errno)); pa_assert_se(pa_close(fd) == 0); diff --git a/src/modules/module-esound-compat-spawnpid.c b/src/modules/module-esound-compat-spawnpid.c index 1cc86d20..6ad7db7b 100644 --- a/src/modules/module-esound-compat-spawnpid.c +++ b/src/modules/module-esound-compat-spawnpid.c @@ -62,7 +62,7 @@ int pa__init(pa_module*m) { } if (kill(pid, SIGUSR1) < 0) - pa_log_warn("WARNING: kill(%u) failed: %s", pid, pa_cstrerror(errno)); + pa_log_warn("kill(%u) failed: %s", pid, pa_cstrerror(errno)); pa_module_unload_request(m); diff --git a/src/modules/module-esound-sink.c b/src/modules/module-esound-sink.c index 39886d04..faa77a54 100644 --- a/src/modules/module-esound-sink.c +++ b/src/modules/module-esound-sink.c @@ -210,7 +210,7 @@ static int handle_response(struct userdata *u) { /* Process latency info */ u->latency = (pa_usec_t) ((double) (*(int32_t*) u->read_data) * 1000000 / 44100); if (u->latency > 10000000) { - pa_log("WARNING! Invalid latency information received from server"); + pa_log_warn("Invalid latency information received from server"); u->latency = 0; } diff --git a/src/pulse/client-conf.c b/src/pulse/client-conf.c index 447d1857..abd277a6 100644 --- a/src/pulse/client-conf.c +++ b/src/pulse/client-conf.c @@ -117,7 +117,7 @@ int pa_client_conf_load(pa_client_conf *c, const char *filename) { pa_open_config_file(DEFAULT_CLIENT_CONFIG_FILE, DEFAULT_CLIENT_CONFIG_FILE_USER, ENV_CLIENT_CONFIG_FILE, &fn, "r"); if (!f && errno != EINTR) { - pa_log_warn("WARNING: failed to open configuration file '%s': %s", fn, pa_cstrerror(errno)); + pa_log_warn("Failed to open configuration file '%s': %s", fn, pa_cstrerror(errno)); goto finish; } diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index 641eded4..c69c6653 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -194,7 +194,7 @@ static pa_io_event* mainloop_io_new( if ((select((SELECT_TYPE_ARG1) fd, NULL, NULL, SELECT_TYPE_ARG234 &xset, SELECT_TYPE_ARG5 &tv) == -1) && (WSAGetLastError() == WSAENOTSOCK)) { - pa_log_warn("WARNING: cannot monitor non-socket file descriptors."); + pa_log_warn("Cannot monitor non-socket file descriptors."); e->dead = 1; } } diff --git a/src/pulsecore/conf-parser.c b/src/pulsecore/conf-parser.c index 47ec72c2..ee43b05a 100644 --- a/src/pulsecore/conf-parser.c +++ b/src/pulsecore/conf-parser.c @@ -120,7 +120,7 @@ int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void goto finish; } - pa_log_warn("WARNING: failed to open configuration file '%s': %s", + pa_log_warn("Failed to open configuration file '%s': %s", filename, pa_cstrerror(errno)); goto finish; } @@ -131,7 +131,7 @@ int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void if (feof(f)) break; - pa_log_warn("WARNING: failed to read configuration file '%s': %s", + pa_log_warn("Failed to read configuration file '%s': %s", filename, pa_cstrerror(errno)); goto finish; } diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 5becdef0..a729cbbb 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -141,10 +141,10 @@ void pa_make_nonblock_fd(int fd) { u_long arg = 1; if (ioctlsocket(fd, FIONBIO, &arg) < 0) { if (WSAGetLastError() == WSAENOTSOCK) - pa_log_warn("WARNING: Only sockets can be made non-blocking!"); + pa_log_warn("Only sockets can be made non-blocking!"); } #else - pa_log_warn("WARNING: Non-blocking I/O not supported.!"); + pa_log_warn("Non-blocking I/O not supported.!"); #endif } @@ -411,9 +411,9 @@ void pa_check_signal_is_blocked(int sig) { if (sa.sa_handler != SIG_DFL) return; - pa_log("WARNING: %s is not trapped. This might cause malfunction!", pa_strsignal(sig)); + pa_log_warn("%s is not trapped. This might cause malfunction!", pa_strsignal(sig)); #else /* HAVE_SIGACTION */ - pa_log("WARNING: %s might not be trapped. This might cause malfunction!", pa_strsignal(sig)); + pa_log_warn("%s might not be trapped. This might cause malfunction!", pa_strsignal(sig)); #endif } @@ -995,10 +995,8 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env return f; } - if (errno != ENOENT) { - pa_log_warn("WARNING: failed to open configuration file '%s': %s", - lfn, pa_cstrerror(errno)); - } + if (errno != ENOENT) + pa_log_warn("Failed to open configuration file '%s': %s", lfn, pa_cstrerror(errno)); pa_xfree(lfn); } diff --git a/src/pulsecore/flist.c b/src/pulsecore/flist.c index 680a9f76..d9740777 100644 --- a/src/pulsecore/flist.c +++ b/src/pulsecore/flist.c @@ -186,7 +186,7 @@ int pa_flist_push(pa_flist*l, void *p) { #ifdef PROFILE if (len > N_EXTRA_SCAN) - pa_log("WARNING: Didn't find free cell after %u iterations.", len); + pa_log_warn("Didn't find free cell after %u iterations.", len); #endif return -1; @@ -227,7 +227,7 @@ void* pa_flist_pop(pa_flist*l) { #ifdef PROFILE if (len > N_EXTRA_SCAN) - pa_log("WARNING: Didn't find used cell after %u iterations.", len); + pa_log_warn("Didn't find used cell after %u iterations.", len); #endif return NULL; diff --git a/src/pulsecore/ipacl.c b/src/pulsecore/ipacl.c index 8a8eac78..9b22e8f5 100644 --- a/src/pulsecore/ipacl.c +++ b/src/pulsecore/ipacl.c @@ -109,7 +109,7 @@ pa_ip_acl* pa_ip_acl_new(const char *s) { e.family = AF_INET; if (e.bits < 32 && (uint32_t) (ntohl(e.address_ipv4.s_addr) << e.bits) != 0) - pa_log_warn("WARNING: Host part of ACL entry '%s/%u' is not zero!", a, e.bits); + pa_log_warn("Host part of ACL entry '%s/%u' is not zero!", a, e.bits); } else if (inet_pton(AF_INET6, a, &e.address_ipv6) > 0) { @@ -138,7 +138,7 @@ pa_ip_acl* pa_ip_acl_new(const char *s) { } if (t) - pa_log_warn("WARNING: Host part of ACL entry '%s/%u' is not zero!", a, e.bits); + pa_log_warn("Host part of ACL entry '%s/%u' is not zero!", a, e.bits); } } else { diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index 3827dc03..e05304ba 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -704,7 +704,7 @@ void pa_mempool_free(pa_mempool *p) { if (pa_atomic_load(&p->stat.n_allocated) > 0) { /* raise(SIGTRAP); */ - pa_log_warn("WARNING! Memory pool destroyed but not all memory blocks freed! %u remain.", pa_atomic_load(&p->stat.n_allocated)); + pa_log_warn("Memory pool destroyed but not all memory blocks freed! %u remain.", pa_atomic_load(&p->stat.n_allocated)); } pa_shm_free(&p->memory); diff --git a/src/pulsecore/pid.c b/src/pulsecore/pid.c index 6bc9f06a..44f5e84c 100644 --- a/src/pulsecore/pid.c +++ b/src/pulsecore/pid.c @@ -90,7 +90,7 @@ static int open_pid_file(const char *fn, int mode) { if ((fd = open(fn, mode, S_IRUSR|S_IWUSR)) < 0) { if (mode != O_RDONLY || errno != ENOENT) - pa_log_warn("WARNING: failed to open PID file '%s': %s", fn, pa_cstrerror(errno)); + pa_log_warn("Failed to open PID file '%s': %s", fn, pa_cstrerror(errno)); goto fail; } @@ -204,7 +204,7 @@ int pa_pid_file_remove(void) { pa_runtime_path("pid", fn, sizeof(fn)); if ((fd = open_pid_file(fn, O_RDWR)) < 0) { - pa_log_warn("WARNING: failed to open PID file '%s': %s", + pa_log_warn("Failed to open PID file '%s': %s", fn, pa_cstrerror(errno)); goto fail; } -- cgit From 26a1ae7bbb5f95aa9117cac1f693c79289c8e124 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 17 Sep 2007 15:26:18 +0000 Subject: Rename pa_strsignal() to pa_sig2str(), since we return the symbolical signal name, not a human readable string. This follows the Solaris API of sig2str() a bit. Also, add all remaining signals to the list of signal names. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1843 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 2 +- src/Makefile.am | 8 +++- src/daemon/main.c | 2 +- src/pulsecore/core-util.c | 95 +++++++++++++++++++++++++++++++++++++++-------- src/pulsecore/core-util.h | 2 +- src/pulsecore/rtpoll.c | 2 +- src/tests/sig2str-test.c | 39 +++++++++++++++++++ 7 files changed, 129 insertions(+), 21 deletions(-) create mode 100644 src/tests/sig2str-test.c diff --git a/configure.ac b/configure.ac index 869db01a..c1666084 100644 --- a/configure.ac +++ b/configure.ac @@ -291,7 +291,7 @@ AC_CHECK_FUNCS([lstat]) # Non-standard -AC_CHECK_FUNCS([setresuid setresgid setreuid setregid seteuid setegid ppoll]) +AC_CHECK_FUNCS([setresuid setresgid setreuid setregid seteuid setegid ppoll strsignal sig2str]) #### POSIX threads #### diff --git a/src/Makefile.am b/src/Makefile.am index 95a0e928..06f061d5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -235,7 +235,8 @@ noinst_PROGRAMS = \ asyncq-test \ asyncmsgq-test \ queue-test \ - rtpoll-test + rtpoll-test \ + sig2str-test if HAVE_SIGXCPU noinst_PROGRAMS += \ @@ -375,6 +376,11 @@ interpol_test_LDADD = $(AM_LDADD) libpulse.la interpol_test_CFLAGS = $(AM_CFLAGS) interpol_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) +sig2str_test_SOURCES = tests/sig2str-test.c +sig2str_test_LDADD = $(AM_LDADD) libpulsecore.la +sig2str_test_CFLAGS = $(AM_CFLAGS) +sig2str_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + ################################### # Client library # ################################### diff --git a/src/daemon/main.c b/src/daemon/main.c index ba2a33d5..a660ab10 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -130,7 +130,7 @@ static void message_cb(pa_mainloop_api*a, pa_time_event*e, PA_GCC_UNUSED const s #endif static void signal_callback(pa_mainloop_api*m, PA_GCC_UNUSED pa_signal_event *e, int sig, void *userdata) { - pa_log_info("Got signal %s.", pa_strsignal(sig)); + pa_log_info("Got signal %s.", pa_sig2str(sig)); switch (sig) { #ifdef SIGUSR1 diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index a729cbbb..37e7f183 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -90,6 +90,7 @@ #include #include #include +#include #include "core-util.h" @@ -411,9 +412,9 @@ void pa_check_signal_is_blocked(int sig) { if (sa.sa_handler != SIG_DFL) return; - pa_log_warn("%s is not trapped. This might cause malfunction!", pa_strsignal(sig)); + pa_log_warn("%s is not trapped. This might cause malfunction!", pa_sig2str(sig)); #else /* HAVE_SIGACTION */ - pa_log_warn("%s might not be trapped. This might cause malfunction!", pa_strsignal(sig)); + pa_log_warn("%s might not be trapped. This might cause malfunction!", pa_sig2str(sig)); #endif } @@ -616,31 +617,93 @@ char *pa_split_spaces(const char *c, const char **state) { return pa_xstrndup(current, l); } -/* Return the name of an UNIX signal. Similar to GNU's strsignal() */ -const char *pa_strsignal(int sig) { +PA_STATIC_TLS_DECLARE(signame, pa_xfree); + +/* Return the name of an UNIX signal. Similar to Solaris sig2str() */ +const char *pa_sig2str(int sig) { + char *t; + + if (sig <= 0 || sig >= _NSIG) + goto fail; + +#ifdef HAVE_SIG2STR + { + char buf[SIG2STR_MAX]; + + if (str2sig(sig, buf) == 0) { + pa_xfree(PA_STATIC_TLS_GET(signame)); + t = pa_sprintf_malloc("SIG%s", buf); + PA_STATIC_TLS_SET(signame, t); + return t; + } + } +#else + switch(sig) { - case SIGINT: return "SIGINT"; - case SIGTERM: return "SIGTERM"; +#ifdef SIGHUP + case SIGHUP: return "SIGHUP"; +#endif + case SIGINT: return "SIGINT"; + case SIGQUIT: return "SIGQUIT"; + case SIGILL: return "SIGULL"; + case SIGTRAP: return "SIGTRAP"; + case SIGABRT: return "SIGABRT"; + case SIGBUS: return "SIGBUS"; + case SIGFPE: return "SIGFPE"; + case SIGKILL: return "SIGKILL"; #ifdef SIGUSR1 - case SIGUSR1: return "SIGUSR1"; + case SIGUSR1: return "SIGUSR1"; #endif + case SIGSEGV: return "SIGSEGV"; #ifdef SIGUSR2 - case SIGUSR2: return "SIGUSR2"; -#endif -#ifdef SIGXCPU - case SIGXCPU: return "SIGXCPU"; + case SIGUSR2: return "SIGUSR2"; #endif #ifdef SIGPIPE - case SIGPIPE: return "SIGPIPE"; + case SIGPIPE: return "SIGPIPE"; #endif + case SIGALRM: return "SIGALRM"; + case SIGTERM: return "SIGTERM"; + case SIGSTKFLT: return "SIGSTKFLT"; #ifdef SIGCHLD - case SIGCHLD: return "SIGCHLD"; + case SIGCHLD: return "SIGCHLD"; #endif -#ifdef SIGHUP - case SIGHUP: return "SIGHUP"; + case SIGCONT: return "SIGCONT"; + case SIGSTOP: return "SIGSTOP"; + case SIGTSTP: return "SIGTSTP"; + case SIGTTIN: return "SIGTTIN"; + case SIGTTOU: return "SIGTTOU"; + case SIGURG: return "SIGURG"; +#ifdef SIGXCPU + case SIGXCPU: return "SIGXCPU"; +#endif +#ifdef SIGXFSZ + case SIGXFSZ: return "SIGXFSZ"; #endif - default: return "UNKNOWN SIGNAL"; + case SIGVTALRM: return "SIGVTALRM"; + case SIGPROF: return "SIGPROF"; + case SIGWINCH: return "SIGWINCH"; + case SIGIO: return "SIGIO"; + case SIGPWR: return "SIGPWR"; + case SIGSYS: return "SIGSYS"; + } + +#ifdef SIGRTMIN + if (sig >= SIGRTMIN && sig <= SIGRTMAX) { + pa_xfree(PA_STATIC_TLS_GET(signame)); + t = pa_sprintf_malloc("SIGRTMIN+%i", sig - SIGRTMIN); + PA_STATIC_TLS_SET(signame, t); + return t; } +#endif + +#endif + +fail: + + pa_xfree(PA_STATIC_TLS_GET(signame)); + t = pa_sprintf_malloc("SIG%i", sig); + PA_STATIC_TLS_SET(signame, t); + return t; } #ifdef HAVE_GRP_H diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index af97e4bf..4429f418 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -68,7 +68,7 @@ char *pa_split_spaces(const char *c, const char **state); char *pa_strip_nl(char *s); -const char *pa_strsignal(int sig) PA_GCC_PURE; +const char *pa_sig2str(int sig) PA_GCC_PURE; int pa_own_uid_in_group(const char *name, gid_t *gid); int pa_uid_in_group(uid_t uid, const char *name); diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c index 0de8d0ce..e7ccd908 100644 --- a/src/pulsecore/rtpoll.c +++ b/src/pulsecore/rtpoll.c @@ -157,7 +157,7 @@ void pa_rtpoll_install(pa_rtpoll *p) { return; } - pa_log_debug("Acquired POSIX realtime signal SIGRTMIN+%i", p->rtsig - SIGRTMIN); + pa_log_debug("Acquired POSIX realtime signal %s", pa_sig2str(p->rtsig)); { sigset_t ss; diff --git a/src/tests/sig2str-test.c b/src/tests/sig2str-test.c new file mode 100644 index 00000000..b3cc99d3 --- /dev/null +++ b/src/tests/sig2str-test.c @@ -0,0 +1,39 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include + +int main(int argc, char *argv[]) { + int sig; + + for (sig = -1; sig < _NSIG+1; sig++) + printf("%i = %s\n", sig, pa_sig2str(sig)); + + return 0; +} -- cgit From 1ae473bd1bb0f9087aa260a57cda869d9609f61f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 17 Sep 2007 17:00:50 +0000 Subject: fall back to plughw: if hw: doesn't work git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1844 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 52 ++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 70685e40..fb3f926b 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -678,7 +678,7 @@ int pa__init(pa_module*m) { pa_modargs *ma = NULL; struct userdata *u = NULL; - const char *dev; + char *dev; pa_sample_spec ss; pa_channel_map map; uint32_t nfrags, frag_size; @@ -737,24 +737,39 @@ int pa__init(pa_module*m) { pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); snd_config_update_free_global(); - if ((err = snd_pcm_open(&u->pcm_handle, dev = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { - pa_log("Error opening PCM device %s: %s", dev, snd_strerror(err)); - goto fail; - } - u->device_name = pa_xstrdup(dev); + dev = pa_xstrdup(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE)); - if ((err = snd_pcm_info(u->pcm_handle, pcm_info)) < 0) { - pa_log("Error fetching PCM info: %s", snd_strerror(err)); - goto fail; - } + for (;;) { + + if ((err = snd_pcm_open(&u->pcm_handle, dev, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { + pa_log("Error opening PCM device %s: %s", dev, snd_strerror(err)); + pa_xfree(dev); + goto fail; + } + + b = use_mmap; + if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) { - b = use_mmap; - if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) { - pa_log("Failed to set hardware parameters: %s", snd_strerror(err)); - goto fail; - } + if (err == -EPERM) { + /* Hmm, some hw is very exotic, so we retry with plughw, if hw didn't work */ + + if (pa_startswith(dev, "hw:")) { + char *d = pa_sprintf_malloc("plughw:%s", dev+3); + pa_xfree(dev); + dev = d; + continue; + } + } + + pa_log("Failed to set hardware parameters: %s", snd_strerror(err)); + pa_xfree(dev); + goto fail; + } + break; + } + if (use_mmap && !b) { pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode."); u->use_mmap = use_mmap = b; @@ -763,6 +778,13 @@ int pa__init(pa_module*m) { if (u->use_mmap) pa_log_info("Successfully enabled mmap() mode."); + if ((err = snd_pcm_info(u->pcm_handle, pcm_info)) < 0) { + pa_log("Error fetching PCM info: %s", snd_strerror(err)); + goto fail; + } + + u->device_name = dev; + if ((err = pa_alsa_set_sw_params(u->pcm_handle)) < 0) { pa_log("Failed to set software parameters: %s", snd_strerror(err)); goto fail; -- cgit -- cgit From 8ff7d567d364e60283a73486889876c454566eea Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 17 Sep 2007 22:39:51 +0000 Subject: add a locale-independant pa_atof() implementation git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1846 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 2 +- src/pulsecore/core-util.c | 61 +++++++++++++++++++++++++++++++++++++++++++++-- src/pulsecore/core-util.h | 1 + 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index c1666084..5b6c6474 100644 --- a/configure.ac +++ b/configure.ac @@ -291,7 +291,7 @@ AC_CHECK_FUNCS([lstat]) # Non-standard -AC_CHECK_FUNCS([setresuid setresgid setreuid setregid seteuid setegid ppoll strsignal sig2str]) +AC_CHECK_FUNCS([setresuid setresgid setreuid setregid seteuid setegid ppoll strsignal sig2str strtof_l]) #### POSIX threads #### diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 37e7f183..aac7629e 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -42,6 +42,10 @@ #include #include +#ifdef HAVE_STRTOF_L +#include +#endif + #ifdef HAVE_SCHED_H #include #endif @@ -1221,11 +1225,15 @@ int pa_atoi(const char *s, int32_t *ret_i) { pa_assert(s); pa_assert(ret_i); + errno = 0; l = strtol(s, &x, 0); - if (!x || *x) + if (!x || *x || errno != 0) return -1; + if ((int32_t) l != l) + return -1; + *ret_i = (int32_t) l; return 0; @@ -1239,9 +1247,13 @@ int pa_atou(const char *s, uint32_t *ret_u) { pa_assert(s); pa_assert(ret_u); + errno = 0; l = strtoul(s, &x, 0); - if (!x || *x) + if (!x || *x || errno != 0) + return -1; + + if ((uint32_t) l != l) return -1; *ret_u = (uint32_t) l; @@ -1249,6 +1261,51 @@ int pa_atou(const char *s, uint32_t *ret_u) { return 0; } +#ifdef HAVE_STRTOF_L +static locale_t c_locale = NULL; + +static void c_locale_destroy(void) { + freelocale(c_locale); +} +#endif + +int pa_atof(const char *s, float *ret_f) { + char *x = NULL; + float f; + int r = 0; + + pa_assert(s); + pa_assert(ret_f); + + /* This should be locale independent */ + +#ifdef HAVE_STRTOF_L + + PA_ONCE_BEGIN { + + if ((c_locale = newlocale(LC_ALL_MASK, "C", NULL))) + atexit(c_locale_destroy); + + } PA_ONCE_END; + + if (c_locale) { + errno = 0; + f = strtof_l(s, &x, c_locale); + } else +#endif + { + errno = 0; + f = strtof(s, &x); + } + + if (!x || *x || errno != 0) + r = -1; + else + *ret_f = f; + + return r; +} + /* Same as snprintf, but guarantees NUL-termination on every platform */ int pa_snprintf(char *str, size_t size, const char *format, ...) { int ret; diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index 4429f418..b8ef464e 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -92,6 +92,7 @@ char *pa_runtime_path(const char *fn, char *s, size_t l); int pa_atoi(const char *s, int32_t *ret_i); int pa_atou(const char *s, uint32_t *ret_u); +int pa_atof(const char *s, float *ret_f); int pa_snprintf(char *str, size_t size, const char *format, ...); -- cgit From 7b4f981e4fb72b333cc154e5f11bba3d2562bd2d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 17 Sep 2007 22:40:42 +0000 Subject: print a message when we fall back on plughw git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1847 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index fb3f926b..84f1d4ef 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -756,6 +756,7 @@ int pa__init(pa_module*m) { if (pa_startswith(dev, "hw:")) { char *d = pa_sprintf_malloc("plughw:%s", dev+3); + pa_log_debug("Opening the device as '%s' didn't work, retrying with '%s'.", dev, d); pa_xfree(dev); dev = d; continue; -- cgit From 4cde5073f034545dd9dc200efe5fe873760a55c0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 17 Sep 2007 22:42:20 +0000 Subject: add LADSPA sink than can be piggy-backed ontop of another sink git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1848 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 9 +- src/modules/ladspa.h | 603 +++++++++++++++++++++++++++++++++++++++ src/modules/module-ladspa-sink.c | 565 ++++++++++++++++++++++++++++++++++++ 3 files changed, 1176 insertions(+), 1 deletion(-) create mode 100644 src/modules/ladspa.h create mode 100644 src/modules/module-ladspa-sink.c diff --git a/src/Makefile.am b/src/Makefile.am index 06f061d5..c564ff38 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -940,7 +940,8 @@ modlibexec_LTLIBRARIES += \ module-native-protocol-fd.la \ module-esound-protocol-tcp.la \ module-combine.la \ - module-remap-sink.la + module-remap-sink.la \ + module-ladspa-sink.la # module-tunnel-sink.la \ # module-tunnel-source.la \ # module-esound-sink.la @@ -1061,6 +1062,7 @@ SYMDEF_FILES = \ modules/module-sine-symdef.h \ modules/module-combine-symdef.h \ modules/module-remap-sink-symdef.h \ + modules/module-ladspa-sink-symdef.h \ modules/module-esound-compat-spawnfd-symdef.h \ modules/module-esound-compat-spawnpid-symdef.h \ modules/module-match-symdef.h \ @@ -1213,6 +1215,11 @@ module_remap_sink_la_SOURCES = modules/module-remap-sink.c module_remap_sink_la_LDFLAGS = -module -avoid-version module_remap_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la +module_ladspa_sink_la_SOURCES = modules/module-ladspa-sink.c modules/ladspa.h +module_ladspa_sink_la_CFLAGS = -DLADSPA_PATH=\"$(libdir)/ladspa:/usr/local/lib/ladspa:/usr/lib/ladspa\" $(AM_CFLAGS) +module_ladspa_sink_la_LDFLAGS = -module -avoid-version +module_ladspa_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la + module_match_la_SOURCES = modules/module-match.c module_match_la_LDFLAGS = -module -avoid-version module_match_la_LIBADD = $(AM_LIBADD) libpulsecore.la diff --git a/src/modules/ladspa.h b/src/modules/ladspa.h new file mode 100644 index 00000000..5c30a8a4 --- /dev/null +++ b/src/modules/ladspa.h @@ -0,0 +1,603 @@ +/* ladspa.h + + Linux Audio Developer's Simple Plugin API Version 1.1[LGPL]. + Copyright (C) 2000-2002 Richard W.E. Furse, Paul Barton-Davis, + Stefan Westerfeld. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. */ + +#ifndef LADSPA_INCLUDED +#define LADSPA_INCLUDED + +#define LADSPA_VERSION "1.1" +#define LADSPA_VERSION_MAJOR 1 +#define LADSPA_VERSION_MINOR 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/*****************************************************************************/ + +/* Overview: + + There is a large number of synthesis packages in use or development + on the Linux platform at this time. This API (`The Linux Audio + Developer's Simple Plugin API') attempts to give programmers the + ability to write simple `plugin' audio processors in C/C++ and link + them dynamically (`plug') into a range of these packages (`hosts'). + It should be possible for any host and any plugin to communicate + completely through this interface. + + This API is deliberately short and simple. To achieve compatibility + with a range of promising Linux sound synthesis packages it + attempts to find the `greatest common divisor' in their logical + behaviour. Having said this, certain limiting decisions are + implicit, notably the use of a fixed type (LADSPA_Data) for all + data transfer and absence of a parameterised `initialisation' + phase. See below for the LADSPA_Data typedef. + + Plugins are expected to distinguish between control and audio + data. Plugins have `ports' that are inputs or outputs for audio or + control data and each plugin is `run' for a `block' corresponding + to a short time interval measured in samples. Audio data is + communicated using arrays of LADSPA_Data, allowing a block of audio + to be processed by the plugin in a single pass. Control data is + communicated using single LADSPA_Data values. Control data has a + single value at the start of a call to the `run()' or `run_adding()' + function, and may be considered to remain this value for its + duration. The plugin may assume that all its input and output ports + have been connected to the relevant data location (see the + `connect_port()' function below) before it is asked to run. + + Plugins will reside in shared object files suitable for dynamic + linking by dlopen() and family. The file will provide a number of + `plugin types' that can be used to instantiate actual plugins + (sometimes known as `plugin instances') that can be connected + together to perform tasks. + + This API contains very limited error-handling. */ + +/*****************************************************************************/ + +/* Fundamental data type passed in and out of plugin. This data type + is used to communicate audio samples and control values. It is + assumed that the plugin will work sensibly given any numeric input + value although it may have a preferred range (see hints below). + + For audio it is generally assumed that 1.0f is the `0dB' reference + amplitude and is a `normal' signal level. */ + +typedef float LADSPA_Data; + +/*****************************************************************************/ + +/* Special Plugin Properties: + + Optional features of the plugin type are encapsulated in the + LADSPA_Properties type. This is assembled by ORing individual + properties together. */ + +typedef int LADSPA_Properties; + +/* Property LADSPA_PROPERTY_REALTIME indicates that the plugin has a + real-time dependency (e.g. listens to a MIDI device) and so its + output must not be cached or subject to significant latency. */ +#define LADSPA_PROPERTY_REALTIME 0x1 + +/* Property LADSPA_PROPERTY_INPLACE_BROKEN indicates that the plugin + may cease to work correctly if the host elects to use the same data + location for both input and output (see connect_port()). This + should be avoided as enabling this flag makes it impossible for + hosts to use the plugin to process audio `in-place.' */ +#define LADSPA_PROPERTY_INPLACE_BROKEN 0x2 + +/* Property LADSPA_PROPERTY_HARD_RT_CAPABLE indicates that the plugin + is capable of running not only in a conventional host but also in a + `hard real-time' environment. To qualify for this the plugin must + satisfy all of the following: + + (1) The plugin must not use malloc(), free() or other heap memory + management within its run() or run_adding() functions. All new + memory used in run() must be managed via the stack. These + restrictions only apply to the run() function. + + (2) The plugin will not attempt to make use of any library + functions with the exceptions of functions in the ANSI standard C + and C maths libraries, which the host is expected to provide. + + (3) The plugin will not access files, devices, pipes, sockets, IPC + or any other mechanism that might result in process or thread + blocking. + + (4) The plugin will take an amount of time to execute a run() or + run_adding() call approximately of form (A+B*SampleCount) where A + and B depend on the machine and host in use. This amount of time + may not depend on input signals or plugin state. The host is left + the responsibility to perform timings to estimate upper bounds for + A and B. */ +#define LADSPA_PROPERTY_HARD_RT_CAPABLE 0x4 + +#define LADSPA_IS_REALTIME(x) ((x) & LADSPA_PROPERTY_REALTIME) +#define LADSPA_IS_INPLACE_BROKEN(x) ((x) & LADSPA_PROPERTY_INPLACE_BROKEN) +#define LADSPA_IS_HARD_RT_CAPABLE(x) ((x) & LADSPA_PROPERTY_HARD_RT_CAPABLE) + +/*****************************************************************************/ + +/* Plugin Ports: + + Plugins have `ports' that are inputs or outputs for audio or + data. Ports can communicate arrays of LADSPA_Data (for audio + inputs/outputs) or single LADSPA_Data values (for control + input/outputs). This information is encapsulated in the + LADSPA_PortDescriptor type which is assembled by ORing individual + properties together. + + Note that a port must be an input or an output port but not both + and that a port must be a control or audio port but not both. */ + +typedef int LADSPA_PortDescriptor; + +/* Property LADSPA_PORT_INPUT indicates that the port is an input. */ +#define LADSPA_PORT_INPUT 0x1 + +/* Property LADSPA_PORT_OUTPUT indicates that the port is an output. */ +#define LADSPA_PORT_OUTPUT 0x2 + +/* Property LADSPA_PORT_CONTROL indicates that the port is a control + port. */ +#define LADSPA_PORT_CONTROL 0x4 + +/* Property LADSPA_PORT_AUDIO indicates that the port is a audio + port. */ +#define LADSPA_PORT_AUDIO 0x8 + +#define LADSPA_IS_PORT_INPUT(x) ((x) & LADSPA_PORT_INPUT) +#define LADSPA_IS_PORT_OUTPUT(x) ((x) & LADSPA_PORT_OUTPUT) +#define LADSPA_IS_PORT_CONTROL(x) ((x) & LADSPA_PORT_CONTROL) +#define LADSPA_IS_PORT_AUDIO(x) ((x) & LADSPA_PORT_AUDIO) + +/*****************************************************************************/ + +/* Plugin Port Range Hints: + + The host may wish to provide a representation of data entering or + leaving a plugin (e.g. to generate a GUI automatically). To make + this more meaningful, the plugin should provide `hints' to the host + describing the usual values taken by the data. + + Note that these are only hints. The host may ignore them and the + plugin must not assume that data supplied to it is meaningful. If + the plugin receives invalid input data it is expected to continue + to run without failure and, where possible, produce a sensible + output (e.g. a high-pass filter given a negative cutoff frequency + might switch to an all-pass mode). + + Hints are meaningful for all input and output ports but hints for + input control ports are expected to be particularly useful. + + More hint information is encapsulated in the + LADSPA_PortRangeHintDescriptor type which is assembled by ORing + individual hint types together. Hints may require further + LowerBound and UpperBound information. + + All the hint information for a particular port is aggregated in the + LADSPA_PortRangeHint structure. */ + +typedef int LADSPA_PortRangeHintDescriptor; + +/* Hint LADSPA_HINT_BOUNDED_BELOW indicates that the LowerBound field + of the LADSPA_PortRangeHint should be considered meaningful. The + value in this field should be considered the (inclusive) lower + bound of the valid range. If LADSPA_HINT_SAMPLE_RATE is also + specified then the value of LowerBound should be multiplied by the + sample rate. */ +#define LADSPA_HINT_BOUNDED_BELOW 0x1 + +/* Hint LADSPA_HINT_BOUNDED_ABOVE indicates that the UpperBound field + of the LADSPA_PortRangeHint should be considered meaningful. The + value in this field should be considered the (inclusive) upper + bound of the valid range. If LADSPA_HINT_SAMPLE_RATE is also + specified then the value of UpperBound should be multiplied by the + sample rate. */ +#define LADSPA_HINT_BOUNDED_ABOVE 0x2 + +/* Hint LADSPA_HINT_TOGGLED indicates that the data item should be + considered a Boolean toggle. Data less than or equal to zero should + be considered `off' or `false,' and data above zero should be + considered `on' or `true.' LADSPA_HINT_TOGGLED may not be used in + conjunction with any other hint except LADSPA_HINT_DEFAULT_0 or + LADSPA_HINT_DEFAULT_1. */ +#define LADSPA_HINT_TOGGLED 0x4 + +/* Hint LADSPA_HINT_SAMPLE_RATE indicates that any bounds specified + should be interpreted as multiples of the sample rate. For + instance, a frequency range from 0Hz to the Nyquist frequency (half + the sample rate) could be requested by this hint in conjunction + with LowerBound = 0 and UpperBound = 0.5. Hosts that support bounds + at all must support this hint to retain meaning. */ +#define LADSPA_HINT_SAMPLE_RATE 0x8 + +/* Hint LADSPA_HINT_LOGARITHMIC indicates that it is likely that the + user will find it more intuitive to view values using a logarithmic + scale. This is particularly useful for frequencies and gains. */ +#define LADSPA_HINT_LOGARITHMIC 0x10 + +/* Hint LADSPA_HINT_INTEGER indicates that a user interface would + probably wish to provide a stepped control taking only integer + values. Any bounds set should be slightly wider than the actual + integer range required to avoid floating point rounding errors. For + instance, the integer set {0,1,2,3} might be described as [-0.1, + 3.1]. */ +#define LADSPA_HINT_INTEGER 0x20 + +/* The various LADSPA_HINT_HAS_DEFAULT_* hints indicate a `normal' + value for the port that is sensible as a default. For instance, + this value is suitable for use as an initial value in a user + interface or as a value the host might assign to a control port + when the user has not provided one. Defaults are encoded using a + mask so only one default may be specified for a port. Some of the + hints make use of lower and upper bounds, in which case the + relevant bound or bounds must be available and + LADSPA_HINT_SAMPLE_RATE must be applied as usual. The resulting + default must be rounded if LADSPA_HINT_INTEGER is present. Default + values were introduced in LADSPA v1.1. */ +#define LADSPA_HINT_DEFAULT_MASK 0x3C0 + +/* This default values indicates that no default is provided. */ +#define LADSPA_HINT_DEFAULT_NONE 0x0 + +/* This default hint indicates that the suggested lower bound for the + port should be used. */ +#define LADSPA_HINT_DEFAULT_MINIMUM 0x40 + +/* This default hint indicates that a low value between the suggested + lower and upper bounds should be chosen. For ports with + LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.75 + + log(upper) * 0.25). Otherwise, this should be (lower * 0.75 + upper + * 0.25). */ +#define LADSPA_HINT_DEFAULT_LOW 0x80 + +/* This default hint indicates that a middle value between the + suggested lower and upper bounds should be chosen. For ports with + LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.5 + + log(upper) * 0.5). Otherwise, this should be (lower * 0.5 + upper * + 0.5). */ +#define LADSPA_HINT_DEFAULT_MIDDLE 0xC0 + +/* This default hint indicates that a high value between the suggested + lower and upper bounds should be chosen. For ports with + LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.25 + + log(upper) * 0.75). Otherwise, this should be (lower * 0.25 + upper + * 0.75). */ +#define LADSPA_HINT_DEFAULT_HIGH 0x100 + +/* This default hint indicates that the suggested upper bound for the + port should be used. */ +#define LADSPA_HINT_DEFAULT_MAXIMUM 0x140 + +/* This default hint indicates that the number 0 should be used. Note + that this default may be used in conjunction with + LADSPA_HINT_TOGGLED. */ +#define LADSPA_HINT_DEFAULT_0 0x200 + +/* This default hint indicates that the number 1 should be used. Note + that this default may be used in conjunction with + LADSPA_HINT_TOGGLED. */ +#define LADSPA_HINT_DEFAULT_1 0x240 + +/* This default hint indicates that the number 100 should be used. */ +#define LADSPA_HINT_DEFAULT_100 0x280 + +/* This default hint indicates that the Hz frequency of `concert A' + should be used. This will be 440 unless the host uses an unusual + tuning convention, in which case it may be within a few Hz. */ +#define LADSPA_HINT_DEFAULT_440 0x2C0 + +#define LADSPA_IS_HINT_BOUNDED_BELOW(x) ((x) & LADSPA_HINT_BOUNDED_BELOW) +#define LADSPA_IS_HINT_BOUNDED_ABOVE(x) ((x) & LADSPA_HINT_BOUNDED_ABOVE) +#define LADSPA_IS_HINT_TOGGLED(x) ((x) & LADSPA_HINT_TOGGLED) +#define LADSPA_IS_HINT_SAMPLE_RATE(x) ((x) & LADSPA_HINT_SAMPLE_RATE) +#define LADSPA_IS_HINT_LOGARITHMIC(x) ((x) & LADSPA_HINT_LOGARITHMIC) +#define LADSPA_IS_HINT_INTEGER(x) ((x) & LADSPA_HINT_INTEGER) + +#define LADSPA_IS_HINT_HAS_DEFAULT(x) ((x) & LADSPA_HINT_DEFAULT_MASK) +#define LADSPA_IS_HINT_DEFAULT_MINIMUM(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ + == LADSPA_HINT_DEFAULT_MINIMUM) +#define LADSPA_IS_HINT_DEFAULT_LOW(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ + == LADSPA_HINT_DEFAULT_LOW) +#define LADSPA_IS_HINT_DEFAULT_MIDDLE(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ + == LADSPA_HINT_DEFAULT_MIDDLE) +#define LADSPA_IS_HINT_DEFAULT_HIGH(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ + == LADSPA_HINT_DEFAULT_HIGH) +#define LADSPA_IS_HINT_DEFAULT_MAXIMUM(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ + == LADSPA_HINT_DEFAULT_MAXIMUM) +#define LADSPA_IS_HINT_DEFAULT_0(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ + == LADSPA_HINT_DEFAULT_0) +#define LADSPA_IS_HINT_DEFAULT_1(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ + == LADSPA_HINT_DEFAULT_1) +#define LADSPA_IS_HINT_DEFAULT_100(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ + == LADSPA_HINT_DEFAULT_100) +#define LADSPA_IS_HINT_DEFAULT_440(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ + == LADSPA_HINT_DEFAULT_440) + +typedef struct _LADSPA_PortRangeHint { + + /* Hints about the port. */ + LADSPA_PortRangeHintDescriptor HintDescriptor; + + /* Meaningful when hint LADSPA_HINT_BOUNDED_BELOW is active. When + LADSPA_HINT_SAMPLE_RATE is also active then this value should be + multiplied by the relevant sample rate. */ + LADSPA_Data LowerBound; + + /* Meaningful when hint LADSPA_HINT_BOUNDED_ABOVE is active. When + LADSPA_HINT_SAMPLE_RATE is also active then this value should be + multiplied by the relevant sample rate. */ + LADSPA_Data UpperBound; + +} LADSPA_PortRangeHint; + +/*****************************************************************************/ + +/* Plugin Handles: + + This plugin handle indicates a particular instance of the plugin + concerned. It is valid to compare this to NULL (0 for C++) but + otherwise the host should not attempt to interpret it. The plugin + may use it to reference internal instance data. */ + +typedef void * LADSPA_Handle; + +/*****************************************************************************/ + +/* Descriptor for a Type of Plugin: + + This structure is used to describe a plugin type. It provides a + number of functions to examine the type, instantiate it, link it to + buffers and workspaces and to run it. */ + +typedef struct _LADSPA_Descriptor { + + /* This numeric identifier indicates the plugin type + uniquely. Plugin programmers may reserve ranges of IDs from a + central body to avoid clashes. Hosts may assume that IDs are + below 0x1000000. */ + unsigned long UniqueID; + + /* This identifier can be used as a unique, case-sensitive + identifier for the plugin type within the plugin file. Plugin + types should be identified by file and label rather than by index + or plugin name, which may be changed in new plugin + versions. Labels must not contain white-space characters. */ + const char * Label; + + /* This indicates a number of properties of the plugin. */ + LADSPA_Properties Properties; + + /* This member points to the null-terminated name of the plugin + (e.g. "Sine Oscillator"). */ + const char * Name; + + /* This member points to the null-terminated string indicating the + maker of the plugin. This can be an empty string but not NULL. */ + const char * Maker; + + /* This member points to the null-terminated string indicating any + copyright applying to the plugin. If no Copyright applies the + string "None" should be used. */ + const char * Copyright; + + /* This indicates the number of ports (input AND output) present on + the plugin. */ + unsigned long PortCount; + + /* This member indicates an array of port descriptors. Valid indices + vary from 0 to PortCount-1. */ + const LADSPA_PortDescriptor * PortDescriptors; + + /* This member indicates an array of null-terminated strings + describing ports (e.g. "Frequency (Hz)"). Valid indices vary from + 0 to PortCount-1. */ + const char * const * PortNames; + + /* This member indicates an array of range hints for each port (see + above). Valid indices vary from 0 to PortCount-1. */ + const LADSPA_PortRangeHint * PortRangeHints; + + /* This may be used by the plugin developer to pass any custom + implementation data into an instantiate call. It must not be used + or interpreted by the host. It is expected that most plugin + writers will not use this facility as LADSPA_Handle should be + used to hold instance data. */ + void * ImplementationData; + + /* This member is a function pointer that instantiates a plugin. A + handle is returned indicating the new plugin instance. The + instantiation function accepts a sample rate as a parameter. The + plugin descriptor from which this instantiate function was found + must also be passed. This function must return NULL if + instantiation fails. + + Note that instance initialisation should generally occur in + activate() rather than here. */ + LADSPA_Handle (*instantiate)(const struct _LADSPA_Descriptor * Descriptor, + unsigned long SampleRate); + + /* This member is a function pointer that connects a port on an + instantiated plugin to a memory location at which a block of data + for the port will be read/written. The data location is expected + to be an array of LADSPA_Data for audio ports or a single + LADSPA_Data value for control ports. Memory issues will be + managed by the host. The plugin must read/write the data at these + locations every time run() or run_adding() is called and the data + present at the time of this connection call should not be + considered meaningful. + + connect_port() may be called more than once for a plugin instance + to allow the host to change the buffers that the plugin is + reading or writing. These calls may be made before or after + activate() or deactivate() calls. + + connect_port() must be called at least once for each port before + run() or run_adding() is called. When working with blocks of + LADSPA_Data the plugin should pay careful attention to the block + size passed to the run function as the block allocated may only + just be large enough to contain the block of samples. + + Plugin writers should be aware that the host may elect to use the + same buffer for more than one port and even use the same buffer + for both input and output (see LADSPA_PROPERTY_INPLACE_BROKEN). + However, overlapped buffers or use of a single buffer for both + audio and control data may result in unexpected behaviour. */ + void (*connect_port)(LADSPA_Handle Instance, + unsigned long Port, + LADSPA_Data * DataLocation); + + /* This member is a function pointer that initialises a plugin + instance and activates it for use. This is separated from + instantiate() to aid real-time support and so that hosts can + reinitialise a plugin instance by calling deactivate() and then + activate(). In this case the plugin instance must reset all state + information dependent on the history of the plugin instance + except for any data locations provided by connect_port() and any + gain set by set_run_adding_gain(). If there is nothing for + activate() to do then the plugin writer may provide a NULL rather + than an empty function. + + When present, hosts must call this function once before run() (or + run_adding()) is called for the first time. This call should be + made as close to the run() call as possible and indicates to + real-time plugins that they are now live. Plugins should not rely + on a prompt call to run() after activate(). activate() may not be + called again unless deactivate() is called first. Note that + connect_port() may be called before or after a call to + activate(). */ + void (*activate)(LADSPA_Handle Instance); + + /* This method is a function pointer that runs an instance of a + plugin for a block. Two parameters are required: the first is a + handle to the particular instance to be run and the second + indicates the block size (in samples) for which the plugin + instance may run. + + Note that if an activate() function exists then it must be called + before run() or run_adding(). If deactivate() is called for a + plugin instance then the plugin instance may not be reused until + activate() has been called again. + + If the plugin has the property LADSPA_PROPERTY_HARD_RT_CAPABLE + then there are various things that the plugin should not do + within the run() or run_adding() functions (see above). */ + void (*run)(LADSPA_Handle Instance, + unsigned long SampleCount); + + /* This method is a function pointer that runs an instance of a + plugin for a block. This has identical behaviour to run() except + in the way data is output from the plugin. When run() is used, + values are written directly to the memory areas associated with + the output ports. However when run_adding() is called, values + must be added to the values already present in the memory + areas. Furthermore, output values written must be scaled by the + current gain set by set_run_adding_gain() (see below) before + addition. + + run_adding() is optional. When it is not provided by a plugin, + this function pointer must be set to NULL. When it is provided, + the function set_run_adding_gain() must be provided also. */ + void (*run_adding)(LADSPA_Handle Instance, + unsigned long SampleCount); + + /* This method is a function pointer that sets the output gain for + use when run_adding() is called (see above). If this function is + never called the gain is assumed to default to 1. Gain + information should be retained when activate() or deactivate() + are called. + + This function should be provided by the plugin if and only if the + run_adding() function is provided. When it is absent this + function pointer must be set to NULL. */ + void (*set_run_adding_gain)(LADSPA_Handle Instance, + LADSPA_Data Gain); + + /* This is the counterpart to activate() (see above). If there is + nothing for deactivate() to do then the plugin writer may provide + a NULL rather than an empty function. + + Hosts must deactivate all activated units after they have been + run() (or run_adding()) for the last time. This call should be + made as close to the last run() call as possible and indicates to + real-time plugins that they are no longer live. Plugins should + not rely on prompt deactivation. Note that connect_port() may be + called before or after a call to deactivate(). + + Deactivation is not similar to pausing as the plugin instance + will be reinitialised when activate() is called to reuse it. */ + void (*deactivate)(LADSPA_Handle Instance); + + /* Once an instance of a plugin has been finished with it can be + deleted using the following function. The instance handle passed + ceases to be valid after this call. + + If activate() was called for a plugin instance then a + corresponding call to deactivate() must be made before cleanup() + is called. */ + void (*cleanup)(LADSPA_Handle Instance); + +} LADSPA_Descriptor; + +/**********************************************************************/ + +/* Accessing a Plugin: */ + +/* The exact mechanism by which plugins are loaded is host-dependent, + however all most hosts will need to know is the name of shared + object file containing the plugin types. To allow multiple hosts to + share plugin types, hosts may wish to check for environment + variable LADSPA_PATH. If present, this should contain a + colon-separated path indicating directories that should be searched + (in order) when loading plugin types. + + A plugin programmer must include a function called + "ladspa_descriptor" with the following function prototype within + the shared object file. This function will have C-style linkage (if + you are using C++ this is taken care of by the `extern "C"' clause + at the top of the file). + + A host will find the plugin shared object file by one means or + another, find the ladspa_descriptor() function, call it, and + proceed from there. + + Plugin types are accessed by index (not ID) using values from 0 + upwards. Out of range indexes must result in this function + returning NULL, so the plugin count can be determined by checking + for the least index that results in NULL being returned. */ + +const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index); + +/* Datatype corresponding to the ladspa_descriptor() function. */ +typedef const LADSPA_Descriptor * +(*LADSPA_Descriptor_Function)(unsigned long Index); + +/**********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* LADSPA_INCLUDED */ + +/* EOF */ diff --git a/src/modules/module-ladspa-sink.c b/src/modules/module-ladspa-sink.c new file mode 100644 index 00000000..0ff0ba37 --- /dev/null +++ b/src/modules/module-ladspa-sink.c @@ -0,0 +1,565 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "module-ladspa-sink-symdef.h" +#include "ladspa.h" + +PA_MODULE_AUTHOR("Lennart Poettering") +PA_MODULE_DESCRIPTION("Virtual LADSPA sink") +PA_MODULE_VERSION(PACKAGE_VERSION) +PA_MODULE_USAGE( + "sink_name= " + "master= " + "format= " + "channels= " + "rate= " + "channel_map= " + "plugin= " + "label= " + "control=") + +#define DEFAULT_SINK_NAME "ladspa" + +struct userdata { + pa_core *core; + pa_module *module; + + pa_sink *sink, *master; + pa_sink_input *sink_input; + + const LADSPA_Descriptor *descriptor; + unsigned channels; + LADSPA_Handle handle[PA_CHANNELS_MAX]; + LADSPA_Data *input, *output; + size_t block_size; + unsigned long input_port, output_port; + LADSPA_Data *control; + + pa_memchunk memchunk; +}; + +static const char* const valid_modargs[] = { + "sink_name", + "master", + "format", + "channels", + "rate", + "channel_map", + "plugin", + "label", + "control", + NULL +}; + +/* Called from I/O thread context */ +static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { + struct userdata *u = PA_SINK(o)->userdata; + + switch (code) { + + case PA_SINK_MESSAGE_GET_LATENCY: { + pa_usec_t usec = 0; + + if (PA_MSGOBJECT(u->master)->process_msg(PA_MSGOBJECT(u->master), PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0) + usec = 0; + + *((pa_usec_t*) data) = usec + pa_bytes_to_usec(u->memchunk.length, &u->sink->sample_spec); + return 0; + } + } + + return pa_sink_process_msg(o, code, data, offset, chunk); +} + +/* Called from main context */ +static int sink_set_state(pa_sink *s, pa_sink_state_t state) { + struct userdata *u; + + pa_sink_assert_ref(s); + pa_assert_se(u = s->userdata); + + if (PA_SINK_LINKED(state) && u->sink_input) + pa_sink_input_cork(u->sink_input, state == PA_SINK_SUSPENDED); + + return 0; +} + +/* Called from I/O thread context */ +static int sink_input_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { + struct userdata *u = PA_SINK_INPUT(o)->userdata; + + switch (code) { + case PA_SINK_INPUT_MESSAGE_GET_LATENCY: + *((pa_usec_t*) data) = pa_bytes_to_usec(u->memchunk.length, &u->sink_input->sample_spec); + + /* Fall through, the default handler will add in the extra + * latency added by the resampler */ + break; + } + + return pa_sink_input_process_msg(o, code, data, offset, chunk); +} + +/* Called from I/O thread context */ +static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) { + struct userdata *u; + + pa_sink_input_assert_ref(i); + pa_assert_se(u = i->userdata); + + if (!u->memchunk.memblock) { + pa_memchunk tchunk; + float *src, *dst; + size_t fs; + unsigned n, c; + + pa_sink_render(u->sink, length, &tchunk); + + fs = pa_frame_size(&i->sample_spec); + n = tchunk.length / fs; + + pa_assert(n > 0); + + u->memchunk.memblock = pa_memblock_new(i->sink->core->mempool, tchunk.length); + u->memchunk.index = 0; + u->memchunk.length = tchunk.length; + + src = (float*) ((uint8_t*) pa_memblock_acquire(tchunk.memblock) + tchunk.index); + dst = (float*) pa_memblock_acquire(u->memchunk.memblock); + + for (c = 0; c < u->channels; c++) { + unsigned j; + float *p, *q; + + p = src + c; + q = u->input; + for (j = 0; j < n; j++, p += u->channels, q++) + *q = *p; + + u->descriptor->run(u->handle[c], n); + + q = u->output; + p = dst + c; + for (j = 0; j < n; j++, q++, p += u->channels) + *p = *q; + } + + pa_memblock_release(tchunk.memblock); + pa_memblock_release(u->memchunk.memblock); + + pa_memblock_unref(tchunk.memblock); + } + + pa_assert(u->memchunk.memblock); + *chunk = u->memchunk; + pa_memblock_ref(chunk->memblock); + return 0; +} + +/* Called from I/O thread context */ +static void sink_input_drop_cb(pa_sink_input *i, size_t length) { + struct userdata *u; + + pa_sink_input_assert_ref(i); + pa_assert_se(u = i->userdata); + pa_assert(length > 0); + + if (u->memchunk.memblock) { + + if (length < u->memchunk.length) { + u->memchunk.index += length; + u->memchunk.length -= length; + return; + } + + pa_memblock_unref(u->memchunk.memblock); + length -= u->memchunk.length; + pa_memchunk_reset(&u->memchunk); + } + + if (length > 0) + pa_sink_skip(u->sink, length); +} + +/* Called from I/O thread context */ +static void sink_input_detach_cb(pa_sink_input *i) { + struct userdata *u; + + pa_sink_input_assert_ref(i); + pa_assert_se(u = i->userdata); + + pa_sink_detach_within_thread(u->sink); +} + +/* Called from I/O thread context */ +static void sink_input_attach_cb(pa_sink_input *i) { + struct userdata *u; + + pa_sink_input_assert_ref(i); + pa_assert_se(u = i->userdata); + + pa_sink_set_asyncmsgq(u->sink, i->sink->asyncmsgq); + pa_sink_set_rtpoll(u->sink, i->sink->rtpoll); + + pa_sink_attach_within_thread(u->sink); +} + +/* Called from main context */ +static void sink_input_kill_cb(pa_sink_input *i) { + struct userdata *u; + + pa_sink_input_assert_ref(i); + pa_assert_se(u = i->userdata); + + pa_sink_input_unlink(u->sink_input); + pa_sink_input_unref(u->sink_input); + u->sink_input = NULL; + + pa_sink_unlink(u->sink); + pa_sink_unref(u->sink); + u->sink = NULL; + + pa_module_unload_request(u->module); +} + +int pa__init(pa_module*m) { + struct userdata *u; + pa_sample_spec ss; + pa_channel_map map; + pa_modargs *ma; + char *t; + pa_sink *master; + pa_sink_input_new_data data; + const char *plugin, *label; + LADSPA_Descriptor_Function descriptor_func; + const char *e, *cdata; + const LADSPA_Descriptor *d; + unsigned long input_port, output_port, p, j, n_control; + unsigned c; + + pa_assert(m); + + pa_assert(sizeof(LADSPA_Data) == sizeof(float)); + + if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { + pa_log("Failed to parse module arguments."); + goto fail; + } + + if (!(master = pa_namereg_get(m->core, pa_modargs_get_value(ma, "master", NULL), PA_NAMEREG_SINK, 1))) { + pa_log("Master sink not found"); + goto fail; + } + + ss = master->sample_spec; + ss.format = PA_SAMPLE_FLOAT32; + map = master->channel_map; + if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) { + pa_log("Invalid sample format specification or channel map"); + goto fail; + } + + if (!(plugin = pa_modargs_get_value(ma, "plugin", NULL))) { + pa_log("Missing LADSPA plugin name"); + goto fail; + } + + if (!(label = pa_modargs_get_value(ma, "label", NULL))) { + pa_log("Missing LADSPA plugin label"); + goto fail; + } + + cdata = pa_modargs_get_value(ma, "control", NULL); + + u = pa_xnew0(struct userdata, 1); + u->core = m->core; + u->module = m; + m->userdata = u; + u->master = master; + pa_memchunk_reset(&u->memchunk); + + if (!(e = getenv("LADSPA_PATH"))) + e = LADSPA_PATH; + + /* FIXME: This is not exactly thread safe */ + t = pa_xstrdup(lt_dlgetsearchpath()); + lt_dlsetsearchpath(e); + m->dl = lt_dlopenext(plugin); + lt_dlsetsearchpath(t); + pa_xfree(t); + + if (!m->dl) { + pa_log("Failed to load LADSPA plugin: %s", lt_dlerror()); + goto fail; + } + + if (!(descriptor_func = (LADSPA_Descriptor_Function) lt_dlsym(m->dl, "ladspa_descriptor"))) { + pa_log("LADSPA module lacks ladspa_descriptor() symbol."); + goto fail; + } + + for (j = 0;; j++) { + + if (!(d = descriptor_func(j))) { + pa_log("Failed to find plugin label '%s' in plugin '%s'.", plugin, label); + goto fail; + } + + if (strcmp(d->Label, label) == 0) + break; + } + + u->descriptor = d; + + pa_log_debug("Module: %s", plugin); + pa_log_debug("Label: %s", d->Label); + pa_log_debug("Unique ID: %lu", d->UniqueID); + pa_log_debug("Name: %s", d->Name); + pa_log_debug("Maker: %s", d->Maker); + pa_log_debug("Copyright: %s", d->Copyright); + + input_port = output_port = (unsigned long) -1; + n_control = 0; + + for (p = 0; p < d->PortCount; p++) { + + if (LADSPA_IS_PORT_INPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p])) { + + if (strcmp(d->PortNames[p], "Input") == 0) { + pa_assert(input_port == (unsigned long) -1); + input_port = p; + } else { + pa_log("Found audio input port on plugin we cannot handle: %s", d->PortNames[p]); + goto fail; + } + + } else if (LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p])) { + + if (strcmp(d->PortNames[p], "Output") == 0) { + pa_assert(output_port == (unsigned long) -1); + output_port = p; + } else { + pa_log("Found audio output port on plugin we cannot handle: %s", d->PortNames[p]); + goto fail; + } + + } else if (LADSPA_IS_PORT_INPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p])) + n_control++; + else + pa_log("Cannot handle type of port %s", d->PortNames[p]); + } + + if ((input_port == (unsigned long) -1) || (output_port == (unsigned long) -1)) { + pa_log("Failed to identify input and output ports. " + "Right now this module can only deal with plugins which provide an 'Input' and an 'Output' audio port. " + "Patches welcome!"); + goto fail; + } + + u->block_size = pa_frame_align(pa_mempool_block_size_max(m->core->mempool), &ss); + + u->input = (LADSPA_Data*) pa_xnew(uint8_t, u->block_size); + if (LADSPA_IS_INPLACE_BROKEN(d->Properties)) + u->output = (LADSPA_Data*) pa_xnew(uint8_t, u->block_size); + else + u->output = u->input; + + u->channels = ss.channels; + + for (c = 0; c < ss.channels; c++) { + if (!(u->handle[c] = d->instantiate(d, ss.rate))) { + pa_log("Failed to instantiate plugin %s with label %s for channel %i", plugin, d->Label, c); + goto fail; + } + + d->connect_port(u->handle[c], input_port, u->input); + d->connect_port(u->handle[c], output_port, u->output); + } + + if (!cdata && n_control > 0) { + pa_log("This plugin requires specification of %lu control parameters.", n_control); + goto fail; + } + + if (n_control > 0) { + const char *state = NULL; + char *k; + unsigned long h; + + u->control = pa_xnew(LADSPA_Data, n_control); + p = 0; + + while ((k = pa_split(cdata, ",", &state))) { + float f; + + if (pa_atof(k, &f) < 0) { + pa_log("Failed to parse control value '%s'", k); + pa_xfree(k); + goto fail; + } + + pa_xfree(k); + + if (p >= n_control) { + pa_log("Too many control values passed, %lu expected.", n_control); + goto fail; + } + + u->control[p++] = f; + } + + if (p < n_control) { + pa_log("Not enough control values passed, %lu expected, %lu passed.", n_control, p); + goto fail; + } + + h = 0; + for (p = 0; p < d->PortCount; p++) { + + if (!LADSPA_IS_PORT_INPUT(d->PortDescriptors[p]) || !LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p])) + continue; + + pa_assert(h < n_control); + + for (c = 0; c < ss.channels; c++) + d->connect_port(u->handle[c], p, &u->control[h]); + + h++; + } + + pa_assert(h == n_control); + } + + if (d->activate) + for (c = 0; c < u->channels; c++) + d->activate(u->handle[c]); + + /* Create sink */ + if (!(u->sink = pa_sink_new(m->core, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map))) { + pa_log("Failed to create sink."); + goto fail; + } + + u->sink->parent.process_msg = sink_process_msg; + u->sink->set_state = sink_set_state; + u->sink->userdata = u; + u->sink->flags = PA_SINK_LATENCY|PA_SINK_CAN_SUSPEND; + + pa_sink_set_module(u->sink, m); + pa_sink_set_description(u->sink, t = pa_sprintf_malloc("LADSPA on '%s'", master->description)); + pa_xfree(t); + pa_sink_set_asyncmsgq(u->sink, master->asyncmsgq); + pa_sink_set_rtpoll(u->sink, master->rtpoll); + + /* Create sink input */ + pa_sink_input_new_data_init(&data); + data.sink = u->master; + data.driver = __FILE__; + data.name = "LADSPA Stream"; + pa_sink_input_new_data_set_sample_spec(&data, &ss); + pa_sink_input_new_data_set_channel_map(&data, &map); + data.module = m; + + if (!(u->sink_input = pa_sink_input_new(m->core, &data, PA_SINK_INPUT_DONT_MOVE))) + goto fail; + + u->sink_input->parent.process_msg = sink_input_process_msg; + u->sink_input->peek = sink_input_peek_cb; + u->sink_input->drop = sink_input_drop_cb; + u->sink_input->kill = sink_input_kill_cb; + u->sink_input->attach = sink_input_attach_cb; + u->sink_input->detach = sink_input_detach_cb; + u->sink_input->userdata = u; + + pa_sink_put(u->sink); + pa_sink_input_put(u->sink_input); + + pa_modargs_free(ma); + + return 0; + +fail: + if (ma) + pa_modargs_free(ma); + + pa__done(m); + + return -1; +} + +void pa__done(pa_module*m) { + struct userdata *u; + unsigned c; + + pa_assert(m); + + if (!(u = m->userdata)) + return; + + if (u->sink_input) { + pa_sink_input_unlink(u->sink_input); + pa_sink_input_unref(u->sink_input); + } + + if (u->sink) { + pa_sink_unlink(u->sink); + pa_sink_unref(u->sink); + } + + if (u->memchunk.memblock) + pa_memblock_unref(u->memchunk.memblock); + + for (c = 0; c < u->channels; c++) + if (u->handle[c]) { + if (u->descriptor->deactivate) + u->descriptor->deactivate(u->handle[c]); + u->descriptor->cleanup(u->handle[c]); + } + + if (u->output != u->input) + pa_xfree(u->output); + + pa_xfree(u->input); + + pa_xfree(u->control); + + pa_xfree(u); +} -- cgit From df1d34753fd906eb5fce53d5639c45e6d3ee0a89 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 18 Sep 2007 08:57:54 +0000 Subject: NSIG is not defined by neither C99 nor POSIX so we can't rely on it. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1849 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core-util.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index aac7629e..6a0bd0ac 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -627,9 +627,14 @@ PA_STATIC_TLS_DECLARE(signame, pa_xfree); const char *pa_sig2str(int sig) { char *t; - if (sig <= 0 || sig >= _NSIG) + if (sig <= 0) goto fail; - + +#ifdef NSIG + if (sig >= NSIG) + goto fail; +#endif + #ifdef HAVE_SIG2STR { char buf[SIG2STR_MAX]; -- cgit From 31dfb317fa0693ad41172befe2360f346d5b9093 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 18 Sep 2007 10:36:17 +0000 Subject: Make sure the header file is only included on linux (as this is a linux-only feature). git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1850 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/utils/pasuspender.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/utils/pasuspender.c b/src/utils/pasuspender.c index a546f9a4..ad86b943 100644 --- a/src/utils/pasuspender.c +++ b/src/utils/pasuspender.c @@ -25,7 +25,6 @@ #include #endif -#include #include #include @@ -41,6 +40,10 @@ #include +#ifdef __linux__ +#include +#endif + #include #include -- cgit From 03d98639808805d13dbe8915f30dd935d1a11991 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 18 Sep 2007 10:38:07 +0000 Subject: Emulate lrintf with simple truncation if it isn't available. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1851 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 3 +++ src/pulsecore/ffmpeg/resample2.c | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/configure.ac b/configure.ac index 5b6c6474..5250804b 100644 --- a/configure.ac +++ b/configure.ac @@ -266,6 +266,9 @@ AC_CHECK_FUNCS([getopt_long], [], [AC_CHECK_LIB([iberty], [getopt_long])]) #### Check for functions #### +# ISO +AC_CHECK_FUNCS([lrintf]) + # POSIX AC_FUNC_FORK AC_FUNC_GETGROUPS diff --git a/src/pulsecore/ffmpeg/resample2.c b/src/pulsecore/ffmpeg/resample2.c index da1443d9..dfbd5287 100644 --- a/src/pulsecore/ffmpeg/resample2.c +++ b/src/pulsecore/ffmpeg/resample2.c @@ -86,6 +86,13 @@ static double bessel(double x){ return v; } +/* + * crude lrintf for non-C99 systems. + */ +#ifndef HAVE_LFRINTF +#define lrintf(x) ((long int)(x)) +#endif + /** * builds a polyphase filterbank. * @param factor resampling factor -- cgit From aff22cfc6276ad33f793081cf4e8bb09cec95aa6 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 18 Sep 2007 10:45:54 +0000 Subject: NSIG seems to be more common than _NSIG. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1852 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/tests/sig2str-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/sig2str-test.c b/src/tests/sig2str-test.c index b3cc99d3..e8f36292 100644 --- a/src/tests/sig2str-test.c +++ b/src/tests/sig2str-test.c @@ -32,7 +32,7 @@ int main(int argc, char *argv[]) { int sig; - for (sig = -1; sig < _NSIG+1; sig++) + for (sig = -1; sig <= NSIG; sig++) printf("%i = %s\n", sig, pa_sig2str(sig)); return 0; -- cgit From 4ed41f3dab352757513cb8f5c49485de4bec6d6d Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 18 Sep 2007 10:47:03 +0000 Subject: strtof() is a rather recent addition to C. Fall back to strtod() if it isn't available. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1853 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 2 +- src/pulsecore/core-util.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 5250804b..d03774ed 100644 --- a/configure.ac +++ b/configure.ac @@ -267,7 +267,7 @@ AC_CHECK_FUNCS([getopt_long], [], [AC_CHECK_LIB([iberty], [getopt_long])]) #### Check for functions #### # ISO -AC_CHECK_FUNCS([lrintf]) +AC_CHECK_FUNCS([lrintf strtof]) # POSIX AC_FUNC_FORK diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 6a0bd0ac..afd89bad 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -1300,7 +1300,11 @@ int pa_atof(const char *s, float *ret_f) { #endif { errno = 0; +#ifdef HAVE_STRTOF f = strtof(s, &x); +#else + f = strtod(s, &x); +#endif } if (!x || *x || errno != 0) -- cgit From 08d4b237a32f060c173b5bdd9ed04d6541f61971 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Sep 2007 12:53:42 +0000 Subject: actually close the alsa device before we try to reopen it as plughw git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1854 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 84f1d4ef..108ed90c 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -759,6 +759,9 @@ int pa__init(pa_module*m) { pa_log_debug("Opening the device as '%s' didn't work, retrying with '%s'.", dev, d); pa_xfree(dev); dev = d; + + snd_pcm_close(u->pcm_handle); + u->pcm_handle = NULL; continue; } } -- cgit From a558e9312e440bc674fdda627edb31dd989c38a5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Sep 2007 17:41:51 +0000 Subject: port module-rtp-send.c to lock-free core git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1855 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 28 ++-- src/modules/rtp/module-rtp-recv.c | 311 +++++++++++++++++++++++--------------- src/modules/rtp/module-rtp-send.c | 118 ++++++++------- src/modules/rtp/rtp.c | 84 +++++----- src/modules/rtp/sap.c | 40 ++--- src/modules/rtp/sdp.c | 35 ++--- src/pulsecore/rtpoll.h | 1 - 7 files changed, 352 insertions(+), 265 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index c564ff38..3e4acd59 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -947,11 +947,11 @@ modlibexec_LTLIBRARIES += \ # module-esound-sink.la # See comment at librtp.la above -#if !OS_IS_WIN32 -#modlibexec_LTLIBRARIES += \ -# module-rtp-send.la \ -# module-rtp-recv.la -#endif +if !OS_IS_WIN32 +modlibexec_LTLIBRARIES += \ + module-rtp-send.la \ + module-rtp-recv.la +endif if HAVE_AF_UNIX modlibexec_LTLIBRARIES += \ @@ -1342,15 +1342,15 @@ module_suspend_on_idle_la_LIBADD = $(AM_LIBADD) libpulsecore.la module_suspend_on_idle_la_CFLAGS = $(AM_CFLAGS) # RTP modules -#module_rtp_send_la_SOURCES = modules/rtp/module-rtp-send.c -#module_rtp_send_la_LDFLAGS = -module -avoid-version -#module_rtp_send_la_LIBADD = $(AM_LIBADD) libpulsecore.la librtp.la -#module_rtp_send_la_CFLAGS = $(AM_CFLAGS) - -#module_rtp_recv_la_SOURCES = modules/rtp/module-rtp-recv.c -#module_rtp_recv_la_LDFLAGS = -module -avoid-version -#module_rtp_recv_la_LIBADD = $(AM_LIBADD) libpulsecore.la librtp.la -#module_rtp_recv_la_CFLAGS = $(AM_CFLAGS) +module_rtp_send_la_SOURCES = modules/rtp/module-rtp-send.c +module_rtp_send_la_LDFLAGS = -module -avoid-version +module_rtp_send_la_LIBADD = $(AM_LIBADD) libpulsecore.la librtp.la +module_rtp_send_la_CFLAGS = $(AM_CFLAGS) + +module_rtp_recv_la_SOURCES = modules/rtp/module-rtp-recv.c +module_rtp_recv_la_LDFLAGS = -module -avoid-version +module_rtp_recv_la_LIBADD = $(AM_LIBADD) libpulsecore.la librtp.la +module_rtp_recv_la_CFLAGS = $(AM_CFLAGS) # JACK diff --git a/src/modules/rtp/module-rtp-recv.c b/src/modules/rtp/module-rtp-recv.c index 62ef561f..f5e9c3c2 100644 --- a/src/modules/rtp/module-rtp-recv.c +++ b/src/modules/rtp/module-rtp-recv.c @@ -24,7 +24,6 @@ #include #endif -#include #include #include #include @@ -47,6 +46,10 @@ #include #include #include +#include +#include +#include +#include #include "module-rtp-recv-symdef.h" @@ -66,7 +69,7 @@ PA_MODULE_USAGE( #define DEFAULT_SAP_ADDRESS "224.0.0.56" #define MEMBLOCKQ_MAXLENGTH (1024*170) #define MAX_SESSIONS 16 -#define DEATH_TIMEOUT 20000000 +#define DEATH_TIMEOUT 20 static const char* const valid_modargs[] = { "sink", @@ -76,102 +79,113 @@ static const char* const valid_modargs[] = { struct session { struct userdata *userdata; + PA_LLIST_FIELDS(struct session); pa_sink_input *sink_input; pa_memblockq *memblockq; - pa_time_event *death_event; - - int first_packet; + pa_bool_t first_packet; uint32_t ssrc; uint32_t offset; struct pa_sdp_info sdp_info; pa_rtp_context rtp_context; - pa_io_event* rtp_event; + + pa_rtpoll_item *rtpoll_item; + + pa_atomic_t timestamp; }; struct userdata { pa_module *module; - pa_core *core; pa_sap_context sap_context; pa_io_event* sap_event; - pa_hashmap *by_origin; + pa_time_event *check_death_event; char *sink_name; + PA_LLIST_HEAD(struct session, sessions); + pa_hashmap *by_origin; int n_sessions; }; -static void session_free(struct session *s, int from_hash); +static void session_free(struct session *s); -static int sink_input_peek(pa_sink_input *i, pa_memchunk *chunk) { - struct session *s; - assert(i); - s = i->userdata; +/* Called from I/O thread context */ +static int sink_input_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { + struct session *s = PA_SINK_INPUT(o)->userdata; - return pa_memblockq_peek(s->memblockq, chunk); + switch (code) { + case PA_SINK_INPUT_MESSAGE_GET_LATENCY: + *((pa_usec_t*) data) = pa_bytes_to_usec(pa_memblockq_get_length(s->memblockq), &s->sink_input->sample_spec); + + /* Fall through, the default handler will add in the extra + * latency added by the resampler */ + break; + } + + return pa_sink_input_process_msg(o, code, data, offset, chunk); } -static void sink_input_drop(pa_sink_input *i, const pa_memchunk *chunk, size_t length) { +/* Called from I/O thread context */ +static int sink_input_peek(pa_sink_input *i, size_t length, pa_memchunk *chunk) { struct session *s; - assert(i); - s = i->userdata; + pa_sink_input_assert_ref(i); + pa_assert_se(s = i->userdata); - pa_memblockq_drop(s->memblockq, chunk, length); + return pa_memblockq_peek(s->memblockq, chunk); } -static void sink_input_kill(pa_sink_input* i) { +/* Called from I/O thread context */ +static void sink_input_drop(pa_sink_input *i, size_t length) { struct session *s; - assert(i); - s = i->userdata; + pa_sink_input_assert_ref(i); + pa_assert_se(s = i->userdata); - session_free(s, 1); + pa_memblockq_drop(s->memblockq, length); } -static pa_usec_t sink_input_get_latency(pa_sink_input *i) { +/* Called from main context */ +static void sink_input_kill(pa_sink_input* i) { struct session *s; - assert(i); - s = i->userdata; + pa_sink_input_assert_ref(i); + pa_assert_se(s = i->userdata); - return pa_bytes_to_usec(pa_memblockq_get_length(s->memblockq), &i->sample_spec); + session_free(s); } -static void rtp_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event_flags_t flags, void *userdata) { - struct session *s = userdata; +/* Called from I/O thread context */ +static int rtpoll_work_cb(pa_rtpoll_item *i) { pa_memchunk chunk; int64_t k, j, delta; - struct timeval tv; + struct timespec now; + struct session *s; - assert(m); - assert(e); - assert(s); - assert(fd == s->rtp_context.fd); - assert(flags == PA_IO_EVENT_INPUT); + pa_assert_se(s = pa_rtpoll_item_get_userdata(i)); - if (pa_rtp_recv(&s->rtp_context, &chunk, s->userdata->core->mempool) < 0) - return; + if (pa_rtp_recv(&s->rtp_context, &chunk, s->userdata->module->core->mempool) < 0) + return 0; if (s->sdp_info.payload != s->rtp_context.payload) { pa_memblock_unref(chunk.memblock); - return; + return 0; } if (!s->first_packet) { - s->first_packet = 1; + s->first_packet = TRUE; s->ssrc = s->rtp_context.ssrc; s->offset = s->rtp_context.timestamp; - if (s->ssrc == s->userdata->core->cookie) - pa_log_warn("WARNING! Detected RTP packet loop!"); + if (s->ssrc == s->userdata->module->core->cookie) + pa_log_warn("Detected RTP packet loop!"); } else { if (s->ssrc != s->rtp_context.ssrc) { pa_memblock_unref(chunk.memblock); - return; + return 0; } } @@ -197,26 +211,49 @@ static void rtp_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event pa_memblock_unref(chunk.memblock); - /* Reset death timer */ - pa_gettimeofday(&tv); - pa_timeval_add(&tv, DEATH_TIMEOUT); - m->time_restart(s->death_event, &tv); + pa_rtclock_get(&now); + pa_atomic_store(&s->timestamp, now.tv_sec); + + return 1; } -static void death_event_cb(pa_mainloop_api *m, pa_time_event *t, const struct timeval *tv, void *userdata) { - struct session *s = userdata; +/* Called from I/O thread context */ +static void sink_input_attach(pa_sink_input *i) { + struct session *s; + struct pollfd *p; + + pa_sink_input_assert_ref(i); + pa_assert_se(s = i->userdata); + + pa_assert(!s->rtpoll_item); + s->rtpoll_item = pa_rtpoll_item_new(i->sink->rtpoll, PA_RTPOLL_LATE, 1); - assert(m); - assert(t); - assert(tv); - assert(s); + p = pa_rtpoll_item_get_pollfd(s->rtpoll_item, NULL); + p->fd = s->rtp_context.fd; + p->events = POLLIN; + p->revents = 0; + + pa_rtpoll_item_set_work_callback(s->rtpoll_item, rtpoll_work_cb); + pa_rtpoll_item_set_userdata(s->rtpoll_item, s); +} + +/* Called from I/O thread context */ +static void sink_input_detach(pa_sink_input *i) { + struct session *s; + pa_sink_input_assert_ref(i); + pa_assert_se(s = i->userdata); - session_free(s, 1); + pa_assert(s->rtpoll_item); + pa_rtpoll_item_free(s->rtpoll_item); + s->rtpoll_item = NULL; } static int mcast_socket(const struct sockaddr* sa, socklen_t salen) { int af, fd = -1, r, one; + pa_assert(sa); + pa_assert(salen > 0); + af = sa->sa_family; if ((fd = socket(af, SOCK_DGRAM, 0)) < 0) { pa_log("Failed to create socket: %s", pa_cstrerror(errno)); @@ -262,27 +299,34 @@ fail: static struct session *session_new(struct userdata *u, const pa_sdp_info *sdp_info) { struct session *s = NULL; - struct timeval tv; char *c; pa_sink *sink; int fd = -1; pa_memblock *silence; pa_sink_input_new_data data; + struct timespec now; + + pa_assert(u); + pa_assert(sdp_info); if (u->n_sessions >= MAX_SESSIONS) { - pa_log("session limit reached."); + pa_log("Session limit reached."); goto fail; } - if (!(sink = pa_namereg_get(u->core, u->sink_name, PA_NAMEREG_SINK, 1))) { - pa_log("sink does not exist."); + if (!(sink = pa_namereg_get(u->module->core, u->sink_name, PA_NAMEREG_SINK, 1))) { + pa_log("Sink does not exist."); goto fail; } s = pa_xnew0(struct session, 1); s->userdata = u; - s->first_packet = 0; + s->first_packet = FALSE; s->sdp_info = *sdp_info; + s->rtpoll_item = NULL; + + pa_rtclock_get(&now); + pa_atomic_store(&s->timestamp, now.tv_sec); if ((fd = mcast_socket((const struct sockaddr*) &sdp_info->sa, sdp_info->salen)) < 0) goto fail; @@ -299,25 +343,27 @@ static struct session *session_new(struct userdata *u, const pa_sdp_info *sdp_in data.module = u->module; pa_sink_input_new_data_set_sample_spec(&data, &sdp_info->sample_spec); - s->sink_input = pa_sink_input_new(u->core, &data, 0); + s->sink_input = pa_sink_input_new(u->module->core, &data, 0); pa_xfree(c); if (!s->sink_input) { - pa_log("failed to create sink input."); + pa_log("Failed to create sink input."); goto fail; } s->sink_input->userdata = s; + s->sink_input->parent.process_msg = sink_input_process_msg; s->sink_input->peek = sink_input_peek; s->sink_input->drop = sink_input_drop; s->sink_input->kill = sink_input_kill; - s->sink_input->get_latency = sink_input_get_latency; + s->sink_input->attach = sink_input_attach; + s->sink_input->detach = sink_input_detach; - silence = pa_silence_memblock_new(s->userdata->core->mempool, - &s->sink_input->sample_spec, - (pa_bytes_per_second(&s->sink_input->sample_spec)/128/pa_frame_size(&s->sink_input->sample_spec))* - pa_frame_size(&s->sink_input->sample_spec)); + silence = pa_silence_memblock_new( + s->userdata->module->core->mempool, + &s->sink_input->sample_spec, + pa_frame_align(pa_bytes_per_second(&s->sink_input->sample_spec)/128, &s->sink_input->sample_spec)); s->memblockq = pa_memblockq_new( 0, @@ -330,53 +376,43 @@ static struct session *session_new(struct userdata *u, const pa_sdp_info *sdp_in pa_memblock_unref(silence); - s->rtp_event = u->core->mainloop->io_new(u->core->mainloop, fd, PA_IO_EVENT_INPUT, rtp_event_cb, s); - - pa_gettimeofday(&tv); - pa_timeval_add(&tv, DEATH_TIMEOUT); - s->death_event = u->core->mainloop->time_new(u->core->mainloop, &tv, death_event_cb, s); + pa_rtp_context_init_recv(&s->rtp_context, fd, pa_frame_size(&s->sdp_info.sample_spec)); pa_hashmap_put(s->userdata->by_origin, s->sdp_info.origin, s); + u->n_sessions++; + PA_LLIST_PREPEND(struct session, s->userdata->sessions, s); - pa_rtp_context_init_recv(&s->rtp_context, fd, pa_frame_size(&s->sdp_info.sample_spec)); - - pa_log_info("Found new session '%s'", s->sdp_info.session_name); + pa_sink_input_put(s->sink_input); - u->n_sessions++; + pa_log_info("New session '%s'", s->sdp_info.session_name); return s; fail: - if (s) { - if (fd >= 0) - close(fd); - - pa_xfree(s); - } + pa_xfree(s); + if (fd >= 0) + pa_close(fd); + return NULL; } -static void session_free(struct session *s, int from_hash) { - assert(s); +static void session_free(struct session *s) { + pa_assert(s); pa_log_info("Freeing session '%s'", s->sdp_info.session_name); - s->userdata->core->mainloop->time_free(s->death_event); - s->userdata->core->mainloop->io_free(s->rtp_event); - - if (from_hash) - pa_hashmap_remove(s->userdata->by_origin, s->sdp_info.origin); - - pa_sink_input_disconnect(s->sink_input); + pa_sink_input_unlink(s->sink_input); pa_sink_input_unref(s->sink_input); pa_memblockq_free(s->memblockq); pa_sdp_info_destroy(&s->sdp_info); pa_rtp_context_destroy(&s->rtp_context); - assert(s->userdata->n_sessions >= 1); + PA_LLIST_REMOVE(struct session, s->userdata->sessions, s); + pa_assert(s->userdata->n_sessions >= 1); s->userdata->n_sessions--; + pa_hashmap_remove(s->userdata->by_origin, s->sdp_info.origin); pa_xfree(s); } @@ -387,11 +423,11 @@ static void sap_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event pa_sdp_info info; struct session *s; - assert(m); - assert(e); - assert(u); - assert(fd == u->sap_context.fd); - assert(flags == PA_IO_EVENT_INPUT); + pa_assert(m); + pa_assert(e); + pa_assert(u); + pa_assert(fd == u->sap_context.fd); + pa_assert(flags == PA_IO_EVENT_INPUT); if (pa_sap_recv(&u->sap_context, &goodbye) < 0) return; @@ -402,7 +438,7 @@ static void sap_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event if (goodbye) { if ((s = pa_hashmap_get(u->by_origin, info.origin))) - session_free(s, 1); + session_free(s); pa_sdp_info_destroy(&info); } else { @@ -412,18 +448,47 @@ static void sap_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event pa_sdp_info_destroy(&info); } else { - struct timeval tv; - - pa_gettimeofday(&tv); - pa_timeval_add(&tv, DEATH_TIMEOUT); - m->time_restart(s->death_event, &tv); - + struct timespec now; + pa_rtclock_get(&now); + pa_atomic_store(&s->timestamp, now.tv_sec); + pa_sdp_info_destroy(&info); } } } -int pa__init(pa_core *c, pa_module*m) { +static void check_death_event_cb(pa_mainloop_api *m, pa_time_event *t, const struct timeval *ptv, void *userdata) { + struct session *s, *n; + struct userdata *u = userdata; + struct timespec now; + struct timeval tv; + + pa_assert(m); + pa_assert(t); + pa_assert(ptv); + pa_assert(s); + + pa_rtclock_get(&now); + + pa_log_debug("Checking for dead streams ..."); + + for (s = u->sessions; s; s = n) { + int k; + n = s->next; + + k = pa_atomic_load(&s->timestamp); + + if (k + DEATH_TIMEOUT < now.tv_sec) + session_free(s); + } + + /* Restart timer */ + pa_gettimeofday(&tv); + pa_timeval_add(&tv, DEATH_TIMEOUT*PA_USEC_PER_SEC); + m->time_restart(t, &tv); +} + +int pa__init(pa_module*m) { struct userdata *u; pa_modargs *ma = NULL; struct sockaddr_in sa4; @@ -432,9 +497,9 @@ int pa__init(pa_core *c, pa_module*m) { socklen_t salen; const char *sap_address; int fd = -1; - - assert(c); - assert(m); + struct timeval tv; + + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("failed to parse module arguments"); @@ -454,7 +519,7 @@ int pa__init(pa_core *c, pa_module*m) { sa = (struct sockaddr*) &sa4; salen = sizeof(sa4); } else { - pa_log("invalid SAP address '%s'", sap_address); + pa_log("Invalid SAP address '%s'", sap_address); goto fail; } @@ -464,16 +529,19 @@ int pa__init(pa_core *c, pa_module*m) { u = pa_xnew(struct userdata, 1); m->userdata = u; u->module = m; - u->core = c; u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL)); u->n_sessions = 0; - u->sap_event = c->mainloop->io_new(c->mainloop, fd, PA_IO_EVENT_INPUT, sap_event_cb, u); + u->sap_event = m->core->mainloop->io_new(m->core->mainloop, fd, PA_IO_EVENT_INPUT, sap_event_cb, u); u->by_origin = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); pa_sap_context_init_recv(&u->sap_context, fd); + pa_gettimeofday(&tv); + pa_timeval_add(&tv, DEATH_TIMEOUT * PA_USEC_PER_SEC); + u->check_death_event = m->core->mainloop->time_new(m->core->mainloop, &tv, check_death_event_cb, u); + pa_modargs_free(ma); return 0; @@ -483,27 +551,34 @@ fail: pa_modargs_free(ma); if (fd >= 0) - close(fd); + pa_close(fd); return -1; } -static void free_func(void *p, PA_GCC_UNUSED void *userdata) { - session_free(p, 0); -} - -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - assert(c); - assert(m); + struct session *s; + + pa_assert(m); if (!(u = m->userdata)) return; - c->mainloop->io_free(u->sap_event); + if (u->sap_event) + m->core->mainloop->io_free(u->sap_event); + + if (u->check_death_event) + m->core->mainloop->time_free(u->check_death_event); + pa_sap_context_destroy(&u->sap_context); - pa_hashmap_free(u->by_origin, free_func, NULL); + if (u->by_origin) { + while ((s = pa_hashmap_get_first(u->by_origin))) + session_free(s); + + pa_hashmap_free(u->by_origin, NULL, NULL); + } pa_xfree(u->sink_name); pa_xfree(u); diff --git a/src/modules/rtp/module-rtp-send.c b/src/modules/rtp/module-rtp-send.c index 8c9e5f23..7e9168e0 100644 --- a/src/modules/rtp/module-rtp-send.c +++ b/src/modules/rtp/module-rtp-send.c @@ -25,7 +25,6 @@ #include #endif -#include #include #include #include @@ -48,6 +47,8 @@ #include #include #include +#include +#include #include "module-rtp-send-symdef.h" @@ -74,7 +75,7 @@ PA_MODULE_USAGE( #define DEFAULT_DESTINATION "224.0.0.56" #define MEMBLOCKQ_MAXLENGTH (1024*170) #define DEFAULT_MTU 1280 -#define SAP_INTERVAL 5000000 +#define SAP_INTERVAL 5 static const char* const valid_modargs[] = { "source", @@ -90,7 +91,6 @@ static const char* const valid_modargs[] = { struct userdata { pa_module *module; - pa_core *core; pa_source_output *source_output; pa_memblockq *memblockq; @@ -102,56 +102,67 @@ struct userdata { pa_time_event *sap_event; }; +/* Called from I/O thread context */ +static int source_output_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { + struct userdata *u; + pa_assert_se(u = PA_SOURCE_OUTPUT(o)->userdata); + + switch (code) { + case PA_SOURCE_OUTPUT_MESSAGE_GET_LATENCY: + *((pa_usec_t*) data) = pa_bytes_to_usec(pa_memblockq_get_length(u->memblockq), &u->source_output->sample_spec); + + /* Fall through, the default handler will add in the extra + * latency added by the resampler */ + break; + } + + return pa_source_output_process_msg(o, code, data, offset, chunk); +} + +/* Called from I/O thread context */ static void source_output_push(pa_source_output *o, const pa_memchunk *chunk) { struct userdata *u; - assert(o); - u = o->userdata; + pa_source_output_assert_ref(o); + pa_assert_se(u = o->userdata); if (pa_memblockq_push(u->memblockq, chunk) < 0) { - pa_log("Failed to push chunk into memblockq."); + pa_log_warn("Failed to push chunk into memblockq."); return; } pa_rtp_send(&u->rtp_context, u->mtu, u->memblockq); } +/* Called from main context */ static void source_output_kill(pa_source_output* o) { struct userdata *u; - assert(o); - u = o->userdata; + pa_source_output_assert_ref(o); + pa_assert_se(u = o->userdata); pa_module_unload_request(u->module); - pa_source_output_disconnect(u->source_output); + pa_source_output_unlink(u->source_output); pa_source_output_unref(u->source_output); u->source_output = NULL; } -static pa_usec_t source_output_get_latency (pa_source_output *o) { - struct userdata *u; - assert(o); - u = o->userdata; - - return pa_bytes_to_usec(pa_memblockq_get_length(u->memblockq), &o->sample_spec); -} - static void sap_event_cb(pa_mainloop_api *m, pa_time_event *t, const struct timeval *tv, void *userdata) { struct userdata *u = userdata; struct timeval next; - assert(m); - assert(t); - assert(tv); - assert(u); + pa_assert(m); + pa_assert(t); + pa_assert(tv); + pa_assert(u); pa_sap_send(&u->sap_context, 0); pa_gettimeofday(&next); - pa_timeval_add(&next, SAP_INTERVAL); + pa_timeval_add(&next, SAP_INTERVAL * PA_USEC_PER_SEC); m->time_restart(t, &next); } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { struct userdata *u; pa_modargs *ma = NULL; const char *dest; @@ -173,21 +184,20 @@ int pa__init(pa_core *c, pa_module*m) { int loop = 0; pa_source_output_new_data data; - assert(c); - assert(m); + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { - pa_log("failed to parse module arguments"); + pa_log("Failed to parse module arguments"); goto fail; } if (!(s = pa_namereg_get(m->core, pa_modargs_get_value(ma, "source", NULL), PA_NAMEREG_SOURCE, 1))) { - pa_log("source does not exist."); + pa_log("Source does not exist."); goto fail; } if (pa_modargs_get_value_boolean(ma, "loop", &loop) < 0) { - pa_log("failed to parse \"loop\" parameter."); + pa_log("Failed to parse \"loop\" parameter."); goto fail; } @@ -195,12 +205,12 @@ int pa__init(pa_core *c, pa_module*m) { pa_rtp_sample_spec_fixup(&ss); cm = s->channel_map; if (pa_modargs_get_sample_spec(ma, &ss) < 0) { - pa_log("failed to parse sample specification"); + pa_log("Failed to parse sample specification"); goto fail; } if (!pa_rtp_sample_spec_valid(&ss)) { - pa_log("specified sample type not compatible with RTP"); + pa_log("Specified sample type not compatible with RTP"); goto fail; } @@ -209,10 +219,10 @@ int pa__init(pa_core *c, pa_module*m) { payload = pa_rtp_payload_from_sample_spec(&ss); - mtu = (DEFAULT_MTU/pa_frame_size(&ss))*pa_frame_size(&ss); + mtu = pa_frame_align(DEFAULT_MTU, &ss); if (pa_modargs_get_value_u32(ma, "mtu", &mtu) < 0 || mtu < 1 || mtu % pa_frame_size(&ss) != 0) { - pa_log("invalid mtu."); + pa_log("Invalid MTU."); goto fail; } @@ -223,7 +233,7 @@ int pa__init(pa_core *c, pa_module*m) { } if (port & 1) - pa_log_warn("WARNING: port number not even as suggested in RFC3550!"); + pa_log_warn("Port number not even as suggested in RFC3550!"); dest = pa_modargs_get_value(ma, "destination", DEFAULT_DESTINATION); @@ -238,7 +248,7 @@ int pa__init(pa_core *c, pa_module*m) { sap_sa4 = sa4; sap_sa4.sin_port = htons(SAP_PORT); } else { - pa_log("invalid destination '%s'", dest); + pa_log("Invalid destination '%s'", dest); goto fail; } @@ -268,6 +278,9 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } + /* If the socket queue is full, let's drop packets */ + pa_make_nonblock_fd(fd); + pa_source_output_new_data_init(&data); data.name = "RTP Monitor Stream"; data.driver = __FILE__; @@ -276,21 +289,20 @@ int pa__init(pa_core *c, pa_module*m) { pa_source_output_new_data_set_sample_spec(&data, &ss); pa_source_output_new_data_set_channel_map(&data, &cm); - if (!(o = pa_source_output_new(c, &data, 0))) { + if (!(o = pa_source_output_new(m->core, &data, 0))) { pa_log("failed to create source output."); goto fail; } + o->parent.process_msg = source_output_process_msg; o->push = source_output_push; o->kill = source_output_kill; - o->get_latency = source_output_get_latency; u = pa_xnew(struct userdata, 1); m->userdata = u; o->userdata = u; u->module = m; - u->core = c; u->source_output = o; u->memblockq = pa_memblockq_new( @@ -305,8 +317,7 @@ int pa__init(pa_core *c, pa_module*m) { u->mtu = mtu; k = sizeof(sa_dst); - r = getsockname(fd, (struct sockaddr*) &sa_dst, &k); - assert(r >= 0); + pa_assert_se((r = getsockname(fd, (struct sockaddr*) &sa_dst, &k)) >= 0); n = pa_sprintf_malloc("PulseAudio RTP Stream on %s", pa_get_fqdn(hn, sizeof(hn))); @@ -317,18 +328,20 @@ int pa__init(pa_core *c, pa_module*m) { pa_xfree(n); - pa_rtp_context_init_send(&u->rtp_context, fd, c->cookie, payload, pa_frame_size(&ss)); + pa_rtp_context_init_send(&u->rtp_context, fd, m->core->cookie, payload, pa_frame_size(&ss)); pa_sap_context_init_send(&u->sap_context, sap_fd, p); pa_log_info("RTP stream initialized with mtu %u on %s:%u, SSRC=0x%08x, payload=%u, initial sequence #%u", mtu, dest, port, u->rtp_context.ssrc, payload, u->rtp_context.sequence); - pa_log_info("SDP-Data:\n%s\n"__FILE__": EOF", p); + pa_log_info("SDP-Data:\n%s\nEOF", p); pa_sap_send(&u->sap_context, 0); pa_gettimeofday(&tv); - pa_timeval_add(&tv, SAP_INTERVAL); - u->sap_event = c->mainloop->time_new(c->mainloop, &tv, sap_event_cb, u); + pa_timeval_add(&tv, SAP_INTERVAL * PA_USEC_PER_SEC); + u->sap_event = m->core->mainloop->time_new(m->core->mainloop, &tv, sap_event_cb, u); + pa_source_output_put(u->source_output); + pa_modargs_free(ma); return 0; @@ -338,31 +351,31 @@ fail: pa_modargs_free(ma); if (fd >= 0) - close(fd); + pa_close(fd); if (sap_fd >= 0) - close(sap_fd); + pa_close(sap_fd); if (o) { - pa_source_output_disconnect(o); + pa_source_output_unlink(o); pa_source_output_unref(o); } return -1; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - assert(c); - assert(m); + pa_assert(m); if (!(u = m->userdata)) return; - c->mainloop->time_free(u->sap_event); + if (u->sap_event) + m->core->mainloop->time_free(u->sap_event); if (u->source_output) { - pa_source_output_disconnect(u->source_output); + pa_source_output_unlink(u->source_output); pa_source_output_unref(u->source_output); } @@ -371,7 +384,8 @@ void pa__done(pa_core *c, pa_module*m) { pa_sap_send(&u->sap_context, 1); pa_sap_context_destroy(&u->sap_context); - pa_memblockq_free(u->memblockq); + if (u->memblockq) + pa_memblockq_free(u->memblockq); pa_xfree(u); } diff --git a/src/modules/rtp/rtp.c b/src/modules/rtp/rtp.c index 31dec653..e2496c7d 100644 --- a/src/modules/rtp/rtp.c +++ b/src/modules/rtp/rtp.c @@ -25,7 +25,6 @@ #include #endif -#include #include #include #include @@ -40,12 +39,14 @@ #include #include +#include +#include #include "rtp.h" pa_rtp_context* pa_rtp_context_init_send(pa_rtp_context *c, int fd, uint32_t ssrc, uint8_t payload, size_t frame_size) { - assert(c); - assert(fd >= 0); + pa_assert(c); + pa_assert(fd >= 0); c->fd = fd; c->sequence = (uint16_t) (rand()*rand()); @@ -63,11 +64,11 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) { struct iovec iov[MAX_IOVECS]; pa_memblock* mb[MAX_IOVECS]; int iov_idx = 1; - size_t n = 0, skip = 0; + size_t n = 0; - assert(c); - assert(size > 0); - assert(q); + pa_assert(c); + pa_assert(size > 0); + pa_assert(q); if (pa_memblockq_get_length(q) < size) return 0; @@ -76,24 +77,26 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) { int r; pa_memchunk chunk; + pa_memchunk_reset(&chunk); + if ((r = pa_memblockq_peek(q, &chunk)) >= 0) { size_t k = n + chunk.length > size ? size - n : chunk.length; - if (chunk.memblock) { - iov[iov_idx].iov_base = (void*)((uint8_t*) pa_memblock_acquire(chunk.memblock) + chunk.index); - iov[iov_idx].iov_len = k; - mb[iov_idx] = chunk.memblock; - iov_idx ++; - - n += k; - } - - skip += k; + pa_assert(chunk.memblock); + + iov[iov_idx].iov_base = ((uint8_t*) pa_memblock_acquire(chunk.memblock) + chunk.index); + iov[iov_idx].iov_len = k; + mb[iov_idx] = chunk.memblock; + iov_idx ++; + + n += k; pa_memblockq_drop(q, k); } - if (r < 0 || !chunk.memblock || n >= size || iov_idx >= MAX_IOVECS) { + pa_assert(n % c->frame_size == 0); + + if (r < 0 || n >= size || iov_idx >= MAX_IOVECS) { uint32_t header[3]; struct msghdr m; int k, i; @@ -125,10 +128,10 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) { } else k = 0; - c->timestamp += skip/c->frame_size; + c->timestamp += n/c->frame_size; if (k < 0) { - if (errno != EAGAIN) /* If the queue is full, just ignore it */ + if (errno != EAGAIN && errno != EINTR) /* If the queue is full, just ignore it */ pa_log("sendmsg() failed: %s", pa_cstrerror(errno)); return -1; } @@ -137,7 +140,6 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) { break; n = 0; - skip = 0; iov_idx = 1; } } @@ -146,7 +148,7 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) { } pa_rtp_context* pa_rtp_context_init_recv(pa_rtp_context *c, int fd, size_t frame_size) { - assert(c); + pa_assert(c); c->fd = fd; c->frame_size = frame_size; @@ -161,13 +163,13 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) { int cc; ssize_t r; - assert(c); - assert(chunk); + pa_assert(c); + pa_assert(chunk); chunk->memblock = NULL; if (ioctl(c->fd, FIONREAD, &size) < 0) { - pa_log("FIONREAD failed: %s", pa_cstrerror(errno)); + pa_log_warn("FIONREAD failed: %s", pa_cstrerror(errno)); goto fail; } @@ -188,12 +190,14 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) { m.msg_flags = 0; if ((r = recvmsg(c->fd, &m, 0)) != size) { - pa_log("recvmsg() failed: %s", r < 0 ? pa_cstrerror(errno) : "size mismatch"); + if (r < 0 && errno != EAGAIN && errno != EINTR) + pa_log_warn("recvmsg() failed: %s", r < 0 ? pa_cstrerror(errno) : "size mismatch"); + goto fail; } if (size < 12) { - pa_log("RTP packet too short."); + pa_log_warn("RTP packet too short."); goto fail; } @@ -206,17 +210,17 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) { c->ssrc = ntohl(c->ssrc); if ((header >> 30) != 2) { - pa_log("Unsupported RTP version."); + pa_log_warn("Unsupported RTP version."); goto fail; } if ((header >> 29) & 1) { - pa_log("RTP padding not supported."); + pa_log_warn("RTP padding not supported."); goto fail; } if ((header >> 28) & 1) { - pa_log("RTP header extensions not supported."); + pa_log_warn("RTP header extensions not supported."); goto fail; } @@ -225,7 +229,7 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) { c->sequence = header & 0xFFFF; if (12 + cc*4 > size) { - pa_log("RTP packet too short. (CSRC)"); + pa_log_warn("RTP packet too short. (CSRC)"); goto fail; } @@ -233,7 +237,7 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) { chunk->length = size - chunk->index; if (chunk->length % c->frame_size != 0) { - pa_log("Vad RTP packet size."); + pa_log_warn("Bad RTP packet size."); goto fail; } @@ -249,7 +253,7 @@ fail: } uint8_t pa_rtp_payload_from_sample_spec(const pa_sample_spec *ss) { - assert(ss); + pa_assert(ss); if (ss->format == PA_SAMPLE_ULAW && ss->rate == 8000 && ss->channels == 1) return 0; @@ -264,7 +268,7 @@ uint8_t pa_rtp_payload_from_sample_spec(const pa_sample_spec *ss) { } pa_sample_spec *pa_rtp_sample_spec_from_payload(uint8_t payload, pa_sample_spec *ss) { - assert(ss); + pa_assert(ss); switch (payload) { case 0: @@ -299,17 +303,17 @@ pa_sample_spec *pa_rtp_sample_spec_from_payload(uint8_t payload, pa_sample_spec } pa_sample_spec *pa_rtp_sample_spec_fixup(pa_sample_spec * ss) { - assert(ss); + pa_assert(ss); if (!pa_rtp_sample_spec_valid(ss)) ss->format = PA_SAMPLE_S16BE; - assert(pa_rtp_sample_spec_valid(ss)); + pa_assert(pa_rtp_sample_spec_valid(ss)); return ss; } int pa_rtp_sample_spec_valid(const pa_sample_spec *ss) { - assert(ss); + pa_assert(ss); if (!pa_sample_spec_valid(ss)) return 0; @@ -322,9 +326,9 @@ int pa_rtp_sample_spec_valid(const pa_sample_spec *ss) { } void pa_rtp_context_destroy(pa_rtp_context *c) { - assert(c); + pa_assert(c); - close(c->fd); + pa_close(c->fd); } const char* pa_rtp_format_to_string(pa_sample_format_t f) { @@ -343,7 +347,7 @@ const char* pa_rtp_format_to_string(pa_sample_format_t f) { } pa_sample_format_t pa_rtp_string_to_format(const char *s) { - assert(s); + pa_assert(s); if (!(strcmp(s, "L16"))) return PA_SAMPLE_S16BE; diff --git a/src/modules/rtp/sap.c b/src/modules/rtp/sap.c index 82421807..ed7eb0be 100644 --- a/src/modules/rtp/sap.c +++ b/src/modules/rtp/sap.c @@ -25,7 +25,6 @@ #include #endif -#include #include #include #include @@ -46,6 +45,7 @@ #include #include #include +#include #include "sap.h" #include "sdp.h" @@ -53,9 +53,9 @@ #define MIME_TYPE "application/sdp" pa_sap_context* pa_sap_context_init_send(pa_sap_context *c, int fd, char *sdp_data) { - assert(c); - assert(fd >= 0); - assert(sdp_data); + pa_assert(c); + pa_assert(fd >= 0); + pa_assert(sdp_data); c->fd = fd; c->sdp_data = sdp_data; @@ -65,9 +65,9 @@ pa_sap_context* pa_sap_context_init_send(pa_sap_context *c, int fd, char *sdp_da } void pa_sap_context_destroy(pa_sap_context *c) { - assert(c); + pa_assert(c); - close(c->fd); + pa_close(c->fd); pa_xfree(c->sdp_data); } @@ -85,7 +85,7 @@ int pa_sap_send(pa_sap_context *c, int goodbye) { return -1; } - assert(sa->sa_family == AF_INET || sa->sa_family == AF_INET6); + pa_assert(sa->sa_family == AF_INET || sa->sa_family == AF_INET6); header = htonl(((uint32_t) 1 << 29) | (sa->sa_family == AF_INET6 ? (uint32_t) 1 << 28 : 0) | @@ -113,14 +113,14 @@ int pa_sap_send(pa_sap_context *c, int goodbye) { m.msg_flags = 0; if ((k = sendmsg(c->fd, &m, MSG_DONTWAIT)) < 0) - pa_log("sendmsg() failed: %s\n", pa_cstrerror(errno)); + pa_log_warn("sendmsg() failed: %s\n", pa_cstrerror(errno)); return k; } pa_sap_context* pa_sap_context_init_recv(pa_sap_context *c, int fd) { - assert(c); - assert(fd >= 0); + pa_assert(c); + pa_assert(fd >= 0); c->fd = fd; c->sdp_data = NULL; @@ -136,11 +136,11 @@ int pa_sap_recv(pa_sap_context *c, int *goodbye) { int six, ac; ssize_t r; - assert(c); - assert(goodbye); + pa_assert(c); + pa_assert(goodbye); if (ioctl(c->fd, FIONREAD, &size) < 0) { - pa_log("FIONREAD failed: %s", pa_cstrerror(errno)); + pa_log_warn("FIONREAD failed: %s", pa_cstrerror(errno)); goto fail; } @@ -159,12 +159,12 @@ int pa_sap_recv(pa_sap_context *c, int *goodbye) { m.msg_flags = 0; if ((r = recvmsg(c->fd, &m, 0)) != size) { - pa_log("recvmsg() failed: %s", r < 0 ? pa_cstrerror(errno) : "size mismatch"); + pa_log_warn("recvmsg() failed: %s", r < 0 ? pa_cstrerror(errno) : "size mismatch"); goto fail; } if (size < 4) { - pa_log("SAP packet too short."); + pa_log_warn("SAP packet too short."); goto fail; } @@ -172,17 +172,17 @@ int pa_sap_recv(pa_sap_context *c, int *goodbye) { header = ntohl(header); if (header >> 29 != 1) { - pa_log("Unsupported SAP version."); + pa_log_warn("Unsupported SAP version."); goto fail; } if ((header >> 25) & 1) { - pa_log("Encrypted SAP not supported."); + pa_log_warn("Encrypted SAP not supported."); goto fail; } if ((header >> 24) & 1) { - pa_log("Compressed SAP not supported."); + pa_log_warn("Compressed SAP not supported."); goto fail; } @@ -191,7 +191,7 @@ int pa_sap_recv(pa_sap_context *c, int *goodbye) { k = 4 + (six ? 16 : 4) + ac*4; if (size < k) { - pa_log("SAP packet too short (AD)."); + pa_log_warn("SAP packet too short (AD)."); goto fail; } @@ -202,7 +202,7 @@ int pa_sap_recv(pa_sap_context *c, int *goodbye) { e += sizeof(MIME_TYPE); size -= sizeof(MIME_TYPE); } else if ((unsigned) size < sizeof(PA_SDP_HEADER)-1 || strncmp(e, PA_SDP_HEADER, sizeof(PA_SDP_HEADER)-1)) { - pa_log("Invalid SDP header."); + pa_log_warn("Invalid SDP header."); goto fail; } diff --git a/src/modules/rtp/sdp.c b/src/modules/rtp/sdp.c index 8b0bd535..983e5c95 100644 --- a/src/modules/rtp/sdp.c +++ b/src/modules/rtp/sdp.c @@ -25,7 +25,6 @@ #include #endif -#include #include #include #include @@ -38,33 +37,29 @@ #include #include +#include #include "sdp.h" #include "rtp.h" - char *pa_sdp_build(int af, const void *src, const void *dst, const char *name, uint16_t port, uint8_t payload, const pa_sample_spec *ss) { uint32_t ntp; - char buf_src[64], buf_dst[64]; + char buf_src[64], buf_dst[64], un[64]; const char *u, *f, *a; - assert(src); - assert(dst); - assert(af == AF_INET || af == AF_INET6); + pa_assert(src); + pa_assert(dst); + pa_assert(af == AF_INET || af == AF_INET6); - f = pa_rtp_format_to_string(ss->format); - assert(f); + pa_assert_se(f = pa_rtp_format_to_string(ss->format)); - if (!(u = getenv("USER"))) - if (!(u = getenv("USERNAME"))) - u = "-"; + if (!(u = pa_get_user_name(un, sizeof(un)))) + u = "-"; ntp = time(NULL) + 2208988800U; - a = inet_ntop(af, src, buf_src, sizeof(buf_src)); - assert(a); - a = inet_ntop(af, dst, buf_dst, sizeof(buf_dst)); - assert(a); + pa_assert_se(a = inet_ntop(af, src, buf_src, sizeof(buf_src))); + pa_assert_se(a = inet_ntop(af, dst, buf_dst, sizeof(buf_dst))); return pa_sprintf_malloc( PA_SDP_HEADER @@ -86,8 +81,8 @@ char *pa_sdp_build(int af, const void *src, const void *dst, const char *name, u static pa_sample_spec *parse_sdp_sample_spec(pa_sample_spec *ss, char *c) { unsigned rate, channels; - assert(ss); - assert(c); + pa_assert(ss); + pa_assert(c); if (pa_startswith(c, "L16/")) { ss->format = PA_SAMPLE_S16BE; @@ -123,8 +118,8 @@ pa_sdp_info *pa_sdp_parse(const char *t, pa_sdp_info *i, int is_goodbye) { uint16_t port = 0; int ss_valid = 0; - assert(t); - assert(i); + pa_assert(t); + pa_assert(i); i->origin = i->session_name = NULL; i->salen = 0; @@ -258,7 +253,7 @@ fail: } void pa_sdp_info_destroy(pa_sdp_info *i) { - assert(i); + pa_assert(i); pa_xfree(i->origin); pa_xfree(i->session_name); diff --git a/src/pulsecore/rtpoll.h b/src/pulsecore/rtpoll.h index 9a368d36..ee6cc06c 100644 --- a/src/pulsecore/rtpoll.h +++ b/src/pulsecore/rtpoll.h @@ -103,7 +103,6 @@ void pa_rtpoll_item_set_before_callback(pa_rtpoll_item *i, int (*before_cb)(pa_r * entered the sleeping poll */ void pa_rtpoll_item_set_after_callback(pa_rtpoll_item *i, void (*after_cb)(pa_rtpoll_item *i)); - void pa_rtpoll_item_set_userdata(pa_rtpoll_item *i, void *userdata); void* pa_rtpoll_item_get_userdata(pa_rtpoll_item *i); -- cgit From ca717643ee768307475fc36ea29d920a13db0a8e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Sep 2007 19:51:26 +0000 Subject: If PTHREAD_PRIO_INHERIT mutexes are not available fall back to normal mutexes git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1856 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/mutex-posix.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/mutex-posix.c b/src/pulsecore/mutex-posix.c index 19e095bb..805f11de 100644 --- a/src/pulsecore/mutex-posix.c +++ b/src/pulsecore/mutex-posix.c @@ -26,9 +26,12 @@ #endif #include +#include #include #include +#include +#include #include "mutex.h" @@ -43,19 +46,36 @@ struct pa_cond { pa_mutex* pa_mutex_new(pa_bool_t recursive, pa_bool_t inherit_priority) { pa_mutex *m; pthread_mutexattr_t attr; + int r; - pthread_mutexattr_init(&attr); + pa_assert_se(pthread_mutexattr_init(&attr) == 0); if (recursive) pa_assert_se(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) == 0); #ifdef HAVE_PTHREAD_PRIO_INHERIT if (inherit_priority) - pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT); + pa_assert_se(pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT) == 0); #endif m = pa_xnew(pa_mutex, 1); + +#ifndef HAVE_PTHREAD_PRIO_INHERIT pa_assert_se(pthread_mutex_init(&m->mutex, &attr) == 0); + +#else + if ((r = pthread_mutex_init(&m->mutex, &attr))) { + + /* If this failed, then this was probably due to non-available + * priority inheritance. In which case we fall back to normal + * mutexes. */ + pa_assert(r == ENOTSUP && inherit_priority); + + pa_assert_se(pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_NONE) == 0); + pa_assert_se(pthread_mutex_init(&m->mutex, &attr) == 0); + } +#endif + return m; } -- cgit From 8fdf054e686b7bc488a510029a7b216c6aeaa50b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Sep 2007 19:52:20 +0000 Subject: make sure we don't call pa_source_post() for a monitor source after it was unlinked git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1857 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 98f117cf..886d7442 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -216,11 +216,11 @@ void pa_sink_unlink(pa_sink* s) { j = i; } + sink_set_state(s, PA_SINK_UNLINKED); + if (s->monitor_source) pa_source_unlink(s->monitor_source); - sink_set_state(s, PA_SINK_UNLINKED); - s->get_latency = NULL; s->get_volume = NULL; s->set_volume = NULL; -- cgit From eb23601bb7771bce74e6b87a222b174660e86a0d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Sep 2007 19:52:45 +0000 Subject: bug fixes for module-rtp-recv git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1858 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/rtp/module-rtp-recv.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/modules/rtp/module-rtp-recv.c b/src/modules/rtp/module-rtp-recv.c index f5e9c3c2..62be53ff 100644 --- a/src/modules/rtp/module-rtp-recv.c +++ b/src/modules/rtp/module-rtp-recv.c @@ -163,9 +163,22 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) { int64_t k, j, delta; struct timespec now; struct session *s; - + struct pollfd *p; + pa_assert_se(s = pa_rtpoll_item_get_userdata(i)); + p = pa_rtpoll_item_get_pollfd(i, NULL); + + if (p->revents & (POLLERR|POLLNVAL|POLLHUP|POLLOUT)) { + pa_log("poll() signalled bad revents."); + return -1; + } + + if ((p->revents & POLLIN) == 0) + return 0; + + p->revents = 0; + if (pa_rtp_recv(&s->rtp_context, &chunk, s->userdata->module->core->mempool) < 0) return 0; @@ -405,14 +418,14 @@ static void session_free(struct session *s) { pa_sink_input_unlink(s->sink_input); pa_sink_input_unref(s->sink_input); - pa_memblockq_free(s->memblockq); - pa_sdp_info_destroy(&s->sdp_info); - pa_rtp_context_destroy(&s->rtp_context); - PA_LLIST_REMOVE(struct session, s->userdata->sessions, s); pa_assert(s->userdata->n_sessions >= 1); s->userdata->n_sessions--; pa_hashmap_remove(s->userdata->by_origin, s->sdp_info.origin); + + pa_memblockq_free(s->memblockq); + pa_sdp_info_destroy(&s->sdp_info); + pa_rtp_context_destroy(&s->rtp_context); pa_xfree(s); } @@ -466,7 +479,7 @@ static void check_death_event_cb(pa_mainloop_api *m, pa_time_event *t, const str pa_assert(m); pa_assert(t); pa_assert(ptv); - pa_assert(s); + pa_assert(u); pa_rtclock_get(&now); @@ -530,14 +543,14 @@ int pa__init(pa_module*m) { m->userdata = u; u->module = m; u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL)); - u->n_sessions = 0; u->sap_event = m->core->mainloop->io_new(m->core->mainloop, fd, PA_IO_EVENT_INPUT, sap_event_cb, u); + pa_sap_context_init_recv(&u->sap_context, fd); + PA_LLIST_HEAD_INIT(struct session, u->sessions); + u->n_sessions = 0; u->by_origin = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - pa_sap_context_init_recv(&u->sap_context, fd); - pa_gettimeofday(&tv); pa_timeval_add(&tv, DEATH_TIMEOUT * PA_USEC_PER_SEC); u->check_death_event = m->core->mainloop->time_new(m->core->mainloop, &tv, check_death_event_cb, u); -- cgit From 6b2fd2328ab715fb5ce4544fc431e545747ca95f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Sep 2007 21:31:21 +0000 Subject: add two missing header file inclusions git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1859 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/rtp/sdp.c | 1 + src/pulsecore/rtpoll.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/modules/rtp/sdp.c b/src/modules/rtp/sdp.c index 983e5c95..50ac157a 100644 --- a/src/modules/rtp/sdp.c +++ b/src/modules/rtp/sdp.c @@ -34,6 +34,7 @@ #include #include +#include #include #include diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c index e7ccd908..e72bf3f4 100644 --- a/src/pulsecore/rtpoll.c +++ b/src/pulsecore/rtpoll.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "rtpoll.h" -- cgit From f44ddd1052af8026ce3bcb91b377d980a0913445 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Sep 2007 22:24:45 +0000 Subject: add new pa_socket_udp_low_delay() API git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1860 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/socket-util.c | 36 +++++++++++++++++++++++++++++++++++- src/pulsecore/socket-util.h | 1 + 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/socket-util.c b/src/pulsecore/socket-util.c index 4026b9b1..cd912bf0 100644 --- a/src/pulsecore/socket-util.c +++ b/src/pulsecore/socket-util.c @@ -144,13 +144,16 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) { } int pa_socket_low_delay(int fd) { + #ifdef SO_PRIORITY int priority; pa_assert(fd >= 0); priority = 7; - if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (void*)&priority, sizeof(priority)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (void*)&priority, sizeof(priority)) < 0) { + pa_log_warn("SO_PRIORITY failed: %s", pa_cstrerror(errno)); return -1; + } #endif return 0; @@ -172,9 +175,37 @@ int pa_socket_tcp_low_delay(int fd) { #else if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*)&on, sizeof(on)) < 0) #endif + { + pa_log_warn("TCP_NODELAY failed: %s", pa_cstrerror(errno)); + ret = -1; + } +#endif + +#if defined(IPTOS_LOWDELAY) && defined(IP_TOS) && (defined(SOL_IP) || defined(IPPROTO_IP)) + tos = IPTOS_LOWDELAY; +#ifdef SOL_IP + if (setsockopt(fd, SOL_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) +#else + if (setsockopt(fd, IPPROTO_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) +#endif + { + pa_log_warn("IP_TOS failed: %s", pa_cstrerror(errno)); ret = -1; + } #endif + return ret; +} + +int pa_socket_udp_low_delay(int fd) { + int ret, tos; + + pa_assert(fd >= 0); + + ret = pa_socket_low_delay(fd); + + tos = 0; + #if defined(IPTOS_LOWDELAY) && defined(IP_TOS) && (defined(SOL_IP) || defined(IPPROTO_IP)) tos = IPTOS_LOWDELAY; #ifdef SOL_IP @@ -182,7 +213,10 @@ int pa_socket_tcp_low_delay(int fd) { #else if (setsockopt(fd, IPPROTO_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) #endif + { ret = -1; + pa_log_warn("IP_TOS failed: %s", pa_cstrerror(errno)); + } #endif return ret; diff --git a/src/pulsecore/socket-util.h b/src/pulsecore/socket-util.h index 616c40ac..abe9ce10 100644 --- a/src/pulsecore/socket-util.h +++ b/src/pulsecore/socket-util.h @@ -31,6 +31,7 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l); int pa_socket_low_delay(int fd); int pa_socket_tcp_low_delay(int fd); +int pa_socket_udp_low_delay(int fd); int pa_socket_set_sndbuf(int fd, size_t l); int pa_socket_set_rcvbuf(int fd, size_t l); -- cgit From ef8df4104294a58af643b908077a90c78c4055da Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Sep 2007 22:25:18 +0000 Subject: make rtp send socket low delay git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1861 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 2 +- src/modules/rtp/module-rtp-send.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 3e4acd59..21136aac 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1344,7 +1344,7 @@ module_suspend_on_idle_la_CFLAGS = $(AM_CFLAGS) # RTP modules module_rtp_send_la_SOURCES = modules/rtp/module-rtp-send.c module_rtp_send_la_LDFLAGS = -module -avoid-version -module_rtp_send_la_LIBADD = $(AM_LIBADD) libpulsecore.la librtp.la +module_rtp_send_la_LIBADD = $(AM_LIBADD) libpulsecore.la librtp.la libsocket-util.la module_rtp_send_la_CFLAGS = $(AM_CFLAGS) module_rtp_recv_la_SOURCES = modules/rtp/module-rtp-recv.c diff --git a/src/modules/rtp/module-rtp-send.c b/src/modules/rtp/module-rtp-send.c index 7e9168e0..8fac44f0 100644 --- a/src/modules/rtp/module-rtp-send.c +++ b/src/modules/rtp/module-rtp-send.c @@ -49,6 +49,7 @@ #include #include #include +#include #include "module-rtp-send-symdef.h" @@ -280,6 +281,7 @@ int pa__init(pa_module*m) { /* If the socket queue is full, let's drop packets */ pa_make_nonblock_fd(fd); + pa_socket_udp_low_delay(fd); pa_source_output_new_data_init(&data); data.name = "RTP Monitor Stream"; -- cgit From b3093d84055ddc6cf26853a676f04692f748049b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Sep 2007 22:29:24 +0000 Subject: lower SO_PRIORITY priority to 6, since this is the best we get without being root git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1862 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/socket-util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/socket-util.c b/src/pulsecore/socket-util.c index cd912bf0..b7361e90 100644 --- a/src/pulsecore/socket-util.c +++ b/src/pulsecore/socket-util.c @@ -149,7 +149,7 @@ int pa_socket_low_delay(int fd) { int priority; pa_assert(fd >= 0); - priority = 7; + priority = 6; if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (void*)&priority, sizeof(priority)) < 0) { pa_log_warn("SO_PRIORITY failed: %s", pa_cstrerror(errno)); return -1; -- cgit From 1fd9afdf7d4a46ec324d002b3f23c23eebff1795 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Sep 2007 23:21:06 +0000 Subject: make use of pa_bool_t on a few places where applicable; really start work_cb git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1863 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/rtpoll.c | 57 +++++++++++++++++++++++++------------------------- src/pulsecore/rtpoll.h | 3 ++- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c index e72bf3f4..1b523851 100644 --- a/src/pulsecore/rtpoll.c +++ b/src/pulsecore/rtpoll.c @@ -49,19 +49,19 @@ struct pa_rtpoll { struct pollfd *pollfd, *pollfd2; unsigned n_pollfd_alloc, n_pollfd_used; - int timer_enabled; + pa_bool_t timer_enabled; struct timespec next_elapse; pa_usec_t period; - int scan_for_dead; - int running, installed, rebuild_needed, quit; + pa_bool_t scan_for_dead; + pa_bool_t running, installed, rebuild_needed, quit; #ifdef HAVE_PPOLL int rtsig; sigset_t sigset_unblocked; timer_t timer; #ifdef __linux__ - int dont_use_ppoll; + pa_bool_t dont_use_ppoll; #endif #endif @@ -70,7 +70,7 @@ struct pa_rtpoll { struct pa_rtpoll_item { pa_rtpoll *rtpoll; - int dead; + pa_bool_t dead; pa_rtpoll_priority_t priority; @@ -98,9 +98,8 @@ pa_rtpoll *pa_rtpoll_new(void) { #ifdef __linux__ /* ppoll is broken on Linux < 2.6.16 */ + p->dont_use_ppoll = FALSE; - p->dont_use_ppoll = 0; - { struct utsname u; unsigned major, minor, micro; @@ -112,7 +111,7 @@ pa_rtpoll *pa_rtpoll_new(void) { (major == 2 && minor < 6) || (major == 2 && minor == 6 && micro < 16)) - p->dont_use_ppoll = 1; + p->dont_use_ppoll = TRUE; } #endif @@ -130,13 +129,13 @@ pa_rtpoll *pa_rtpoll_new(void) { p->period = 0; memset(&p->next_elapse, 0, sizeof(p->next_elapse)); - p->timer_enabled = 0; + p->timer_enabled = FALSE; - p->running = 0; - p->installed = 0; - p->scan_for_dead = 0; - p->rebuild_needed = 0; - p->quit = 0; + p->running = FALSE; + p->installed = FALSE; + p->scan_for_dead = FALSE; + p->rebuild_needed = FALSE; + p->quit = FALSE; PA_LLIST_HEAD_INIT(pa_rtpoll_item, p->items); @@ -189,7 +188,7 @@ static void rtpoll_rebuild(pa_rtpoll *p) { pa_assert(p); - p->rebuild_needed = 0; + p->rebuild_needed = FALSE; if (p->n_pollfd_used > p->n_pollfd_alloc) { /* Hmm, we have to allocate some more space */ @@ -241,7 +240,7 @@ static void rtpoll_item_destroy(pa_rtpoll_item *i) { if (pa_flist_push(PA_STATIC_FLIST_GET(items), i) < 0) pa_xfree(i); - p->rebuild_needed = 1; + p->rebuild_needed = TRUE; } void pa_rtpoll_free(pa_rtpoll *p) { @@ -288,7 +287,7 @@ static void reset_all_revents(pa_rtpoll *p) { } } -int pa_rtpoll_run(pa_rtpoll *p, int wait) { +int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { pa_rtpoll_item *i; int r = 0; struct timespec timeout; @@ -297,7 +296,7 @@ int pa_rtpoll_run(pa_rtpoll *p, int wait) { pa_assert(!p->running); pa_assert(p->installed); - p->running = 1; + p->running = TRUE; /* First, let's do some work */ for (i = p->items; i && i->priority < PA_RTPOLL_NEVER; i = i->next) { @@ -306,7 +305,7 @@ int pa_rtpoll_run(pa_rtpoll *p, int wait) { if (i->dead) continue; - if (!i->before_cb) + if (!i->work_cb) continue; if (p->quit) @@ -422,12 +421,12 @@ int pa_rtpoll_run(pa_rtpoll *p, int wait) { finish: - p->running = 0; + p->running = FALSE; if (p->scan_for_dead) { pa_rtpoll_item *n; - p->scan_for_dead = 0; + p->scan_for_dead = FALSE; for (i = p->items; i; i = n) { n = i->next; @@ -495,7 +494,7 @@ void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timespec *ts) { p->next_elapse = *ts; p->period = 0; - p->timer_enabled = 1; + p->timer_enabled = TRUE; update_timer(p); } @@ -506,7 +505,7 @@ void pa_rtpoll_set_timer_periodic(pa_rtpoll *p, pa_usec_t usec) { p->period = usec; pa_rtclock_get(&p->next_elapse); pa_timespec_add(&p->next_elapse, usec); - p->timer_enabled = 1; + p->timer_enabled = TRUE; update_timer(p); } @@ -517,7 +516,7 @@ void pa_rtpoll_set_timer_relative(pa_rtpoll *p, pa_usec_t usec) { p->period = 0; pa_rtclock_get(&p->next_elapse); pa_timespec_add(&p->next_elapse, usec); - p->timer_enabled = 1; + p->timer_enabled = TRUE; update_timer(p); } @@ -527,7 +526,7 @@ void pa_rtpoll_set_timer_disabled(pa_rtpoll *p) { p->period = 0; memset(&p->next_elapse, 0, sizeof(p->next_elapse)); - p->timer_enabled = 0; + p->timer_enabled = FALSE; update_timer(p); } @@ -541,7 +540,7 @@ pa_rtpoll_item *pa_rtpoll_item_new(pa_rtpoll *p, pa_rtpoll_priority_t prio, unsi i = pa_xnew(pa_rtpoll_item, 1); i->rtpoll = p; - i->dead = 0; + i->dead = FALSE; i->n_pollfd = n_fds; i->pollfd = NULL; i->priority = prio; @@ -572,8 +571,8 @@ void pa_rtpoll_item_free(pa_rtpoll_item *i) { pa_assert(i); if (i->rtpoll->running) { - i->dead = 1; - i->rtpoll->scan_for_dead = 1; + i->dead = TRUE; + i->rtpoll->scan_for_dead = TRUE; return; } @@ -728,5 +727,5 @@ pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq(pa_rtpoll *p, pa_rtpoll_priority_t void pa_rtpoll_quit(pa_rtpoll *p) { pa_assert(p); - p->quit = 1; + p->quit = TRUE; } diff --git a/src/pulsecore/rtpoll.h b/src/pulsecore/rtpoll.h index ee6cc06c..a1242b38 100644 --- a/src/pulsecore/rtpoll.h +++ b/src/pulsecore/rtpoll.h @@ -31,6 +31,7 @@ #include #include #include +#include /* An implementation of a "real-time" poll loop. Basically, this is * yet another wrapper around poll(). However it has certain @@ -72,7 +73,7 @@ void pa_rtpoll_install(pa_rtpoll *p); * struct pollfd. Returns negative on error, positive if the loop * should continue to run, 0 when the loop should be terminated * cleanly. */ -int pa_rtpoll_run(pa_rtpoll *f, int wait); +int pa_rtpoll_run(pa_rtpoll *f, pa_bool_t wait); void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timespec *ts); void pa_rtpoll_set_timer_periodic(pa_rtpoll *p, pa_usec_t usec); -- cgit From 781cf499cf1cc36bd4774ff7e4a09f6db4e65038 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Sep 2007 23:24:13 +0000 Subject: properly release memblock always abd as soon as possible git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1864 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/rtp/rtp.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/modules/rtp/rtp.c b/src/modules/rtp/rtp.c index e2496c7d..60df7274 100644 --- a/src/modules/rtp/rtp.c +++ b/src/modules/rtp/rtp.c @@ -166,7 +166,7 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) { pa_assert(c); pa_assert(chunk); - chunk->memblock = NULL; + pa_memchunk_reset(chunk); if (ioctl(c->fd, FIONREAD, &size) < 0) { pa_log_warn("FIONREAD failed: %s", pa_cstrerror(errno)); @@ -189,7 +189,10 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) { m.msg_controllen = 0; m.msg_flags = 0; - if ((r = recvmsg(c->fd, &m, 0)) != size) { + r = recvmsg(c->fd, &m, 0); + pa_memblock_release(chunk->memblock); + + if (r != size) { if (r < 0 && errno != EAGAIN && errno != EINTR) pa_log_warn("recvmsg() failed: %s", r < 0 ? pa_cstrerror(errno) : "size mismatch"); @@ -244,10 +247,8 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) { return 0; fail: - if (chunk->memblock) { - pa_memblock_release(chunk->memblock); + if (chunk->memblock) pa_memblock_unref(chunk->memblock); - } return -1; } -- cgit From ac66b6af0837ae3fa1b77c6f335951574c7da150 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Sep 2007 23:35:05 +0000 Subject: fall back to plughw:, if hw: doesn't work, in the alsa source, too git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1865 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 4 +-- src/modules/module-alsa-source.c | 54 +++++++++++++++++++++++++++++----------- 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 108ed90c..4f2e570a 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -774,6 +774,8 @@ int pa__init(pa_module*m) { break; } + u->device_name = dev; + if (use_mmap && !b) { pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode."); u->use_mmap = use_mmap = b; @@ -787,8 +789,6 @@ int pa__init(pa_module*m) { goto fail; } - u->device_name = dev; - if ((err = pa_alsa_set_sw_params(u->pcm_handle)) < 0) { pa_log("Failed to set software parameters: %s", snd_strerror(err)); goto fail; diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 870f204d..82f66bb9 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -660,7 +660,7 @@ int pa__init(pa_module*m) { pa_modargs *ma = NULL; struct userdata *u = NULL; - const char *dev; + char *dev; pa_sample_spec ss; pa_channel_map map; unsigned nfrags, frag_size; @@ -718,24 +718,45 @@ int pa__init(pa_module*m) { pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); snd_config_update_free_global(); - if ((err = snd_pcm_open(&u->pcm_handle, dev = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) { - pa_log("Error opening PCM device %s: %s", dev, snd_strerror(err)); - goto fail; - } - u->device_name = pa_xstrdup(dev); + dev = pa_xstrdup(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE)); + + for (;;) { + + if ((err = snd_pcm_open(&u->pcm_handle, dev, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) { + pa_log("Error opening PCM device %s: %s", dev, snd_strerror(err)); + pa_xfree(dev); + goto fail; + } - if ((err = snd_pcm_info(u->pcm_handle, pcm_info)) < 0) { - pa_log("Error fetching PCM info: %s", snd_strerror(err)); - goto fail; - } + b = use_mmap; + if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) { - b = use_mmap; - if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) { - pa_log("Failed to set hardware parameters: %s", snd_strerror(err)); - goto fail; + if (err == -EPERM) { + /* Hmm, some hw is very exotic, so we retry with plughw, if hw didn't work */ + + if (pa_startswith(dev, "hw:")) { + char *d = pa_sprintf_malloc("plughw:%s", dev+3); + pa_log_debug("Opening the device as '%s' didn't work, retrying with '%s'.", dev, d); + pa_xfree(dev); + dev = d; + + snd_pcm_close(u->pcm_handle); + u->pcm_handle = NULL; + continue; + } + } + + pa_log("Failed to set hardware parameters: %s", snd_strerror(err)); + pa_xfree(dev); + goto fail; + } + + break; } + u->device_name = dev; + if (use_mmap && !b) { pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode."); u->use_mmap = use_mmap = b; @@ -744,6 +765,11 @@ int pa__init(pa_module*m) { if (u->use_mmap) pa_log_info("Successfully enabled mmap() mode."); + if ((err = snd_pcm_info(u->pcm_handle, pcm_info)) < 0) { + pa_log("Error fetching PCM info: %s", snd_strerror(err)); + goto fail; + } + if ((err = pa_alsa_set_sw_params(u->pcm_handle)) < 0) { pa_log("Failed to set software parameters: %s", snd_strerror(err)); goto fail; -- cgit From 0fcad977828665e46849cc4efe758ebc42450a66 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 19 Sep 2007 00:08:40 +0000 Subject: copy free_cb into a temporary variable first, to avoid compiler warning git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1866 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/thread.h b/src/pulsecore/thread.h index 0c6c859d..6aaf8c84 100644 --- a/src/pulsecore/thread.h +++ b/src/pulsecore/thread.h @@ -70,9 +70,10 @@ void *pa_tls_set(pa_tls *t, void *userdata); } \ static void name##_tls_destructor(void) PA_GCC_DESTRUCTOR; \ static void name##_tls_destructor(void) { \ + static void (*_free_cb)(void*) = free_cb; \ if (!name##_tls.tls) \ return; \ - if (free_cb) { \ + if (_free_cb) { \ void *p; \ if ((p = pa_tls_get(name##_tls.tls))) \ free_cb(p); \ -- cgit From 75f799a3d885a5af42c5cb3af49da1299b8425cc Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 19 Sep 2007 00:12:01 +0000 Subject: make O_CLOEXEC, O_NONBLOCK and socket low latency fd ops more uniform: always return void, name them similarly, only pass a single fd git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1867 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/cpulimit.c | 8 ++--- src/modules/module-pipe-sink.c | 4 +-- src/modules/module-pipe-source.c | 4 +-- src/modules/oss-util.c | 2 +- src/modules/rtp/module-rtp-send.c | 6 ++-- src/pulse/context.c | 6 ++-- src/pulse/mainloop-signal.c | 8 ++--- src/pulse/mainloop.c | 8 ++--- src/pulsecore/core-util.c | 58 ++++++++++++++++---------------- src/pulsecore/core-util.h | 5 ++- src/pulsecore/fdsem.c | 4 +-- src/pulsecore/iochannel.c | 6 ++-- src/pulsecore/socket-client.c | 8 ++--- src/pulsecore/socket-server.c | 18 +++++----- src/pulsecore/socket-util.c | 69 ++++++++++++++------------------------- src/pulsecore/socket-util.h | 6 ++-- 16 files changed, 101 insertions(+), 119 deletions(-) diff --git a/src/daemon/cpulimit.c b/src/daemon/cpulimit.c index 0fe11ea6..a61f43eb 100644 --- a/src/daemon/cpulimit.c +++ b/src/daemon/cpulimit.c @@ -184,10 +184,10 @@ int pa_cpu_limit_init(pa_mainloop_api *m) { return -1; } - pa_make_nonblock_fd(the_pipe[0]); - pa_make_nonblock_fd(the_pipe[1]); - pa_fd_set_cloexec(the_pipe[0], 1); - pa_fd_set_cloexec(the_pipe[1], 1); + pa_make_fd_nonblock(the_pipe[0]); + pa_make_fd_nonblock(the_pipe[1]); + pa_make_fd_cloexec(the_pipe[0]); + pa_make_fd_cloexec(the_pipe[1]); api = m; io_event = api->io_new(m, the_pipe[0], PA_IO_EVENT_INPUT, callback, NULL); diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index a1bdc8fb..edacf04b 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -236,8 +236,8 @@ int pa__init(pa_module*m) { goto fail; } - pa_fd_set_cloexec(u->fd, 1); - pa_make_nonblock_fd(u->fd); + pa_make_fd_cloexec(u->fd); + pa_make_fd_nonblock(u->fd); if (fstat(u->fd, &st) < 0) { pa_log("fstat('%s'): %s", u->filename, pa_cstrerror(errno)); diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c index 382da8f9..2313df67 100644 --- a/src/modules/module-pipe-source.c +++ b/src/modules/module-pipe-source.c @@ -214,8 +214,8 @@ int pa__init(pa_module*m) { goto fail; } - pa_fd_set_cloexec(u->fd, 1); - pa_make_nonblock_fd(u->fd); + pa_make_fd_cloexec(u->fd); + pa_make_fd_nonblock(u->fd); if (fstat(u->fd, &st) < 0) { pa_log("fstat('%s'): %s",u->filename, pa_cstrerror(errno)); diff --git a/src/modules/oss-util.c b/src/modules/oss-util.c index 36498809..3bef8a39 100644 --- a/src/modules/oss-util.c +++ b/src/modules/oss-util.c @@ -141,7 +141,7 @@ success: #endif *pcaps & DSP_CAP_TRIGGER ? " TRIGGER" : ""); - pa_fd_set_cloexec(fd, 1); + pa_make_fd_cloexec(fd); return fd; diff --git a/src/modules/rtp/module-rtp-send.c b/src/modules/rtp/module-rtp-send.c index 8fac44f0..f79867c2 100644 --- a/src/modules/rtp/module-rtp-send.c +++ b/src/modules/rtp/module-rtp-send.c @@ -280,8 +280,10 @@ int pa__init(pa_module*m) { } /* If the socket queue is full, let's drop packets */ - pa_make_nonblock_fd(fd); - pa_socket_udp_low_delay(fd); + pa_make_fd_nonblock(fd); + pa_make_udp_socket_low_delay(fd); + pa_make_fd_cloexec(fd); + pa_make_fd_cloexec(sap_fd); pa_source_output_new_data_init(&data); data.name = "RTP Monitor Stream"; diff --git a/src/pulse/context.c b/src/pulse/context.c index a39646d3..805cd44e 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -498,10 +498,10 @@ static int context_connect_spawn(pa_context *c) { goto fail; } - pa_fd_set_cloexec(fds[0], 1); + pa_make_fd_cloexec(fds[0]); - pa_socket_low_delay(fds[0]); - pa_socket_low_delay(fds[1]); + pa_make_socket_low_delay(fds[0]); + pa_make_socket_low_delay(fds[1]); if (c->spawn_api.prefork) c->spawn_api.prefork(); diff --git a/src/pulse/mainloop-signal.c b/src/pulse/mainloop-signal.c index b6414c4e..a986b241 100644 --- a/src/pulse/mainloop-signal.c +++ b/src/pulse/mainloop-signal.c @@ -123,10 +123,10 @@ int pa_signal_init(pa_mainloop_api *a) { return -1; } - pa_make_nonblock_fd(signal_pipe[0]); - pa_make_nonblock_fd(signal_pipe[1]); - pa_assert_se(pa_fd_set_cloexec(signal_pipe[0], 1) == 0); - pa_assert_se(pa_fd_set_cloexec(signal_pipe[1], 1) == 0); + pa_make_fd_nonblock(signal_pipe[0]); + pa_make_fd_nonblock(signal_pipe[1]); + pa_make_fd_cloexec(signal_pipe[0]); + pa_make_fd_cloexec(signal_pipe[1]); api = a; diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index c69c6653..bab8eb5c 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -457,10 +457,10 @@ pa_mainloop *pa_mainloop_new(void) { return NULL; } - pa_make_nonblock_fd(m->wakeup_pipe[0]); - pa_make_nonblock_fd(m->wakeup_pipe[1]); - pa_fd_set_cloexec(m->wakeup_pipe[0], 1); - pa_fd_set_cloexec(m->wakeup_pipe[1], 1); + pa_make_fd_nonblock(m->wakeup_pipe[0]); + pa_make_fd_nonblock(m->wakeup_pipe[1]); + pa_make_fd_cloexec(m->wakeup_pipe[0]); + pa_make_fd_cloexec(m->wakeup_pipe[1]); m->wakeup_requested = 0; PA_LLIST_HEAD_INIT(pa_io_event, m->io_events); diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index afd89bad..5532c40a 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -134,23 +134,42 @@ int pa_set_root(HANDLE handle) { #endif /** Make a file descriptor nonblock. Doesn't do any error checking */ -void pa_make_nonblock_fd(int fd) { +void pa_make_fd_nonblock(int fd) { + #ifdef O_NONBLOCK int v; pa_assert(fd >= 0); - if ((v = fcntl(fd, F_GETFL)) >= 0) - if (!(v & O_NONBLOCK)) - fcntl(fd, F_SETFL, v|O_NONBLOCK); + pa_assert_se((v = fcntl(fd, F_GETFL)) >= 0); + + if (!(v & O_NONBLOCK)) + pa_assert_se(fcntl(fd, F_SETFL, v|O_NONBLOCK) >= 0); + #elif defined(OS_IS_WIN32) u_long arg = 1; if (ioctlsocket(fd, FIONBIO, &arg) < 0) { - if (WSAGetLastError() == WSAENOTSOCK) - pa_log_warn("Only sockets can be made non-blocking!"); + pa_assert_se(WSAGetLastError() == WSAENOTSOCK); + pa_log_warn("Only sockets can be made non-blocking!"); } #else pa_log_warn("Non-blocking I/O not supported.!"); #endif + +} + +/* Set the FD_CLOEXEC flag for a fd */ +void pa_make_fd_cloexec(int fd) { + +#ifdef FD_CLOEXEC + int v; + pa_assert(fd >= 0); + + pa_assert_se((v = fcntl(fd, F_GETFD, 0)) >= 0); + + if (!(v & FD_CLOEXEC)) + pa_assert_se(fcntl(fd, F_SETFD, v|FD_CLOEXEC) >= 0); +#endif + } /** Creates a directory securely */ @@ -552,25 +571,6 @@ void pa_reset_priority(void) { #endif } -/* Set the FD_CLOEXEC flag for a fd */ -int pa_fd_set_cloexec(int fd, int b) { - -#ifdef FD_CLOEXEC - int v; - pa_assert(fd >= 0); - - if ((v = fcntl(fd, F_GETFD, 0)) < 0) - return -1; - - v = (v & ~FD_CLOEXEC) | (b ? FD_CLOEXEC : 0); - - if (fcntl(fd, F_SETFD, v) < 0) - return -1; -#endif - - return 0; -} - /* Try to parse a boolean string value.*/ int pa_parse_boolean(const char *v) { @@ -629,12 +629,12 @@ const char *pa_sig2str(int sig) { if (sig <= 0) goto fail; - + #ifdef NSIG - if (sig >= NSIG) - goto fail; + if (sig >= NSIG) + goto fail; #endif - + #ifdef HAVE_SIG2STR { char buf[SIG2STR_MAX]; diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index b8ef464e..44c7574e 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -34,7 +34,8 @@ struct timeval; -void pa_make_nonblock_fd(int fd); +void pa_make_fd_nonblock(int fd); +void pa_make_fd_cloexec(int fd); int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid); int pa_make_secure_parent_dir(const char *fn, mode_t, uid_t uid, gid_t gid); @@ -59,8 +60,6 @@ void pa_make_realtime(void); void pa_raise_priority(void); void pa_reset_priority(void); -int pa_fd_set_cloexec(int fd, int b); - int pa_parse_boolean(const char *s) PA_GCC_PURE; char *pa_split(const char *c, const char*delimiters, const char **state); diff --git a/src/pulsecore/fdsem.c b/src/pulsecore/fdsem.c index 68207a76..c81797e0 100644 --- a/src/pulsecore/fdsem.c +++ b/src/pulsecore/fdsem.c @@ -54,8 +54,8 @@ pa_fdsem *pa_fdsem_new(void) { return NULL; } - pa_fd_set_cloexec(f->fds[0], 1); - pa_fd_set_cloexec(f->fds[1], 1); + pa_make_fd_cloexec(f->fds[0]); + pa_make_fd_cloexec(f->fds[1]); pa_atomic_store(&f->waiting, 0); pa_atomic_store(&f->signalled, 0); diff --git a/src/pulsecore/iochannel.c b/src/pulsecore/iochannel.c index 2f586cbf..90136fe6 100644 --- a/src/pulsecore/iochannel.c +++ b/src/pulsecore/iochannel.c @@ -145,17 +145,17 @@ pa_iochannel* pa_iochannel_new(pa_mainloop_api*m, int ifd, int ofd) { if (ifd == ofd) { pa_assert(ifd >= 0); - pa_make_nonblock_fd(io->ifd); + pa_make_fd_nonblock(io->ifd); io->input_event = io->output_event = m->io_new(m, ifd, PA_IO_EVENT_INPUT|PA_IO_EVENT_OUTPUT, callback, io); } else { if (ifd >= 0) { - pa_make_nonblock_fd(io->ifd); + pa_make_fd_nonblock(io->ifd); io->input_event = m->io_new(m, ifd, PA_IO_EVENT_INPUT, callback, io); } if (ofd >= 0) { - pa_make_nonblock_fd(io->ofd); + pa_make_fd_nonblock(io->ofd); io->output_event = m->io_new(m, ofd, PA_IO_EVENT_OUTPUT, callback, io); } } diff --git a/src/pulsecore/socket-client.c b/src/pulsecore/socket-client.c index 360a0b48..6748c285 100644 --- a/src/pulsecore/socket-client.c +++ b/src/pulsecore/socket-client.c @@ -208,7 +208,7 @@ static int do_connect(pa_socket_client *c, const struct sockaddr *sa, socklen_t pa_assert(sa); pa_assert(len > 0); - pa_make_nonblock_fd(c->fd); + pa_make_fd_nonblock(c->fd); if ((r = connect(c->fd, sa, len)) < 0) { #ifdef OS_IS_WIN32 @@ -293,11 +293,11 @@ static int sockaddr_prepare(pa_socket_client *c, const struct sockaddr *sa, size return -1; } - pa_fd_set_cloexec(c->fd, 1); + pa_make_fd_cloexec(c->fd); if (sa->sa_family == AF_INET || sa->sa_family == AF_INET6) - pa_socket_tcp_low_delay(c->fd); + pa_make_tcp_socket_low_delay(c->fd); else - pa_socket_low_delay(c->fd); + pa_make_socket_low_delay(c->fd); if (do_connect(c, sa, salen) < 0) return -1; diff --git a/src/pulsecore/socket-server.c b/src/pulsecore/socket-server.c index 502005d2..e0d2f164 100644 --- a/src/pulsecore/socket-server.c +++ b/src/pulsecore/socket-server.c @@ -111,7 +111,7 @@ static void callback(pa_mainloop_api *mainloop, pa_io_event *e, int fd, PA_GCC_U goto finish; } - pa_fd_set_cloexec(nfd, 1); + pa_make_fd_cloexec(nfd); if (!s->on_connection) { pa_close(nfd); @@ -137,9 +137,9 @@ static void callback(pa_mainloop_api *mainloop, pa_io_event *e, int fd, PA_GCC_U /* There should be a check for socket type here */ if (s->type == SOCKET_SERVER_IPV4) - pa_socket_tcp_low_delay(fd); + pa_make_tcp_socket_low_delay(fd); else - pa_socket_low_delay(fd); + pa_make_socket_low_delay(fd); pa_assert_se(io = pa_iochannel_new(s->mainloop, nfd, nfd)); s->on_connection(s, io, s->userdata); @@ -193,13 +193,13 @@ pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *file goto fail; } - pa_fd_set_cloexec(fd, 1); + pa_make_fd_cloexec(fd); sa.sun_family = AF_UNIX; strncpy(sa.sun_path, filename, sizeof(sa.sun_path)-1); sa.sun_path[sizeof(sa.sun_path) - 1] = 0; - pa_socket_low_delay(fd); + pa_make_socket_low_delay(fd); if (bind(fd, (struct sockaddr*) &sa, SUN_LEN(&sa)) < 0) { pa_log("bind(): %s", pa_cstrerror(errno)); @@ -253,14 +253,14 @@ pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address goto fail; } - pa_fd_set_cloexec(fd, 1); + pa_make_fd_cloexec(fd); #ifdef SO_REUSEADDR if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) pa_log("setsockopt(): %s", pa_cstrerror(errno)); #endif - pa_socket_tcp_low_delay(fd); + pa_make_tcp_socket_low_delay(fd); memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; @@ -305,7 +305,7 @@ pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t ad goto fail; } - pa_fd_set_cloexec(fd, 1); + pa_make_fd_cloexec(fd); #ifdef IPV6_V6ONLY if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) @@ -317,7 +317,7 @@ pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t ad pa_log("setsockopt(SOL_SOCKET, SO_REUSEADDR, 1): %s", pa_cstrerror(errno)); #endif - pa_socket_tcp_low_delay(fd); + pa_make_tcp_socket_low_delay(fd); memset(&sa, 0, sizeof(sa)); sa.sin6_family = AF_INET6; diff --git a/src/pulsecore/socket-util.c b/src/pulsecore/socket-util.c index b7361e90..085edeb8 100644 --- a/src/pulsecore/socket-util.c +++ b/src/pulsecore/socket-util.c @@ -143,83 +143,64 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l) { pa_snprintf(c, l, "Unknown client"); } -int pa_socket_low_delay(int fd) { +void pa_make_socket_low_delay(int fd) { #ifdef SO_PRIORITY int priority; pa_assert(fd >= 0); priority = 6; - if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (void*)&priority, sizeof(priority)) < 0) { + if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (void*)&priority, sizeof(priority)) < 0) pa_log_warn("SO_PRIORITY failed: %s", pa_cstrerror(errno)); - return -1; - } #endif - - return 0; } -int pa_socket_tcp_low_delay(int fd) { - int ret, tos, on; - +void pa_make_tcp_socket_low_delay(int fd) { pa_assert(fd >= 0); - - ret = pa_socket_low_delay(fd); - - on = 1; - tos = 0; + + pa_make_socket_low_delay(fd); #if defined(SOL_TCP) || defined(IPPROTO_TCP) + { + int on = 1; #if defined(SOL_TCP) - if (setsockopt(fd, SOL_TCP, TCP_NODELAY, (void*)&on, sizeof(on)) < 0) + if (setsockopt(fd, SOL_TCP, TCP_NODELAY, (void*)&on, sizeof(on)) < 0) #else - if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*)&on, sizeof(on)) < 0) + if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*)&on, sizeof(on)) < 0) #endif - { - pa_log_warn("TCP_NODELAY failed: %s", pa_cstrerror(errno)); - ret = -1; + pa_log_warn("TCP_NODELAY failed: %s", pa_cstrerror(errno)); } #endif - + #if defined(IPTOS_LOWDELAY) && defined(IP_TOS) && (defined(SOL_IP) || defined(IPPROTO_IP)) - tos = IPTOS_LOWDELAY; + { + int tos = IPTOS_LOWDELAY; #ifdef SOL_IP - if (setsockopt(fd, SOL_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) + if (setsockopt(fd, SOL_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) #else - if (setsockopt(fd, IPPROTO_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) + if (setsockopt(fd, IPPROTO_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) #endif - { - pa_log_warn("IP_TOS failed: %s", pa_cstrerror(errno)); - ret = -1; + pa_log_warn("IP_TOS failed: %s", pa_cstrerror(errno)); } #endif - - return ret; } -int pa_socket_udp_low_delay(int fd) { - int ret, tos; - +void pa_make_udp_socket_low_delay(int fd) { pa_assert(fd >= 0); - - ret = pa_socket_low_delay(fd); - - tos = 0; - + + pa_make_socket_low_delay(fd); + #if defined(IPTOS_LOWDELAY) && defined(IP_TOS) && (defined(SOL_IP) || defined(IPPROTO_IP)) - tos = IPTOS_LOWDELAY; + { + int tos = IPTOS_LOWDELAY; #ifdef SOL_IP - if (setsockopt(fd, SOL_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) + if (setsockopt(fd, SOL_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) #else - if (setsockopt(fd, IPPROTO_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) + if (setsockopt(fd, IPPROTO_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) #endif - { - ret = -1; - pa_log_warn("IP_TOS failed: %s", pa_cstrerror(errno)); + pa_log_warn("IP_TOS failed: %s", pa_cstrerror(errno)); } #endif - - return ret; } int pa_socket_set_rcvbuf(int fd, size_t l) { diff --git a/src/pulsecore/socket-util.h b/src/pulsecore/socket-util.h index abe9ce10..a0344c68 100644 --- a/src/pulsecore/socket-util.h +++ b/src/pulsecore/socket-util.h @@ -29,9 +29,9 @@ void pa_socket_peer_to_string(int fd, char *c, size_t l); -int pa_socket_low_delay(int fd); -int pa_socket_tcp_low_delay(int fd); -int pa_socket_udp_low_delay(int fd); +void pa_make_socket_low_delay(int fd); +void pa_make_tcp_socket_low_delay(int fd); +void pa_make_udp_socket_low_delay(int fd); int pa_socket_set_sndbuf(int fd, size_t l); int pa_socket_set_rcvbuf(int fd, size_t l); -- cgit From d716e3cd7b73b12e40fed20e9e00ea55fba62eb2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 19 Sep 2007 19:03:38 +0000 Subject: fix check for lrintf, make resample2.c again identical to upstream ffmpeg git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1868 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/ffmpeg/avcodec.h | 11 +++++++++++ src/pulsecore/ffmpeg/resample2.c | 7 ------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/pulsecore/ffmpeg/avcodec.h b/src/pulsecore/ffmpeg/avcodec.h index 775ec962..7e86e7f6 100644 --- a/src/pulsecore/ffmpeg/avcodec.h +++ b/src/pulsecore/ffmpeg/avcodec.h @@ -25,6 +25,10 @@ * ffmpeg, just enough to get resample2.c to compile without * modification -- Lennart */ +#if !defined(PACKAGE) && defined(HAVE_CONFIG_H) +#include +#endif + #include #include #include @@ -68,4 +72,11 @@ void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int c void av_resample_close(struct AVResampleContext *c); void av_build_filter(int16_t *filter, double factor, int tap_count, int phase_count, int scale, int type); +/* + * crude lrintf for non-C99 systems. + */ +#ifndef HAVE_LFRINTF +#define lrintf(x) ((long int)(x)) +#endif + #endif /* AVCODEC_H */ diff --git a/src/pulsecore/ffmpeg/resample2.c b/src/pulsecore/ffmpeg/resample2.c index dfbd5287..da1443d9 100644 --- a/src/pulsecore/ffmpeg/resample2.c +++ b/src/pulsecore/ffmpeg/resample2.c @@ -86,13 +86,6 @@ static double bessel(double x){ return v; } -/* - * crude lrintf for non-C99 systems. - */ -#ifndef HAVE_LFRINTF -#define lrintf(x) ((long int)(x)) -#endif - /** * builds a polyphase filterbank. * @param factor resampling factor -- cgit From 42b71ff9656904668d3abcf0016768701148301b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 19 Sep 2007 19:06:25 +0000 Subject: fix trivial typo git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1869 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/ffmpeg/avcodec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/ffmpeg/avcodec.h b/src/pulsecore/ffmpeg/avcodec.h index 7e86e7f6..bf8b84ea 100644 --- a/src/pulsecore/ffmpeg/avcodec.h +++ b/src/pulsecore/ffmpeg/avcodec.h @@ -75,7 +75,7 @@ void av_build_filter(int16_t *filter, double factor, int tap_count, int phase_co /* * crude lrintf for non-C99 systems. */ -#ifndef HAVE_LFRINTF +#ifndef HAVE_LRINTF #define lrintf(x) ((long int)(x)) #endif -- cgit From a8a9ee499d400fd54d4f67340247f78fb4ab2a5c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 19 Sep 2007 21:20:15 +0000 Subject: make sure we initialize thread private data before we move our ghost sink to the rt thread, not after git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1870 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink-input.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index b8ca5e1b..3993e337 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -774,6 +774,10 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { NULL, NULL); + info.ghost_sink_input->thread_info.state = info.ghost_sink_input->state = PA_SINK_INPUT_RUNNING; + info.ghost_sink_input->thread_info.volume = info.ghost_sink_input->volume; + info.ghost_sink_input->thread_info.muted = info.ghost_sink_input->muted; + info.buffer = pa_memblockq_new(0, MOVE_BUFFER_LENGTH, 0, pa_frame_size(&origin->sample_spec), 0, 0, NULL); } } @@ -782,9 +786,6 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { if (info.ghost_sink_input) { /* Basically, do what pa_sink_input_put() does ...*/ - info.ghost_sink_input->thread_info.state = info.ghost_sink_input->state = PA_SINK_INPUT_RUNNING; - info.ghost_sink_input->thread_info.volume = info.ghost_sink_input->volume; - info.ghost_sink_input->thread_info.muted = info.ghost_sink_input->muted; pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, info.ghost_sink_input->index); pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], info.ghost_sink_input); -- cgit From 75647bc38f8a65f45c6cee23d5b373c6c3b3ecdc Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 19 Sep 2007 22:21:55 +0000 Subject: render new data always in the master sink's thread, fixing missing locking git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1871 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-combine.c | 198 +++++++++++++++++++++++++++++-------------- 1 file changed, 133 insertions(+), 65 deletions(-) diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index feadf4f9..9923f2e8 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -87,8 +87,9 @@ struct output { pa_sink *sink; pa_sink_input *sink_input; - pa_asyncmsgq *asyncmsgq; - pa_rtpoll_item *rtpoll_item; + pa_asyncmsgq *inq, /* Message queue from the master to this sink input */ + *outq; /* Message queue from this sink input to the master */ + pa_rtpoll_item *inq_rtpoll_item, *outq_rtpoll_item; pa_memblockq *memblockq; @@ -106,8 +107,6 @@ struct userdata { pa_thread_mq thread_mq; pa_rtpoll *rtpoll; - pa_mutex *mutex; - struct output *master; pa_time_event *time_event; @@ -134,7 +133,8 @@ struct userdata { enum { SINK_MESSAGE_ADD_OUTPUT = PA_SINK_MESSAGE_MAX, - SINK_MESSAGE_REMOVE_OUTPUT + SINK_MESSAGE_REMOVE_OUTPUT, + SINK_MESSAGE_NEED }; enum { @@ -275,9 +275,51 @@ finish: pa_log_debug("Thread shutting down"); } -static void request_memblock(struct output *o, size_t length) { - pa_memchunk chunk; +static void render_memblock(struct userdata *u, struct output *o, size_t length) { + pa_assert(u); + pa_assert(o); + + if (!PA_SINK_OPENED(u->sink->thread_info.state)) + return; + + /* We are run by the master output (u->master), possibly on behalf + * of another output (o). The other output is waiting for us, + * hence it is safe to access its mainblockq directly. */ + /* Maybe there's some data in the requesting output's queue + * now? */ + while (pa_asyncmsgq_process_one(o->inq) > 0) + ; + + /* Ok, now let's prepare some data if we really have to */ + while (!pa_memblockq_is_readable(o->memblockq)) { + struct output *j; + pa_memchunk chunk; + + /* Render data! */ + pa_sink_render(u->sink, length, &chunk); + + /* OK, let's send this data to the other threads */ + for (j = o->userdata->thread_info.outputs; j; j = j->next) + + /* Send to other outputs, which are not the requesting + * one, and not the master */ + + if (j != o && j != u->master && j->sink_input) + pa_asyncmsgq_post(j->inq, PA_MSGOBJECT(j->sink_input), SINK_INPUT_MESSAGE_POST, NULL, 0, &chunk, NULL); + + /* Now push it into the master queue */ + pa_memblockq_push_align(u->master->memblockq, &chunk); + + /* And into the requesting output's queue */ + if (o != u->master) + pa_memblockq_push_align(o->memblockq, &chunk); + + pa_memblock_unref(chunk.memblock); + } +} + +static void request_memblock(struct output *o, size_t length) { pa_assert(o); pa_sink_input_assert_ref(o->sink_input); pa_sink_assert_ref(o->userdata->sink); @@ -285,7 +327,7 @@ static void request_memblock(struct output *o, size_t length) { /* If another thread already prepared some data we received * the data over the asyncmsgq, hence let's first process * it. */ - while (pa_asyncmsgq_process_one(o->asyncmsgq) > 0) + while (pa_asyncmsgq_process_one(o->inq) > 0) ; /* Check whether we're now readable */ @@ -293,33 +335,16 @@ static void request_memblock(struct output *o, size_t length) { return; /* OK, we need to prepare new data */ - pa_mutex_lock(o->userdata->mutex); - if (PA_SINK_OPENED(o->userdata->sink->thread_info.state)) { - - /* Maybe there's some data now? */ - while (pa_asyncmsgq_process_one(o->asyncmsgq) > 0) - ; - - /* Ok, now let's prepare some data if we really have to */ - while (!pa_memblockq_is_readable(o->memblockq)) { - struct output *j; - - /* Do it! */ - pa_sink_render(o->userdata->sink, length, &chunk); - - /* OK, let's send this data to the other threads */ - for (j = o->userdata->thread_info.outputs; j; j = j->next) - if (j != o && j->sink_input) - pa_asyncmsgq_post(j->asyncmsgq, PA_MSGOBJECT(j->sink_input), SINK_INPUT_MESSAGE_POST, NULL, 0, &chunk, NULL); - - /* And push it into our own queue */ - pa_memblockq_push_align(o->memblockq, &chunk); - pa_memblock_unref(chunk.memblock); - } - } - - pa_mutex_unlock(o->userdata->mutex); + if (o == o->userdata->master) + /* OK, we're the master, so let's render some data */ + render_memblock(o->userdata, o, length); + + else + /* We're not the master, we need to ask the master to do the + * rendering for us */ + + pa_asyncmsgq_send(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_NEED, o, length, NULL); } /* Called from I/O thread context */ @@ -327,8 +352,7 @@ static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chun struct output *o; pa_sink_input_assert_ref(i); - o = i->userdata; - pa_assert(o); + pa_assert_se(o = i->userdata); /* If necessary, get some new data */ request_memblock(o, length); @@ -342,8 +366,7 @@ static void sink_input_drop_cb(pa_sink_input *i, size_t length) { pa_sink_input_assert_ref(i); pa_assert(length > 0); - o = i->userdata; - pa_assert(o); + pa_assert_se(o = i->userdata); pa_memblockq_drop(o->memblockq, length); } @@ -353,23 +376,42 @@ static void sink_input_attach_cb(pa_sink_input *i) { struct output *o; pa_sink_input_assert_ref(i); - o = i->userdata; - pa_assert(o); + pa_assert_se(o = i->userdata); + pa_assert(!o->inq_rtpoll_item); + if (o->userdata->master == o) { + struct output *k; + + pa_assert(!o->outq_rtpoll_item); + + /* Set up the queues from the outputs to the master */ + for (k = o->userdata->thread_info.outputs; k; k = k->next) { + + pa_assert(!k->outq_rtpoll_item); + + if (o == k) + continue; + + k->outq_rtpoll_item = pa_rtpoll_item_new_asyncmsgq( + i->sink->rtpoll, + PA_RTPOLL_EARLY+1, /* This one has a slightly lower priority than the normal message handling */ + k->outq); + } + /* Calling these two functions here is safe, because both - * threads that might access this sink input are known to be + * threads that might access this sink are known to be * waiting for us. */ pa_sink_set_asyncmsgq(o->userdata->sink, i->sink->asyncmsgq); pa_sink_set_rtpoll(o->userdata->sink, i->sink->rtpoll); pa_sink_attach_within_thread(o->userdata->sink); } - - pa_assert(!o->rtpoll_item); - o->rtpoll_item = pa_rtpoll_item_new_asyncmsgq( + + /* Set up the queues from the inputs to the master */ + o->inq_rtpoll_item = pa_rtpoll_item_new_asyncmsgq( i->sink->rtpoll, PA_RTPOLL_NORMAL, /* This one has a lower priority than the normal message handling */ - o->asyncmsgq); + o->inq); } /* Called from I/O thread context */ @@ -377,15 +419,27 @@ static void sink_input_detach_cb(pa_sink_input *i) { struct output *o; pa_sink_input_assert_ref(i); - o = i->userdata; - pa_assert(o); + pa_assert_se(o = i->userdata); - pa_assert(o->rtpoll_item); - pa_rtpoll_item_free(o->rtpoll_item); - o->rtpoll_item = NULL; + pa_assert(o->inq_rtpoll_item); + pa_rtpoll_item_free(o->inq_rtpoll_item); + o->inq_rtpoll_item = NULL; - if (o->userdata->master == o) + if (o->userdata->master == o) { + struct output *k; + pa_sink_detach_within_thread(o->userdata->sink); + + for (k = o->userdata->thread_info.outputs; k; k = k->next) { + + if (o == k) + continue; + + pa_assert(k->outq_rtpoll_item); + pa_rtpoll_item_free(k->outq_rtpoll_item); + k->outq_rtpoll_item = NULL; + } + } } /* Called from main context */ @@ -433,6 +487,7 @@ static int sink_input_process_msg(pa_msgobject *obj, int code, void *data, int64 return pa_sink_input_process_msg(obj, code, data, offset, chunk); } +/* Called from main context */ static int suspend(struct userdata *u) { struct output *o; uint32_t idx; @@ -458,6 +513,7 @@ static int suspend(struct userdata *u) { return 0; } +/* Called from main context */ static int unsuspend(struct userdata *u) { struct output *o; uint32_t idx; @@ -485,12 +541,12 @@ static int unsuspend(struct userdata *u) { return 0; } +/* Called from main context */ static int sink_set_state(pa_sink *sink, pa_sink_state_t state) { struct userdata *u; pa_sink_assert_ref(sink); - u = sink->userdata; - pa_assert(u); + pa_assert_se(u = sink->userdata); /* Please note that in contrast to the ALSA modules we call * suspend/unsuspend from main context here! */ @@ -575,6 +631,10 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse case SINK_MESSAGE_REMOVE_OUTPUT: PA_LLIST_REMOVE(struct output, u->thread_info.outputs, (struct output*) data); break; + + case SINK_MESSAGE_NEED: + render_memblock(u, data, (size_t) offset); + break; } return pa_sink_process_msg(o, code, data, offset, chunk); @@ -765,8 +825,10 @@ static struct output *output_new(struct userdata *u, pa_sink *sink) { o = pa_xnew(struct output, 1); o->userdata = u; - o->asyncmsgq = pa_asyncmsgq_new(0); - o->rtpoll_item = NULL; + o->inq = pa_asyncmsgq_new(0); + o->outq = pa_asyncmsgq_new(0); + o->inq_rtpoll_item = NULL; + o->outq_rtpoll_item = NULL; o->sink = sink; o->sink_input = NULL; o->memblockq = pa_memblockq_new( @@ -809,9 +871,12 @@ fail: if (o->memblockq) pa_memblockq_free(o->memblockq); - if (o->asyncmsgq) - pa_asyncmsgq_unref(o->asyncmsgq); + if (o->inq) + pa_asyncmsgq_unref(o->inq); + if (o->outq) + pa_asyncmsgq_unref(o->outq); + pa_xfree(o); } @@ -947,7 +1012,6 @@ int pa__init(pa_module*m) { u->thread_info.master = u->master = NULL; u->time_event = NULL; u->adjust_time = DEFAULT_ADJUST_TIME; - u->mutex = pa_mutex_new(FALSE, TRUE); pa_thread_mq_init(&u->thread_mq, m->core->mainloop); u->rtpoll = NULL; u->thread = NULL; @@ -1134,14 +1198,20 @@ static void output_free(struct output *o) { pa_sink_input_unref(o->sink_input); } - if (o->rtpoll_item) - pa_rtpoll_item_free(o->rtpoll_item); + if (o->inq_rtpoll_item) + pa_rtpoll_item_free(o->inq_rtpoll_item); + + if (o->outq_rtpoll_item) + pa_rtpoll_item_free(o->outq_rtpoll_item); + + if (o->inq) + pa_asyncmsgq_unref(o->inq); + + if (o->outq) + pa_asyncmsgq_unref(o->outq); if (o->memblockq) pa_memblockq_free(o->memblockq); - - if (o->asyncmsgq) - pa_asyncmsgq_unref(o->asyncmsgq); pa_xfree(o); } @@ -1190,8 +1260,6 @@ void pa__done(pa_module*m) { if (u->time_event) u->core->mainloop->time_free(u->time_event); - pa_mutex_free(u->mutex); - pa_xfree(u); } -- cgit From c40c1682be62ccccedf626b1d9e335efe7a1101a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 20 Sep 2007 20:30:03 +0000 Subject: maintain the attach status in a boolean variable 'attach' accessible from the IO thread for sink_inputs/source_outputs git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1872 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink-input.c | 78 ++++++++++++++++++++++--------------------- src/pulsecore/sink-input.h | 2 ++ src/pulsecore/sink.c | 67 ++++++++++++++++++++----------------- src/pulsecore/source-output.c | 17 ++++++---- src/pulsecore/source-output.h | 2 ++ src/pulsecore/source.c | 32 ++++++++++-------- 6 files changed, 109 insertions(+), 89 deletions(-) diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 3993e337..c06da13f 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -189,9 +189,9 @@ pa_sink_input* pa_sink_input_new( if (data->sync_base->sync_next) data->sync_base->sync_next->sync_prev = i; data->sync_base->sync_next = i; - } else + } else i->sync_next = i->sync_prev = NULL; - + i->peek = NULL; i->drop = NULL; i->kill = NULL; @@ -205,11 +205,12 @@ pa_sink_input* pa_sink_input_new( pa_atomic_store(&i->thread_info.drained, 1); i->thread_info.sample_spec = i->sample_spec; i->thread_info.silence_memblock = NULL; - i->thread_info.move_silence = 0; + i->thread_info.move_silence = 0; pa_memchunk_reset(&i->thread_info.resampled_chunk); i->thread_info.resampler = resampler; i->thread_info.volume = i->volume; i->thread_info.muted = i->muted; + i->thread_info.attached = FALSE; pa_assert_se(pa_idxset_put(core->sink_inputs, pa_sink_input_ref(i), &i->index) == 0); pa_assert_se(pa_idxset_put(i->sink->inputs, i, NULL) == 0); @@ -249,7 +250,7 @@ static int sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) { update_n_corked(i, state); i->state = state; - + for (ssync = i->sync_prev; ssync; ssync = ssync->sync_prev) { update_n_corked(ssync, state); ssync->state = state; @@ -258,7 +259,7 @@ static int sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) { update_n_corked(ssync, state); ssync->state = state; } - + return 0; } @@ -267,14 +268,14 @@ void pa_sink_input_unlink(pa_sink_input *i) { pa_assert(PA_SINK_INPUT_LINKED(i->state)); pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], i); - + if (i->sync_prev) i->sync_prev->sync_next = i->sync_next; if (i->sync_next) i->sync_next->sync_prev = i->sync_prev; - + i->sync_prev = i->sync_next = NULL; - + pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, 0, NULL); pa_idxset_remove_by_data(i->sink->core->sink_inputs, i, NULL); pa_idxset_remove_by_data(i->sink->inputs, i, NULL); @@ -283,7 +284,7 @@ void pa_sink_input_unlink(pa_sink_input *i) { sink_input_set_state(i, PA_SINK_INPUT_UNLINKED); pa_sink_update_status(i->sink); - + i->peek = NULL; i->drop = NULL; i->kill = NULL; @@ -308,6 +309,8 @@ static void sink_input_free(pa_object *o) { pa_log_info("Freeing output %u \"%s\"", i->index, i->name); + pa_assert(!i->thread_info.attached); + if (i->thread_info.resampled_chunk.memblock) pa_memblock_unref(i->thread_info.resampled_chunk.memblock); @@ -393,7 +396,7 @@ int pa_sink_input_peek(pa_sink_input *i, size_t length, pa_memchunk *chunk, pa_c block_size_max = pa_mempool_block_size_max(i->sink->core->mempool); if (length > block_size_max) length = pa_frame_align(block_size_max, &i->sink->sample_spec); - + if (i->thread_info.move_silence > 0) { size_t l; @@ -437,7 +440,7 @@ int pa_sink_input_peek(pa_sink_input *i, size_t length, pa_memchunk *chunk, pa_c rmbs = pa_resampler_max_block_size(i->thread_info.resampler); if (l > rmbs) l = rmbs; - + if ((ret = i->peek(i, l, &tchunk)) < 0) goto finish; @@ -451,7 +454,7 @@ int pa_sink_input_peek(pa_sink_input *i, size_t length, pa_memchunk *chunk, pa_c /* It might be necessary to adjust the volume here */ if (do_volume_adj_here && !volume_is_norm) { pa_memchunk_make_writable(&tchunk, 0); - + if (i->thread_info.muted) pa_silence_memchunk(&tchunk, &i->thread_info.sample_spec); else @@ -529,7 +532,7 @@ void pa_sink_input_drop(pa_sink_input *i, size_t length) { i->thread_info.resampled_chunk.index += l; i->thread_info.resampled_chunk.length -= l; - + if (i->thread_info.resampled_chunk.length <= 0) { pa_memblock_unref(i->thread_info.resampled_chunk.memblock); pa_memchunk_reset(&i->thread_info.resampled_chunk); @@ -539,7 +542,7 @@ void pa_sink_input_drop(pa_sink_input *i, size_t length) { } if (length > 0) { - + if (i->thread_info.resampler) { /* So, we have a resampler. To avoid discontinuities we * have to actually read all data that could be read and @@ -548,31 +551,31 @@ void pa_sink_input_drop(pa_sink_input *i, size_t length) { while (length > 0) { pa_memchunk chunk; pa_cvolume volume; - + if (pa_sink_input_peek(i, length, &chunk, &volume) >= 0) { size_t l; - + pa_memblock_unref(chunk.memblock); l = chunk.length; if (l > length) l = length; - + pa_sink_input_drop(i, l); length -= l; - + } else { size_t l; - + l = pa_resampler_request(i->thread_info.resampler, length); - + /* Hmmm, peeking failed, so let's at least drop * the right amount of data */ if (l > 0) if (i->drop) i->drop(i, l); - + break; } } @@ -728,7 +731,7 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { memset(&info, 0, sizeof(info)); info.sink_input = i; - + if (!immediately) { pa_usec_t old_latency, new_latency; @@ -763,9 +766,9 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { } /* Okey, let's move it */ - + if (info.buffer_bytes > 0) { - + info.ghost_sink_input = pa_memblockq_sink_input_new( origin, "Ghost Stream", @@ -777,7 +780,7 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { info.ghost_sink_input->thread_info.state = info.ghost_sink_input->state = PA_SINK_INPUT_RUNNING; info.ghost_sink_input->thread_info.volume = info.ghost_sink_input->volume; info.ghost_sink_input->thread_info.muted = info.ghost_sink_input->muted; - + info.buffer = pa_memblockq_new(0, MOVE_BUFFER_LENGTH, 0, pa_frame_size(&origin->sample_spec), 0, 0, NULL); } } @@ -786,12 +789,12 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { if (info.ghost_sink_input) { /* Basically, do what pa_sink_input_put() does ...*/ - + pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, info.ghost_sink_input->index); pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], info.ghost_sink_input); pa_sink_input_unref(info.ghost_sink_input); } - + pa_idxset_remove_by_data(origin->inputs, i, NULL); pa_idxset_put(dest->inputs, i, NULL); i->sink = dest; @@ -828,14 +831,14 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { &dest->sample_spec); pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, i, 0, NULL); - + pa_sink_update_status(origin); pa_sink_update_status(dest); pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_POST], i); - + pa_log_debug("Successfully moved sink input %i from %s to %s.", i->index, origin->name, dest->name); - + /* Notify everyone */ pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); @@ -864,13 +867,13 @@ int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t if (i->thread_info.resampled_chunk.memblock) *r += pa_bytes_to_usec(i->thread_info.resampled_chunk.length, &i->sink->sample_spec); - if (i->thread_info.move_silence) - *r += pa_bytes_to_usec(i->thread_info.move_silence, &i->sink->sample_spec); + if (i->thread_info.move_silence) + *r += pa_bytes_to_usec(i->thread_info.move_silence, &i->sink->sample_spec); return 0; } - case PA_SINK_INPUT_MESSAGE_SET_RATE: + case PA_SINK_INPUT_MESSAGE_SET_RATE: i->thread_info.sample_spec.rate = PA_PTR_TO_UINT(userdata); pa_resampler_set_input_rate(i->thread_info.resampler, PA_PTR_TO_UINT(userdata)); @@ -879,11 +882,11 @@ int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t case PA_SINK_INPUT_MESSAGE_SET_STATE: { pa_sink_input *ssync; - + if ((PA_PTR_TO_UINT(userdata) == PA_SINK_INPUT_DRAINED || PA_PTR_TO_UINT(userdata) == PA_SINK_INPUT_RUNNING) && (i->thread_info.state != PA_SINK_INPUT_DRAINED) && (i->thread_info.state != PA_SINK_INPUT_RUNNING)) pa_atomic_store(&i->thread_info.drained, 1); - + i->thread_info.state = PA_PTR_TO_UINT(userdata); for (ssync = i->thread_info.sync_prev; ssync; ssync = ssync->thread_info.sync_prev) { @@ -892,14 +895,14 @@ int pa_sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int64_t pa_atomic_store(&ssync->thread_info.drained, 1); ssync->thread_info.state = PA_PTR_TO_UINT(userdata); } - + for (ssync = i->thread_info.sync_next; ssync; ssync = ssync->thread_info.sync_next) { if ((PA_PTR_TO_UINT(userdata) == PA_SINK_INPUT_DRAINED || PA_PTR_TO_UINT(userdata) == PA_SINK_INPUT_RUNNING) && (ssync->thread_info.state != PA_SINK_INPUT_DRAINED) && (ssync->thread_info.state != PA_SINK_INPUT_RUNNING)) pa_atomic_store(&ssync->thread_info.drained, 1); ssync->thread_info.state = PA_PTR_TO_UINT(userdata); } - + return 0; } } @@ -915,4 +918,3 @@ pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i) { return i->state; } - diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h index 152c24e6..fec431f0 100644 --- a/src/pulsecore/sink-input.h +++ b/src/pulsecore/sink-input.h @@ -124,6 +124,8 @@ struct pa_sink_input { struct { pa_sink_input_state_t state; pa_atomic_t drained; + + pa_bool_t attached; /* True only between ->attach() and ->detach() calls */ pa_sample_spec sample_spec; diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 886d7442..81258e7a 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -155,7 +155,7 @@ void pa_sink_put(pa_sink* s) { pa_assert(s->rtpoll); s->thread_info.state = s->state = PA_SINK_IDLE; - + pa_source_put(s->monitor_source); pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index); @@ -164,7 +164,7 @@ void pa_sink_put(pa_sink* s) { static int sink_set_state(pa_sink *s, pa_sink_state_t state) { int ret; - + pa_assert(s); if (s->state == state) @@ -177,14 +177,14 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state) { (PA_SINK_OPENED(s->state) && state == PA_SINK_SUSPENDED)) { pa_sink_input *i; uint32_t idx; - + /* We're suspending or resuming, tell everyone about it */ - + for (i = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); i; i = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx))) if (i->suspend) i->suspend(i, state == PA_SINK_SUSPENDED); } - + if (s->set_state) if ((ret = s->set_state(s, state)) < 0) return -1; @@ -206,7 +206,7 @@ void pa_sink_unlink(pa_sink* s) { pa_assert(PA_SINK_LINKED(s->state)); pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK], s); - + pa_namereg_unregister(s->core, s->name); pa_idxset_remove_by_data(s->core->sinks, s, NULL); @@ -254,12 +254,12 @@ static void sink_free(pa_object *o) { while ((i = pa_hashmap_steal_first(s->thread_info.inputs))) pa_sink_input_unref(i); - + pa_hashmap_free(s->thread_info.inputs, NULL, NULL); if (s->silence) pa_memblock_unref(s->silence); - + pa_xfree(s->name); pa_xfree(s->description); pa_xfree(s->driver); @@ -401,7 +401,7 @@ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) { pa_mix_info info[MAX_MIX_CHANNELS]; unsigned n; size_t block_size_max; - + pa_sink_assert_ref(s); pa_assert(PA_SINK_OPENED(s->thread_info.state)); pa_assert(pa_frame_aligned(length, &s->sample_spec)); @@ -417,7 +417,7 @@ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) { length = pa_frame_align(block_size_max, &s->sample_spec); pa_assert(length > 0); - + n = s->thread_info.state == PA_SINK_RUNNING ? fill_mix_info(s, length, info, MAX_MIX_CHANNELS) : 0; if (n == 0) { @@ -595,10 +595,10 @@ void pa_sink_skip(pa_sink *s, size_t length) { pa_assert(PA_SINK_OPENED(s->thread_info.state)); pa_assert(length > 0); pa_assert(pa_frame_aligned(length, &s->sample_spec)); - + if (pa_source_used_by(s->monitor_source)) { pa_memchunk chunk; - + /* If something is connected to our monitor source, we have to * pass valid data to it */ @@ -609,7 +609,7 @@ void pa_sink_skip(pa_sink *s, size_t length) { pa_assert(chunk.length <= length); length -= chunk.length; } - + } else { /* Ok, noone cares about the rendered data, so let's not even render it */ @@ -792,7 +792,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse pa_assert(PA_SINK_LINKED(s->thread_info.state)); switch ((pa_sink_message_t) code) { - + case PA_SINK_MESSAGE_ADD_INPUT: { pa_sink_input *i = PA_SINK_INPUT(userdata); pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), pa_sink_input_ref(i)); @@ -813,6 +813,9 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse i->thread_info.sync_next->thread_info.sync_prev = i; } + pa_assert(!i->thread_info.attached); + i->thread_info.attached = TRUE; + if (i->attach) i->attach(i); @@ -824,14 +827,17 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse if (i->detach) i->detach(i); - + + pa_assert(i->thread_info.attached); + i->thread_info.attached = FALSE; + /* Since the caller sleeps in pa_sink_input_unlink(), * we can safely access data outside of thread_info even * though it is mutable */ pa_assert(!i->thread_info.sync_prev); pa_assert(!i->thread_info.sync_next); - + if (i->thread_info.sync_prev) { i->thread_info.sync_prev->thread_info.sync_next = i->thread_info.sync_prev->sync_next; i->thread_info.sync_prev = NULL; @@ -841,10 +847,10 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse i->thread_info.sync_next->thread_info.sync_prev = i->thread_info.sync_next->sync_prev; i->thread_info.sync_next = NULL; } - + if (pa_hashmap_remove(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index))) pa_sink_input_unref(i); - + return 0; } @@ -857,37 +863,37 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse pa_assert(!info->sink_input->sync_next); pa_assert(!info->sink_input->thread_info.sync_next); pa_assert(!info->sink_input->thread_info.sync_prev); - + if (info->ghost_sink_input) { pa_assert(info->buffer_bytes > 0); pa_assert(info->buffer); - + volume_is_norm = pa_cvolume_is_norm(&info->sink_input->thread_info.volume); pa_log_debug("Buffering %lu bytes ...", (unsigned long) info->buffer_bytes); - + while (info->buffer_bytes > 0) { pa_memchunk memchunk; pa_cvolume volume; size_t n; - + if (pa_sink_input_peek(info->sink_input, info->buffer_bytes, &memchunk, &volume) < 0) break; - + n = memchunk.length > info->buffer_bytes ? info->buffer_bytes : memchunk.length; pa_sink_input_drop(info->sink_input, n); memchunk.length = n; - + if (!volume_is_norm) { pa_memchunk_make_writable(&memchunk, 0); pa_volume_memchunk(&memchunk, &s->sample_spec, &volume); } - + if (pa_memblockq_push(info->buffer, &memchunk) < 0) { pa_memblock_unref(memchunk.memblock); break; } - + pa_memblock_unref(memchunk.memblock); info->buffer_bytes -= n; } @@ -910,7 +916,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(info->ghost_sink_input->index), pa_sink_input_ref(info->ghost_sink_input)); info->ghost_sink_input->thread_info.sync_prev = info->ghost_sink_input->thread_info.sync_next = NULL; } - + return 0; } @@ -934,7 +940,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse return 0; case PA_SINK_MESSAGE_SET_STATE: - + s->thread_info.state = PA_PTR_TO_UINT(userdata); return 0; @@ -951,7 +957,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse /* Reattach all streams */ pa_sink_attach_within_thread(s); break; - + case PA_SINK_MESSAGE_GET_LATENCY: case PA_SINK_MESSAGE_MAX: ; @@ -964,7 +970,7 @@ int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend) { pa_sink *sink; uint32_t idx; int ret = 0; - + pa_core_assert_ref(c); for (sink = PA_SINK(pa_idxset_first(c->sinks, &idx)); sink; sink = PA_SINK(pa_idxset_next(c->sinks, &idx))) @@ -1016,4 +1022,3 @@ void pa_sink_attach_within_thread(pa_sink *s) { if (s->monitor_source) pa_source_attach_within_thread(s->monitor_source); } - diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index df5dc8c2..34eef8ba 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -156,6 +156,7 @@ pa_source_output* pa_source_output_new( o->userdata = NULL; o->thread_info.state = o->state; + o->thread_info.attached = FALSE; o->thread_info.sample_spec = o->sample_spec; o->thread_info.resampler = resampler; @@ -186,9 +187,9 @@ static int source_output_set_state(pa_source_output *o, pa_source_output_state_t pa_assert_se(o->source->n_corked -- >= 1); else if (o->state != PA_SOURCE_OUTPUT_CORKED && state == PA_SOURCE_OUTPUT_CORKED) o->source->n_corked++; - + o->state = state; - + return 0; } @@ -197,7 +198,7 @@ void pa_source_output_unlink(pa_source_output*o) { pa_assert(PA_SOURCE_OUTPUT_LINKED(o->state)); pa_hook_fire(&o->source->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK], o); - + pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, 0, NULL); pa_idxset_remove_by_data(o->source->core->source_outputs, o, NULL); @@ -231,6 +232,8 @@ static void source_output_free(pa_object* mo) { pa_log_info("Freeing output %u \"%s\"", o->index, o->name); + pa_assert(!o->thread_info.attached); + if (o->thread_info.resampler) pa_resampler_free(o->thread_info.resampler); @@ -258,7 +261,7 @@ void pa_source_output_put(pa_source_output *o) { void pa_source_output_kill(pa_source_output*o) { pa_source_output_assert_ref(o); pa_assert(PA_SOURCE_OUTPUT_LINKED(o->state)); - + if (o->kill) o->kill(o); } @@ -357,7 +360,7 @@ int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { pa_source_output_assert_ref(o); pa_assert(PA_SOURCE_OUTPUT_LINKED(o->state)); pa_source_assert_ref(dest); - + origin = o->source; if (dest == origin) @@ -399,7 +402,7 @@ int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { /* Okey, let's move it */ pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, 0, NULL); - + pa_idxset_remove_by_data(origin->outputs, o, NULL); pa_idxset_put(dest->outputs, o, NULL); o->source = dest; @@ -448,7 +451,7 @@ int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, int return 0; } - + } return -1; diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h index 96ded863..60552d43 100644 --- a/src/pulsecore/source-output.h +++ b/src/pulsecore/source-output.h @@ -99,6 +99,8 @@ struct pa_source_output { struct { pa_source_output_state_t state; + + pa_bool_t attached; /* True only between ->attach() and ->detach() calls */ pa_sample_spec sample_spec; diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 315c2ce5..8f9cbc4a 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -139,7 +139,7 @@ void pa_source_put(pa_source *s) { static int source_set_state(pa_source *s, pa_source_state_t state) { int ret; - + pa_assert(s); if (s->state == state) @@ -147,14 +147,14 @@ static int source_set_state(pa_source *s, pa_source_state_t state) { if (state == PA_SOURCE_SUSPENDED && !(s->flags & PA_SOURCE_CAN_SUSPEND)) return -1; - + if ((s->state == PA_SOURCE_SUSPENDED && PA_SOURCE_OPENED(state)) || (PA_SOURCE_OPENED(s->state) && state == PA_SOURCE_SUSPENDED)) { pa_source_output *o; uint32_t idx; - + /* We're suspending or resuming, tell everyone about it */ - + for (o = PA_SOURCE_OUTPUT(pa_idxset_first(s->outputs, &idx)); o; o = PA_SOURCE_OUTPUT(pa_idxset_next(s->outputs, &idx))) if (o->suspend) o->suspend(o, state == PA_SINK_SUSPENDED); @@ -180,7 +180,7 @@ void pa_source_unlink(pa_source *s) { pa_assert(s); pa_assert(PA_SOURCE_LINKED(s->state)); - pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], s); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], s); pa_namereg_unregister(s->core, s->name); pa_idxset_remove_by_data(s->core->sources, s, NULL); @@ -202,7 +202,7 @@ void pa_source_unlink(pa_source *s) { pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_REMOVE, s->index); - pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK_POST], s); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK_POST], s); } static void source_free(pa_object *o) { @@ -221,7 +221,7 @@ static void source_free(pa_object *o) { while ((so = pa_hashmap_steal_first(s->thread_info.outputs))) pa_source_output_unref(so); - + pa_hashmap_free(s->thread_info.outputs, NULL, NULL); pa_xfree(s->name); @@ -267,7 +267,7 @@ void pa_source_post(pa_source*s, const pa_memchunk *chunk) { if (s->thread_info.state != PA_SOURCE_RUNNING) return; - + if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&s->thread_info.soft_volume)) { pa_memchunk vchunk = *chunk; @@ -436,7 +436,7 @@ unsigned pa_source_linked_by(pa_source *s) { unsigned pa_source_used_by(pa_source *s) { unsigned ret; - + pa_source_assert_ref(s); pa_assert(PA_SOURCE_LINKED(s->state)); @@ -456,9 +456,12 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_ pa_source_output *o = PA_SOURCE_OUTPUT(userdata); pa_hashmap_put(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index), pa_source_output_ref(o)); + pa_assert(!o->thread_info.attached); + o->thread_info.attached = TRUE; + if (o->attach) o->attach(o); - + return 0; } @@ -468,6 +471,9 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_ if (o->detach) o->detach(o); + pa_assert(o->thread_info.attached); + o->thread_info.attached = FALSE; + if (pa_hashmap_remove(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index))) pa_source_output_unref(o); @@ -510,7 +516,7 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_ /* Reattach all streams */ pa_source_attach_within_thread(s); break; - + case PA_SOURCE_MESSAGE_GET_LATENCY: case PA_SOURCE_MESSAGE_MAX: ; @@ -523,9 +529,9 @@ int pa_source_suspend_all(pa_core *c, pa_bool_t suspend) { uint32_t idx; pa_source *source; int ret = 0; - + pa_core_assert_ref(c); - + for (source = PA_SOURCE(pa_idxset_first(c->sources, &idx)); source; source = PA_SOURCE(pa_idxset_next(c->sources, &idx))) ret -= pa_source_suspend(source, suspend) < 0; -- cgit From f3f44dab379f4791a51642d49fcf20284856ec9e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 20 Sep 2007 20:33:34 +0000 Subject: rework module-combine again git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1873 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-combine.c | 432 ++++++++++++++++++++++++------------------- 1 file changed, 245 insertions(+), 187 deletions(-) diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 9923f2e8..90433e0c 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -90,7 +90,7 @@ struct output { pa_asyncmsgq *inq, /* Message queue from the master to this sink input */ *outq; /* Message queue from this sink input to the master */ pa_rtpoll_item *inq_rtpoll_item, *outq_rtpoll_item; - + pa_memblockq *memblockq; pa_usec_t total_latency; @@ -109,8 +109,8 @@ struct userdata { struct output *master; - pa_time_event *time_event; - uint32_t adjust_time; + pa_time_event *time_event; + uint32_t adjust_time; int automatic; size_t block_size; @@ -122,7 +122,7 @@ struct userdata { pa_resample_method_t resample_method; struct timespec adjust_timestamp; - + pa_idxset* outputs; /* managed in main context */ struct { @@ -134,7 +134,8 @@ struct userdata { enum { SINK_MESSAGE_ADD_OUTPUT = PA_SINK_MESSAGE_MAX, SINK_MESSAGE_REMOVE_OUTPUT, - SINK_MESSAGE_NEED + SINK_MESSAGE_NEED, + SINK_MESSAGE_SET_MASTER }; enum { @@ -144,7 +145,7 @@ enum { static void output_free(struct output *o); static int output_create_sink_input(struct userdata *u, struct output *o); static int update_master(struct userdata *u, struct output *o); -static int pick_master(struct userdata *u); +static int pick_master(struct userdata *u, struct output *except); static void adjust_rates(struct userdata *u) { struct output *o; @@ -160,7 +161,7 @@ static void adjust_rates(struct userdata *u) { if (!PA_SINK_OPENED(pa_sink_get_state(u->sink))) return; - + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) { uint32_t sink_latency; @@ -169,35 +170,35 @@ static void adjust_rates(struct userdata *u) { sink_latency = o->sink_input->sink ? pa_sink_get_latency(o->sink_input->sink) : 0; o->total_latency = sink_latency + pa_sink_input_get_latency(o->sink_input); - + if (sink_latency > max_sink_latency) max_sink_latency = sink_latency; - + if (o->total_latency < min_total_latency) min_total_latency = o->total_latency; } if (min_total_latency == (pa_usec_t) -1) return; - + target_latency = max_sink_latency > min_total_latency ? max_sink_latency : min_total_latency; - + pa_log_info("[%s] target latency is %0.0f usec.", u->sink->name, (float) target_latency); pa_log_info("[%s] master is %s", u->sink->name, u->master->sink->description); - + base_rate = u->sink->sample_spec.rate; - + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) { uint32_t r = base_rate; if (!o->sink_input || !PA_SINK_OPENED(pa_sink_get_state(o->sink))) continue; - + if (o->total_latency < target_latency) r -= (uint32_t) (((((double) target_latency - o->total_latency))/u->adjust_time)*r/ 1000000); else if (o->total_latency > target_latency) r += (uint32_t) (((((double) o->total_latency - target_latency))/u->adjust_time)*r/ 1000000); - + if (r < (uint32_t) (base_rate*0.9) || r > (uint32_t) (base_rate*1.1)) { pa_log_warn("[%s] sample rates too different, not adjusting (%u vs. %u).", o->sink_input->name, base_rate, r); pa_sink_input_set_rate(o->sink_input, base_rate); @@ -211,7 +212,7 @@ static void adjust_rates(struct userdata *u) { static void time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *tv, void *userdata) { struct userdata *u = userdata; struct timeval n; - + pa_assert(u); pa_assert(a); pa_assert(u->time_event == e); @@ -238,14 +239,14 @@ static void thread_func(void *userdata) { /* This is only run when we are in NULL mode, to make sure that * playback doesn't stop. In all other cases we hook our stuff * into the master sink. */ - + for (;;) { int ret; /* Render some data and drop it immediately */ if (u->sink->thread_info.state == PA_SINK_RUNNING) { struct timespec now; - + pa_rtclock_get(&now); if (pa_timespec_cmp(&u->timestamp, &now) <= 0) { @@ -275,6 +276,7 @@ finish: pa_log_debug("Thread shutting down"); } +/* Called from I/O thread context */ static void render_memblock(struct userdata *u, struct output *o, size_t length) { pa_assert(u); pa_assert(o); @@ -285,58 +287,59 @@ static void render_memblock(struct userdata *u, struct output *o, size_t length) /* We are run by the master output (u->master), possibly on behalf * of another output (o). The other output is waiting for us, * hence it is safe to access its mainblockq directly. */ - + /* Maybe there's some data in the requesting output's queue * now? */ while (pa_asyncmsgq_process_one(o->inq) > 0) ; - + /* Ok, now let's prepare some data if we really have to */ while (!pa_memblockq_is_readable(o->memblockq)) { struct output *j; pa_memchunk chunk; - + /* Render data! */ pa_sink_render(u->sink, length, &chunk); - + /* OK, let's send this data to the other threads */ for (j = o->userdata->thread_info.outputs; j; j = j->next) /* Send to other outputs, which are not the requesting * one, and not the master */ - - if (j != o && j != u->master && j->sink_input) + + if (j != o && j != u->thread_info.master && j->sink_input) pa_asyncmsgq_post(j->inq, PA_MSGOBJECT(j->sink_input), SINK_INPUT_MESSAGE_POST, NULL, 0, &chunk, NULL); - + /* Now push it into the master queue */ - pa_memblockq_push_align(u->master->memblockq, &chunk); + pa_memblockq_push_align(u->thread_info.master->memblockq, &chunk); /* And into the requesting output's queue */ - if (o != u->master) + if (o != u->thread_info.master) pa_memblockq_push_align(o->memblockq, &chunk); - + pa_memblock_unref(chunk.memblock); } } +/* Called from I/O thread context */ static void request_memblock(struct output *o, size_t length) { pa_assert(o); pa_sink_input_assert_ref(o->sink_input); pa_sink_assert_ref(o->userdata->sink); - + /* If another thread already prepared some data we received * the data over the asyncmsgq, hence let's first process * it. */ while (pa_asyncmsgq_process_one(o->inq) > 0) ; - + /* Check whether we're now readable */ if (pa_memblockq_is_readable(o->memblockq)) return; - + /* OK, we need to prepare new data */ - if (o == o->userdata->master) + if (o == o->userdata->thread_info.master) /* OK, we're the master, so let's render some data */ render_memblock(o->userdata, o, length); @@ -371,6 +374,51 @@ static void sink_input_drop_cb(pa_sink_input *i, size_t length) { pa_memblockq_drop(o->memblockq, length); } +/* Called from I/O thread context for the master */ +static void create_master_rtpolls(struct userdata *u) { + struct output *k; + + pa_assert(u); + + pa_assert(!u->master->outq_rtpoll_item); + + /* Set up the queues from the outputs to the master */ + for (k = u->thread_info.outputs; k; k = k->next) { + + pa_assert(!k->outq_rtpoll_item); + + if (k == u->master) + continue; + + k->outq_rtpoll_item = pa_rtpoll_item_new_asyncmsgq( + u->master->sink->rtpoll, + PA_RTPOLL_EARLY+1, /* This one has a slightly lower priority than the normal message handling */ + k->outq); + + pa_log("1: %p now has rptoll item %p", k, k->outq_rtpoll_item); + } +} + +/* Called from I/O thread context for the master */ +static void free_master_rtpolls(struct userdata *u) { + struct output *k; + + pa_assert(!u->master->outq_rtpoll_item); + + for (k = u->thread_info.outputs; k; k = k->next) { + + if (k == u->master) + continue; + + if (k->outq_rtpoll_item) { + pa_rtpoll_item_free(k->outq_rtpoll_item); + k->outq_rtpoll_item = NULL; + } + + pa_assert(!k->outq_rtpoll_item); + } +} + /* Called from I/O thread context */ static void sink_input_attach_cb(pa_sink_input *i) { struct output *o; @@ -378,27 +426,11 @@ static void sink_input_attach_cb(pa_sink_input *i) { pa_sink_input_assert_ref(i); pa_assert_se(o = i->userdata); - pa_assert(!o->inq_rtpoll_item); - - if (o->userdata->master == o) { - struct output *k; - - pa_assert(!o->outq_rtpoll_item); - - /* Set up the queues from the outputs to the master */ - for (k = o->userdata->thread_info.outputs; k; k = k->next) { + pa_log("attaching %s", i->sink->name); - pa_assert(!k->outq_rtpoll_item); + if (o->userdata->thread_info.master == o) { + create_master_rtpolls(o->userdata); - if (o == k) - continue; - - k->outq_rtpoll_item = pa_rtpoll_item_new_asyncmsgq( - i->sink->rtpoll, - PA_RTPOLL_EARLY+1, /* This one has a slightly lower priority than the normal message handling */ - k->outq); - } - /* Calling these two functions here is safe, because both * threads that might access this sink are known to be * waiting for us. */ @@ -408,6 +440,7 @@ static void sink_input_attach_cb(pa_sink_input *i) { } /* Set up the queues from the inputs to the master */ + pa_assert(!o->inq_rtpoll_item); o->inq_rtpoll_item = pa_rtpoll_item_new_asyncmsgq( i->sink->rtpoll, PA_RTPOLL_NORMAL, /* This one has a lower priority than the normal message handling */ @@ -421,24 +454,15 @@ static void sink_input_detach_cb(pa_sink_input *i) { pa_sink_input_assert_ref(i); pa_assert_se(o = i->userdata); + pa_log("detaching %s", i->sink->name); + pa_assert(o->inq_rtpoll_item); pa_rtpoll_item_free(o->inq_rtpoll_item); o->inq_rtpoll_item = NULL; - if (o->userdata->master == o) { - struct output *k; - + if (o->userdata->thread_info.master == o) { pa_sink_detach_within_thread(o->userdata->sink); - - for (k = o->userdata->thread_info.outputs; k; k = k->next) { - - if (o == k) - continue; - - pa_assert(k->outq_rtpoll_item); - pa_rtpoll_item_free(k->outq_rtpoll_item); - k->outq_rtpoll_item = NULL; - } + free_master_rtpolls(o->userdata); } } @@ -453,7 +477,7 @@ static void sink_input_kill_cb(pa_sink_input *i) { pa_sink_input_unlink(o->sink_input); pa_sink_input_unref(o->sink_input); o->sink_input = NULL; - + pa_module_unload_request(o->userdata->module); } @@ -462,7 +486,7 @@ static int sink_input_process_msg(pa_msgobject *obj, int code, void *data, int64 struct output *o = PA_SINK_INPUT(obj)->userdata; switch (code) { - + case PA_SINK_INPUT_MESSAGE_GET_LATENCY: { pa_usec_t *r = data; @@ -479,11 +503,11 @@ static int sink_input_process_msg(pa_msgobject *obj, int code, void *data, int64 pa_memblockq_push_align(o->memblockq, chunk); else pa_memblockq_flush(o->memblockq); - + break; } } - + return pa_sink_input_process_msg(obj, code, data, offset, chunk); } @@ -491,11 +515,11 @@ static int sink_input_process_msg(pa_msgobject *obj, int code, void *data, int64 static int suspend(struct userdata *u) { struct output *o; uint32_t idx; - + pa_assert(u); /* Let's suspend by unlinking all streams */ - + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) { if (o->sink_input) { @@ -505,11 +529,11 @@ static int suspend(struct userdata *u) { } } - if (pick_master(u) < 0) + if (pick_master(u, NULL) < 0) pa_module_unload_request(u->module); pa_log_info("Device suspended..."); - + return 0; } @@ -519,24 +543,26 @@ static int unsuspend(struct userdata *u) { uint32_t idx; pa_assert(u); - + /* Let's resume */ - + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) { pa_sink_suspend(o->sink, 0); - + if (PA_SINK_OPENED(pa_sink_get_state(o->sink))) { if (output_create_sink_input(u, o) < 0) output_free(o); - else - pa_sink_input_put(o->sink_input); } } - if (pick_master(u) < 0) + if (pick_master(u, NULL) < 0) pa_module_unload_request(u->module); - + + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) + if (o->sink_input && pa_sink_get_state(o->sink_input) == PA_SINK_INPUT_INIT) + pa_sink_input_put(o->sink_input); + pa_log_info("Resumed successfully..."); return 0; } @@ -544,17 +570,17 @@ static int unsuspend(struct userdata *u) { /* Called from main context */ static int sink_set_state(pa_sink *sink, pa_sink_state_t state) { struct userdata *u; - + pa_sink_assert_ref(sink); pa_assert_se(u = sink->userdata); /* Please note that in contrast to the ALSA modules we call * suspend/unsuspend from main context here! */ - + switch (state) { case PA_SINK_SUSPENDED: pa_assert(PA_SINK_OPENED(pa_sink_get_state(u->sink))); - + if (suspend(u) < 0) return -1; @@ -567,7 +593,7 @@ static int sink_set_state(pa_sink *sink, pa_sink_state_t state) { if (unsuspend(u) < 0) return -1; } - + break; case PA_SINK_UNLINKED: @@ -583,17 +609,17 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse struct userdata *u = PA_SINK(o)->userdata; switch (code) { - + case PA_SINK_MESSAGE_SET_STATE: if ((pa_sink_state_t) PA_PTR_TO_UINT(data) == PA_SINK_RUNNING) { /* Only useful when running in NULL mode, i.e. when no - * master sink is attached */ + * master sink is attached */ pa_rtclock_get(&u->timestamp); } - + break; - + case PA_SINK_MESSAGE_GET_LATENCY: { struct timespec now; @@ -601,7 +627,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse * mode, i.e. when no master sink is attached. See * sink_get_latency_cb() below */ pa_rtclock_get(&now); - + if (pa_timespec_cmp(&u->timestamp, &now) > 0) *((pa_usec_t*) data) = 0; else @@ -609,34 +635,69 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse break; } - case PA_SINK_MESSAGE_DETACH: + case SINK_MESSAGE_SET_MASTER: + if ((u->thread_info.master = data)) { - /* We're detaching all our input streams artificially, so - * that we can drive our sink from a different sink */ + /* There's now a master, and we're being executed in + * its thread, let's register the asyncmsgqs from other + * outputs to us */ - u->thread_info.master = NULL; - break; + if (u->thread_info.master->sink_input->thread_info.attached) + create_master_rtpolls(u); - case PA_SINK_MESSAGE_ATTACH: + } else { - /* We're attached all our input streams artificially again */ - - u->thread_info.master = data; - break; + if (u->thread_info.master->sink_input->thread_info.attached) + free_master_rtpolls(u); - case SINK_MESSAGE_ADD_OUTPUT: - PA_LLIST_PREPEND(struct output, u->thread_info.outputs, (struct output*) data); - break; + } + return 0; - case SINK_MESSAGE_REMOVE_OUTPUT: - PA_LLIST_REMOVE(struct output, u->thread_info.outputs, (struct output*) data); - break; + case SINK_MESSAGE_ADD_OUTPUT: { + struct output *op = data; + + PA_LLIST_PREPEND(struct output, u->thread_info.outputs, op); + + pa_assert(!op->outq_rtpoll_item); + + if (op != u->thread_info.master) { + /* Create pa_asyncmsgq to master */ + + op->outq_rtpoll_item = pa_rtpoll_item_new_asyncmsgq( + u->thread_info.master->sink->rtpoll, + PA_RTPOLL_EARLY+1, /* This one has a slightly lower priority than the normal message handling */ + op->outq); + + pa_log("2: %p now has rptoll item %p", op, op->outq_rtpoll_item); + } + + pa_log("Added output %s", op->sink_input->sink->name); + + return 0; + } + + case SINK_MESSAGE_REMOVE_OUTPUT: { + struct output *op = data; + + pa_log("Remove output %s", op->sink_input->sink->name); + + PA_LLIST_REMOVE(struct output, u->thread_info.outputs, op); + + /* Remove the q that leads from this output to the master output */ + + if (op->outq_rtpoll_item) { + pa_rtpoll_item_free(op->outq_rtpoll_item); + op->outq_rtpoll_item = NULL; + } + + return 0; + } case SINK_MESSAGE_NEED: render_memblock(u, data, (size_t) offset); - break; + return 0; } - + return pa_sink_process_msg(o, code, data, offset, chunk); } @@ -654,17 +715,17 @@ static pa_usec_t sink_get_latency_cb(pa_sink *s) { if (!u->master->sink_input) return 0; - + return pa_sink_input_get_latency(u->master->sink_input) + pa_sink_get_latency(u->master->sink_input->sink); - + } else { pa_usec_t usec; /* We have no master, hence let's ask our own thread which * implements the NULL sink */ - + if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0) return 0; @@ -677,7 +738,7 @@ static void update_description(struct userdata *u) { char *t; struct output *o; uint32_t idx; - + pa_assert(u); if (pa_idxset_isempty(u->outputs)) { @@ -686,20 +747,20 @@ static void update_description(struct userdata *u) { } t = pa_xstrdup("Simultaneous output to"); - + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) { char *e; - + if (first) { e = pa_sprintf_malloc("%s %s", t, o->sink->description); first = 0; } else e = pa_sprintf_malloc("%s, %s", t, o->sink->description); - + pa_xfree(t); t = e; } - + pa_sink_set_description(u->sink, t); pa_xfree(t); } @@ -708,15 +769,18 @@ static int update_master(struct userdata *u, struct output *o) { pa_assert(u); /* Make sure everything is detached from the old thread before we move our stuff to a new thread */ - if (u->sink && PA_SINK_LINKED(pa_sink_get_state(u->sink))) + if (u->sink && PA_SINK_LINKED(pa_sink_get_state(u->sink))) { pa_sink_detach(u->sink); - + pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_SET_MASTER, NULL, 0, NULL); + } else + u->thread_info.master = NULL; + if (o) { /* If we have a master sink we run our own sink in its thread */ pa_assert(o->sink_input); pa_assert(PA_SINK_OPENED(pa_sink_get_state(o->sink))); - + if (u->thread) { /* If we previously were in NULL mode, let's kill the thread */ pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); @@ -737,44 +801,47 @@ static int update_master(struct userdata *u, struct output *o) { } else { /* We have no master sink, let's create our own thread */ - + pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); u->master = NULL; if (!u->thread) { pa_assert(!u->rtpoll); - + u->rtpoll = pa_rtpoll_new(); pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); pa_sink_set_rtpoll(u->sink, u->rtpoll); - + if (!(u->thread = pa_thread_new(thread_func, u))) { pa_log("Failed to create thread."); return -1; } } - + pa_log_info("No suitable master sink found, going to NULL mode\n"); } /* Now attach everything again */ - if (u->sink && PA_SINK_LINKED(pa_sink_get_state(u->sink))) + if (u->sink && PA_SINK_LINKED(pa_sink_get_state(u->sink))) { + pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_SET_MASTER, u->master, 0, NULL); pa_sink_attach(u->sink); + } else + u->thread_info.master = u->master; return 0; } -static int pick_master(struct userdata *u) { +static int pick_master(struct userdata *u, struct output *except) { struct output *o; uint32_t idx; pa_assert(u); - if (u->master && u->master->sink_input && PA_SINK_OPENED(pa_sink_get_state(u->master->sink))) + if (u->master && u->master != except && u->master->sink_input && PA_SINK_OPENED(pa_sink_get_state(u->master->sink))) return update_master(u, u->master); for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) - if (o->sink_input && PA_SINK_OPENED(pa_sink_get_state(o->sink))) + if (o != except && o->sink_input && PA_SINK_OPENED(pa_sink_get_state(o->sink))) return update_master(u, o); return update_master(u, NULL); @@ -783,12 +850,12 @@ static int pick_master(struct userdata *u) { static int output_create_sink_input(struct userdata *u, struct output *o) { pa_sink_input_new_data data; char *t; - + pa_assert(u); pa_assert(!o->sink_input); t = pa_sprintf_malloc("Simultaneous output on %s", o->sink->description); - + pa_sink_input_new_data_init(&data); data.sink = o->sink; data.driver = __FILE__; @@ -797,14 +864,14 @@ static int output_create_sink_input(struct userdata *u, struct output *o) { pa_sink_input_new_data_set_channel_map(&data, &u->sink->channel_map); data.module = u->module; data.resample_method = u->resample_method; - + o->sink_input = pa_sink_input_new(u->core, &data, PA_SINK_INPUT_VARIABLE_RATE|PA_SINK_INPUT_DONT_MOVE); pa_xfree(t); if (!o->sink_input) return -1; - + o->sink_input->parent.process_msg = sink_input_process_msg; o->sink_input->peek = sink_input_peek_cb; o->sink_input->drop = sink_input_drop_cb; @@ -812,7 +879,7 @@ static int output_create_sink_input(struct userdata *u, struct output *o) { o->sink_input->detach = sink_input_detach_cb; o->sink_input->kill = sink_input_kill_cb; o->sink_input->userdata = o; - + return 0; } @@ -852,7 +919,7 @@ static struct output *output_new(struct userdata *u, pa_sink *sink) { if (PA_SINK_OPENED(pa_sink_get_state(u->sink)) || pa_sink_get_state(u->sink) == PA_SINK_INIT) { pa_sink_suspend(sink, 0); - + if (PA_SINK_OPENED(pa_sink_get_state(sink))) if (output_create_sink_input(u, o) < 0) goto fail; @@ -876,7 +943,7 @@ fail: if (o->outq) pa_asyncmsgq_unref(o->outq); - + pa_xfree(o); } @@ -885,7 +952,7 @@ fail: static pa_hook_result_t sink_new_hook_cb(pa_core *c, pa_sink *s, struct userdata* u) { struct output *o; - + pa_core_assert_ref(c); pa_sink_assert_ref(s); pa_assert(u); @@ -895,25 +962,25 @@ static pa_hook_result_t sink_new_hook_cb(pa_core *c, pa_sink *s, struct userdata return PA_HOOK_OK; pa_log_info("Configuring new sink: %s", s->name); - + if (!(o = output_new(u, s))) { pa_log("Failed to create sink input on sink '%s'.", s->name); return PA_HOOK_OK; } - if (pick_master(u) < 0) + if (pick_master(u, NULL) < 0) pa_module_unload_request(u->module); - + if (o->sink_input) pa_sink_input_put(o->sink_input); - + return PA_HOOK_OK; } static pa_hook_result_t sink_unlink_hook_cb(pa_core *c, pa_sink *s, struct userdata* u) { struct output *o; uint32_t idx; - + pa_assert(c); pa_sink_assert_ref(s); pa_assert(u); @@ -929,12 +996,9 @@ static pa_hook_result_t sink_unlink_hook_cb(pa_core *c, pa_sink *s, struct userd return PA_HOOK_OK; pa_log_info("Unconfiguring sink: %s", s->name); - + output_free(o); - if (pick_master(u) < 0) - pa_module_unload_request(u->module); - return PA_HOOK_OK; } @@ -954,17 +1018,17 @@ static pa_hook_result_t sink_state_changed_hook_cb(pa_core *c, pa_sink *s, struc return PA_HOOK_OK; state = pa_sink_get_state(s); - + if (PA_SINK_OPENED(state) && PA_SINK_OPENED(pa_sink_get_state(u->sink)) && !o->sink_input) { output_create_sink_input(u, o); - if (pick_master(u) < 0) + if (pick_master(u, NULL) < 0) pa_module_unload_request(u->module); if (o->sink_input) pa_sink_input_put(o->sink_input); } - + if (state == PA_SINK_SUSPENDED && o->sink_input) { pa_sink_input_unlink(o->sink_input); pa_sink_input_unref(o->sink_input); @@ -972,7 +1036,7 @@ static pa_hook_result_t sink_state_changed_hook_cb(pa_core *c, pa_sink *s, struc pa_memblockq_flush(o->memblockq); - if (pick_master(u) < 0) + if (pick_master(u, o) < 0) pa_module_unload_request(u->module); } @@ -1010,8 +1074,8 @@ int pa__init(pa_module*m) { m->userdata = u; u->sink = NULL; u->thread_info.master = u->master = NULL; - u->time_event = NULL; - u->adjust_time = DEFAULT_ADJUST_TIME; + u->time_event = NULL; + u->adjust_time = DEFAULT_ADJUST_TIME; pa_thread_mq_init(&u->thread_mq, m->core->mainloop); u->rtpoll = NULL; u->thread = NULL; @@ -1019,7 +1083,7 @@ int pa__init(pa_module*m) { u->resample_method = resample_method; u->outputs = pa_idxset_new(NULL, NULL); pa_timespec_reset(&u->adjust_timestamp); - + if (pa_modargs_get_value_u32(ma, "adjust_time", &u->adjust_time) < 0) { pa_log("Failed to parse adjust_time value"); goto fail; @@ -1037,7 +1101,7 @@ int pa__init(pa_module*m) { pa_log("Invalid master sink '%s'", master_name); goto fail; } - + ss = master_sink->sample_spec; u->automatic = 0; } else { @@ -1060,7 +1124,7 @@ int pa__init(pa_module*m) { pa_log("Invalid channel map."); goto fail; } - + if (ss.channels != map.channels) { pa_log("Channel map and sample specification don't match."); goto fail; @@ -1083,31 +1147,31 @@ int pa__init(pa_module*m) { u->block_size = pa_bytes_per_second(&ss) / 20; /* 50 ms */ if (u->block_size <= 0) u->block_size = pa_frame_size(&ss); - + if (!u->automatic) { const char*split_state; char *n = NULL; pa_assert(slaves); /* The master and slaves have been specified manually */ - + if (!(u->master = output_new(u, master_sink))) { pa_log("Failed to create master sink input on sink '%s'.", master_sink->name); goto fail; } - + split_state = NULL; while ((n = pa_split(slaves, ",", &split_state))) { pa_sink *slave_sink; - + if (!(slave_sink = pa_namereg_get(m->core, n, PA_NAMEREG_SINK, 1)) || slave_sink == u->sink) { pa_log("Invalid slave sink '%s'", n); pa_xfree(n); goto fail; } - + pa_xfree(n); - + if (!output_new(u, slave_sink)) { pa_log("Failed to create slave sink input on sink '%s'.", slave_sink->name); goto fail; @@ -1118,7 +1182,7 @@ int pa__init(pa_module*m) { pa_log_warn("No slave sinks specified."); u->sink_new_slot = NULL; - + } else { pa_sink *s; @@ -1141,13 +1205,13 @@ int pa__init(pa_module*m) { u->sink_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], (pa_hook_cb_t) sink_unlink_hook_cb, u); u->sink_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], (pa_hook_cb_t) sink_state_changed_hook_cb, u); - - if (pick_master(u) < 0) + + if (pick_master(u, NULL) < 0) goto fail; - + /* Activate the sink and the sink inputs */ pa_sink_put(u->sink); - + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) if (o->sink_input) pa_sink_input_put(o->sink_input); @@ -1160,7 +1224,7 @@ int pa__init(pa_module*m) { } pa_modargs_free(ma); - + return 0; fail: @@ -1169,35 +1233,31 @@ fail: pa_modargs_free(ma); pa__done(m); - + return -1; } static void output_free(struct output *o) { pa_assert(o); - if (o->userdata) { - if (o->userdata->sink && PA_SINK_LINKED(pa_sink_get_state(o->userdata->sink))) - pa_asyncmsgq_send(o->userdata->sink->asyncmsgq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_REMOVE_OUTPUT, o, 0, NULL); - else - PA_LLIST_REMOVE(struct output, o->userdata->thread_info.outputs, o); - } + /* Make sure the master points to a different output */ + if (pick_master(o->userdata, o) < 0) + pa_module_unload_request(o->userdata->module); + + if (o->userdata->sink && PA_SINK_LINKED(pa_sink_get_state(o->userdata->sink))) + pa_asyncmsgq_send(o->userdata->sink->asyncmsgq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_REMOVE_OUTPUT, o, 0, NULL); + else + PA_LLIST_REMOVE(struct output, o->userdata->thread_info.outputs, o); pa_assert_se(pa_idxset_remove_by_data(o->userdata->outputs, o, NULL)); - if (o->userdata->master == o) { - /* Make sure the master points to a different output */ - o->userdata->master = NULL; - pick_master(o->userdata); - } - - update_description(o->userdata); - if (o->sink_input) { pa_sink_input_unlink(o->sink_input); pa_sink_input_unref(o->sink_input); } + update_description(o->userdata); + if (o->inq_rtpoll_item) pa_rtpoll_item_free(o->inq_rtpoll_item); @@ -1212,14 +1272,14 @@ static void output_free(struct output *o) { if (o->memblockq) pa_memblockq_free(o->memblockq); - + pa_xfree(o); } void pa__done(pa_module*m) { struct userdata *u; struct output *o; - + pa_assert(m); if (!(u = m->userdata)) @@ -1230,7 +1290,7 @@ void pa__done(pa_module*m) { if (u->sink_unlink_slot) pa_hook_slot_free(u->sink_unlink_slot); - + if (u->sink_state_changed_slot) pa_hook_slot_free(u->sink_state_changed_slot); @@ -1240,7 +1300,7 @@ void pa__done(pa_module*m) { if (u->outputs) { while ((o = pa_idxset_first(u->outputs, NULL))) output_free(o); - + pa_idxset_free(u->outputs, NULL, NULL); } @@ -1250,17 +1310,15 @@ void pa__done(pa_module*m) { } pa_thread_mq_done(&u->thread_mq); - + if (u->sink) pa_sink_unref(u->sink); if (u->rtpoll) pa_rtpoll_free(u->rtpoll); - + if (u->time_event) u->core->mainloop->time_free(u->time_event); - + pa_xfree(u); } - - -- cgit From 3b2835d3345bfe74afb3e811967b966aa9058606 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 20 Sep 2007 22:01:07 +0000 Subject: properly detach/attach when moving sink inputs git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1874 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 81258e7a..409d0260 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -819,12 +819,20 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse if (i->attach) i->attach(i); + /* If you change anything here, make sure to change the + * ghost sink input handling a few lines down at + * PA_SINK_MESSAGE_REMOVE_INPUT_AND_BUFFER, too. */ + return 0; } case PA_SINK_MESSAGE_REMOVE_INPUT: { pa_sink_input *i = PA_SINK_INPUT(userdata); + /* If you change anything here, make sure to change the + * sink input handling a few lines down at + * PA_SINK_MESSAGE_REMOVE_INPUT_AND_BUFFER, too. */ + if (i->detach) i->detach(i); @@ -864,6 +872,12 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse pa_assert(!info->sink_input->thread_info.sync_next); pa_assert(!info->sink_input->thread_info.sync_prev); + if (info->sink_input->detach) + info->sink_input->detach(info->sink_input); + + pa_assert(info->sink_input->thread_info.attached); + info->sink_input->thread_info.attached = FALSE; + if (info->ghost_sink_input) { pa_assert(info->buffer_bytes > 0); pa_assert(info->buffer); @@ -915,6 +929,12 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse if (info->ghost_sink_input) { pa_hashmap_put(s->thread_info.inputs, PA_UINT32_TO_PTR(info->ghost_sink_input->index), pa_sink_input_ref(info->ghost_sink_input)); info->ghost_sink_input->thread_info.sync_prev = info->ghost_sink_input->thread_info.sync_next = NULL; + + pa_assert(!info->ghost_sink_input->thread_info.attached); + info->ghost_sink_input->thread_info.attached = TRUE; + + if (info->ghost_sink_input->attach) + info->ghost_sink_input->attach(info->ghost_sink_input); } return 0; -- cgit From e205bb2555d8c723d0343e97c87c3d82e063c7ff Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 20 Sep 2007 22:01:58 +0000 Subject: don't segfault when the master changes git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1875 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-combine.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 90433e0c..af5ddb1c 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -394,8 +394,6 @@ static void create_master_rtpolls(struct userdata *u) { u->master->sink->rtpoll, PA_RTPOLL_EARLY+1, /* This one has a slightly lower priority than the normal message handling */ k->outq); - - pa_log("1: %p now has rptoll item %p", k, k->outq_rtpoll_item); } } @@ -426,8 +424,6 @@ static void sink_input_attach_cb(pa_sink_input *i) { pa_sink_input_assert_ref(i); pa_assert_se(o = i->userdata); - pa_log("attaching %s", i->sink->name); - if (o->userdata->thread_info.master == o) { create_master_rtpolls(o->userdata); @@ -636,6 +632,14 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse } case SINK_MESSAGE_SET_MASTER: + + if (u->thread_info.master && data != u->thread_info.master) { + + if (u->thread_info.master->sink_input->thread_info.attached) + free_master_rtpolls(u); + + } + if ((u->thread_info.master = data)) { /* There's now a master, and we're being executed in @@ -645,12 +649,8 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse if (u->thread_info.master->sink_input->thread_info.attached) create_master_rtpolls(u); - } else { - - if (u->thread_info.master->sink_input->thread_info.attached) - free_master_rtpolls(u); - } + return 0; case SINK_MESSAGE_ADD_OUTPUT: { @@ -667,20 +667,14 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse u->thread_info.master->sink->rtpoll, PA_RTPOLL_EARLY+1, /* This one has a slightly lower priority than the normal message handling */ op->outq); - - pa_log("2: %p now has rptoll item %p", op, op->outq_rtpoll_item); } - pa_log("Added output %s", op->sink_input->sink->name); - return 0; } case SINK_MESSAGE_REMOVE_OUTPUT: { struct output *op = data; - pa_log("Remove output %s", op->sink_input->sink->name); - PA_LLIST_REMOVE(struct output, u->thread_info.outputs, op); /* Remove the q that leads from this output to the master output */ -- cgit From 29d25ec8d99a362030b9c4bd4ad3f9c4ad6f95c7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 21 Sep 2007 00:14:20 +0000 Subject: add CLAMP macro git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1876 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/macro.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/macro.h b/src/pulsecore/macro.h index d0dff5e1..c6bba437 100644 --- a/src/pulsecore/macro.h +++ b/src/pulsecore/macro.h @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include @@ -72,6 +72,10 @@ static inline size_t pa_page_align(size_t l) { #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif +#ifndef CLAMP +#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) +#endif + /* This type is not intended to be used in exported APIs! Use classic "int" there! */ #ifdef HAVE_STD_BOOL typedef _Bool pa_bool_t; -- cgit From 1fc168b02f9f2ee1b16eeaeee7adcf554c42de64 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 21 Sep 2007 00:16:34 +0000 Subject: clamp sample data to -1 .. 1, before passing it to the plugin; if a control port data specification is left empty, initialize with the default value of the plugin git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1877 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-ladspa-sink.c | 156 ++++++++++++++++++++++++++++++--------- 1 file changed, 123 insertions(+), 33 deletions(-) diff --git a/src/modules/module-ladspa-sink.c b/src/modules/module-ladspa-sink.c index 0ff0ba37..fb6da94f 100644 --- a/src/modules/module-ladspa-sink.c +++ b/src/modules/module-ladspa-sink.c @@ -52,7 +52,7 @@ PA_MODULE_USAGE( "channels= " "rate= " "channel_map= " - "plugin= " + "plugin= " "label= " "control=") @@ -61,7 +61,7 @@ PA_MODULE_USAGE( struct userdata { pa_core *core; pa_module *module; - + pa_sink *sink, *master; pa_sink_input *sink_input; @@ -92,7 +92,7 @@ static const char* const valid_modargs[] = { /* Called from I/O thread context */ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { struct userdata *u = PA_SINK(o)->userdata; - + switch (code) { case PA_SINK_MESSAGE_GET_LATENCY: { @@ -100,25 +100,25 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse if (PA_MSGOBJECT(u->master)->process_msg(PA_MSGOBJECT(u->master), PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0) usec = 0; - + *((pa_usec_t*) data) = usec + pa_bytes_to_usec(u->memchunk.length, &u->sink->sample_spec); return 0; } } - + return pa_sink_process_msg(o, code, data, offset, chunk); } /* Called from main context */ static int sink_set_state(pa_sink *s, pa_sink_state_t state) { struct userdata *u; - + pa_sink_assert_ref(s); pa_assert_se(u = s->userdata); if (PA_SINK_LINKED(state) && u->sink_input) pa_sink_input_cork(u->sink_input, state == PA_SINK_SUSPENDED); - + return 0; } @@ -157,14 +157,14 @@ static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chun n = tchunk.length / fs; pa_assert(n > 0); - + u->memchunk.memblock = pa_memblock_new(i->sink->core->mempool, tchunk.length); u->memchunk.index = 0; u->memchunk.length = tchunk.length; - + src = (float*) ((uint8_t*) pa_memblock_acquire(tchunk.memblock) + tchunk.index); dst = (float*) pa_memblock_acquire(u->memchunk.memblock); - + for (c = 0; c < u->channels; c++) { unsigned j; float *p, *q; @@ -172,14 +172,14 @@ static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chun p = src + c; q = u->input; for (j = 0; j < n; j++, p += u->channels, q++) - *q = *p; + *q = CLAMP(*p, -1.0, 1.0); u->descriptor->run(u->handle[c], n); q = u->output; p = dst + c; for (j = 0; j < n; j++, q++, p += u->channels) - *p = *q; + *p = CLAMP(*q, -1.0, 1.0); } pa_memblock_release(tchunk.memblock); @@ -188,9 +188,12 @@ static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chun pa_memblock_unref(tchunk.memblock); } + pa_assert(u->memchunk.length > 0); pa_assert(u->memchunk.memblock); + *chunk = u->memchunk; pa_memblock_ref(chunk->memblock); + return 0; } @@ -203,13 +206,13 @@ static void sink_input_drop_cb(pa_sink_input *i, size_t length) { pa_assert(length > 0); if (u->memchunk.memblock) { - + if (length < u->memchunk.length) { u->memchunk.index += length; u->memchunk.length -= length; return; } - + pa_memblock_unref(u->memchunk.memblock); length -= u->memchunk.length; pa_memchunk_reset(&u->memchunk); @@ -238,7 +241,7 @@ static void sink_input_attach_cb(pa_sink_input *i) { pa_sink_set_asyncmsgq(u->sink, i->sink->asyncmsgq); pa_sink_set_rtpoll(u->sink, i->sink->rtpoll); - + pa_sink_attach_within_thread(u->sink); } @@ -256,7 +259,7 @@ static void sink_input_kill_cb(pa_sink_input *i) { pa_sink_unlink(u->sink); pa_sink_unref(u->sink); u->sink = NULL; - + pa_module_unload_request(u->module); } @@ -274,11 +277,12 @@ int pa__init(pa_module*m) { const LADSPA_Descriptor *d; unsigned long input_port, output_port, p, j, n_control; unsigned c; - + pa_bool_t *use_default = NULL; + pa_assert(m); pa_assert(sizeof(LADSPA_Data) == sizeof(float)); - + if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments."); goto fail; @@ -308,7 +312,7 @@ int pa__init(pa_module*m) { } cdata = pa_modargs_get_value(ma, "control", NULL); - + u = pa_xnew0(struct userdata, 1); u->core = m->core; u->module = m; @@ -358,7 +362,7 @@ int pa__init(pa_module*m) { input_port = output_port = (unsigned long) -1; n_control = 0; - + for (p = 0; p < d->PortCount; p++) { if (LADSPA_IS_PORT_INPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p])) { @@ -370,7 +374,7 @@ int pa__init(pa_module*m) { pa_log("Found audio input port on plugin we cannot handle: %s", d->PortNames[p]); goto fail; } - + } else if (LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_AUDIO(d->PortDescriptors[p])) { if (strcmp(d->PortNames[p], "Output") == 0) { @@ -381,7 +385,7 @@ int pa__init(pa_module*m) { goto fail; } - } else if (LADSPA_IS_PORT_INPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p])) + } else if (LADSPA_IS_PORT_INPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p])) n_control++; else pa_log("Cannot handle type of port %s", d->PortNames[p]); @@ -401,9 +405,9 @@ int pa__init(pa_module*m) { u->output = (LADSPA_Data*) pa_xnew(uint8_t, u->block_size); else u->output = u->input; - + u->channels = ss.channels; - + for (c = 0; c < ss.channels; c++) { if (!(u->handle[c] = d->instantiate(d, ss.rate))) { pa_log("Failed to instantiate plugin %s with label %s for channel %i", plugin, d->Label, c); @@ -423,13 +427,20 @@ int pa__init(pa_module*m) { const char *state = NULL; char *k; unsigned long h; - + u->control = pa_xnew(LADSPA_Data, n_control); + use_default = pa_xnew(pa_bool_t, n_control); p = 0; - + while ((k = pa_split(cdata, ",", &state))) { float f; + if (*k == 0) { + use_default[p++] = TRUE; + pa_xfree(k); + continue; + } + if (pa_atof(k, &f) < 0) { pa_log("Failed to parse control value '%s'", k); pa_xfree(k); @@ -443,6 +454,7 @@ int pa__init(pa_module*m) { goto fail; } + use_default[p] = FALSE; u->control[p++] = f; } @@ -453,15 +465,89 @@ int pa__init(pa_module*m) { h = 0; for (p = 0; p < d->PortCount; p++) { - + LADSPA_PortRangeHintDescriptor hint = d->PortRangeHints[p].HintDescriptor; + if (!LADSPA_IS_PORT_INPUT(d->PortDescriptors[p]) || !LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p])) continue; pa_assert(h < n_control); - + + if (use_default[c]) { + LADSPA_Data lower, upper; + + if (!LADSPA_IS_HINT_HAS_DEFAULT(hint)) { + pa_log("Control port value left empty but plugin defines no default."); + goto fail; + } + + lower = d->PortRangeHints[p].LowerBound; + upper = d->PortRangeHints[p].UpperBound; + + if (LADSPA_IS_HINT_SAMPLE_RATE(hint)) { + lower *= ss.rate; + upper *= ss.rate; + } + + switch (hint & LADSPA_HINT_DEFAULT_MASK) { + + case LADSPA_HINT_DEFAULT_MINIMUM: + u->control[h] = lower; + break; + + case LADSPA_HINT_DEFAULT_MAXIMUM: + u->control[h] = upper; + break; + + case LADSPA_HINT_DEFAULT_LOW: + if (LADSPA_IS_HINT_LOGARITHMIC(hint)) + u->control[h] = exp(log(lower) * 0.75 + log(upper) * 0.25); + else + u->control[h] = lower * 0.75 + upper * 0.25; + break; + + case LADSPA_HINT_DEFAULT_MIDDLE: + if (LADSPA_IS_HINT_LOGARITHMIC(hint)) + u->control[h] = exp(log(lower) * 0.5 + log(upper) * 0.5); + else + u->control[h] = lower * 0.5 + upper * 0.5; + break; + + case LADSPA_HINT_DEFAULT_HIGH: + if (LADSPA_IS_HINT_LOGARITHMIC(hint)) + u->control[h] = exp(log(lower) * 0.25 + log(upper) * 0.75); + else + u->control[h] = lower * 0.25 + upper * 0.75; + break; + + case LADSPA_HINT_DEFAULT_0: + u->control[h] = 0; + break; + + case LADSPA_HINT_DEFAULT_1: + u->control[h] = 1; + break; + + case LADSPA_HINT_DEFAULT_100: + u->control[h] = 100; + break; + + case LADSPA_HINT_DEFAULT_440: + u->control[h] = 440; + break; + + default: + pa_assert_not_reached(); + } + } + + if (LADSPA_IS_HINT_INTEGER(hint)) + u->control[h] = roundf(u->control[h]); + + pa_log_debug("Binding %f to port %s", u->control[h], d->PortNames[p]); + for (c = 0; c < ss.channels; c++) d->connect_port(u->handle[c], p, &u->control[h]); - + h++; } @@ -482,7 +568,7 @@ int pa__init(pa_module*m) { u->sink->set_state = sink_set_state; u->sink->userdata = u; u->sink->flags = PA_SINK_LATENCY|PA_SINK_CAN_SUSPEND; - + pa_sink_set_module(u->sink, m); pa_sink_set_description(u->sink, t = pa_sprintf_malloc("LADSPA on '%s'", master->description)); pa_xfree(t); @@ -514,12 +600,16 @@ int pa__init(pa_module*m) { pa_modargs_free(ma); + pa_xfree(use_default); + return 0; fail: if (ma) pa_modargs_free(ma); + pa_xfree(use_default); + pa__done(m); return -1; @@ -528,7 +618,7 @@ fail: void pa__done(pa_module*m) { struct userdata *u; unsigned c; - + pa_assert(m); if (!(u = m->userdata)) @@ -558,8 +648,8 @@ void pa__done(pa_module*m) { pa_xfree(u->output); pa_xfree(u->input); - + pa_xfree(u->control); - + pa_xfree(u); } -- cgit From c34a2635b20cf72f906999c3ccedf4433ddf96ed Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 21 Sep 2007 13:32:00 +0000 Subject: allow _unlink() functions to be called as many times as people want, even before _put() was called git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1878 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink-input.c | 32 +++++++++++++++++++++++--------- src/pulsecore/sink.c | 34 +++++++++++++++++++++++++--------- src/pulsecore/source-output.c | 31 +++++++++++++++++++++---------- src/pulsecore/source.c | 25 ++++++++++++++++++------- 4 files changed, 87 insertions(+), 35 deletions(-) diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index c06da13f..57c6c601 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -264,10 +264,18 @@ static int sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) { } void pa_sink_input_unlink(pa_sink_input *i) { + pa_bool_t linked; pa_assert(i); - pa_assert(PA_SINK_INPUT_LINKED(i->state)); - pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], i); + /* See pa_sink_unlink() for a couple of comments how this function + * works */ + + pa_sink_input_ref(i); + + linked = PA_SINK_INPUT_LINKED(i->state); + + if (linked) + pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], i); if (i->sync_prev) i->sync_prev->sync_next = i->sync_next; @@ -276,14 +284,16 @@ void pa_sink_input_unlink(pa_sink_input *i) { i->sync_prev = i->sync_next = NULL; - pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, 0, NULL); pa_idxset_remove_by_data(i->sink->core->sink_inputs, i, NULL); - pa_idxset_remove_by_data(i->sink->inputs, i, NULL); - - pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE, i->index); + if (pa_idxset_remove_by_data(i->sink->inputs, i, NULL)) + pa_sink_input_unref(i); - sink_input_set_state(i, PA_SINK_INPUT_UNLINKED); - pa_sink_update_status(i->sink); + if (linked) { + pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, 0, NULL); + sink_input_set_state(i, PA_SINK_INPUT_UNLINKED); + pa_sink_update_status(i->sink); + } else + i->state = PA_SINK_INPUT_UNLINKED; i->peek = NULL; i->drop = NULL; @@ -293,7 +303,11 @@ void pa_sink_input_unlink(pa_sink_input *i) { i->detach = NULL; i->suspend = NULL; - pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST], i); + if (linked) { + pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE, i->index); + pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK_POST], i); + } + i->sink = NULL; pa_sink_input_unref(i); } diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 409d0260..b814f837 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -200,14 +200,26 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state) { } void pa_sink_unlink(pa_sink* s) { + pa_bool_t linked; pa_sink_input *i, *j = NULL; pa_assert(s); - pa_assert(PA_SINK_LINKED(s->state)); - pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK], s); + /* Please note that pa_sink_unlink() does more than simply + * reversing pa_sink_put(). It also undoes the registrations + * already done in pa_sink_new()! */ + + /* All operations here shall be idempotent, i.e. pa_sink_unlink() + * may be called multiple times on the same sink without bad + * effects. */ + + linked = PA_SINK_LINKED(s->state); - pa_namereg_unregister(s->core, s->name); + if (linked) + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK], s); + + if (s->state != PA_SINK_UNLINKED) + pa_namereg_unregister(s->core, s->name); pa_idxset_remove_by_data(s->core->sinks, s, NULL); while ((i = pa_idxset_first(s->inputs, NULL))) { @@ -216,10 +228,10 @@ void pa_sink_unlink(pa_sink* s) { j = i; } - sink_set_state(s, PA_SINK_UNLINKED); - - if (s->monitor_source) - pa_source_unlink(s->monitor_source); + if (linked) + sink_set_state(s, PA_SINK_UNLINKED); + else + s->state = PA_SINK_UNLINKED; s->get_latency = NULL; s->get_volume = NULL; @@ -228,9 +240,13 @@ void pa_sink_unlink(pa_sink* s) { s->get_mute = NULL; s->set_state = NULL; - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_REMOVE, s->index); + if (s->monitor_source) + pa_source_unlink(s->monitor_source); - pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK_POST], s); + if (linked) { + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_REMOVE, s->index); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK_POST], s); + } } static void sink_free(pa_object *o) { diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 34eef8ba..1991613e 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -194,20 +194,29 @@ static int source_output_set_state(pa_source_output *o, pa_source_output_state_t } void pa_source_output_unlink(pa_source_output*o) { + pa_bool_t linked; pa_assert(o); - pa_assert(PA_SOURCE_OUTPUT_LINKED(o->state)); - pa_hook_fire(&o->source->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK], o); + /* See pa_sink_unlink() for a couple of comments how this function + * works */ - pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, 0, NULL); + pa_source_output_ref(o); - pa_idxset_remove_by_data(o->source->core->source_outputs, o, NULL); - pa_idxset_remove_by_data(o->source->outputs, o, NULL); + linked = PA_SOURCE_OUTPUT_LINKED(o->state); - pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_REMOVE, o->index); + if (linked) + pa_hook_fire(&o->source->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK], o); - source_output_set_state(o, PA_SOURCE_OUTPUT_UNLINKED); - pa_source_update_status(o->source); + pa_idxset_remove_by_data(o->source->core->source_outputs, o, NULL); + if (pa_idxset_remove_by_data(o->source->outputs, o, NULL)) + pa_source_output_unref(o); + + if (linked) { + pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_REMOVE_OUTPUT, o, 0, NULL); + source_output_set_state(o, PA_SOURCE_OUTPUT_UNLINKED); + pa_source_update_status(o->source); + } else + o->state = PA_SOURCE_OUTPUT_UNLINKED; o->push = NULL; o->kill = NULL; @@ -216,7 +225,10 @@ void pa_source_output_unlink(pa_source_output*o) { o->detach = NULL; o->suspend = NULL; - pa_hook_fire(&o->source->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK_POST], o); + if (linked) { + pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_REMOVE, o->index); + pa_hook_fire(&o->source->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK_POST], o); + } o->source = NULL; pa_source_output_unref(o); @@ -451,7 +463,6 @@ int pa_source_output_process_msg(pa_msgobject *mo, int code, void *userdata, int return 0; } - } return -1; diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 8f9cbc4a..9745a13e 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -175,14 +175,21 @@ static int source_set_state(pa_source *s, pa_source_state_t state) { } void pa_source_unlink(pa_source *s) { + pa_bool_t linked; pa_source_output *o, *j = NULL; pa_assert(s); - pa_assert(PA_SOURCE_LINKED(s->state)); - pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], s); + /* See pa_sink_unlink() for a couple of comments how this function + * works. */ + + linked = PA_SOURCE_LINKED(s->state); + + if (linked) + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], s); - pa_namereg_unregister(s->core, s->name); + if (s->state != PA_SOURCE_UNLINKED) + pa_namereg_unregister(s->core, s->name); pa_idxset_remove_by_data(s->core->sources, s, NULL); while ((o = pa_idxset_first(s->outputs, NULL))) { @@ -191,7 +198,10 @@ void pa_source_unlink(pa_source *s) { j = o; } - source_set_state(s, PA_SOURCE_UNLINKED); + if (linked) + source_set_state(s, PA_SOURCE_UNLINKED); + else + s->state = PA_SOURCE_UNLINKED; s->get_latency = NULL; s->get_volume = NULL; @@ -200,9 +210,10 @@ void pa_source_unlink(pa_source *s) { s->get_mute = NULL; s->set_state = NULL; - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_REMOVE, s->index); - - pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK_POST], s); + if (linked) { + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_REMOVE, s->index); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK_POST], s); + } } static void source_free(pa_object *o) { -- cgit From f26de8077d02c8bba2ed96b4dfb0e6d9f9a2485b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 22 Sep 2007 00:19:56 +0000 Subject: add test program for the resampler git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1879 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 14 ++- src/tests/resampler-test.c | 227 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 237 insertions(+), 4 deletions(-) create mode 100644 src/tests/resampler-test.c diff --git a/src/Makefile.am b/src/Makefile.am index 21136aac..9b4cb519 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -236,7 +236,8 @@ noinst_PROGRAMS = \ asyncmsgq-test \ queue-test \ rtpoll-test \ - sig2str-test + sig2str-test \ + resampler-test if HAVE_SIGXCPU noinst_PROGRAMS += \ @@ -381,6 +382,11 @@ sig2str_test_LDADD = $(AM_LDADD) libpulsecore.la sig2str_test_CFLAGS = $(AM_CFLAGS) sig2str_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) +resampler_test_SOURCES = tests/resampler-test.c +resampler_test_LDADD = $(AM_LDADD) libpulsecore.la +resampler_test_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS) +resampler_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS) + ################################### # Client library # ################################### @@ -567,10 +573,10 @@ noinst_LTLIBRARIES = libspeex-resampler-fixed.la libspeex-resampler-float.la lib libspeex_resampler_fixed_la_CPPFLAGS = $(AM_CPPFLAGS) -DRANDOM_PREFIX=paspfx -DOUTSIDE_SPEEX -DFIXED_POINT libspeex_resampler_fixed_la_SOURCES = pulsecore/speex/resample.c pulsecore/speex/speex_resampler.h pulsecore/speex/arch.h pulsecore/speex/fixed_generic.h pulsecore/speexwrap.h -libspeex_resampler_float_la_CPPFLAGS = $(AM_CPPFLAGS) -DRANDOM_PREFIX=paspfl -DOUTSIDE_SPEEX +libspeex_resampler_float_la_CPPFLAGS = $(AM_CPPFLAGS) -DRANDOM_PREFIX=paspfl -DOUTSIDE_SPEEX libspeex_resampler_float_la_SOURCES = pulsecore/speex/resample.c pulsecore/speex/speex_resampler.h pulsecore/speex/arch.h -libffmpeg_resampler_la_CPPFLAGS = $(AM_CPPFLAGS) +libffmpeg_resampler_la_CPPFLAGS = $(AM_CPPFLAGS) libffmpeg_resampler_la_SOURCES = pulsecore/ffmpeg/resample2.c pulsecore/ffmpeg/avcodec.h pulsecore/ffmpeg/dsputil.h ################################### @@ -959,7 +965,7 @@ modlibexec_LTLIBRARIES += \ module-simple-protocol-unix.la \ module-http-protocol-unix.la \ module-native-protocol-unix.la \ - module-esound-protocol-unix.la + module-esound-protocol-unix.la endif if HAVE_MKFIFO diff --git a/src/tests/resampler-test.c b/src/tests/resampler-test.c new file mode 100644 index 00000000..e2cf1d8a --- /dev/null +++ b/src/tests/resampler-test.c @@ -0,0 +1,227 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include + +static float swap_float(float a) { + uint32_t *b = (uint32_t*) &a; + *b = UINT32_SWAP(*b); + return a; +} + +static void dump_block(const pa_sample_spec *ss, const pa_memchunk *chunk) { + void *d; + unsigned i; + + d = pa_memblock_acquire(chunk->memblock); + + switch (ss->format) { + + case PA_SAMPLE_U8: + case PA_SAMPLE_ULAW: + case PA_SAMPLE_ALAW: { + uint8_t *u = d; + + for (i = 0; i < chunk->length / pa_frame_size(ss); i++) + printf("0x%02x ", *(u++)); + + break; + } + + case PA_SAMPLE_S16NE: + case PA_SAMPLE_S16RE: { + uint16_t *u = d; + + for (i = 0; i < chunk->length / pa_frame_size(ss); i++) + printf("0x%04x ", *(u++)); + + break; + } + + case PA_SAMPLE_FLOAT32NE: + case PA_SAMPLE_FLOAT32RE: { + float *u = d; + + for (i = 0; i < chunk->length / pa_frame_size(ss); i++) { + printf("%1.3g ", ss->format == PA_SAMPLE_FLOAT32NE ? *u : swap_float(*u)); + u++; + } + + break; + } + + default: + pa_assert_not_reached(); + } + + printf("\n"); + + pa_memblock_release(chunk->memblock); +} + +static pa_memblock* generate_block(pa_mempool *pool, const pa_sample_spec *ss) { + pa_memblock *r; + void *d; + unsigned i; + + pa_assert_se(r = pa_memblock_new(pool, pa_frame_size(ss) * 10)); + d = pa_memblock_acquire(r); + + switch (ss->format) { + + case PA_SAMPLE_U8: + case PA_SAMPLE_ULAW: + case PA_SAMPLE_ALAW: { + uint8_t *u = d; + + u[0] = 0x00; + u[1] = 0xFF; + u[2] = 0x7F; + u[3] = 0x80; + u[4] = 0x9f; + u[5] = 0x3f; + u[6] = 0x1; + u[7] = 0xF0; + u[8] = 0x20; + u[9] = 0x21; + break; + } + + case PA_SAMPLE_S16NE: + case PA_SAMPLE_S16RE: { + uint16_t *u = d; + + u[0] = 0x0000; + u[1] = 0xFFFF; + u[2] = 0x7FFF; + u[3] = 0x8000; + u[4] = 0x9fff; + u[5] = 0x3fff; + u[6] = 0x1; + u[7] = 0xF000; + u[8] = 0x20; + u[9] = 0x21; + break; + } + + case PA_SAMPLE_FLOAT32NE: + case PA_SAMPLE_FLOAT32RE: { + float *u = d; + + u[0] = 0.0; + u[1] = -1.0; + u[2] = 1.0; + u[3] = 4711; + u[4] = 0.222; + u[5] = 0.33; + u[6] = -.3; + u[7] = 99; + u[8] = -0.555; + u[9] = -.123; + + if (ss->format == PA_SAMPLE_FLOAT32RE) + for (i = 0; i < 10; i++) + u[i] = swap_float(u[i]); + + break; + } + + default: + pa_assert_not_reached(); + } + + pa_memblock_release(r); + + return r; +} + +int main(int argc, char *argv[]) { + pa_mempool *pool; + pa_sample_spec a, b; + pa_cvolume v; + + oil_init(); + pa_log_set_maximal_level(PA_LOG_DEBUG); + + pa_assert_se(pool = pa_mempool_new(FALSE)); + + a.channels = b.channels = 1; + a.rate = b.rate = 44100; + + v.channels = a.channels; + v.values[0] = pa_sw_volume_from_linear(0.5); + + for (a.format = 0; a.format < PA_SAMPLE_MAX; a.format ++) { + for (b.format = 0; b.format < PA_SAMPLE_MAX; b.format ++) { + + pa_resampler *forth, *back; + pa_memchunk i, j, k; + + printf("=== %s -> %s -> %s -> /2\n", + pa_sample_format_to_string(a.format), + pa_sample_format_to_string(b.format), + pa_sample_format_to_string(a.format)); + + pa_assert_se(forth = pa_resampler_new(pool, &a, NULL, &b, NULL, PA_RESAMPLER_AUTO, FALSE)); + pa_assert_se(back = pa_resampler_new(pool, &b, NULL, &a, NULL, PA_RESAMPLER_AUTO, FALSE)); + + i.memblock = generate_block(pool, &a); + i.length = pa_memblock_get_length(i.memblock); + i.index = 0; + pa_resampler_run(forth, &i, &j); + pa_resampler_run(back, &j, &k); + + dump_block(&a, &i); + dump_block(&b, &j); + dump_block(&a, &k); + + pa_memblock_unref(j.memblock); + pa_memblock_unref(k.memblock); + + pa_volume_memchunk(&i, &a, &v); + dump_block(&a, &i); + + pa_memblock_unref(i.memblock); + + pa_resampler_free(forth); + pa_resampler_free(back); + } + } + + pa_mempool_free(pool); + + return 0; +} -- cgit From 9db42672d466ceec4f3d69f03e2d72ea18a8d62e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 22 Sep 2007 00:21:08 +0000 Subject: make use of byte swap builtins of gcc if they are available git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1880 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 63 ++++++++++++++++++++++---------------------- src/pulsecore/endianmacros.h | 11 ++++++++ 2 files changed, 43 insertions(+), 31 deletions(-) diff --git a/configure.ac b/configure.ac index d03774ed..0da52533 100644 --- a/configure.ac +++ b/configure.ac @@ -97,13 +97,13 @@ if test "x$GCC" = "xyes" ; then for flag in $DESIRED_FLAGS ; do AC_MSG_CHECKING([whether $CC accepts $flag]) - if test_gcc_flag $flag ; then + if test_gcc_flag $flag ; then CFLAGS="$CFLAGS $flag" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi - done + done fi AC_MSG_CHECKING([whether $CC knows __sync_bool_compare_and_swap()]) @@ -221,6 +221,7 @@ AC_CHECK_HEADERS([windows.h winsock2.h ws2tcpip.h]) # Other AC_CHECK_HEADERS([sys/ioctl.h]) +AC_CHECK_HEADERS([byteswap.h]) #### Typdefs, structures, etc. #### @@ -302,7 +303,7 @@ ACX_PTHREAD AC_MSG_CHECKING([for PTHREAD_PRIO_INHERIT]) AC_LANG_CONFTEST([AC_LANG_SOURCE([[ -#include +#include int main() { int i = PTHREAD_PRIO_INHERIT; }]])]) $PTHREAD_CC conftest.c $PTHREAD_CFLAGS $CFLAGS $PTHREAD_LIBS -o conftest > /dev/null 2> /dev/null ret=$? @@ -397,8 +398,8 @@ fi #### Libsamplerate support (optional) #### -AC_ARG_ENABLE([samplerate], - AC_HELP_STRING([--disable-samplerate], [Disable optional libsamplerate support]), +AC_ARG_ENABLE([samplerate], + AC_HELP_STRING([--disable-samplerate], [Disable optional libsamplerate support]), [ case "${enableval}" in yes) samplerate=yes ;; @@ -432,8 +433,8 @@ AM_CONDITIONAL([HAVE_LIBSAMPLERATE], [test "x$HAVE_LIBSAMPLERATE" = x1]) #### OSS support (optional) #### -AC_ARG_ENABLE([oss], - AC_HELP_STRING([--disable-oss], [Disable optional OSS support]), +AC_ARG_ENABLE([oss], + AC_HELP_STRING([--disable-oss], [Disable optional OSS support]), [ case "${enableval}" in yes) oss=yes ;; @@ -465,8 +466,8 @@ AM_CONDITIONAL([HAVE_OSS], [test "x$HAVE_OSS" = x1]) #### ALSA support (optional) #### -AC_ARG_ENABLE([alsa], - AC_HELP_STRING([--disable-alsa], [Disable optional ALSA support]), +AC_ARG_ENABLE([alsa], + AC_HELP_STRING([--disable-alsa], [Disable optional ALSA support]), [ case "${enableval}" in yes) alsa=yes ;; @@ -493,14 +494,14 @@ else fi AC_SUBST(ASOUNDLIB_CFLAGS) -AC_SUBST(ASOUNDLIB_LIBS) +AC_SUBST(ASOUNDLIB_LIBS) AC_SUBST(HAVE_ALSA) AM_CONDITIONAL([HAVE_ALSA], [test "x$HAVE_ALSA" = x1]) #### Solaris audio support (optional) #### -AC_ARG_ENABLE([solaris], - AC_HELP_STRING([--disable-solaris], [Disable optional Solaris audio support]), +AC_ARG_ENABLE([solaris], + AC_HELP_STRING([--disable-solaris], [Disable optional Solaris audio support]), [ case "${enableval}" in yes) solaris=yes ;; @@ -531,8 +532,8 @@ AM_CONDITIONAL([HAVE_SOLARIS], [test "x$HAVE_SOLARIS" = x1]) #### GLib 2 support (optional) #### -AC_ARG_ENABLE([glib2], - AC_HELP_STRING([--disable-glib2], [Disable optional GLib 2 support]), +AC_ARG_ENABLE([glib2], + AC_HELP_STRING([--disable-glib2], [Disable optional GLib 2 support]), [ case "${enableval}" in yes) glib2=yes ;; @@ -562,8 +563,8 @@ AM_CONDITIONAL([HAVE_GLIB20], [test "x$HAVE_GLIB20" = x1]) #### GConf support (optional) #### -AC_ARG_ENABLE([gconf], - AC_HELP_STRING([--disable-gconf], [Disable optional GConf support]), +AC_ARG_ENABLE([gconf], + AC_HELP_STRING([--disable-gconf], [Disable optional GConf support]), [ case "${enableval}" in yes) gconf=yes ;; @@ -593,8 +594,8 @@ AM_CONDITIONAL([HAVE_GCONF], [test "x$HAVE_GCONF" = x1]) #### Avahi support (optional) #### -AC_ARG_ENABLE([avahi], - AC_HELP_STRING([--disable-avahi], [Disable optional Avahi support]), +AC_ARG_ENABLE([avahi], + AC_HELP_STRING([--disable-avahi], [Disable optional Avahi support]), [ case "${enableval}" in yes) avahi=yes ;; @@ -630,8 +631,8 @@ AC_SUBST(LIBOIL_LIBS) ### JACK (optional) #### -AC_ARG_ENABLE([jack], - AC_HELP_STRING([--disable-jack], [Disable optional JACK support]), +AC_ARG_ENABLE([jack], + AC_HELP_STRING([--disable-jack], [Disable optional JACK support]), [ case "${enableval}" in yes) jack=yes ;; @@ -661,8 +662,8 @@ AM_CONDITIONAL([HAVE_JACK], [test "x$HAVE_JACK" = x1]) #### Async DNS support (optional) #### -AC_ARG_ENABLE([asyncns], - AC_HELP_STRING([--disable-asyncns], [Disable optional Async DNS support]), +AC_ARG_ENABLE([asyncns], + AC_HELP_STRING([--disable-asyncns], [Disable optional Async DNS support]), [ case "${enableval}" in yes) asyncns=yes ;; @@ -696,8 +697,8 @@ fi #### TCP wrappers (optional) #### -AC_ARG_ENABLE([tcpwrap], - AC_HELP_STRING([--disable-tcpwrap], [Disable optional TCP wrappers support]), +AC_ARG_ENABLE([tcpwrap], + AC_HELP_STRING([--disable-tcpwrap], [Disable optional TCP wrappers support]), [ case "${enableval}" in yes) tcpwrap=yes ;; @@ -720,8 +721,8 @@ AC_SUBST(LIBWRAP_LIBS) #### LIRC support (optional) #### -AC_ARG_ENABLE([lirc], - AC_HELP_STRING([--disable-lirc], [Disable optional LIRC support]), +AC_ARG_ENABLE([lirc], + AC_HELP_STRING([--disable-lirc], [Disable optional LIRC support]), [ case "${enableval}" in yes) lirc=yes ;; @@ -746,8 +747,8 @@ AM_CONDITIONAL([HAVE_LIRC], [test "x$HAVE_LIRC" = x1]) #### HAL support (optional) #### -AC_ARG_ENABLE([hal], - AC_HELP_STRING([--disable-hal], [Disable optional HAL support]), +AC_ARG_ENABLE([hal], + AC_HELP_STRING([--disable-hal], [Disable optional HAL support]), [ case "${enableval}" in yes) hal=yes ;; @@ -776,8 +777,8 @@ AM_CONDITIONAL([HAVE_HAL], [test "x$HAVE_HAL" = x1]) #### D-Bus support (optional) #### -AC_ARG_ENABLE([dbus], - AC_HELP_STRING([--disable-dbus], [Disable optional D-Bus support]), +AC_ARG_ENABLE([dbus], + AC_HELP_STRING([--disable-dbus], [Disable optional D-Bus support]), [ case "${enableval}" in yes) dbus=yes ;; @@ -787,7 +788,7 @@ AC_ARG_ENABLE([dbus], ], [dbus=auto]) -if test "x$HAVE_HAL" = x1 ; then +if test "x$HAVE_HAL" = x1 ; then dbus=yes fi diff --git a/src/pulsecore/endianmacros.h b/src/pulsecore/endianmacros.h index a29699b9..e2801c10 100644 --- a/src/pulsecore/endianmacros.h +++ b/src/pulsecore/endianmacros.h @@ -31,10 +31,21 @@ #error "Please include config.h before including this file!" #endif +#ifdef HAVE_BYTESWAP_H +#include +#endif + +#ifdef HAVE_BYTESWAP_H +#define INT16_SWAP(x) ((int16_t) bswap_16((uint16_t) x)) +#define UINT16_SWAP(x) ((uint16_t) bswap_16((uint16_t) x)) +#define INT32_SWAP(x) ((int32_t) bswap_32((uint32_t) x)) +#define UINT32_SWAP(x) ((uint32_t) bswap_32((uint32_t) x)) +#else #define INT16_SWAP(x) ( (int16_t) ( ((uint16_t) x >> 8) | ((uint16_t) x << 8) ) ) #define UINT16_SWAP(x) ( (uint16_t) ( ((uint16_t) x >> 8) | ((uint16_t) x << 8) ) ) #define INT32_SWAP(x) ( (int32_t) ( ((uint32_t) x >> 24) | ((uint32_t) x << 24) | (((uint32_t) x & 0xFF00) << 8) | ((((uint32_t) x) >> 8) & 0xFF00) ) ) #define UINT32_SWAP(x) ( (uint32_t) ( ((uint32_t) x >> 24) | ((uint32_t) x << 24) | (((uint32_t) x & 0xFF00) << 8) | ((((uint32_t) x) >> 8) & 0xFF00) ) ) +#endif #define MAYBE_INT32_SWAP(c,x) ((c) ? INT32_SWAP(x) : x) #define MAYBE_UINT32_SWAP(c,x) ((c) ? UINT32_SWAP(x) : x) -- cgit From d7a0876d7ffdac7e48b0664c20408fd429b41d06 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 22 Sep 2007 00:22:36 +0000 Subject: fix selection of working format git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1881 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/resampler.c | 123 ++++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 60 deletions(-) diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c index c4b8179d..5bbc6bf4 100644 --- a/src/pulsecore/resampler.c +++ b/src/pulsecore/resampler.c @@ -29,7 +29,7 @@ #if HAVE_LIBSAMPLERATE #include -#endif +#endif #include #include @@ -59,7 +59,7 @@ struct pa_resampler { unsigned buf1_samples, buf2_samples, buf3_samples, buf4_samples; pa_sample_format_t work_format; - + pa_convert_func_t to_work_format_func; pa_convert_func_t from_work_format_func; @@ -69,7 +69,7 @@ struct pa_resampler { void (*impl_free)(pa_resampler *r); void (*impl_update_rates)(pa_resampler *r); void (*impl_resample)(pa_resampler *r, const pa_memchunk *in, unsigned in_samples, pa_memchunk *out, unsigned *out_samples); - + struct { /* data specific to the trivial resampler */ unsigned o_counter; unsigned i_counter; @@ -114,7 +114,7 @@ static int (* const init_table[])(pa_resampler*r) = { [PA_RESAMPLER_SRC_SINC_FASTEST] = NULL, [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD] = NULL, [PA_RESAMPLER_SRC_LINEAR] = NULL, -#endif +#endif [PA_RESAMPLER_TRIVIAL] = trivial_init, [PA_RESAMPLER_SPEEX_FLOAT_BASE+0] = speex_init, [PA_RESAMPLER_SPEEX_FLOAT_BASE+1] = speex_init, @@ -178,12 +178,12 @@ pa_resampler* pa_resampler_new( pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates."); resample_method = PA_RESAMPLER_COPY; } - + if (!pa_resample_method_supported(resample_method)) { pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(resample_method)); resample_method = PA_RESAMPLER_AUTO; } - + if (resample_method == PA_RESAMPLER_FFMPEG && variable_rate) { pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'."); resample_method = PA_RESAMPLER_AUTO; @@ -232,27 +232,30 @@ pa_resampler* pa_resampler_new( calc_map_table(r); pa_log_info("Using resampler '%s'", pa_resample_method_to_string(resample_method)); - + if ((resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) || (resample_method == PA_RESAMPLER_FFMPEG)) r->work_format = PA_SAMPLE_S16NE; - else if (resample_method == PA_RESAMPLER_TRIVIAL) { + else if (resample_method == PA_RESAMPLER_TRIVIAL || resample_method == PA_RESAMPLER_COPY) { if (r->map_required || a->format != b->format) { - if (a->format == PA_SAMPLE_FLOAT32NE || a->format == PA_SAMPLE_FLOAT32RE) + if (a->format == PA_SAMPLE_FLOAT32NE || a->format == PA_SAMPLE_FLOAT32RE || + b->format == PA_SAMPLE_FLOAT32NE || b->format == PA_SAMPLE_FLOAT32RE) r->work_format = PA_SAMPLE_FLOAT32NE; else r->work_format = PA_SAMPLE_S16NE; - + } else r->work_format = a->format; - + } else r->work_format = PA_SAMPLE_FLOAT32NE; + pa_log_info("Using %s as working format.", pa_sample_format_to_string(r->work_format)); + r->w_sz = sample_size(r->work_format); - + if (r->i_ss.format == r->work_format) r->to_work_format_func = NULL; else if (r->work_format == PA_SAMPLE_FLOAT32NE) { @@ -302,7 +305,7 @@ void pa_resampler_free(pa_resampler *r) { pa_memblock_unref(r->buf3.memblock); if (r->buf4.memblock) pa_memblock_unref(r->buf4.memblock); - + pa_xfree(r); } @@ -340,7 +343,7 @@ size_t pa_resampler_max_block_size(pa_resampler *r) { size_t block_size_max; pa_sample_spec ss; size_t fs; - + pa_assert(r); block_size_max = pa_mempool_block_size_max(r->mempool); @@ -352,7 +355,7 @@ size_t pa_resampler_max_block_size(pa_resampler *r) { ss.channels = r->o_ss.channels; /* We silently assume that the format enum is ordered by size */ - if (r->o_ss.format > ss.format) + if (r->o_ss.format > ss.format) ss.format = r->o_ss.format; if (r->work_format > ss.format) ss.format = r->work_format; @@ -361,13 +364,13 @@ size_t pa_resampler_max_block_size(pa_resampler *r) { ss.rate = r->o_ss.rate; fs = pa_frame_size(&ss); - + return (((block_size_max/fs + EXTRA_SAMPLES)*r->i_ss.rate)/ss.rate)*r->i_fz; } pa_resample_method_t pa_resampler_get_method(pa_resampler *r) { pa_assert(r); - + return r->resample_method; } @@ -422,7 +425,7 @@ int pa_resample_method_supported(pa_resample_method_t m) { if (m <= PA_RESAMPLER_SRC_LINEAR) return 0; #endif - + return 1; } @@ -446,7 +449,7 @@ pa_resample_method_t pa_parse_resample_method(const char *string) { static void calc_map_table(pa_resampler *r) { unsigned oc; - + pa_assert(r); if (!(r->map_required = (r->i_ss.channels != r->o_ss.channels || !pa_channel_map_equal(&r->i_cm, &r->o_cm)))) @@ -493,7 +496,7 @@ static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input) r->buf1.index = 0; r->buf1.length = r->w_sz * n_samples; - + if (!r->buf1.memblock || r->buf1_samples < n_samples) { if (r->buf1.memblock) pa_memblock_unref(r->buf1.memblock); @@ -534,7 +537,7 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) { r->buf2.index = 0; r->buf2.length = r->w_sz * out_n_samples; - + if (!r->buf2.memblock || r->buf2_samples < out_n_samples) { if (r->buf2.memblock) pa_memblock_unref(r->buf2.memblock); @@ -553,11 +556,11 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) { switch (r->work_format) { case PA_SAMPLE_FLOAT32NE: - + for (oc = 0; oc < r->o_ss.channels; oc++) { unsigned i; static const float one = 1.0; - + for (i = 0; i < PA_CHANNELS_MAX && r->map_table[oc][i] >= 0; i++) oil_vectoradd_f32( (float*) dst + oc, o_skip, @@ -574,7 +577,7 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) { for (oc = 0; oc < r->o_ss.channels; oc++) { unsigned i; static const int16_t one = 1; - + for (i = 0; i < PA_CHANNELS_MAX && r->map_table[oc][i] >= 0; i++) oil_vectoradd_s16( (int16_t*) dst + oc, o_skip, @@ -618,7 +621,7 @@ static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) { r->buf3.index = 0; r->buf3.length = r->w_sz * out_n_samples; - + if (!r->buf3.memblock || r->buf3_samples < out_n_samples) { if (r->buf3.memblock) pa_memblock_unref(r->buf3.memblock); @@ -629,7 +632,7 @@ static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) { r->impl_resample(r, input, in_n_frames, &r->buf3, &out_n_frames); r->buf3.length = out_n_frames * r->w_sz * r->o_ss.channels; - + return &r->buf3; } @@ -650,7 +653,7 @@ static pa_memchunk *convert_from_work_format(pa_resampler *r, pa_memchunk *input r->buf4.index = 0; r->buf4.length = r->o_fz * n_frames; - + if (!r->buf4.memblock || r->buf4_samples < n_samples) { if (r->buf4.memblock) pa_memblock_unref(r->buf4.memblock); @@ -688,7 +691,7 @@ void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) if (buf->length) { buf = convert_from_work_format(r, buf); *out = *buf; - + if (buf == in) pa_memblock_ref(buf->memblock); else @@ -702,14 +705,14 @@ void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) #ifdef HAVE_LIBSAMPLERATE static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) { SRC_DATA data; - + pa_assert(r); pa_assert(input); pa_assert(output); pa_assert(out_n_frames); - + memset(&data, 0, sizeof(data)); - + data.data_in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); data.input_frames = in_n_frames; @@ -736,16 +739,16 @@ static void libsamplerate_update_rates(pa_resampler *r) { static void libsamplerate_free(pa_resampler *r) { pa_assert(r); - + if (r->src.state) src_delete(r->src.state); } static int libsamplerate_init(pa_resampler *r) { int err; - + pa_assert(r); - + if (!(r->src.state = src_new(r->resample_method, r->o_ss.channels, &err))) return -1; @@ -767,7 +770,7 @@ static void speex_resample_float(pa_resampler *r, const pa_memchunk *input, unsi pa_assert(input); pa_assert(output); pa_assert(out_n_frames); - + in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index); @@ -788,7 +791,7 @@ static void speex_resample_int(pa_resampler *r, const pa_memchunk *input, unsign pa_assert(input); pa_assert(output); pa_assert(out_n_frames); - + in = (int16_t*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index); out = (int16_t*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index); @@ -804,7 +807,7 @@ static void speex_resample_int(pa_resampler *r, const pa_memchunk *input, unsign static void speex_update_rates(pa_resampler *r) { pa_assert(r); - if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) + if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) pa_assert_se(paspfx_resampler_set_rate(r->speex.state, r->i_ss.rate, r->o_ss.rate) == 0); else { pa_assert(r->resample_method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FLOAT_MAX); @@ -814,11 +817,11 @@ static void speex_update_rates(pa_resampler *r) { static void speex_free(pa_resampler *r) { pa_assert(r); - + if (!r->speex.state) return; - - if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) + + if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) paspfx_resampler_destroy(r->speex.state); else { pa_assert(r->resample_method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FLOAT_MAX); @@ -828,17 +831,17 @@ static void speex_free(pa_resampler *r) { static int speex_init(pa_resampler *r) { int q, err; - + pa_assert(r); r->impl_free = speex_free; r->impl_update_rates = speex_update_rates; - + if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) { q = r->resample_method - PA_RESAMPLER_SPEEX_FIXED_BASE; pa_log_info("Choosing speex quality setting %i.", q); - + if (!(r->speex.state = paspfx_resampler_init(r->o_ss.channels, r->i_ss.rate, r->o_ss.rate, q, &err))) return -1; @@ -848,7 +851,7 @@ static int speex_init(pa_resampler *r) { q = r->resample_method - PA_RESAMPLER_SPEEX_FLOAT_BASE; pa_log_info("Choosing speex quality setting %i.", q); - + if (!(r->speex.state = paspfl_resampler_init(r->o_ss.channels, r->i_ss.rate, r->o_ss.rate, q, &err))) return -1; @@ -864,35 +867,35 @@ static void trivial_resample(pa_resampler *r, const pa_memchunk *input, unsigned size_t fz; unsigned o_index; void *src, *dst; - + pa_assert(r); pa_assert(input); pa_assert(output); pa_assert(out_n_frames); fz = r->w_sz * r->o_ss.channels; - + src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index; dst = (uint8_t*) pa_memblock_acquire(output->memblock) + output->index; - + for (o_index = 0;; o_index++, r->trivial.o_counter++) { unsigned j; - + j = ((r->trivial.o_counter * r->i_ss.rate) / r->o_ss.rate); j = j > r->trivial.i_counter ? j - r->trivial.i_counter : 0; - + if (j >= in_n_frames) break; pa_assert(o_index * fz < pa_memblock_get_length(output->memblock)); - + oil_memcpy((uint8_t*) dst + fz * o_index, - (uint8_t*) src + fz * j, fz); + (uint8_t*) src + fz * j, fz); } - + pa_memblock_release(input->memblock); pa_memblock_release(output->memblock); - + *out_n_frames = o_index; r->trivial.i_counter += in_n_frames; @@ -929,7 +932,7 @@ static int trivial_init(pa_resampler*r) { static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) { unsigned used_frames = 0, c; - + pa_assert(r); pa_assert(input); pa_assert(output); @@ -1008,9 +1011,9 @@ static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned static void ffmpeg_free(pa_resampler *r) { unsigned c; - + pa_assert(r); - + if (r->ffmpeg.state) av_resample_close(r->ffmpeg.state); @@ -1021,21 +1024,21 @@ static void ffmpeg_free(pa_resampler *r) { static int ffmpeg_init(pa_resampler *r) { unsigned c; - + pa_assert(r); /* We could probably implement different quality levels by * adjusting the filter parameters here. However, ffmpeg * internally only uses these hardcoded values, so let's use them * here for now as well until ffmpeg makes this configurable. */ - + if (!(r->ffmpeg.state = av_resample_init(r->o_ss.rate, r->i_ss.rate, 16, 10, 0, 0.8))) return -1; r->impl_free = ffmpeg_free; r->impl_resample = ffmpeg_resample; - for (c = 0; c < PA_ELEMENTSOF(r->ffmpeg.buf); c++) + for (c = 0; c < PA_ELEMENTSOF(r->ffmpeg.buf); c++) pa_memchunk_reset(&r->ffmpeg.buf[c]); return 0; @@ -1047,7 +1050,7 @@ static int copy_init(pa_resampler *r) { pa_assert(r); pa_assert(r->o_ss.rate == r->i_ss.rate); - + r->impl_free = NULL; r->impl_resample = NULL; r->impl_update_rates = NULL; -- cgit From 78a9ad336bc9f06f3995dac824fb4e1e724d3cdb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 22 Sep 2007 00:25:17 +0000 Subject: - rework volume adjustment code to not require fp - don't hit an assert when we cannot do a volume adjustment, instead, print a warning and go on git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1882 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sample-util.c | 76 ++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 43 deletions(-) diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c index add6608d..248a09b6 100644 --- a/src/pulsecore/sample-util.c +++ b/src/pulsecore/sample-util.c @@ -57,7 +57,7 @@ pa_memblock *pa_silence_memblock_new(pa_mempool *pool, const pa_sample_spec *spe if (length <= 0) length = 1; - + length *= fs; return pa_silence_memblock(pa_memblock_new(pool, length), spec); @@ -173,12 +173,10 @@ size_t pa_mix( if (volume->values[channel] != PA_VOLUME_NORM) sum = (int32_t) (sum * pa_sw_volume_to_linear(volume->values[channel])); - if (sum < -0x8000) sum = -0x8000; - if (sum > 0x7FFF) sum = 0x7FFF; - + sum = CLAMP(sum, -0x8000, 0x7FFF); } - *((int16_t*) data) = sum; + *((int16_t*) data) = (int16_t) sum; data = (uint8_t*) data + sizeof(int16_t); if (++channel >= spec->channels) @@ -222,12 +220,10 @@ size_t pa_mix( if (volume->values[channel] != PA_VOLUME_NORM) sum = (int32_t) (sum * pa_sw_volume_to_linear(volume->values[channel])); - if (sum < -0x8000) sum = -0x8000; - if (sum > 0x7FFF) sum = 0x7FFF; - + sum = CLAMP(sum, -0x8000, 0x7FFF); } - *((int16_t*) data) = INT16_SWAP(sum); + *((int16_t*) data) = INT16_SWAP((int16_t) sum); data = (uint8_t*) data + sizeof(int16_t); if (++channel >= spec->channels) @@ -271,9 +267,7 @@ size_t pa_mix( if (volume->values[channel] != PA_VOLUME_NORM) sum = (int32_t) (sum * pa_sw_volume_to_linear(volume->values[channel])); - if (sum < -0x80) sum = -0x80; - if (sum > 0x7F) sum = 0x7F; - + sum = CLAMP(sum, -0x80, 0x7F); } *((uint8_t*) data) = (uint8_t) (sum + 0x80); @@ -368,23 +362,22 @@ void pa_volume_memchunk( ptr = pa_memblock_acquire(c->memblock); switch (spec->format) { + case PA_SAMPLE_S16NE: { int16_t *d; size_t n; unsigned channel; - double linear[PA_CHANNELS_MAX]; + int32_t linear[PA_CHANNELS_MAX]; for (channel = 0; channel < spec->channels; channel++) - linear[channel] = pa_sw_volume_to_linear(volume->values[channel]); + linear[channel] = (int32_t) (pa_sw_volume_to_linear(volume->values[channel]) * 0x10000); for (channel = 0, d = (int16_t*) ((uint8_t*) ptr + c->index), n = c->length/sizeof(int16_t); n > 0; d++, n--) { - int32_t t = (int32_t)(*d); - - t = (int32_t) (t * linear[channel]); - - if (t < -0x8000) t = -0x8000; - if (t > 0x7FFF) t = 0x7FFF; + int32_t t; + t = (int32_t)(*d); + t = (t * linear[channel]) / 0x10000; + t = CLAMP(t, -0x8000, 0x7FFF); *d = (int16_t) t; if (++channel >= spec->channels) @@ -397,19 +390,17 @@ void pa_volume_memchunk( int16_t *d; size_t n; unsigned channel; - double linear[PA_CHANNELS_MAX]; + int32_t linear[PA_CHANNELS_MAX]; for (channel = 0; channel < spec->channels; channel++) - linear[channel] = pa_sw_volume_to_linear(volume->values[channel]); + linear[channel] = (int32_t) (pa_sw_volume_to_linear(volume->values[channel]) * 0x10000); for (channel = 0, d = (int16_t*) ((uint8_t*) ptr + c->index), n = c->length/sizeof(int16_t); n > 0; d++, n--) { - int32_t t = (int32_t)(INT16_SWAP(*d)); - - t = (int32_t) (t * linear[channel]); - - if (t < -0x8000) t = -0x8000; - if (t > 0x7FFF) t = 0x7FFF; + int32_t t; + t = (int32_t)(INT16_SWAP(*d)); + t = (t * linear[channel]) / 0x10000; + t = CLAMP(t, -0x8000, 0x7FFF); *d = INT16_SWAP((int16_t) t); if (++channel >= spec->channels) @@ -422,16 +413,18 @@ void pa_volume_memchunk( case PA_SAMPLE_U8: { uint8_t *d; size_t n; - unsigned channel = 0; - - for (d = (uint8_t*) ptr + c->index, n = c->length; n > 0; d++, n--) { - int32_t t = (int32_t) *d - 0x80; + unsigned channel; + int32_t linear[PA_CHANNELS_MAX]; - t = (int32_t) (t * pa_sw_volume_to_linear(volume->values[channel])); + for (channel = 0; channel < spec->channels; channel++) + linear[channel] = (int32_t) (pa_sw_volume_to_linear(volume->values[channel]) * 0x10000); - if (t < -0x80) t = -0x80; - if (t > 0x7F) t = 0x7F; + for (channel = 0, d = (uint8_t*) ptr + c->index, n = c->length; n > 0; d++, n--) { + int32_t t; + t = (int32_t) *d - 0x80; + t = (t * linear[channel]) / 0x10000; + t = CLAMP(t, -0x80, 0x7F); *d = (uint8_t) (t + 0x80); if (++channel >= spec->channels) @@ -457,7 +450,6 @@ void pa_volume_memchunk( continue; v = (float) pa_sw_volume_to_linear(volume->values[channel]); - t = d + channel; oil_scalarmult_f32(t, skip, t, skip, &v, n); } @@ -465,9 +457,8 @@ void pa_volume_memchunk( } default: - pa_log_error("ERROR: Unable to change volume of format %s.", - pa_sample_format_to_string(spec->format)); - abort(); + pa_log_warn(" Unable to change volume of format %s.", pa_sample_format_to_string(spec->format)); + /* If we cannot change the volume, we just don't do it */ } pa_memblock_release(c->memblock); @@ -477,7 +468,7 @@ size_t pa_frame_align(size_t l, const pa_sample_spec *ss) { size_t fs; pa_assert(ss); - + fs = pa_frame_size(ss); return (l/fs) * fs; @@ -485,11 +476,10 @@ size_t pa_frame_align(size_t l, const pa_sample_spec *ss) { int pa_frame_aligned(size_t l, const pa_sample_spec *ss) { size_t fs; - + pa_assert(ss); fs = pa_frame_size(ss); - + return l % fs == 0; } - -- cgit From 668340099c1ebc6d3d28bf04dce5249ee28b223a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 22 Sep 2007 00:26:18 +0000 Subject: rework a couple of sample type converters, to actually work git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1883 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sconv-s16le.c | 23 ++--------------------- src/pulsecore/sconv.c | 38 ++++++++++++++------------------------ 2 files changed, 16 insertions(+), 45 deletions(-) diff --git a/src/pulsecore/sconv-s16le.c b/src/pulsecore/sconv-s16le.c index c82708ca..86b37295 100644 --- a/src/pulsecore/sconv-s16le.c +++ b/src/pulsecore/sconv-s16le.c @@ -82,12 +82,7 @@ void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, int16_t *b) { int16_t s; float v = *(a++); - if (v > 1) - v = 1; - - if (v < -1) - v = -1; - + v = CLAMP(v, -1, 1); s = (int16_t) (v * 0x7FFF); *(b++) = INT16_TO(s); } @@ -104,8 +99,6 @@ void pa_sconv_s16le_to_float32re(unsigned n, const int16_t *a, float *b) { pa_assert(a); pa_assert(b); -#if SWAP_WORDS == 1 - for (; n > 0; n--) { int16_t s = *(a++); float k = ((float) INT16_FROM(s))/0x7FFF; @@ -113,31 +106,19 @@ void pa_sconv_s16le_to_float32re(unsigned n, const int16_t *a, float *b) { *j = UINT32_SWAP(*j); *(b++) = k; } - -#endif } void pa_sconv_s16le_from_float32re(unsigned n, const float *a, int16_t *b) { pa_assert(a); pa_assert(b); -#if SWAP_WORDS == 1 - for (; n > 0; n--) { int16_t s; float v = *(a++); uint32_t *j = (uint32_t*) &v; *j = UINT32_SWAP(*j); - - if (v > 1) - v = 1; - - if (v < -1) - v = -1; - + v = CLAMP(v, -1, 1); s = (int16_t) (v * 0x7FFF); *(b++) = INT16_TO(s); } - -#endif } diff --git a/src/pulsecore/sconv.c b/src/pulsecore/sconv.c index 4986ba7c..933192b6 100644 --- a/src/pulsecore/sconv.c +++ b/src/pulsecore/sconv.c @@ -43,7 +43,7 @@ /* u8 */ static void u8_to_float32ne(unsigned n, const uint8_t *a, float *b) { - static const double add = -128.0/127.0, factor = 1.0/127.0; + static const double add = -1, factor = 1.0/128.0; pa_assert(a); pa_assert(b); @@ -52,7 +52,7 @@ static void u8_to_float32ne(unsigned n, const uint8_t *a, float *b) { } static void u8_from_float32ne(unsigned n, const float *a, uint8_t *b) { - static const double add = 128.0, factor = 127.0; + static const double add = 128, factor = 127.0; pa_assert(a); pa_assert(b); @@ -61,7 +61,7 @@ static void u8_from_float32ne(unsigned n, const float *a, uint8_t *b) { } static void u8_to_s16ne(unsigned n, const uint8_t *a, int16_t *b) { - static const int16_t add = -128, factor = 0x100; + static const int16_t add = -0x80, factor = 0x100; pa_assert(a); pa_assert(b); @@ -75,8 +75,8 @@ static void u8_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) { pa_assert(a); pa_assert(b); - - for (; n > 0; n--, a ++, a++) + + for (; n > 0; n--, a++, b++) *b = (uint8_t) (*a / 0x100 + 0x80); } @@ -121,7 +121,7 @@ static void ulaw_to_float32ne(unsigned n, const uint8_t *a, float *b) { pa_assert(b); for (; n > 0; n--) - *(b++) = st_ulaw2linear16(*(a++)) * 1.0F / 0x7FFF; + *(b++) = (float) st_ulaw2linear16(*(a++)) / 0x8000; } static void ulaw_from_float32ne(unsigned n, const float *a, uint8_t *b) { @@ -130,14 +130,9 @@ static void ulaw_from_float32ne(unsigned n, const float *a, uint8_t *b) { for (; n > 0; n--) { float v = *(a++); - - if (v > 1) - v = 1; - - if (v < -1) - v = -1; - - *(b++) = st_14linear2ulaw((int16_t) (v * 0x1FFF)); + v = CLAMP(v, -1, 1); + v *= 0x1FFF; + *(b++) = st_14linear2ulaw((int16_t) v); } } @@ -164,7 +159,7 @@ static void alaw_to_float32ne(unsigned n, const uint8_t *a, float *b) { pa_assert(b); for (; n > 0; n--, a++, b++) - *b = st_alaw2linear16(*a) * 1.0F / 0x7FFF; + *b = (float) st_alaw2linear16(*a) / 0x8000; } static void alaw_from_float32ne(unsigned n, const float *a, uint8_t *b) { @@ -173,14 +168,9 @@ static void alaw_from_float32ne(unsigned n, const float *a, uint8_t *b) { for (; n > 0; n--, a++, b++) { float v = *a; - - if (v > 1) - v = 1; - - if (v < -1) - v = -1; - - *b = st_13linear2alaw((int16_t) (v * 0xFFF)); + v = CLAMP(v, -1, 1); + v *= 0xFFF; + *b = st_13linear2alaw((int16_t) v); } } @@ -196,7 +186,7 @@ static void alaw_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) { pa_assert(a); pa_assert(b); - for (; n > 0; n--) + for (; n > 0; n--, a++, b++) *b = st_13linear2alaw(*a >> 3); } -- cgit From c6b43bf119d59b05cc270027080bd616b560db1b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 22 Sep 2007 01:16:14 +0000 Subject: prefix by order macros with PA_ git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1884 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/endianmacros.h | 71 ++++++++++++++++---------------- src/pulsecore/esound.h | 2 +- src/pulsecore/protocol-esound.c | 90 ++++++++++++++++++++--------------------- src/pulsecore/sample-util.c | 8 ++-- src/pulsecore/sconv-s16be.c | 4 +- src/pulsecore/sconv-s16le.c | 8 ++-- src/pulsecore/sconv.c | 4 +- src/tests/resampler-test.c | 2 +- 8 files changed, 96 insertions(+), 93 deletions(-) diff --git a/src/pulsecore/endianmacros.h b/src/pulsecore/endianmacros.h index e2801c10..8f7cfade 100644 --- a/src/pulsecore/endianmacros.h +++ b/src/pulsecore/endianmacros.h @@ -36,56 +36,59 @@ #endif #ifdef HAVE_BYTESWAP_H -#define INT16_SWAP(x) ((int16_t) bswap_16((uint16_t) x)) -#define UINT16_SWAP(x) ((uint16_t) bswap_16((uint16_t) x)) -#define INT32_SWAP(x) ((int32_t) bswap_32((uint32_t) x)) -#define UINT32_SWAP(x) ((uint32_t) bswap_32((uint32_t) x)) +#define PA_INT16_SWAP(x) ((int16_t) bswap_16((uint16_t) x)) +#define PA_UINT16_SWAP(x) ((uint16_t) bswap_16((uint16_t) x)) +#define PA_INT32_SWAP(x) ((int32_t) bswap_32((uint32_t) x)) +#define PA_UINT32_SWAP(x) ((uint32_t) bswap_32((uint32_t) x)) #else -#define INT16_SWAP(x) ( (int16_t) ( ((uint16_t) x >> 8) | ((uint16_t) x << 8) ) ) -#define UINT16_SWAP(x) ( (uint16_t) ( ((uint16_t) x >> 8) | ((uint16_t) x << 8) ) ) -#define INT32_SWAP(x) ( (int32_t) ( ((uint32_t) x >> 24) | ((uint32_t) x << 24) | (((uint32_t) x & 0xFF00) << 8) | ((((uint32_t) x) >> 8) & 0xFF00) ) ) -#define UINT32_SWAP(x) ( (uint32_t) ( ((uint32_t) x >> 24) | ((uint32_t) x << 24) | (((uint32_t) x & 0xFF00) << 8) | ((((uint32_t) x) >> 8) & 0xFF00) ) ) +#define PA_INT16_SWAP(x) ( (int16_t) ( ((uint16_t) x >> 8) | ((uint16_t) x << 8) ) ) +#define PA_UINT16_SWAP(x) ( (uint16_t) ( ((uint16_t) x >> 8) | ((uint16_t) x << 8) ) ) +#define PA_INT32_SWAP(x) ( (int32_t) ( ((uint32_t) x >> 24) | ((uint32_t) x << 24) | (((uint32_t) x & 0xFF00) << 8) | ((((uint32_t) x) >> 8) & 0xFF00) ) ) +#define PA_UINT32_SWAP(x) ( (uint32_t) ( ((uint32_t) x >> 24) | ((uint32_t) x << 24) | (((uint32_t) x & 0xFF00) << 8) | ((((uint32_t) x) >> 8) & 0xFF00) ) ) #endif -#define MAYBE_INT32_SWAP(c,x) ((c) ? INT32_SWAP(x) : x) -#define MAYBE_UINT32_SWAP(c,x) ((c) ? UINT32_SWAP(x) : x) +#define PA_MAYBE_INT16_SWAP(c,x) ((c) ? PA_INT32_SWAP(x) : x) +#define PA_MAYBE_UINT16_SWAP(c,x) ((c) ? PA_UINT32_SWAP(x) : x) + +#define PA_MAYBE_INT32_SWAP(c,x) ((c) ? PA_INT32_SWAP(x) : x) +#define PA_MAYBE_UINT32_SWAP(c,x) ((c) ? PA_UINT32_SWAP(x) : x) #ifdef WORDS_BIGENDIAN - #define INT16_FROM_LE(x) INT16_SWAP(x) - #define INT16_FROM_BE(x) ((int16_t)(x)) + #define PA_INT16_FROM_LE(x) PA_INT16_SWAP(x) + #define PA_INT16_FROM_BE(x) ((int16_t)(x)) - #define INT16_TO_LE(x) INT16_SWAP(x) - #define INT16_TO_BE(x) ((int16_t)(x)) + #define PA_INT16_TO_LE(x) PA_INT16_SWAP(x) + #define PA_INT16_TO_BE(x) ((int16_t)(x)) - #define UINT16_FROM_LE(x) UINT16_SWAP(x) - #define UINT16_FROM_BE(x) ((uint16_t)(x)) + #define PA_UINT16_FROM_LE(x) PA_UINT16_SWAP(x) + #define PA_UINT16_FROM_BE(x) ((uint16_t)(x)) - #define INT32_FROM_LE(x) INT32_SWAP(x) - #define INT32_FROM_BE(x) ((int32_t)(x)) + #define PA_INT32_FROM_LE(x) PA_INT32_SWAP(x) + #define PA_INT32_FROM_BE(x) ((int32_t)(x)) - #define UINT32_FROM_LE(x) UINT32_SWAP(x) - #define UINT32_FROM_BE(x) ((uint32_t)(x)) + #define PA_UINT32_FROM_LE(x) PA_UINT32_SWAP(x) + #define PA_UINT32_FROM_BE(x) ((uint32_t)(x)) - #define UINT32_TO_LE(x) UINT32_SWAP(x) - #define UINT32_TO_BE(x) ((uint32_t)(x)) + #define PA_UINT32_TO_LE(x) PA_UINT32_SWAP(x) + #define PA_UINT32_TO_BE(x) ((uint32_t)(x)) #else - #define INT16_FROM_LE(x) ((int16_t)(x)) - #define INT16_FROM_BE(x) INT16_SWAP(x) + #define PA_INT16_FROM_LE(x) ((int16_t)(x)) + #define PA_INT16_FROM_BE(x) PA_INT16_SWAP(x) - #define INT16_TO_LE(x) ((int16_t)(x)) - #define INT16_TO_BE(x) INT16_SWAP(x) + #define PA_INT16_TO_LE(x) ((int16_t)(x)) + #define PA_INT16_TO_BE(x) PA_INT16_SWAP(x) - #define UINT16_FROM_LE(x) ((uint16_t)(x)) - #define UINT16_FROM_BE(x) UINT16_SWAP(x) + #define PA_UINT16_FROM_LE(x) ((uint16_t)(x)) + #define PA_UINT16_FROM_BE(x) PA_UINT16_SWAP(x) - #define INT32_FROM_LE(x) ((int32_t)(x)) - #define INT32_FROM_BE(x) INT32_SWAP(x) + #define PA_INT32_FROM_LE(x) ((int32_t)(x)) + #define PA_INT32_FROM_BE(x) PA_INT32_SWAP(x) - #define UINT32_FROM_LE(x) ((uint32_t)(x)) - #define UINT32_FROM_BE(x) UINT32_SWAP(x) + #define PA_UINT32_FROM_LE(x) ((uint32_t)(x)) + #define PA_UINT32_FROM_BE(x) PA_UINT32_SWAP(x) - #define UINT32_TO_LE(x) ((uint32_t)(x)) - #define UINT32_TO_BE(x) UINT32_SWAP(x) + #define PA_UINT32_TO_LE(x) ((uint32_t)(x)) + #define PA_UINT32_TO_BE(x) PA_UINT32_SWAP(x) #endif #endif diff --git a/src/pulsecore/esound.h b/src/pulsecore/esound.h index 3778a535..ea6a5665 100644 --- a/src/pulsecore/esound.h +++ b/src/pulsecore/esound.h @@ -205,7 +205,7 @@ typedef int esd_client_state_t; /* the endian key is transferred in binary, if it's read into int, */ /* and matches ESD_ENDIAN_KEY (ENDN), then the endianness of the */ /* server and the client match; if it's SWAP_ENDIAN_KEY, swap data */ -#define ESD_SWAP_ENDIAN_KEY (UINT32_SWAP(ESD_ENDIAN_KEY)) +#define ESD_SWAP_ENDIAN_KEY (PA_UINT32_SWAP(ESD_ENDIAN_KEY)) #endif diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c index b6943634..adefaf98 100644 --- a/src/pulsecore/protocol-esound.c +++ b/src/pulsecore/protocol-esound.c @@ -80,7 +80,7 @@ typedef struct connection { pa_msgobject parent; - + uint32_t index; int dead; pa_protocol_esound *protocol; @@ -125,7 +125,7 @@ struct pa_protocol_esound { int public; pa_socket_server *server; pa_idxset *connections; - + char *sink_name, *source_name; unsigned n_player; uint8_t esd_key[ESD_KEY_LEN]; @@ -227,7 +227,7 @@ static void connection_unlink(connection *c) { pa_client_free(c->client); c->client = NULL; } - + if (c->state == ESD_STREAMING_DATA) c->protocol->n_player--; @@ -254,7 +254,7 @@ static void connection_unlink(connection *c) { static void connection_free(pa_object *obj) { connection *c = CONNECTION(obj); pa_assert(c); - + if (c->input_memblockq) pa_memblockq_free(c->input_memblockq); if (c->output_memblockq) @@ -381,11 +381,11 @@ static int esd_proto_stream_play(connection *c, PA_GCC_UNUSED esd_proto_t reques pa_assert(length == (sizeof(int32_t)*2+ESD_NAME_MAX)); memcpy(&format, data, sizeof(int32_t)); - format = MAYBE_INT32_SWAP(c->swap_byte_order, format); + format = PA_MAYBE_INT32_SWAP(c->swap_byte_order, format); data = (const char*) data + sizeof(int32_t); memcpy(&rate, data, sizeof(int32_t)); - rate = MAYBE_INT32_SWAP(c->swap_byte_order, rate); + rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate); data = (const char*) data + sizeof(int32_t); ss.rate = rate; @@ -445,7 +445,7 @@ static int esd_proto_stream_play(connection *c, PA_GCC_UNUSED esd_proto_t reques pa_atomic_store(&c->playback.missing, pa_memblockq_missing(c->input_memblockq)); pa_sink_input_put(c->sink_input); - + return 0; } @@ -462,11 +462,11 @@ static int esd_proto_stream_record(connection *c, esd_proto_t request, const voi pa_assert(length == (sizeof(int32_t)*2+ESD_NAME_MAX)); memcpy(&format, data, sizeof(int32_t)); - format = MAYBE_INT32_SWAP(c->swap_byte_order, format); + format = PA_MAYBE_INT32_SWAP(c->swap_byte_order, format); data = (const char*) data + sizeof(int32_t); memcpy(&rate, data, sizeof(int32_t)); - rate = MAYBE_INT32_SWAP(c->swap_byte_order, rate); + rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate); data = (const char*) data + sizeof(int32_t); ss.rate = rate; @@ -559,7 +559,7 @@ static int esd_proto_get_latency(connection *c, PA_GCC_UNUSED esd_proto_t reques latency = (int) ((usec*44100)/1000000); } - latency = MAYBE_INT32_SWAP(c->swap_byte_order, latency); + latency = PA_MAYBE_INT32_SWAP(c->swap_byte_order, latency); connection_write(c, &latency, sizeof(int32_t)); return 0; } @@ -582,9 +582,9 @@ static int esd_proto_server_info(connection *c, PA_GCC_UNUSED esd_proto_t reques response = 0; connection_write(c, &response, sizeof(int32_t)); - rate = MAYBE_INT32_SWAP(c->swap_byte_order, rate); + rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate); connection_write(c, &rate, sizeof(int32_t)); - format = MAYBE_INT32_SWAP(c->swap_byte_order, format); + format = PA_MAYBE_INT32_SWAP(c->swap_byte_order, format); connection_write(c, &format, sizeof(int32_t)); return 0; @@ -631,7 +631,7 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da } /* id */ - id = MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) (conn->index+1)); + id = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) (conn->index+1)); connection_write(c, &id, sizeof(int32_t)); /* name */ @@ -643,19 +643,19 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da connection_write(c, name, ESD_NAME_MAX); /* rate */ - rate = MAYBE_INT32_SWAP(c->swap_byte_order, rate); + rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate); connection_write(c, &rate, sizeof(int32_t)); /* left */ - lvolume = MAYBE_INT32_SWAP(c->swap_byte_order, lvolume); + lvolume = PA_MAYBE_INT32_SWAP(c->swap_byte_order, lvolume); connection_write(c, &lvolume, sizeof(int32_t)); /*right*/ - rvolume = MAYBE_INT32_SWAP(c->swap_byte_order, rvolume); + rvolume = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rvolume); connection_write(c, &rvolume, sizeof(int32_t)); /*format*/ - format = MAYBE_INT32_SWAP(c->swap_byte_order, format); + format = PA_MAYBE_INT32_SWAP(c->swap_byte_order, format); connection_write(c, &format, sizeof(int32_t)); t -= k; @@ -677,7 +677,7 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da pa_assert(t >= s*2); /* id */ - id = MAYBE_INT32_SWAP(c->swap_byte_order, (int) (ce->index+1)); + id = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int) (ce->index+1)); connection_write(c, &id, sizeof(int32_t)); /* name */ @@ -689,23 +689,23 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da connection_write(c, name, ESD_NAME_MAX); /* rate */ - rate = MAYBE_UINT32_SWAP(c->swap_byte_order, ce->sample_spec.rate); + rate = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, ce->sample_spec.rate); connection_write(c, &rate, sizeof(int32_t)); /* left */ - lvolume = MAYBE_UINT32_SWAP(c->swap_byte_order, (ce->volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM); + lvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, (ce->volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM); connection_write(c, &lvolume, sizeof(int32_t)); /*right*/ - rvolume = MAYBE_UINT32_SWAP(c->swap_byte_order, (ce->volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM); + rvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, (ce->volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM); connection_write(c, &rvolume, sizeof(int32_t)); /*format*/ - format = MAYBE_INT32_SWAP(c->swap_byte_order, format_native2esd(&ce->sample_spec)); + format = PA_MAYBE_INT32_SWAP(c->swap_byte_order, format_native2esd(&ce->sample_spec)); connection_write(c, &format, sizeof(int32_t)); /*length*/ - len = MAYBE_INT32_SWAP(c->swap_byte_order, (int) ce->memchunk.length); + len = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int) ce->memchunk.length); connection_write(c, &len, sizeof(int32_t)); t -= s; @@ -729,15 +729,15 @@ static int esd_proto_stream_pan(connection *c, PA_GCC_UNUSED esd_proto_t request pa_assert(length == sizeof(int32_t)*3); memcpy(&idx, data, sizeof(uint32_t)); - idx = MAYBE_UINT32_SWAP(c->swap_byte_order, idx) - 1; + idx = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, idx) - 1; data = (const char*)data + sizeof(uint32_t); memcpy(&lvolume, data, sizeof(uint32_t)); - lvolume = MAYBE_UINT32_SWAP(c->swap_byte_order, lvolume); + lvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, lvolume); data = (const char*)data + sizeof(uint32_t); memcpy(&rvolume, data, sizeof(uint32_t)); - rvolume = MAYBE_UINT32_SWAP(c->swap_byte_order, rvolume); + rvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, rvolume); data = (const char*)data + sizeof(uint32_t); if ((conn = pa_idxset_get_by_index(c->protocol->connections, idx)) && conn->sink_input) { @@ -766,11 +766,11 @@ static int esd_proto_sample_cache(connection *c, PA_GCC_UNUSED esd_proto_t reque pa_assert(length == (ESD_NAME_MAX+3*sizeof(int32_t))); memcpy(&format, data, sizeof(int32_t)); - format = MAYBE_INT32_SWAP(c->swap_byte_order, format); + format = PA_MAYBE_INT32_SWAP(c->swap_byte_order, format); data = (const char*)data + sizeof(int32_t); memcpy(&rate, data, sizeof(int32_t)); - rate = MAYBE_INT32_SWAP(c->swap_byte_order, rate); + rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate); data = (const char*)data + sizeof(int32_t); ss.rate = rate; @@ -779,7 +779,7 @@ static int esd_proto_sample_cache(connection *c, PA_GCC_UNUSED esd_proto_t reque CHECK_VALIDITY(pa_sample_spec_valid(&ss), "Invalid sample specification."); memcpy(&sc_length, data, sizeof(int32_t)); - sc_length = MAYBE_INT32_SWAP(c->swap_byte_order, sc_length); + sc_length = PA_MAYBE_INT32_SWAP(c->swap_byte_order, sc_length); data = (const char*)data + sizeof(int32_t); CHECK_VALIDITY(sc_length <= MAX_CACHE_SAMPLE_SIZE, "Sample too large (%d bytes).", (int)sc_length); @@ -842,7 +842,7 @@ static int esd_proto_sample_free_or_play(connection *c, esd_proto_t request, con pa_assert(length == sizeof(int32_t)); memcpy(&idx, data, sizeof(uint32_t)); - idx = MAYBE_UINT32_SWAP(c->swap_byte_order, idx) - 1; + idx = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, idx) - 1; ok = 0; @@ -884,7 +884,7 @@ static int esd_proto_standby_or_resume(connection *c, PA_GCC_UNUSED esd_proto_t static void client_kill_cb(pa_client *c) { pa_assert(c); - + connection_unlink(CONNECTION(c->userdata)); } @@ -907,7 +907,7 @@ static int do_read(connection *c) { if ((c->read_data_length+= r) >= sizeof(c->request)) { struct proto_handler *handler; - c->request = MAYBE_INT32_SWAP(c->swap_byte_order, c->request); + c->request = PA_MAYBE_INT32_SWAP(c->swap_byte_order, c->request); if (c->request < ESD_PROTO_CONNECT || c->request > ESD_PROTO_MAX) { pa_log("recieved invalid request."); @@ -950,7 +950,7 @@ static int do_read(connection *c) { if ((r = pa_iochannel_read(c->io, (uint8_t*) c->read_data + c->read_data_length, handler->data_length - c->read_data_length)) <= 0) { if (errno == EINTR || errno == EAGAIN) return 0; - + pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); return -1; } @@ -976,11 +976,11 @@ static int do_read(connection *c) { p = pa_memblock_acquire(c->scache.memchunk.memblock); r = pa_iochannel_read(c->io, (uint8_t*) p+c->scache.memchunk.index, c->scache.memchunk.length-c->scache.memchunk.index); pa_memblock_release(c->scache.memchunk.memblock); - + if (r <= 0) { if (errno == EINTR || errno == EAGAIN) return 0; - + pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); return -1; } @@ -1038,9 +1038,9 @@ static int do_read(connection *c) { p = pa_memblock_acquire(c->playback.current_memblock); r = pa_iochannel_read(c->io, (uint8_t*) p+c->playback.memblock_index, l); pa_memblock_release(c->playback.current_memblock); - + if (r <= 0) { - + if (errno == EINTR || errno == EAGAIN) return 0; @@ -1074,7 +1074,7 @@ static int do_write(connection *c) { if (errno == EINTR || errno == EAGAIN) return 0; - + pa_log("write(): %s", pa_cstrerror(errno)); return -1; } @@ -1098,12 +1098,12 @@ static int do_write(connection *c) { pa_memblock_release(chunk.memblock); pa_memblock_unref(chunk.memblock); - + if (r < 0) { if (errno == EINTR || errno == EAGAIN) return 0; - + pa_log("write(): %s", pa_cstrerror(errno)); return -1; } @@ -1178,7 +1178,7 @@ static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int6 case CONNECTION_MESSAGE_REQUEST_DATA: do_work(c); break; - + case CONNECTION_MESSAGE_POST_DATA: /* pa_log("got data %u", chunk->length); */ pa_memblockq_push_align(c->output_memblockq, chunk); @@ -1213,7 +1213,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int pa_memblockq_push_align(c->input_memblockq, chunk); /* pa_log("got data, %u", pa_memblockq_get_length(c->input_memblockq)); */ - + return 0; } @@ -1240,7 +1240,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) { connection*c; int r; - + pa_assert(i); c = CONNECTION(i->userdata); connection_assert_ref(c); @@ -1314,7 +1314,7 @@ static pa_usec_t source_output_get_latency_cb(pa_source_output *o) { static void auth_timeout(pa_mainloop_api*m, pa_time_event *e, const struct timeval *tv, void *userdata) { connection *c = CONNECTION(userdata); - + pa_assert(m); pa_assert(tv); connection_assert_ref(c); @@ -1328,7 +1328,7 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) connection *c; pa_protocol_esound *p = userdata; char cname[256], pname[128]; - + pa_assert(s); pa_assert(io); pa_assert(p); diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c index 248a09b6..bc83ac6f 100644 --- a/src/pulsecore/sample-util.c +++ b/src/pulsecore/sample-util.c @@ -208,7 +208,7 @@ size_t pa_mix( if (cvolume == PA_VOLUME_MUTED) v = 0; else { - v = INT16_SWAP(*((int16_t*) ((uint8_t*) streams[i].internal + streams[i].chunk.index + d))); + v = PA_INT16_SWAP(*((int16_t*) ((uint8_t*) streams[i].internal + streams[i].chunk.index + d))); if (cvolume != PA_VOLUME_NORM) v = (int32_t) (v * pa_sw_volume_to_linear(cvolume)); @@ -223,7 +223,7 @@ size_t pa_mix( sum = CLAMP(sum, -0x8000, 0x7FFF); } - *((int16_t*) data) = INT16_SWAP((int16_t) sum); + *((int16_t*) data) = PA_INT16_SWAP((int16_t) sum); data = (uint8_t*) data + sizeof(int16_t); if (++channel >= spec->channels) @@ -398,10 +398,10 @@ void pa_volume_memchunk( for (channel = 0, d = (int16_t*) ((uint8_t*) ptr + c->index), n = c->length/sizeof(int16_t); n > 0; d++, n--) { int32_t t; - t = (int32_t)(INT16_SWAP(*d)); + t = (int32_t)(PA_INT16_SWAP(*d)); t = (t * linear[channel]) / 0x10000; t = CLAMP(t, -0x8000, 0x7FFF); - *d = INT16_SWAP((int16_t) t); + *d = PA_INT16_SWAP((int16_t) t); if (++channel >= spec->channels) channel = 0; diff --git a/src/pulsecore/sconv-s16be.c b/src/pulsecore/sconv-s16be.c index 658b3f5c..f74d0282 100644 --- a/src/pulsecore/sconv-s16be.c +++ b/src/pulsecore/sconv-s16be.c @@ -27,8 +27,8 @@ #include "endianmacros.h" -#define INT16_FROM INT16_FROM_BE -#define INT16_TO INT16_TO_BE +#define INT16_FROM PA_INT16_FROM_BE +#define INT16_TO PA_INT16_TO_BE #define pa_sconv_s16le_to_float32ne pa_sconv_s16be_to_float32ne #define pa_sconv_s16le_from_float32ne pa_sconv_s16be_from_float32ne diff --git a/src/pulsecore/sconv-s16le.c b/src/pulsecore/sconv-s16le.c index 86b37295..6925052c 100644 --- a/src/pulsecore/sconv-s16le.c +++ b/src/pulsecore/sconv-s16le.c @@ -38,11 +38,11 @@ #include "sconv-s16le.h" #ifndef INT16_FROM -#define INT16_FROM INT16_FROM_LE +#define INT16_FROM PA_INT16_FROM_LE #endif #ifndef INT16_TO -#define INT16_TO INT16_TO_LE +#define INT16_TO PA_INT16_TO_LE #endif #ifndef SWAP_WORDS @@ -103,7 +103,7 @@ void pa_sconv_s16le_to_float32re(unsigned n, const int16_t *a, float *b) { int16_t s = *(a++); float k = ((float) INT16_FROM(s))/0x7FFF; uint32_t *j = (uint32_t*) &k; - *j = UINT32_SWAP(*j); + *j = PA_UINT32_SWAP(*j); *(b++) = k; } } @@ -116,7 +116,7 @@ void pa_sconv_s16le_from_float32re(unsigned n, const float *a, int16_t *b) { int16_t s; float v = *(a++); uint32_t *j = (uint32_t*) &v; - *j = UINT32_SWAP(*j); + *j = PA_UINT32_SWAP(*j); v = CLAMP(v, -1, 1); s = (int16_t) (v * 0x7FFF); *(b++) = INT16_TO(s); diff --git a/src/pulsecore/sconv.c b/src/pulsecore/sconv.c index 933192b6..7f5da63f 100644 --- a/src/pulsecore/sconv.c +++ b/src/pulsecore/sconv.c @@ -94,7 +94,7 @@ static void float32re_to_float32ne(unsigned n, const float *a, float *b) { pa_assert(b); for (; n > 0; n--, a++, b++) - *((uint32_t *) b) = UINT32_SWAP(*((uint32_t *) a)); + *((uint32_t *) b) = PA_UINT32_SWAP(*((uint32_t *) a)); } /* s16 */ @@ -111,7 +111,7 @@ static void s16re_to_s16ne(unsigned n, const int16_t *a, int16_t *b) { pa_assert(b); for (; n > 0; n--, a++, b++) - *b = UINT16_SWAP(*a); + *b = PA_UINT16_SWAP(*a); } /* ulaw */ diff --git a/src/tests/resampler-test.c b/src/tests/resampler-test.c index e2cf1d8a..3b4a7386 100644 --- a/src/tests/resampler-test.c +++ b/src/tests/resampler-test.c @@ -38,7 +38,7 @@ static float swap_float(float a) { uint32_t *b = (uint32_t*) &a; - *b = UINT32_SWAP(*b); + *b = PA_UINT32_SWAP(*b); return a; } -- cgit From 6cfb09698a14b4634b447410496424eb0126bfce Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 22 Sep 2007 01:35:32 +0000 Subject: include the name of the master sink in the name for piggy-backed virtual sinks git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1885 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-ladspa-sink.c | 11 +++++++---- src/modules/module-remap-sink.c | 42 ++++++++++++++++++++++------------------ 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/modules/module-ladspa-sink.c b/src/modules/module-ladspa-sink.c index fb6da94f..69195941 100644 --- a/src/modules/module-ladspa-sink.c +++ b/src/modules/module-ladspa-sink.c @@ -56,8 +56,6 @@ PA_MODULE_USAGE( "label= " "control=") -#define DEFAULT_SINK_NAME "ladspa" - struct userdata { pa_core *core; pa_module *module; @@ -278,6 +276,7 @@ int pa__init(pa_module*m) { unsigned long input_port, output_port, p, j, n_control; unsigned c; pa_bool_t *use_default = NULL; + char *default_sink_name = NULL; pa_assert(m); @@ -558,8 +557,10 @@ int pa__init(pa_module*m) { for (c = 0; c < u->channels; c++) d->activate(u->handle[c]); + default_sink_name = pa_sprintf_malloc("%s.ladspa", master->name); + /* Create sink */ - if (!(u->sink = pa_sink_new(m->core, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map))) { + if (!(u->sink = pa_sink_new(m->core, __FILE__, pa_modargs_get_value(ma, "sink_name", default_sink_name), 0, &ss, &map))) { pa_log("Failed to create sink."); goto fail; } @@ -570,7 +571,7 @@ int pa__init(pa_module*m) { u->sink->flags = PA_SINK_LATENCY|PA_SINK_CAN_SUSPEND; pa_sink_set_module(u->sink, m); - pa_sink_set_description(u->sink, t = pa_sprintf_malloc("LADSPA on '%s'", master->description)); + pa_sink_set_description(u->sink, t = pa_sprintf_malloc("LADSPA plugin '%s' on '%s'", label, master->description)); pa_xfree(t); pa_sink_set_asyncmsgq(u->sink, master->asyncmsgq); pa_sink_set_rtpoll(u->sink, master->rtpoll); @@ -601,6 +602,7 @@ int pa__init(pa_module*m) { pa_modargs_free(ma); pa_xfree(use_default); + pa_xfree(default_sink_name); return 0; @@ -609,6 +611,7 @@ fail: pa_modargs_free(ma); pa_xfree(use_default); + pa_xfree(default_sink_name); pa__done(m); diff --git a/src/modules/module-remap-sink.c b/src/modules/module-remap-sink.c index 1d272b18..bff787bc 100644 --- a/src/modules/module-remap-sink.c +++ b/src/modules/module-remap-sink.c @@ -52,12 +52,10 @@ PA_MODULE_USAGE( "rate= " "channel_map=") -#define DEFAULT_SINK_NAME "remapped" - struct userdata { pa_core *core; pa_module *module; - + pa_sink *sink, *master; pa_sink_input *sink_input; @@ -67,7 +65,7 @@ struct userdata { static const char* const valid_modargs[] = { "sink_name", "master", - "master_channel_map", + "master_channel_map", "rate", "format", "channels", @@ -78,7 +76,7 @@ static const char* const valid_modargs[] = { /* Called from I/O thread context */ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { struct userdata *u = PA_SINK(o)->userdata; - + switch (code) { case PA_SINK_MESSAGE_GET_LATENCY: { @@ -86,25 +84,25 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse if (PA_MSGOBJECT(u->master)->process_msg(PA_MSGOBJECT(u->master), PA_SINK_MESSAGE_GET_LATENCY, &usec, 0, NULL) < 0) usec = 0; - + *((pa_usec_t*) data) = usec + pa_bytes_to_usec(u->memchunk.length, &u->sink->sample_spec); return 0; } } - + return pa_sink_process_msg(o, code, data, offset, chunk); } /* Called from main context */ static int sink_set_state(pa_sink *s, pa_sink_state_t state) { struct userdata *u; - + pa_sink_assert_ref(s); pa_assert_se(u = s->userdata); if (PA_SINK_LINKED(state) && u->sink_input) pa_sink_input_cork(u->sink_input, state == PA_SINK_SUSPENDED); - + return 0; } @@ -149,13 +147,13 @@ static void sink_input_drop_cb(pa_sink_input *i, size_t length) { pa_assert(length > 0); if (u->memchunk.memblock) { - + if (length < u->memchunk.length) { u->memchunk.index += length; u->memchunk.length -= length; return; } - + pa_memblock_unref(u->memchunk.memblock); length -= u->memchunk.length; pa_memchunk_reset(&u->memchunk); @@ -184,7 +182,7 @@ static void sink_input_attach_cb(pa_sink_input *i) { pa_sink_set_asyncmsgq(u->sink, i->sink->asyncmsgq); pa_sink_set_rtpoll(u->sink, i->sink->rtpoll); - + pa_sink_attach_within_thread(u->sink); } @@ -202,7 +200,7 @@ static void sink_input_kill_cb(pa_sink_input *i) { pa_sink_unlink(u->sink); pa_sink_unref(u->sink); u->sink = NULL; - + pa_module_unload_request(u->module); } @@ -214,6 +212,7 @@ int pa__init(pa_module*m) { char *t; pa_sink *master; pa_sink_input_new_data data; + char *default_sink_name = NULL; pa_assert(m); @@ -244,7 +243,7 @@ int pa__init(pa_module*m) { pa_log("Number of channels doesn't match"); goto fail; } - + u = pa_xnew0(struct userdata, 1); u->core = m->core; u->module = m; @@ -252,8 +251,10 @@ int pa__init(pa_module*m) { u->master = master; pa_memchunk_reset(&u->memchunk); + default_sink_name = pa_sprintf_malloc("%s.remapped", master->name); + /* Create sink */ - if (!(u->sink = pa_sink_new(m->core, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &sink_map))) { + if (!(u->sink = pa_sink_new(m->core, __FILE__, pa_modargs_get_value(ma, "sink_name", default_sink_name), 0, &ss, &sink_map))) { pa_log("Failed to create sink."); goto fail; } @@ -262,9 +263,9 @@ int pa__init(pa_module*m) { u->sink->set_state = sink_set_state; u->sink->userdata = u; u->sink->flags = PA_SINK_LATENCY|PA_SINK_CAN_SUSPEND; - + pa_sink_set_module(u->sink, m); - pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Remapped sink of '%s'", master->description)); + pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Remapped %s", master->description)); pa_xfree(t); pa_sink_set_asyncmsgq(u->sink, master->asyncmsgq); pa_sink_set_rtpoll(u->sink, master->rtpoll); @@ -273,7 +274,7 @@ int pa__init(pa_module*m) { pa_sink_input_new_data_init(&data); data.sink = u->master; data.driver = __FILE__; - data.name = "Remapped stream"; + data.name = "Remapped Stream"; pa_sink_input_new_data_set_sample_spec(&data, &ss); pa_sink_input_new_data_set_channel_map(&data, &stream_map); data.module = m; @@ -293,6 +294,7 @@ int pa__init(pa_module*m) { pa_sink_input_put(u->sink_input); pa_modargs_free(ma); + pa_xfree(default_sink_name); return 0; @@ -302,12 +304,14 @@ fail: pa__done(m); + pa_xfree(default_sink_name); + return -1; } void pa__done(pa_module*m) { struct userdata *u; - + pa_assert(m); if (!(u = m->userdata)) -- cgit From e04a8576bb113c19a51d026dd30de700b07055c7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 22 Sep 2007 02:00:32 +0000 Subject: minor optimization git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1886 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink-input.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 57c6c601..9360bee0 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -690,7 +690,7 @@ pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i) { } int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { - pa_resampler *new_resampler = NULL; + pa_resampler *new_resampler; pa_sink *origin; pa_usec_t silence_usec = 0; pa_sink_input_move_info info; @@ -739,7 +739,8 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { pa_log_warn("Unsupported resampling operation."); return -1; } - } + } else + new_resampler = NULL; pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE], i); -- cgit From 1c44be2a7b37584bc95dd25930f7f734cef0e5b8 Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Sat, 22 Sep 2007 07:31:29 +0000 Subject: Correct the parameter positions with the pa_cvolume_set() call. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1887 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-match.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/module-match.c b/src/modules/module-match.c index 373ed487..5a922966 100644 --- a/src/modules/module-match.c +++ b/src/modules/module-match.c @@ -182,7 +182,7 @@ static void callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, v if (!regexec(&r->regex, si->name, 0, NULL, 0)) { pa_cvolume cv; pa_log_debug("changing volume of sink input '%s' to 0x%03x", si->name, r->volume); - pa_cvolume_set(&cv, r->volume, si->sample_spec.channels); + pa_cvolume_set(&cv, si->sample_spec.channels, r->volume); pa_sink_input_set_volume(si, &cv); } } -- cgit From ecad93740968fc84b394b138b23351469ef00f9f Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Sat, 22 Sep 2007 08:39:07 +0000 Subject: Fix the assignment of control values by using the right variable for indexing. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1888 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-ladspa-sink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/module-ladspa-sink.c b/src/modules/module-ladspa-sink.c index 69195941..38b7e011 100644 --- a/src/modules/module-ladspa-sink.c +++ b/src/modules/module-ladspa-sink.c @@ -471,7 +471,7 @@ int pa__init(pa_module*m) { pa_assert(h < n_control); - if (use_default[c]) { + if (use_default[h]) { LADSPA_Data lower, upper; if (!LADSPA_IS_HINT_HAS_DEFAULT(hint)) { -- cgit From 7bcbf16e9483ea111d6c708015b5c0154edca1d4 Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Sun, 23 Sep 2007 14:39:39 +0000 Subject: Comment typo fix. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1889 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/resampler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/resampler.h b/src/pulsecore/resampler.h index 8de8ad71..23e1acb7 100644 --- a/src/pulsecore/resampler.h +++ b/src/pulsecore/resampler.h @@ -63,7 +63,7 @@ void pa_resampler_free(pa_resampler *r); /* Returns the size of an input memory block which is required to return the specified amount of output data */ size_t pa_resampler_request(pa_resampler *r, size_t out_length); -/* Requires the maximum size of input blocks we can process without needing bounce buffers larger than the mempool tile size. */ +/* Returns the maximum size of input blocks we can process without needing bounce buffers larger than the mempool tile size. */ size_t pa_resampler_max_block_size(pa_resampler *r); /* Pass the specified memory chunk to the resampler and return the newly resampled data */ -- cgit From de079ac40474fdf845de799b6ced5892282a70fe Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Sun, 23 Sep 2007 14:51:07 +0000 Subject: Added an assertion for the case when the sink programmer hasn't installed the thread_mq properly. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1890 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-native.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 24f5997e..c282c177 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -792,8 +792,10 @@ static void request_bytes(playback_stream *s) { minreq = pa_memblockq_get_minreq(s->memblockq); previous_missing = pa_atomic_add(&s->missing, delta); - if (previous_missing < minreq && previous_missing+delta >= minreq) + if (previous_missing < minreq && previous_missing+delta >= minreq) { + pa_assert(pa_thread_mq_get()); pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); + } } static void send_memblock(connection *c) { -- cgit From 286068526977a9de141a009897accd4393cce894 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 23 Sep 2007 19:23:44 +0000 Subject: use O_NOFOLLOW when creating PID file, to avoid symlink vulnerability git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1891 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/pid.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/pulsecore/pid.c b/src/pulsecore/pid.c index 44f5e84c..38d26814 100644 --- a/src/pulsecore/pid.c +++ b/src/pulsecore/pid.c @@ -88,7 +88,12 @@ static int open_pid_file(const char *fn, int mode) { for (;;) { struct stat st; - if ((fd = open(fn, mode, S_IRUSR|S_IWUSR)) < 0) { + if ((fd = open(fn, mode|O_NOCTTY +#ifdef O_NOFOLLOW + |O_NOFOLLOW +#endif + , S_IRUSR|S_IWUSR + )) < 0) { if (mode != O_RDONLY || errno != ENOENT) pa_log_warn("Failed to open PID file '%s': %s", fn, pa_cstrerror(errno)); goto fail; @@ -184,7 +189,7 @@ int pa_pid_file_create(void) { fail: if (fd >= 0) { pa_lock_fd(fd, 0); - + if (pa_close(fd) < 0) { pa_log("Failed to close PID file '%s': %s", fn, pa_cstrerror(errno)); ret = -1; @@ -204,8 +209,7 @@ int pa_pid_file_remove(void) { pa_runtime_path("pid", fn, sizeof(fn)); if ((fd = open_pid_file(fn, O_RDWR)) < 0) { - pa_log_warn("Failed to open PID file '%s': %s", - fn, pa_cstrerror(errno)); + pa_log_warn("Failed to open PID file '%s': %s", fn, pa_cstrerror(errno)); goto fail; } -- cgit From fc00eaf1d4b854c4dd25edaf25bdb5a800f7827a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 23 Sep 2007 19:30:56 +0000 Subject: use O_NOFOLLOW when creating lock files, too git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1892 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core-util.c | 79 ++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 5532c40a..6db0870b 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -144,7 +144,7 @@ void pa_make_fd_nonblock(int fd) { if (!(v & O_NONBLOCK)) pa_assert_se(fcntl(fd, F_SETFL, v|O_NONBLOCK) >= 0); - + #elif defined(OS_IS_WIN32) u_long arg = 1; if (ioctlsocket(fd, FIONBIO, &arg) < 0) { @@ -521,21 +521,21 @@ void pa_make_realtime(void) { memset(&sp, 0, sizeof(sp)); policy = 0; - + if ((r = pthread_getschedparam(pthread_self(), &policy, &sp)) != 0) { pa_log("pthread_getschedgetparam(): %s", pa_cstrerror(r)); return; } - + sp.sched_priority = 1; if ((r = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sp)) != 0) { pa_log_warn("pthread_setschedparam(): %s", pa_cstrerror(r)); return; } - + pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread."); #endif - + } #define NICE_LEVEL (-11) @@ -629,16 +629,16 @@ const char *pa_sig2str(int sig) { if (sig <= 0) goto fail; - + #ifdef NSIG if (sig >= NSIG) goto fail; #endif - + #ifdef HAVE_SIG2STR { char buf[SIG2STR_MAX]; - + if (str2sig(sig, buf) == 0) { pa_xfree(PA_STATIC_TLS_GET(signame)); t = pa_sprintf_malloc("SIG%s", buf); @@ -703,8 +703,8 @@ const char *pa_sig2str(int sig) { PA_STATIC_TLS_SET(signame, t); return t; } -#endif - +#endif + #endif fail: @@ -943,7 +943,11 @@ int pa_lock_lockfile(const char *fn) { for (;;) { struct stat st; - if ((fd = open(fn, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)) < 0) { + if ((fd = open(fn, O_CREAT|O_RDWR|O_NOCTTY +#ifdef O_NOFOLLOW + |O_NOFOLLOW +#endif + , S_IRUSR|S_IWUSR)) < 0) { pa_log_warn("Failed to create lock file '%s': %s", fn, pa_cstrerror(errno)); goto fail; } @@ -1131,7 +1135,7 @@ static int hexc(char c) { /* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */ size_t pa_parsehex(const char *p, uint8_t *d, size_t dlength) { size_t j = 0; - + pa_assert(p); pa_assert(d); @@ -1226,7 +1230,7 @@ char *pa_runtime_path(const char *fn, char *s, size_t l) { int pa_atoi(const char *s, int32_t *ret_i) { char *x = NULL; long l; - + pa_assert(s); pa_assert(ret_i); @@ -1238,7 +1242,7 @@ int pa_atoi(const char *s, int32_t *ret_i) { if ((int32_t) l != l) return -1; - + *ret_i = (int32_t) l; return 0; @@ -1248,7 +1252,7 @@ int pa_atoi(const char *s, int32_t *ret_i) { int pa_atou(const char *s, uint32_t *ret_u) { char *x = NULL; unsigned long l; - + pa_assert(s); pa_assert(ret_u); @@ -1278,21 +1282,21 @@ int pa_atof(const char *s, float *ret_f) { char *x = NULL; float f; int r = 0; - + pa_assert(s); pa_assert(ret_f); /* This should be locale independent */ - + #ifdef HAVE_STRTOF_L - + PA_ONCE_BEGIN { - + if ((c_locale = newlocale(LC_ALL_MASK, "C", NULL))) atexit(c_locale_destroy); - + } PA_ONCE_END; - + if (c_locale) { errno = 0; f = strtof_l(s, &x, c_locale); @@ -1311,7 +1315,7 @@ int pa_atof(const char *s, float *ret_f) { r = -1; else *ret_f = f; - + return r; } @@ -1323,7 +1327,7 @@ int pa_snprintf(char *str, size_t size, const char *format, ...) { pa_assert(str); pa_assert(size > 0); pa_assert(format); - + va_start(ap, format); ret = vsnprintf(str, size, format, ap); va_end(ap); @@ -1346,13 +1350,13 @@ char *pa_truncate_utf8(char *c, size_t l) { while (l > 0 && !pa_utf8_valid(c)) c[--l] = 0; - + return c; } char *pa_getcwd(void) { size_t l = 128; - + for (;;) { char *p = pa_xnew(char, l); if (getcwd(p, l)) @@ -1369,7 +1373,7 @@ char *pa_getcwd(void) { char *pa_make_path_absolute(const char *p) { char *r; char *cwd; - + pa_assert(p); if (p[0] == '/') @@ -1391,47 +1395,47 @@ void *pa_will_need(const void *p, size_t l) { size_t size; int r; size_t bs; - + pa_assert(p); pa_assert(l > 0); a = PA_PAGE_ALIGN_PTR(p); size = (const uint8_t*) p + l - (const uint8_t*) a; -#ifdef HAVE_POSIX_MADVISE +#ifdef HAVE_POSIX_MADVISE if ((r = posix_madvise((void*) a, size, POSIX_MADV_WILLNEED)) == 0) { pa_log_debug("posix_madvise() worked fine!"); return (void*) p; } #endif - + /* Most likely the memory was not mmap()ed from a file and thus * madvise() didn't work, so let's misuse mlock() do page this * stuff back into RAM. Yeah, let's fuck with the MM! It's so * inviting, the man page of mlock() tells us: "All pages that * contain a part of the specified address range are guaranteed to * be resident in RAM when the call returns successfully." */ - + #ifdef RLIMIT_MEMLOCK pa_assert_se(getrlimit(RLIMIT_MEMLOCK, &rlim) == 0); - + if (rlim.rlim_cur < PA_PAGE_SIZE) { pa_log_debug("posix_madvise() failed (or doesn't exist), resource limits don't allow mlock(), can't page in data: %s", pa_cstrerror(r)); return (void*) p; } - + bs = PA_PAGE_ALIGN(rlim.rlim_cur); #else bs = PA_PAGE_SIZE*4; #endif - + pa_log_debug("posix_madvise() failed (or doesn't exist), trying mlock(): %s", pa_cstrerror(r)); while (size > 0 && bs > 0) { if (bs > size) bs = size; - + if (mlock(a, bs) < 0) { bs = PA_PAGE_ALIGN(bs / 2); continue; @@ -1453,13 +1457,12 @@ void *pa_will_need(const void *p, size_t l) { void pa_close_pipe(int fds[2]) { pa_assert(fds); - + if (fds[0] >= 0) pa_assert_se(pa_close(fds[0]) == 0); - + if (fds[1] >= 0) pa_assert_se(pa_close(fds[1]) == 0); - + fds[0] = fds[1] = -1; } - -- cgit From 77ed60ce4cd02cb4b383ab4d6e9b51701fb03a07 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 23 Sep 2007 21:03:24 +0000 Subject: instead of using the mixer ioctl()s on the dsp fd, open a seperate fd for the mixer. This allows us the keep the mixer fd open while closing the dsp device while suspending. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1893 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-oss.c | 387 +++++++++++++++++++++++++++-------------------- src/modules/oss-util.c | 86 +++++++---- src/modules/oss-util.h | 9 +- 3 files changed, 290 insertions(+), 192 deletions(-) diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 037c4017..358154ac 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -36,8 +36,6 @@ * */ -/* TODO: handle restoring of volume after suspend */ - #ifdef HAVE_CONFIG_H #include #endif @@ -101,13 +99,13 @@ struct userdata { pa_module *module; pa_sink *sink; pa_source *source; - + pa_thread *thread; pa_thread_mq thread_mq; pa_rtpoll *rtpoll; char *device_name; - + pa_memchunk memchunk; size_t frame_size; @@ -115,14 +113,14 @@ struct userdata { int use_getospace, use_getispace; int use_getodelay; - int use_pcm_volume; - int use_input_volume; - int sink_suspended, source_suspended; int fd; int mode; + int mixer_fd; + int mixer_devmask; + int nfrags, frag_size; int use_mmap; @@ -155,7 +153,7 @@ static void trigger(struct userdata *u, int quick) { int enable_bits = 0, zero = 0; pa_assert(u); - + if (u->fd < 0) return; @@ -163,10 +161,10 @@ static void trigger(struct userdata *u, int quick) { if (u->source && PA_SOURCE_OPENED(u->source->thread_info.state)) enable_bits |= PCM_ENABLE_INPUT; - + if (u->sink && PA_SINK_OPENED(u->sink->thread_info.state)) enable_bits |= PCM_ENABLE_OUTPUT; - + if (u->use_mmap) { if (!quick) @@ -177,28 +175,28 @@ static void trigger(struct userdata *u, int quick) { if (ioctl(u->fd, SNDCTL_DSP_HALT, NULL) < 0) pa_log_warn("SNDCTL_DSP_HALT: %s", pa_cstrerror(errno)); #endif - + if (ioctl(u->fd, SNDCTL_DSP_SETTRIGGER, &enable_bits) < 0) pa_log_warn("SNDCTL_DSP_SETTRIGGER: %s", pa_cstrerror(errno)); - + if (u->sink && !(enable_bits & PCM_ENABLE_OUTPUT)) { pa_log_debug("clearing playback buffer"); pa_silence_memory(u->out_mmap, u->out_hwbuf_size, &u->sink->sample_spec); } - + } else { if (enable_bits) if (ioctl(u->fd, SNDCTL_DSP_POST, NULL) < 0) pa_log_warn("SNDCTL_DSP_POST: %s", pa_cstrerror(errno)); - + if (!quick) { /* * Some crappy drivers do not start the recording until we * read something. Without this snippet, poll will never * register the fd as ready. */ - + if (u->source && PA_SOURCE_OPENED(u->source->thread_info.state)) { uint8_t *buf = pa_xnew(uint8_t, u->in_fragment_size); pa_read(u->fd, buf, u->in_fragment_size, NULL); @@ -213,7 +211,7 @@ static void mmap_fill_memblocks(struct userdata *u, unsigned n) { pa_assert(u->out_mmap_memblocks); /* pa_log("Mmmap writing %u blocks", n); */ - + while (n > 0) { pa_memchunk chunk; @@ -242,12 +240,12 @@ static void mmap_fill_memblocks(struct userdata *u, unsigned n) { static int mmap_write(struct userdata *u) { struct count_info info; - + pa_assert(u); pa_assert(u->sink); /* pa_log("Mmmap writing..."); */ - + if (ioctl(u->fd, SNDCTL_DSP_GETOPTR, &info) < 0) { pa_log("SNDCTL_DSP_GETOPTR: %s", pa_cstrerror(errno)); return -1; @@ -258,7 +256,7 @@ static int mmap_write(struct userdata *u) { if (info.blocks > 0) mmap_fill_memblocks(u, info.blocks); - + return info.blocks; } @@ -272,14 +270,14 @@ static void mmap_post_memblocks(struct userdata *u, unsigned n) { pa_memchunk chunk; if (!u->in_mmap_memblocks[u->in_mmap_current]) { - + chunk.memblock = u->in_mmap_memblocks[u->in_mmap_current] = pa_memblock_new_fixed( u->core->mempool, (uint8_t*) u->in_mmap + u->in_fragment_size*u->in_mmap_current, u->in_fragment_size, 1); - + chunk.length = pa_memblock_get_length(chunk.memblock); chunk.index = 0; @@ -296,7 +294,7 @@ static void mmap_post_memblocks(struct userdata *u, unsigned n) { static void mmap_clear_memblocks(struct userdata*u, unsigned n) { unsigned i = u->in_mmap_current; - + pa_assert(u); pa_assert(u->in_mmap_memblocks); @@ -323,7 +321,7 @@ static int mmap_read(struct userdata *u) { pa_assert(u->source); /* pa_log("Mmmap reading..."); */ - + if (ioctl(u->fd, SNDCTL_DSP_GETIPTR, &info) < 0) { pa_log("SNDCTL_DSP_GETIPTR: %s", pa_cstrerror(errno)); return -1; @@ -336,14 +334,14 @@ static int mmap_read(struct userdata *u) { mmap_post_memblocks(u, info.blocks); mmap_clear_memblocks(u, u->in_nfrags/2); } - + return info.blocks; } static pa_usec_t mmap_sink_get_latency(struct userdata *u) { struct count_info info; size_t bpos, n; - + pa_assert(u); if (ioctl(u->fd, SNDCTL_DSP_GETOPTR, &info) < 0) { @@ -391,23 +389,23 @@ static pa_usec_t mmap_source_get_latency(struct userdata *u) { static pa_usec_t io_sink_get_latency(struct userdata *u) { pa_usec_t r = 0; - + pa_assert(u); - + if (u->use_getodelay) { int arg; - + if (ioctl(u->fd, SNDCTL_DSP_GETODELAY, &arg) < 0) { pa_log_info("Device doesn't support SNDCTL_DSP_GETODELAY: %s", pa_cstrerror(errno)); u->use_getodelay = 0; } else r = pa_bytes_to_usec(arg, &u->sink->sample_spec); - + } - + if (!u->use_getodelay && u->use_getospace) { struct audio_buf_info info; - + if (ioctl(u->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) { pa_log_info("Device doesn't support SNDCTL_DSP_GETOSPACE: %s", pa_cstrerror(errno)); u->use_getospace = 0; @@ -424,9 +422,9 @@ static pa_usec_t io_sink_get_latency(struct userdata *u) { static pa_usec_t io_source_get_latency(struct userdata *u) { pa_usec_t r = 0; - + pa_assert(u); - + if (u->use_getispace) { struct audio_buf_info info; @@ -445,7 +443,7 @@ static int suspend(struct userdata *u) { pa_assert(u->fd >= 0); pa_log_info("Suspending..."); - + if (u->out_mmap_memblocks) { unsigned i; for (i = 0; i < u->out_nfrags; i++) @@ -463,12 +461,12 @@ static int suspend(struct userdata *u) { u->in_mmap_memblocks[i] = NULL; } } - + if (u->in_mmap && u->in_mmap != MAP_FAILED) { munmap(u->in_mmap, u->in_hwbuf_size); u->in_mmap = NULL; } - + if (u->out_mmap && u->out_mmap != MAP_FAILED) { munmap(u->out_mmap, u->out_hwbuf_size); u->out_mmap = NULL; @@ -483,9 +481,9 @@ static int suspend(struct userdata *u) { pa_rtpoll_item_free(u->rtpoll_item); u->rtpoll_item = NULL; } - + pa_log_info("Device suspended..."); - + return 0; } @@ -567,7 +565,7 @@ static int unsuspend(struct userdata *u) { goto fail; } - + pa_silence_memory(u->out_mmap, u->out_hwbuf_size, &ss); } } @@ -576,13 +574,18 @@ static int unsuspend(struct userdata *u) { u->out_mmap_saved_nfrags = u->in_mmap_saved_nfrags = 0; pa_assert(!u->rtpoll_item); - + u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1); pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); pollfd->fd = u->fd; pollfd->events = 0; pollfd->revents = 0; + if (u->sink) + pa_sink_get_volume(u->sink); + if (u->source) + pa_source_get_volume(u->source); + pa_log_info("Resumed successfully..."); return 0; @@ -624,29 +627,29 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse if (!u->source || u->source_suspended) { if (suspend(u) < 0) return -1; - } + } do_trigger = 1; u->sink_suspended = 1; break; - + case PA_SINK_IDLE: case PA_SINK_RUNNING: - + if (u->sink->thread_info.state == PA_SINK_SUSPENDED) { - + if (!u->source || u->source_suspended) { - if (unsuspend(u) < 0) + if (unsuspend(u) < 0) return -1; quick = 0; } do_trigger = 1; - + u->out_mmap_current = 0; u->out_mmap_saved_nfrags = 0; - + u->sink_suspended = 0; } @@ -656,41 +659,16 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse case PA_SINK_INIT: ; } - - break; - - case PA_SINK_MESSAGE_SET_VOLUME: - - if (u->use_pcm_volume && u->fd >= 0) { - - if (pa_oss_set_pcm_volume(u->fd, &u->sink->sample_spec, ((pa_cvolume*) data)) < 0) { - pa_log_info("Device doesn't support setting mixer settings: %s", pa_cstrerror(errno)); - u->use_pcm_volume = 0; - } else - return 0; - } break; - case PA_SINK_MESSAGE_GET_VOLUME: - - if (u->use_pcm_volume && u->fd >= 0) { - - if (pa_oss_get_pcm_volume(u->fd, &u->sink->sample_spec, ((pa_cvolume*) data)) < 0) { - pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno)); - u->use_pcm_volume = 0; - } else - return 0; - } - - break; } ret = pa_sink_process_msg(o, code, data, offset, chunk); if (do_trigger) trigger(u, quick); - + return ret; } @@ -709,7 +687,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off else r = io_source_get_latency(u); } - + *((pa_usec_t*) data) = r; return 0; } @@ -721,31 +699,31 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off pa_assert(PA_SOURCE_OPENED(u->source->thread_info.state)); if (!u->sink || u->sink_suspended) { - if (suspend(u) < 0) + if (suspend(u) < 0) return -1; - } + } do_trigger = 1; - + u->source_suspended = 1; break; case PA_SOURCE_IDLE: case PA_SOURCE_RUNNING: - + if (u->source->thread_info.state == PA_SOURCE_SUSPENDED) { if (!u->sink || u->sink_suspended) { - if (unsuspend(u) < 0) + if (unsuspend(u) < 0) return -1; quick = 0; - } + } do_trigger = 1; - + u->in_mmap_current = 0; u->in_mmap_saved_nfrags = 0; - + u->source_suspended = 0; } break; @@ -757,39 +735,94 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off } break; - case PA_SOURCE_MESSAGE_SET_VOLUME: + } - if (u->use_input_volume && u->fd >= 0) { + ret = pa_source_process_msg(o, code, data, offset, chunk); - if (pa_oss_set_input_volume(u->fd, &u->source->sample_spec, ((pa_cvolume*) data)) < 0) { - pa_log_info("Device doesn't support setting mixer settings: %s", pa_cstrerror(errno)); - u->use_input_volume = 0; - } else - return 0; - } + if (do_trigger) + trigger(u, quick); - break; + return ret; +} - case PA_SOURCE_MESSAGE_GET_VOLUME: +static int sink_get_volume(pa_sink *s) { + struct userdata *u; + int r; - if (u->use_input_volume && u->fd >= 0) { + pa_assert_se(u = s->userdata); - if (pa_oss_get_input_volume(u->fd, &u->source->sample_spec, ((pa_cvolume*) data)) < 0) { - pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno)); - u->use_input_volume = 0; - } else - return 0; - } + pa_assert(u->mixer_devmask & (SOUND_MASK_VOLUME|SOUND_MASK_PCM)); - break; - } + if (u->mixer_devmask & SOUND_MASK_VOLUME) + if ((r = pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_VOLUME, &s->sample_spec, &s->volume)) >= 0) + return r; - ret = pa_source_process_msg(o, code, data, offset, chunk); + if (u->mixer_devmask & SOUND_MASK_PCM) + if ((r = pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_PCM, &s->sample_spec, &s->volume)) >= 0) + return r; - if (do_trigger) - trigger(u, quick); + pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno)); + return -1; +} - return ret; +static int sink_set_volume(pa_sink *s) { + struct userdata *u; + int r; + + pa_assert_se(u = s->userdata); + + pa_assert(u->mixer_devmask & (SOUND_MASK_VOLUME|SOUND_MASK_PCM)); + + if (u->mixer_devmask & SOUND_MASK_VOLUME) + if ((r = pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_VOLUME, &s->sample_spec, &s->volume)) >= 0) + return r; + + if (u->mixer_devmask & SOUND_MASK_PCM) + if ((r = pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_WRITE_PCM, &s->sample_spec, &s->volume)) >= 0) + return r; + + pa_log_info("Device doesn't support writing mixer settings: %s", pa_cstrerror(errno)); + return -1; +} + +static int source_get_volume(pa_source *s) { + struct userdata *u; + int r; + + pa_assert_se(u = s->userdata); + + pa_assert(u->mixer_devmask & (SOUND_MASK_IGAIN|SOUND_MASK_RECLEV)); + + if (u->mixer_devmask & SOUND_MASK_IGAIN) + if ((r = pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_IGAIN, &s->sample_spec, &s->volume)) >= 0) + return r; + + if (u->mixer_devmask & SOUND_MASK_RECLEV) + if ((r = pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_RECLEV, &s->sample_spec, &s->volume)) >= 0) + return r; + + pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno)); + return -1; +} + +static int source_set_volume(pa_source *s) { + struct userdata *u; + int r; + + pa_assert_se(u = s->userdata); + + pa_assert(u->mixer_devmask & (SOUND_MASK_IGAIN|SOUND_MASK_RECLEV)); + + if (u->mixer_devmask & SOUND_MASK_IGAIN) + if ((r = pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_IGAIN, &s->sample_spec, &s->volume)) >= 0) + return r; + + if (u->mixer_devmask & SOUND_MASK_RECLEV) + if ((r = pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_WRITE_RECLEV, &s->sample_spec, &s->volume)) >= 0) + return r; + + pa_log_info("Device doesn't support writing mixer settings: %s", pa_cstrerror(errno)); + return -1; } static void thread_func(void *userdata) { @@ -808,12 +841,12 @@ static void thread_func(void *userdata) { pa_rtpoll_install(u->rtpoll); trigger(u, 0); - + for (;;) { int ret; /* pa_log("loop"); */ - + /* Render some data and write it to the dsp */ if (u->sink && u->sink->thread_info.state != PA_SINK_UNLINKED && u->fd >= 0 && (revents & POLLOUT)) { @@ -824,19 +857,19 @@ static void thread_func(void *userdata) { goto fail; revents &= ~POLLOUT; - + if (ret > 0) continue; } else { ssize_t l; int loop = 0; - + l = u->out_fragment_size; - + if (u->use_getospace) { audio_buf_info info; - + if (ioctl(u->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) { pa_log_info("Device doesn't support SNDCTL_DSP_GETOSPACE: %s", pa_cstrerror(errno)); u->use_getospace = 0; @@ -847,59 +880,59 @@ static void thread_func(void *userdata) { } } } - + do { void *p; ssize_t t; - + pa_assert(l > 0); - + if (u->memchunk.length <= 0) pa_sink_render(u->sink, l, &u->memchunk); - + pa_assert(u->memchunk.length > 0); - + p = pa_memblock_acquire(u->memchunk.memblock); t = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length, &write_type); pa_memblock_release(u->memchunk.memblock); - + /* pa_log("wrote %i bytes of %u", t, l); */ - + pa_assert(t != 0); - + if (t < 0) { - + if (errno == EINTR) continue; - + else if (errno == EAGAIN) { - pa_log_debug("EAGAIN"); - + pa_log_debug("EAGAIN"); + revents &= ~POLLOUT; break; - + } else { pa_log("Failed to write data to DSP: %s", pa_cstrerror(errno)); goto fail; } - + } else { - + u->memchunk.index += t; u->memchunk.length -= t; - + if (u->memchunk.length <= 0) { pa_memblock_unref(u->memchunk.memblock); pa_memchunk_reset(&u->memchunk); } - + l -= t; - + revents &= ~POLLOUT; } - + } while (loop && l > 0); - + continue; } } @@ -914,7 +947,7 @@ static void thread_func(void *userdata) { goto fail; revents &= ~POLLIN; - + if (ret > 0) continue; @@ -954,7 +987,7 @@ static void thread_func(void *userdata) { k = l; k = (k/u->frame_size)*u->frame_size; - + p = pa_memblock_acquire(memchunk.memblock); t = pa_read(u->fd, p, k, &read_type); pa_memblock_release(memchunk.memblock); @@ -962,7 +995,7 @@ static void thread_func(void *userdata) { pa_assert(t != 0); /* EOF cannot happen */ /* pa_log("read %i bytes of %u", t, l); */ - + if (t < 0) { pa_memblock_unref(memchunk.memblock); @@ -970,7 +1003,7 @@ static void thread_func(void *userdata) { continue; else if (errno == EAGAIN) { - pa_log_debug("EAGAIN"); + pa_log_debug("EAGAIN"); revents &= ~POLLIN; break; @@ -1007,19 +1040,19 @@ static void thread_func(void *userdata) { ((u->source && PA_SOURCE_OPENED(u->source->thread_info.state)) ? POLLIN : 0) | ((u->sink && PA_SINK_OPENED(u->sink->thread_info.state)) ? POLLOUT : 0); } - + /* Hmm, nothing to do. Let's sleep */ if ((ret = pa_rtpoll_run(u->rtpoll, 1)) < 0) goto fail; if (ret == 0) goto finish; - + if (u->fd >= 0) { struct pollfd *pollfd; - + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); - + if (pollfd->revents & ~(POLLOUT|POLLIN)) { pa_log("DSP shutdown."); goto fail; @@ -1041,7 +1074,7 @@ finish: } int pa__init(pa_module*m) { - + struct audio_buf_info info; struct userdata *u = NULL; const char *dev; @@ -1096,7 +1129,7 @@ int pa__init(pa_module*m) { pa_log("Failed to parse mmap argument."); goto fail; } - + if ((fd = pa_oss_open(dev = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), &mode, &caps)) < 0) goto fail; @@ -1104,7 +1137,7 @@ int pa__init(pa_module*m) { pa_log_info("OSS device not mmap capable, falling back to UNIX read/write mode."); use_mmap = 0; } - + if (use_mmap && mode == O_WRONLY) { pa_log_info("Device opened for playback only, cannot do memory mapping, falling back to UNIX write() mode."); use_mmap = 0; @@ -1135,9 +1168,9 @@ int pa__init(pa_module*m) { u->module = m; m->userdata = u; u->fd = fd; + u->mixer_fd = -1; u->use_getospace = u->use_getispace = 1; u->use_getodelay = 1; - u->use_input_volume = u->use_pcm_volume = 1; u->mode = mode; u->frame_size = pa_frame_size(&ss); u->device_name = pa_xstrdup(dev); @@ -1152,7 +1185,7 @@ int pa__init(pa_module*m) { pollfd->fd = fd; pollfd->events = 0; pollfd->revents = 0; - + if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) >= 0) { pa_log_info("Input -- %u fragments of size %u.", info.fragstotal, info.fragsize); u->in_fragment_size = info.fragsize; @@ -1169,7 +1202,7 @@ int pa__init(pa_module*m) { u->in_hwbuf_size = u->in_nfrags * u->in_fragment_size; u->out_hwbuf_size = u->out_nfrags * u->out_fragment_size; - + if (mode != O_WRONLY) { char *name_buf = NULL; @@ -1210,7 +1243,7 @@ int pa__init(pa_module*m) { hwdesc[0] ? ")" : "", use_mmap ? " via DMA" : "")); pa_xfree(t); - u->source->flags = PA_SOURCE_HARDWARE|PA_SOURCE_CAN_SUSPEND|PA_SOURCE_LATENCY|PA_SOURCE_HW_VOLUME_CTRL; + u->source->flags = PA_SOURCE_HARDWARE|PA_SOURCE_CAN_SUSPEND|PA_SOURCE_LATENCY; u->source->refresh_volume = 1; if (use_mmap) @@ -1236,7 +1269,7 @@ int pa__init(pa_module*m) { pa_silence_memory(u->out_mmap, u->out_hwbuf_size, &ss); } } - + if ((name = pa_modargs_get_value(ma, "sink_name", NULL))) namereg_fail = 1; else { @@ -1253,7 +1286,7 @@ int pa__init(pa_module*m) { u->sink->parent.process_msg = sink_process_msg; u->sink->userdata = u; - + pa_sink_set_module(u->sink, m); pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); pa_sink_set_rtpoll(u->sink, u->rtpoll); @@ -1265,15 +1298,46 @@ int pa__init(pa_module*m) { hwdesc[0] ? ")" : "", use_mmap ? " via DMA" : "")); pa_xfree(t); - u->sink->flags = PA_SINK_HARDWARE|PA_SINK_CAN_SUSPEND|PA_SINK_LATENCY|PA_SINK_HW_VOLUME_CTRL; + u->sink->flags = PA_SINK_HARDWARE|PA_SINK_CAN_SUSPEND|PA_SINK_LATENCY; u->sink->refresh_volume = 1; if (use_mmap) u->out_mmap_memblocks = pa_xnew0(pa_memblock*, u->out_nfrags); } + if ((u->mixer_fd = pa_oss_open_mixer_for_device(u->device_name)) >= 0) { + int do_close = 1; + u->mixer_devmask = 0; + + if (ioctl(fd, SOUND_MIXER_READ_DEVMASK, &u->mixer_devmask) < 0) + pa_log_warn("SOUND_MIXER_READ_DEVMASK failed: %s", pa_cstrerror(errno)); + + else { + if (u->sink && (u->mixer_devmask & (SOUND_MASK_VOLUME|SOUND_MASK_PCM))) { + pa_log_debug("Found hardware mixer track for playback."); + u->sink->flags |= PA_SINK_HW_VOLUME_CTRL; + u->sink->get_volume = sink_get_volume; + u->sink->set_volume = sink_set_volume; + do_close = 0; + } + + if (u->source && (u->mixer_devmask & (SOUND_MASK_RECLEV|SOUND_MASK_IGAIN))) { + pa_log_debug("Found hardware mixer track for recording."); + u->source->flags |= PA_SOURCE_HW_VOLUME_CTRL; + u->source->get_volume = source_get_volume; + u->source->set_volume = source_set_volume; + do_close = 0; + } + } + + if (do_close) { + pa_close(u->mixer_fd); + u->mixer_fd = -1; + } + } + go_on: - + pa_assert(u->source || u->sink); pa_memchunk_reset(&u->memchunk); @@ -1284,16 +1348,16 @@ go_on: } /* Read mixer settings */ - if (u->source) - pa_asyncmsgq_send(u->thread_mq.inq, PA_MSGOBJECT(u->source), PA_SOURCE_MESSAGE_GET_VOLUME, &u->source->volume, 0, NULL); - if (u->sink) - pa_asyncmsgq_send(u->thread_mq.inq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_GET_VOLUME, &u->sink->volume, 0, NULL); + if (u->sink && u->sink->get_volume) + sink_get_volume(u->sink); + if (u->source && u->source->get_volume) + source_get_volume(u->source); if (u->sink) pa_sink_put(u->sink); if (u->source) pa_source_put(u->source); - + pa_modargs_free(ma); return 0; @@ -1337,16 +1401,16 @@ void pa__done(pa_module*m) { if (u->source) pa_source_unref(u->source); - + if (u->memchunk.memblock) pa_memblock_unref(u->memchunk.memblock); if (u->rtpoll_item) pa_rtpoll_item_free(u->rtpoll_item); - + if (u->rtpoll) pa_rtpoll_free(u->rtpoll); - + if (u->out_mmap_memblocks) { unsigned i; for (i = 0; i < u->out_nfrags; i++) @@ -1368,11 +1432,14 @@ void pa__done(pa_module*m) { if (u->out_mmap && u->out_mmap != MAP_FAILED) munmap(u->out_mmap, u->out_hwbuf_size); - + if (u->fd >= 0) pa_close(u->fd); + if (u->mixer_fd >= 0) + pa_close(u->mixer_fd); + pa_xfree(u->device_name); - + pa_xfree(u); } diff --git a/src/modules/oss-util.c b/src/modules/oss-util.c index 3bef8a39..25e45a35 100644 --- a/src/modules/oss-util.c +++ b/src/modules/oss-util.c @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -248,7 +249,7 @@ int pa_oss_set_fragments(int fd, int nfrags, int frag_size) { return 0; } -static int pa_oss_get_volume(int fd, int mixer, const pa_sample_spec *ss, pa_cvolume *volume) { +int pa_oss_get_volume(int fd, int mixer, const pa_sample_spec *ss, pa_cvolume *volume) { char cv[PA_CVOLUME_SNPRINT_MAX]; unsigned vol; @@ -259,16 +260,18 @@ static int pa_oss_get_volume(int fd, int mixer, const pa_sample_spec *ss, pa_cvo if (ioctl(fd, mixer, &vol) < 0) return -1; + pa_cvolume_reset(volume, ss->channels); + volume->values[0] = ((vol & 0xFF) * PA_VOLUME_NORM) / 100; - if ((volume->channels = ss->channels) >= 2) + if (volume->channels >= 2) volume->values[1] = (((vol >> 8) & 0xFF) * PA_VOLUME_NORM) / 100; pa_log_debug("Read mixer settings: %s", pa_cvolume_snprint(cv, sizeof(cv), volume)); return 0; } -static int pa_oss_set_volume(int fd, long mixer, const pa_sample_spec *ss, const pa_cvolume *volume) { +int pa_oss_set_volume(int fd, long mixer, const pa_sample_spec *ss, const pa_cvolume *volume) { char cv[PA_CVOLUME_SNPRINT_MAX]; unsigned vol; pa_volume_t l, r; @@ -289,40 +292,38 @@ static int pa_oss_set_volume(int fd, long mixer, const pa_sample_spec *ss, const return 0; } -int pa_oss_get_pcm_volume(int fd, const pa_sample_spec *ss, pa_cvolume *volume) { - return pa_oss_get_volume(fd, SOUND_MIXER_READ_PCM, ss, volume); -} +static int get_device_number(const char *dev) { + char buf[PATH_MAX]; + const char *p, *e; -int pa_oss_set_pcm_volume(int fd, const pa_sample_spec *ss, const pa_cvolume *volume) { - return pa_oss_set_volume(fd, SOUND_MIXER_WRITE_PCM, ss, volume); -} + if (readlink(dev, buf, sizeof(buf)) < 0) { + if (errno != EINVAL && errno != ENOLINK) + return -1; -int pa_oss_get_input_volume(int fd, const pa_sample_spec *ss, pa_cvolume *volume) { - return pa_oss_get_volume(fd, SOUND_MIXER_READ_IGAIN, ss, volume); -} + p = dev; + } else + p = buf; + + if ((e = strrchr(p, '/'))) + p = e+1; + + if (p == 0) + return 0; + + p = strchr(p, 0) -1; -int pa_oss_set_input_volume(int fd, const pa_sample_spec *ss, const pa_cvolume *volume) { - return pa_oss_set_volume(fd, SOUND_MIXER_WRITE_IGAIN, ss, volume); + if (*p >= '0' && *p <= '9') + return *p - '0'; + + return -1; } int pa_oss_get_hw_description(const char *dev, char *name, size_t l) { FILE *f; - const char *e = NULL; int n, r = -1; int b = 0; - if (strncmp(dev, "/dev/dsp", 8) == 0) - e = dev+8; - else if (strncmp(dev, "/dev/adsp", 9) == 0) - e = dev+9; - else - return -1; - - if (*e == 0) - n = 0; - else if (*e >= '0' && *e <= '9' && *(e+1) == 0) - n = *e - '0'; - else + if ((n = get_device_number(dev)) < 0) return -1; if (!(f = fopen("/dev/sndstat", "r")) && @@ -373,3 +374,34 @@ int pa_oss_get_hw_description(const char *dev, char *name, size_t l) { fclose(f); return r; } + +static int open_mixer(const char *mixer) { + int fd; + + if ((fd = open(mixer, O_RDWR|O_NDELAY|O_NOCTTY)) >= 0) + return fd; + + return -1; +} + +int pa_oss_open_mixer_for_device(const char *device) { + int n; + char *fn; + int fd; + + if ((n = get_device_number(device)) < 0) + return -1; + + if (n == 0) + if ((fd = open_mixer("/dev/mixer")) >= 0) + return fd; + + fn = pa_sprintf_malloc("/dev/mixer%i", n); + fd = open_mixer(fn); + pa_xfree(fn); + + if (fd < 0) + pa_log_warn("Failed to open mixer '%s': %s", device, pa_cstrerror(errno)); + + return fd; +} diff --git a/src/modules/oss-util.h b/src/modules/oss-util.h index 087e0d22..259a622a 100644 --- a/src/modules/oss-util.h +++ b/src/modules/oss-util.h @@ -33,12 +33,11 @@ int pa_oss_auto_format(int fd, pa_sample_spec *ss); int pa_oss_set_fragments(int fd, int frags, int frag_size); -int pa_oss_get_pcm_volume(int fd, const pa_sample_spec *ss, pa_cvolume *volume); -int pa_oss_set_pcm_volume(int fd, const pa_sample_spec *ss, const pa_cvolume *volume); - -int pa_oss_get_input_volume(int fd, const pa_sample_spec *ss, pa_cvolume *volume); -int pa_oss_set_input_volume(int fd, const pa_sample_spec *ss, const pa_cvolume *volume); +int pa_oss_set_volume(int fd, long mixer, const pa_sample_spec *ss, const pa_cvolume *volume); +int pa_oss_get_volume(int fd, int mixer, const pa_sample_spec *ss, pa_cvolume *volume); int pa_oss_get_hw_description(const char *dev, char *name, size_t l); +int pa_oss_open_mixer_for_device(const char *device); + #endif -- cgit From ba322a49e1754eba11495da9a10e3e0dbbe89244 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 24 Sep 2007 16:10:43 +0000 Subject: drop the PA_SOURCE_CAN_SUSPEND and PA_SINK_CAN_SUSPEND flags, since they were a bad idea in the first place. All sinks/sources are now *required* to handle suspending in one way or another. Luckily all current sink/source implementations handle it fine anyway. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1894 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 159 +++++++++++++++++------------------ src/modules/module-alsa-source.c | 145 ++++++++++++++++---------------- src/modules/module-combine.c | 2 +- src/modules/module-ladspa-sink.c | 2 +- src/modules/module-oss.c | 4 +- src/modules/module-remap-sink.c | 2 +- src/modules/module-suspend-on-idle.c | 64 +++++++------- src/pulse/def.h | 6 +- src/pulse/stream.c | 12 +-- src/pulsecore/cli-text.c | 8 +- src/pulsecore/sink.c | 3 - src/pulsecore/source.c | 3 - 12 files changed, 196 insertions(+), 214 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 4f2e570a..0489fa87 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -70,11 +70,11 @@ struct userdata { pa_core *core; pa_module *module; pa_sink *sink; - + pa_thread *thread; pa_thread_mq thread_mq; pa_rtpoll *rtpoll; - + snd_pcm_t *pcm_handle; pa_alsa_fdlist *mixer_fdl; @@ -110,7 +110,7 @@ static const char* const valid_modargs[] = { static int mmap_write(struct userdata *u) { int work_done = 0; - + pa_assert(u); pa_sink_assert_ref(u->sink); @@ -121,33 +121,33 @@ static int mmap_write(struct userdata *u) { int err; const snd_pcm_channel_area_t *areas; snd_pcm_uframes_t offset, frames; - + if ((n = snd_pcm_avail_update(u->pcm_handle)) < 0) { if (n == -EPIPE) { pa_log_debug("snd_pcm_avail_update: Buffer underrun!"); u->first = 1; } - + if ((err = snd_pcm_recover(u->pcm_handle, n, 1)) == 0) continue; if (err == -EAGAIN) return work_done; - + pa_log("snd_pcm_avail_update: %s", snd_strerror(err)); return -1; } /* pa_log("Got request for %i samples", (int) n); */ - + if (n <= 0) return work_done; frames = n; - + if ((err = snd_pcm_mmap_begin(u->pcm_handle, &areas, &offset, &frames)) < 0) { - + if (err == -EPIPE) { pa_log_debug("snd_pcm_mmap_begin: Buffer underrun!"); u->first = 1; @@ -172,7 +172,7 @@ static int mmap_write(struct userdata *u) { pa_assert((areas[0].step >> 3) == u->frame_size); p = (uint8_t*) areas[0].addr + (offset * u->frame_size); - + chunk.memblock = pa_memblock_new_fixed(u->core->mempool, p, frames * u->frame_size, 1); chunk.length = pa_memblock_get_length(chunk.memblock); chunk.index = 0; @@ -189,13 +189,13 @@ static int mmap_write(struct userdata *u) { pa_log_debug("snd_pcm_mmap_commit: Buffer underrun!"); u->first = 1; } - + if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0) continue; - + if (err == -EAGAIN) return work_done; - + pa_log("Failed to write data to DSP: %s", snd_strerror(err)); return -1; } @@ -204,7 +204,7 @@ static int mmap_write(struct userdata *u) { if (frames >= (snd_pcm_uframes_t) n) return work_done; - + /* pa_log("wrote %i samples", (int) frames); */ } } @@ -214,7 +214,7 @@ static int unix_write(struct userdata *u) { int work_done = 0; snd_pcm_status_alloca(&status); - + pa_assert(u); pa_sink_assert_ref(u->sink); @@ -223,7 +223,7 @@ static int unix_write(struct userdata *u) { snd_pcm_sframes_t t; ssize_t l; int err; - + if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) { pa_log("Failed to query DSP status data: %s", snd_strerror(err)); return -1; @@ -231,32 +231,32 @@ static int unix_write(struct userdata *u) { if (snd_pcm_status_get_avail_max(status)*u->frame_size >= u->hwbuf_size) pa_log_debug("Buffer underrun!"); - + l = snd_pcm_status_get_avail(status) * u->frame_size; /* pa_log("%u bytes to write", l); */ - + if (l <= 0) return work_done; - + if (u->memchunk.length <= 0) pa_sink_render(u->sink, l, &u->memchunk); - + pa_assert(u->memchunk.length > 0); - + p = pa_memblock_acquire(u->memchunk.memblock); t = snd_pcm_writei(u->pcm_handle, (const uint8_t*) p + u->memchunk.index, u->memchunk.length / u->frame_size); pa_memblock_release(u->memchunk.memblock); - + /* pa_log("wrote %i bytes of %u (%u)", t*u->frame_size, u->memchunk.length, l); */ - + pa_assert(t != 0); - + if (t < 0) { if ((t = snd_pcm_recover(u->pcm_handle, t, 1)) == 0) continue; - + if (t == -EAGAIN) { pa_log_debug("EAGAIN"); return work_done; @@ -265,10 +265,10 @@ static int unix_write(struct userdata *u) { return -1; } } - + u->memchunk.index += t * u->frame_size; u->memchunk.length -= t * u->frame_size; - + if (u->memchunk.length <= 0) { pa_memblock_unref(u->memchunk.memblock); pa_memchunk_reset(&u->memchunk); @@ -278,7 +278,7 @@ static int unix_write(struct userdata *u) { if (t * u->frame_size >= (unsigned) l) return work_done; - } + } } static pa_usec_t sink_get_latency(struct userdata *u) { @@ -288,18 +288,18 @@ static pa_usec_t sink_get_latency(struct userdata *u) { int err; snd_pcm_status_alloca(&status); - + pa_assert(u); pa_assert(u->pcm_handle); - if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) + if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) pa_log("Failed to get delay: %s", snd_strerror(err)); else frames = snd_pcm_status_get_delay(status); if (frames > 0) r = pa_bytes_to_usec(frames * u->frame_size, &u->sink->sample_spec); - + if (u->memchunk.memblock) r += pa_bytes_to_usec(u->memchunk.length, &u->sink->sample_spec); @@ -310,7 +310,7 @@ static int build_pollfd(struct userdata *u) { int err; struct pollfd *pollfd; int n; - + pa_assert(u); pa_assert(u->pcm_handle); @@ -329,7 +329,7 @@ static int build_pollfd(struct userdata *u) { pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err)); return -1; } - + return 0; } @@ -338,7 +338,7 @@ static int suspend(struct userdata *u) { pa_assert(u->pcm_handle); /* Let's suspend */ - snd_pcm_drain(u->pcm_handle); + snd_pcm_drain(u->pcm_handle); snd_pcm_close(u->pcm_handle); u->pcm_handle = NULL; @@ -346,9 +346,9 @@ static int suspend(struct userdata *u) { pa_rtpoll_item_free(u->alsa_rtpoll_item); u->alsa_rtpoll_item = NULL; } - + pa_log_info("Device suspended..."); - + return 0; } @@ -373,7 +373,7 @@ static int unsuspend(struct userdata *u) { nfrags = u->nfragments; period_size = u->fragment_size / u->frame_size; b = u->use_mmap; - + if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) { pa_log("Failed to set hardware parameters: %s", snd_strerror(err)); goto fail; @@ -401,11 +401,11 @@ static int unsuspend(struct userdata *u) { if (build_pollfd(u) < 0) goto fail; - + /* FIXME: We need to reload the volume somehow */ - + u->first = 1; - + pa_log_info("Resumed successfully..."); return 0; @@ -438,13 +438,13 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse case PA_SINK_MESSAGE_SET_STATE: switch ((pa_sink_state_t) PA_PTR_TO_UINT(data)) { - + case PA_SINK_SUSPENDED: pa_assert(PA_SINK_OPENED(u->sink->thread_info.state)); if (suspend(u) < 0) return -1; - + break; case PA_SINK_IDLE: @@ -454,14 +454,14 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse if (unsuspend(u) < 0) return -1; } - + break; case PA_SINK_UNLINKED: case PA_SINK_INIT: ; } - + break; } @@ -512,7 +512,7 @@ static int sink_get_volume_cb(pa_sink *s) { fail: pa_log_error("Unable to read volume: %s", snd_strerror(err)); - + s->get_volume = NULL; s->set_volume = NULL; return -1; @@ -547,7 +547,7 @@ static int sink_set_volume_cb(pa_sink *s) { fail: pa_log_error("Unable to set volume: %s", snd_strerror(err)); - + s->get_volume = NULL; s->set_volume = NULL; return -1; @@ -582,7 +582,7 @@ static int sink_set_mute_cb(pa_sink *s) { if ((err = snd_mixer_selem_set_playback_switch_all(u->mixer_elem, !s->muted)) < 0) { pa_log_error("Unable to set switch: %s", snd_strerror(err)); - + s->get_mute = NULL; s->set_mute = NULL; return -1; @@ -593,7 +593,7 @@ static int sink_set_mute_cb(pa_sink *s) { static void thread_func(void *userdata) { struct userdata *u = userdata; - + pa_assert(u); pa_log_debug("Thread starting up"); @@ -603,17 +603,17 @@ static void thread_func(void *userdata) { pa_thread_mq_install(&u->thread_mq); pa_rtpoll_install(u->rtpoll); - + if (build_pollfd(u) < 0) goto fail; for (;;) { int ret; - + /* Render some data and write it to the dsp */ if (PA_SINK_OPENED(u->sink->thread_info.state)) { int work_done = 0; - + if (u->use_mmap) { if ((work_done = mmap_write(u)) < 0) goto fail; @@ -636,7 +636,7 @@ static void thread_func(void *userdata) { if (ret == 0) goto finish; - + /* Tell ALSA about this and process its response */ if (PA_SINK_OPENED(u->sink->thread_info.state)) { struct pollfd *pollfd; @@ -655,7 +655,7 @@ static void thread_func(void *userdata) { if (revents & POLLERR) pa_log_warn("Got POLLERR from ALSA"); if (revents & POLLNVAL) - pa_log_warn("Got POLLNVAL from ALSA"); + pa_log_warn("Got POLLNVAL from ALSA"); if (revents & POLLHUP) pa_log_warn("Got POLLHUP from ALSA"); @@ -675,7 +675,7 @@ finish: } int pa__init(pa_module*m) { - + pa_modargs *ma = NULL; struct userdata *u = NULL; char *dev; @@ -693,7 +693,7 @@ int pa__init(pa_module*m) { int use_mmap = 1, b; snd_pcm_info_alloca(&pcm_info); - + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { @@ -724,7 +724,7 @@ int pa__init(pa_module*m) { pa_log("Failed to parse mmap argument."); goto fail; } - + u = pa_xnew0(struct userdata, 1); u->core = m->core; u->module = m; @@ -741,19 +741,19 @@ int pa__init(pa_module*m) { dev = pa_xstrdup(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE)); for (;;) { - + if ((err = snd_pcm_open(&u->pcm_handle, dev, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { pa_log("Error opening PCM device %s: %s", dev, snd_strerror(err)); pa_xfree(dev); goto fail; } - + b = use_mmap; if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) { if (err == -EPERM) { /* Hmm, some hw is very exotic, so we retry with plughw, if hw didn't work */ - + if (pa_startswith(dev, "hw:")) { char *d = pa_sprintf_malloc("plughw:%s", dev+3); pa_log_debug("Opening the device as '%s' didn't work, retrying with '%s'.", dev, d); @@ -765,7 +765,7 @@ int pa__init(pa_module*m) { continue; } } - + pa_log("Failed to set hardware parameters: %s", snd_strerror(err)); pa_xfree(dev); goto fail; @@ -773,9 +773,9 @@ int pa__init(pa_module*m) { break; } - + u->device_name = dev; - + if (use_mmap && !b) { pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode."); u->use_mmap = use_mmap = b; @@ -807,7 +807,7 @@ int pa__init(pa_module*m) { if ((pa_alsa_prepare_mixer(u->mixer_handle, dev) < 0) || !(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Master", "PCM"))) { - + snd_mixer_close(u->mixer_handle); u->mixer_handle = NULL; } @@ -822,7 +822,7 @@ int pa__init(pa_module*m) { u->sink = pa_sink_new(m->core, __FILE__, name, namereg_fail, &ss, &map); pa_xfree(name_buf); - + if (!u->sink) { pa_log("Failed to create sink object"); goto fail; @@ -840,8 +840,8 @@ int pa__init(pa_module*m) { snd_pcm_info_get_name(pcm_info), use_mmap ? " via DMA" : "")); pa_xfree(t); - - u->sink->flags = PA_SINK_HARDWARE|PA_SINK_CAN_SUSPEND|PA_SINK_HW_VOLUME_CTRL|PA_SINK_LATENCY; + + u->sink->flags = PA_SINK_HARDWARE|PA_SINK_HW_VOLUME_CTRL|PA_SINK_LATENCY; u->frame_size = frame_size; u->fragment_size = frag_size = period_size * frame_size; @@ -854,9 +854,9 @@ int pa__init(pa_module*m) { if (u->mixer_handle) { /* Initialize mixer code */ - + pa_assert(u->mixer_elem); - + if (snd_mixer_selem_has_playback_volume(u->mixer_elem)) { int i; @@ -872,7 +872,7 @@ int pa__init(pa_module*m) { } else pa_log_info("ALSA device lacks separate volumes controls for all %u channels (%u available), falling back to software volume control.", ss.channels, i+1); } - + if (snd_mixer_selem_has_playback_switch(u->mixer_elem)) { u->sink->get_mute = sink_get_mute_cb; u->sink->set_mute = sink_set_mute_cb; @@ -894,7 +894,7 @@ int pa__init(pa_module*m) { pa_log("Failed to create thread."); goto fail; } - + /* Get initial mixer settings */ if (u->sink->get_volume) u->sink->get_volume(u->sink); @@ -902,11 +902,11 @@ int pa__init(pa_module*m) { u->sink->get_mute(u->sink); pa_sink_put(u->sink); - + pa_modargs_free(ma); - + return 0; - + fail: if (ma) @@ -919,7 +919,7 @@ fail: void pa__done(pa_module*m) { struct userdata *u; - + pa_assert(m); if (!(u = m->userdata)) @@ -937,19 +937,19 @@ void pa__done(pa_module*m) { if (u->sink) pa_sink_unref(u->sink); - + if (u->memchunk.memblock) pa_memblock_unref(u->memchunk.memblock); if (u->alsa_rtpoll_item) pa_rtpoll_item_free(u->alsa_rtpoll_item); - + if (u->rtpoll) pa_rtpoll_free(u->rtpoll); - + if (u->mixer_fdl) pa_alsa_fdlist_free(u->mixer_fdl); - + if (u->mixer_handle) snd_mixer_close(u->mixer_handle); @@ -960,7 +960,6 @@ void pa__done(pa_module*m) { pa_xfree(u->device_name); pa_xfree(u); - + snd_config_update_free_global(); } - diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 82f66bb9..de019ffb 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -71,7 +71,7 @@ struct userdata { pa_core *core; pa_module *module; pa_source *source; - + pa_thread *thread; pa_thread_mq thread_mq; pa_rtpoll *rtpoll; @@ -108,7 +108,7 @@ static const char* const valid_modargs[] = { static int mmap_read(struct userdata *u) { int work_done = 0; - + pa_assert(u); pa_source_assert_ref(u->source); @@ -119,31 +119,31 @@ static int mmap_read(struct userdata *u) { snd_pcm_uframes_t offset, frames; pa_memchunk chunk; void *p; - + if ((n = snd_pcm_avail_update(u->pcm_handle)) < 0) { if (n == -EPIPE) pa_log_debug("snd_pcm_avail_update: Buffer underrun!"); - + if ((err = snd_pcm_recover(u->pcm_handle, n, 1)) == 0) continue; if (err == -EAGAIN) return work_done; - + pa_log("snd_pcm_avail_update: %s", snd_strerror(err)); return -1; } /* pa_log("Got request for %i samples", (int) n); */ - + if (n <= 0) return work_done; frames = n; - + if ((err = snd_pcm_mmap_begin(u->pcm_handle, &areas, &offset, &frames)) < 0) { - + if (err == -EPIPE) pa_log_debug("snd_pcm_mmap_begin: Buffer underrun!"); @@ -166,7 +166,7 @@ static int mmap_read(struct userdata *u) { pa_assert((areas[0].step >> 3) == u->frame_size); p = (uint8_t*) areas[0].addr + (offset * u->frame_size); - + chunk.memblock = pa_memblock_new_fixed(u->core->mempool, p, frames * u->frame_size, 1); chunk.length = pa_memblock_get_length(chunk.memblock); chunk.index = 0; @@ -181,13 +181,13 @@ static int mmap_read(struct userdata *u) { if (err == -EPIPE) pa_log_debug("snd_pcm_mmap_commit: Buffer underrun!"); - + if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0) continue; - + if (err == -EAGAIN) return work_done; - + pa_log("Failed to write data to DSP: %s", snd_strerror(err)); return -1; } @@ -213,7 +213,7 @@ static int unix_read(struct userdata *u) { ssize_t l; int err; pa_memchunk chunk; - + if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) { pa_log("Failed to query DSP status data: %s", snd_strerror(err)); return -1; @@ -221,12 +221,12 @@ static int unix_read(struct userdata *u) { if (snd_pcm_status_get_avail_max(status)*u->frame_size >= u->hwbuf_size) pa_log_debug("Buffer overrun!"); - + l = snd_pcm_status_get_avail(status) * u->frame_size; if (l <= 0) return work_done; - + chunk.memblock = pa_memblock_new(u->core->mempool, (size_t) -1); k = pa_memblock_get_length(chunk.memblock); @@ -239,17 +239,17 @@ static int unix_read(struct userdata *u) { p = pa_memblock_acquire(chunk.memblock); t = snd_pcm_readi(u->pcm_handle, (uint8_t*) p, k / u->frame_size); pa_memblock_release(chunk.memblock); - + /* pa_log("wrote %i bytes of %u (%u)", t*u->frame_size, u->memchunk.length, l); */ - + pa_assert(t != 0); - + if (t < 0) { pa_memblock_unref(chunk.memblock); - + if ((t = snd_pcm_recover(u->pcm_handle, t, 1)) == 0) continue; - + if (t == -EAGAIN) { pa_log_debug("EAGAIN"); return work_done; @@ -257,14 +257,14 @@ static int unix_read(struct userdata *u) { pa_log("Failed to read data from DSP: %s", snd_strerror(t)); return -1; } - } - + } + chunk.index = 0; chunk.length = t * u->frame_size; pa_source_post(u->source, &chunk); pa_memblock_unref(chunk.memblock); - + work_done = 1; if (t * u->frame_size >= (unsigned) l) @@ -279,11 +279,11 @@ static pa_usec_t source_get_latency(struct userdata *u) { int err; snd_pcm_status_alloca(&status); - + pa_assert(u); pa_assert(u->pcm_handle); - if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) + if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) pa_log("Failed to get delay: %s", snd_strerror(err)); else frames = snd_pcm_status_get_delay(status); @@ -298,7 +298,7 @@ static int build_pollfd(struct userdata *u) { int err; struct pollfd *pollfd; int n; - + pa_assert(u); pa_assert(u->pcm_handle); @@ -312,12 +312,12 @@ static int build_pollfd(struct userdata *u) { u->alsa_rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, n); pollfd = pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, NULL); - + if ((err = snd_pcm_poll_descriptors(u->pcm_handle, pollfd, n)) < 0) { pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err)); return -1; } - + return 0; } @@ -333,9 +333,9 @@ static int suspend(struct userdata *u) { pa_rtpoll_item_free(u->alsa_rtpoll_item); u->alsa_rtpoll_item = NULL; } - + pa_log_info("Device suspended..."); - + return 0; } @@ -360,7 +360,7 @@ static int unsuspend(struct userdata *u) { nfrags = u->nfragments; period_size = u->fragment_size / u->frame_size; b = u->use_mmap; - + if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) { pa_log("Failed to set hardware parameters: %s", snd_strerror(err)); goto fail; @@ -370,7 +370,7 @@ static int unsuspend(struct userdata *u) { pa_log_warn("Resume failed, couldn't get original access mode."); goto fail; } - + if (!pa_sample_spec_equal(&ss, &u->source->sample_spec)) { pa_log_warn("Resume failed, couldn't restore original sample settings."); goto fail; @@ -388,11 +388,11 @@ static int unsuspend(struct userdata *u) { if (build_pollfd(u) < 0) goto fail; - + snd_pcm_start(u->pcm_handle); - + /* FIXME: We need to reload the volume somehow */ - + pa_log_info("Resumed successfully..."); return 0; @@ -425,13 +425,13 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off case PA_SOURCE_MESSAGE_SET_STATE: switch ((pa_source_state_t) PA_PTR_TO_UINT(data)) { - + case PA_SOURCE_SUSPENDED: pa_assert(PA_SOURCE_OPENED(u->source->thread_info.state)); if (suspend(u) < 0) return -1; - + break; case PA_SOURCE_IDLE: @@ -441,14 +441,14 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off if (unsuspend(u) < 0) return -1; } - + break; case PA_SOURCE_UNLINKED: case PA_SOURCE_INIT: ; } - + break; } @@ -499,7 +499,7 @@ static int source_get_volume_cb(pa_source *s) { fail: pa_log_error("Unable to read volume: %s", snd_strerror(err)); - + s->get_volume = NULL; s->set_volume = NULL; return -1; @@ -534,7 +534,7 @@ static int source_set_volume_cb(pa_source *s) { fail: pa_log_error("Unable to set volume: %s", snd_strerror(err)); - + s->get_volume = NULL; s->set_volume = NULL; return -1; @@ -569,7 +569,7 @@ static int source_set_mute_cb(pa_source *s) { if ((err = snd_mixer_selem_set_capture_switch_all(u->mixer_elem, !s->muted)) < 0) { pa_log_error("Unable to set switch: %s", snd_strerror(err)); - + s->get_mute = NULL; s->set_mute = NULL; return -1; @@ -590,18 +590,18 @@ static void thread_func(void *userdata) { pa_thread_mq_install(&u->thread_mq); pa_rtpoll_install(u->rtpoll); - + if (build_pollfd(u) < 0) goto fail; snd_pcm_start(u->pcm_handle); - + for (;;) { int ret; /* Read some data and pass it to the sources */ if (PA_SOURCE_OPENED(u->source->thread_info.state)) { - + if (u->use_mmap) { if (mmap_read(u) < 0) goto fail; @@ -618,7 +618,7 @@ static void thread_func(void *userdata) { if (ret == 0) goto finish; - + /* Tell ALSA about this and process its response */ if (PA_SOURCE_OPENED(u->source->thread_info.state)) { struct pollfd *pollfd; @@ -627,7 +627,7 @@ static void thread_func(void *userdata) { unsigned n; pollfd = pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, &n); - + if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, pollfd, n, &revents)) < 0) { pa_log("snd_pcm_poll_descriptors_revents() failed: %s", snd_strerror(err)); goto fail; @@ -637,7 +637,7 @@ static void thread_func(void *userdata) { if (revents & POLLERR) pa_log_warn("Got POLLERR from ALSA"); if (revents & POLLNVAL) - pa_log_warn("Got POLLNVAL from ALSA"); + pa_log_warn("Got POLLNVAL from ALSA"); if (revents & POLLHUP) pa_log_warn("Got POLLHUP from ALSA"); @@ -657,7 +657,7 @@ finish: } int pa__init(pa_module*m) { - + pa_modargs *ma = NULL; struct userdata *u = NULL; char *dev; @@ -677,7 +677,7 @@ int pa__init(pa_module*m) { snd_pcm_info_alloca(&pcm_info); pa_assert(m); - + if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments"); goto fail; @@ -706,7 +706,7 @@ int pa__init(pa_module*m) { pa_log("Failed to parse mmap argument."); goto fail; } - + u = pa_xnew0(struct userdata, 1); u->core = m->core; u->module = m; @@ -720,9 +720,9 @@ int pa__init(pa_module*m) { snd_config_update_free_global(); dev = pa_xstrdup(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE)); - + for (;;) { - + if ((err = snd_pcm_open(&u->pcm_handle, dev, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) { pa_log("Error opening PCM device %s: %s", dev, snd_strerror(err)); pa_xfree(dev); @@ -734,7 +734,7 @@ int pa__init(pa_module*m) { if (err == -EPERM) { /* Hmm, some hw is very exotic, so we retry with plughw, if hw didn't work */ - + if (pa_startswith(dev, "hw:")) { char *d = pa_sprintf_malloc("plughw:%s", dev+3); pa_log_debug("Opening the device as '%s' didn't work, retrying with '%s'.", dev, d); @@ -746,7 +746,7 @@ int pa__init(pa_module*m) { continue; } } - + pa_log("Failed to set hardware parameters: %s", snd_strerror(err)); pa_xfree(dev); goto fail; @@ -756,7 +756,7 @@ int pa__init(pa_module*m) { } u->device_name = dev; - + if (use_mmap && !b) { pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode."); u->use_mmap = use_mmap = b; @@ -774,7 +774,7 @@ int pa__init(pa_module*m) { pa_log("Failed to set software parameters: %s", snd_strerror(err)); goto fail; } - + /* ALSA might tweak the sample spec, so recalculate the frame size */ frame_size = pa_frame_size(&ss); @@ -785,7 +785,7 @@ int pa__init(pa_module*m) { if ((err = snd_mixer_open(&u->mixer_handle, 0)) < 0) pa_log("Error opening mixer: %s", snd_strerror(err)); else { - + if ((pa_alsa_prepare_mixer(u->mixer_handle, dev) < 0) || !(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Capture", NULL))) { snd_mixer_close(u->mixer_handle); @@ -802,7 +802,7 @@ int pa__init(pa_module*m) { u->source = pa_source_new(m->core, __FILE__, name, namereg_fail, &ss, &map); pa_xfree(name_buf); - + if (!u->source) { pa_log("Failed to create source object"); goto fail; @@ -821,7 +821,7 @@ int pa__init(pa_module*m) { use_mmap ? " via DMA" : "")); pa_xfree(t); - u->source->flags = PA_SOURCE_HARDWARE|PA_SOURCE_CAN_SUSPEND|PA_SOURCE_LATENCY|PA_SOURCE_HW_VOLUME_CTRL; + u->source->flags = PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY|PA_SOURCE_HW_VOLUME_CTRL; u->frame_size = frame_size; u->fragment_size = frag_size = period_size * frame_size; @@ -832,7 +832,7 @@ int pa__init(pa_module*m) { if (u->mixer_handle) { pa_assert(u->mixer_elem); - + if (snd_mixer_selem_has_capture_volume(u->mixer_elem)) { int i; @@ -847,19 +847,19 @@ int pa__init(pa_module*m) { snd_mixer_selem_get_capture_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max); } } - + if (snd_mixer_selem_has_capture_switch(u->mixer_elem)) { u->source->get_mute = source_get_mute_cb; u->source->set_mute = source_set_mute_cb; } u->mixer_fdl = pa_alsa_fdlist_new(); - + if (pa_alsa_fdlist_set_mixer(u->mixer_fdl, u->mixer_handle, m->core->mainloop) < 0) { pa_log("failed to initialise file descriptor monitoring"); goto fail; } - + snd_mixer_elem_set_callback(u->mixer_elem, mixer_callback); snd_mixer_elem_set_callback_private(u->mixer_elem, u); } else @@ -875,25 +875,25 @@ int pa__init(pa_module*m) { if (u->source->get_mute) u->source->get_mute(u->source); - pa_source_put(u->source); - + pa_source_put(u->source); + pa_modargs_free(ma); - + return 0; - + fail: if (ma) pa_modargs_free(ma); pa__done(m); - + return -1; } void pa__done(pa_module*m) { struct userdata *u; - + pa_assert(m); if (!(u = m->userdata)) @@ -914,10 +914,10 @@ void pa__done(pa_module*m) { if (u->alsa_rtpoll_item) pa_rtpoll_item_free(u->alsa_rtpoll_item); - + if (u->rtpoll) pa_rtpoll_free(u->rtpoll); - + if (u->mixer_fdl) pa_alsa_fdlist_free(u->mixer_fdl); @@ -934,4 +934,3 @@ void pa__done(pa_module*m) { snd_config_update_free_global(); } - diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index af5ddb1c..656cef92 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -1134,7 +1134,7 @@ int pa__init(pa_module*m) { u->sink->set_state = sink_set_state; u->sink->userdata = u; - u->sink->flags = PA_SINK_CAN_SUSPEND|PA_SINK_LATENCY; + u->sink->flags = PA_SINK_LATENCY; pa_sink_set_module(u->sink, m); pa_sink_set_description(u->sink, "Simultaneous output"); diff --git a/src/modules/module-ladspa-sink.c b/src/modules/module-ladspa-sink.c index 38b7e011..9f771c6b 100644 --- a/src/modules/module-ladspa-sink.c +++ b/src/modules/module-ladspa-sink.c @@ -568,7 +568,7 @@ int pa__init(pa_module*m) { u->sink->parent.process_msg = sink_process_msg; u->sink->set_state = sink_set_state; u->sink->userdata = u; - u->sink->flags = PA_SINK_LATENCY|PA_SINK_CAN_SUSPEND; + u->sink->flags = PA_SINK_LATENCY; pa_sink_set_module(u->sink, m); pa_sink_set_description(u->sink, t = pa_sprintf_malloc("LADSPA plugin '%s' on '%s'", label, master->description)); diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 358154ac..8d088997 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -1243,7 +1243,7 @@ int pa__init(pa_module*m) { hwdesc[0] ? ")" : "", use_mmap ? " via DMA" : "")); pa_xfree(t); - u->source->flags = PA_SOURCE_HARDWARE|PA_SOURCE_CAN_SUSPEND|PA_SOURCE_LATENCY; + u->source->flags = PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY; u->source->refresh_volume = 1; if (use_mmap) @@ -1298,7 +1298,7 @@ int pa__init(pa_module*m) { hwdesc[0] ? ")" : "", use_mmap ? " via DMA" : "")); pa_xfree(t); - u->sink->flags = PA_SINK_HARDWARE|PA_SINK_CAN_SUSPEND|PA_SINK_LATENCY; + u->sink->flags = PA_SINK_HARDWARE|PA_SINK_LATENCY; u->sink->refresh_volume = 1; if (use_mmap) diff --git a/src/modules/module-remap-sink.c b/src/modules/module-remap-sink.c index bff787bc..d712a045 100644 --- a/src/modules/module-remap-sink.c +++ b/src/modules/module-remap-sink.c @@ -262,7 +262,7 @@ int pa__init(pa_module*m) { u->sink->parent.process_msg = sink_process_msg; u->sink->set_state = sink_set_state; u->sink->userdata = u; - u->sink->flags = PA_SINK_LATENCY|PA_SINK_CAN_SUSPEND; + u->sink->flags = PA_SINK_LATENCY; pa_sink_set_module(u->sink, m); pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Remapped %s", master->description)); diff --git a/src/modules/module-suspend-on-idle.c b/src/modules/module-suspend-on-idle.c index 79850e71..4fcb404c 100644 --- a/src/modules/module-suspend-on-idle.c +++ b/src/modules/module-suspend-on-idle.c @@ -57,7 +57,7 @@ struct userdata { *source_unlink_slot, *sink_state_changed_slot, *source_state_changed_slot; - + pa_hook_slot *sink_input_new_slot, *source_output_new_slot, @@ -83,7 +83,7 @@ static void timeout_cb(pa_mainloop_api*a, pa_time_event* e, const struct timeval pa_assert(d); d->userdata->core->mainloop->time_restart(d->time_event, NULL); - + if (d->sink && pa_sink_used_by(d->sink) <= 0 && pa_sink_get_state(d->sink) != PA_SINK_SUSPENDED) { pa_log_info("Sink %s idle for too long, suspending ...", d->sink->name); pa_sink_suspend(d->sink, 1); @@ -119,7 +119,7 @@ static void resume(struct device_info *d) { if (d->sink) { pa_sink_suspend(d->sink, 0); pa_source_suspend(d->sink->monitor_source, 0); - + pa_log_debug("Sink %s becomes busy.", d->sink->name); } @@ -134,14 +134,14 @@ static void resume(struct device_info *d) { static pa_hook_result_t sink_input_new_hook_cb(pa_core *c, pa_sink_input *s, struct userdata *u) { struct device_info *d; - + pa_assert(c); pa_sink_input_assert_ref(s); pa_assert(u); - + if ((d = pa_hashmap_get(u->device_infos, s->sink))) resume(d); - + return PA_HOOK_OK; } @@ -151,10 +151,10 @@ static pa_hook_result_t source_output_new_hook_cb(pa_core *c, pa_source_output * pa_assert(c); pa_source_output_assert_ref(s); pa_assert(u); - + if ((d = pa_hashmap_get(u->device_infos, s->source))) resume(d); - + return PA_HOOK_OK; } @@ -168,7 +168,7 @@ static pa_hook_result_t sink_input_unlink_hook_cb(pa_core *c, pa_sink_input *s, if ((d = pa_hashmap_get(u->device_infos, s->sink))) restart(d); } - + return PA_HOOK_OK; } @@ -182,7 +182,7 @@ static pa_hook_result_t source_output_unlink_hook_cb(pa_core *c, pa_source_outpu if ((d = pa_hashmap_get(u->device_infos, s->source))) restart(d); } - + return PA_HOOK_OK; } @@ -196,7 +196,7 @@ static pa_hook_result_t sink_input_move_hook_cb(pa_core *c, pa_sink_input *s, st if ((d = pa_hashmap_get(u->device_infos, s->sink))) restart(d); } - + return PA_HOOK_OK; } @@ -208,7 +208,7 @@ static pa_hook_result_t sink_input_move_post_hook_cb(pa_core *c, pa_sink_input * if ((d = pa_hashmap_get(u->device_infos, s->sink))) resume(d); - + return PA_HOOK_OK; } @@ -223,7 +223,7 @@ static pa_hook_result_t source_output_move_hook_cb(pa_core *c, pa_source_output if ((d = pa_hashmap_get(u->device_infos, s->source))) restart(d); } - + return PA_HOOK_OK; } @@ -235,7 +235,7 @@ static pa_hook_result_t source_output_move_post_hook_cb(pa_core *c, pa_source_ou if ((d = pa_hashmap_get(u->device_infos, s->source))) resume(d); - + return PA_HOOK_OK; } @@ -243,7 +243,7 @@ static pa_hook_result_t device_new_hook_cb(pa_core *c, pa_object *o, struct user struct device_info *d; pa_source *source; pa_sink *sink; - + pa_assert(c); pa_object_assert_ref(o); pa_assert(u); @@ -252,12 +252,6 @@ static pa_hook_result_t device_new_hook_cb(pa_core *c, pa_object *o, struct user sink = pa_sink_isinstance(o) ? PA_SINK(o) : NULL; pa_assert(source || sink); - - if (source && !(source->flags & PA_SOURCE_CAN_SUSPEND)) - return PA_HOOK_OK; - - if (sink && !(sink->flags & PA_SINK_CAN_SUSPEND)) - return PA_HOOK_OK; d = pa_xnew(struct device_info, 1); d->userdata = u; @@ -275,20 +269,20 @@ static pa_hook_result_t device_new_hook_cb(pa_core *c, pa_object *o, struct user static void device_info_free(struct device_info *d) { pa_assert(d); - + if (d->source) pa_source_unref(d->source); if (d->sink) pa_sink_unref(d->sink); - + d->userdata->core->mainloop->time_free(d->time_event); - + pa_xfree(d); } static pa_hook_result_t device_unlink_hook_cb(pa_core *c, pa_object *o, struct userdata *u) { struct device_info *d; - + pa_assert(c); pa_object_assert_ref(o); pa_assert(u); @@ -311,14 +305,14 @@ static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *o, s if (pa_sink_isinstance(o)) { pa_sink *s = PA_SINK(o); - + if (pa_sink_used_by(s) <= 0) { pa_sink_state_t state = pa_sink_get_state(s); if (state == PA_SINK_RUNNING || state == PA_SINK_IDLE) restart(d); } - + } else if (pa_source_isinstance(o)) { pa_source *s = PA_SOURCE(o); @@ -329,7 +323,7 @@ static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *o, s restart(d); } } - + return PA_HOOK_OK; } @@ -352,7 +346,7 @@ int pa__init(pa_module*m) { pa_log("Failed to parse timeout value."); goto fail; } - + m->userdata = u = pa_xnew(struct userdata, 1); u->core = m->core; u->timeout = timeout; @@ -380,29 +374,29 @@ int pa__init(pa_module*m) { u->sink_input_move_post_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_POST], (pa_hook_cb_t) sink_input_move_post_hook_cb, u); u->source_output_move_post_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_POST], (pa_hook_cb_t) source_output_move_post_hook_cb, u); - + pa_modargs_free(ma); return 0; fail: - + if (ma) pa_modargs_free(ma); - + return -1; } void pa__done(pa_module*m) { struct userdata *u; struct device_info *d; - + pa_assert(m); if (!m->userdata) return; u = m->userdata; - + if (u->sink_new_slot) pa_hook_slot_free(u->sink_new_slot); if (u->sink_unlink_slot) @@ -439,6 +433,6 @@ void pa__done(pa_module*m) { device_info_free(d); pa_hashmap_free(u->device_infos, NULL, NULL); - + pa_xfree(u); } diff --git a/src/pulse/def.h b/src/pulse/def.h index 4102ba6e..c2816234 100644 --- a/src/pulse/def.h +++ b/src/pulse/def.h @@ -300,16 +300,14 @@ typedef enum pa_seek_mode { typedef enum pa_sink_flags { PA_SINK_HW_VOLUME_CTRL = 1, /**< Supports hardware volume control */ PA_SINK_LATENCY = 2, /**< Supports latency querying */ - PA_SINK_HARDWARE = 4, /**< Is a hardware sink of some kind, in contrast to "virtual"/software sinks \since 0.9.3 */ - PA_SINK_CAN_SUSPEND = 8 /**< Can suspend \since 0.9.7 */ + PA_SINK_HARDWARE = 4 /**< Is a hardware sink of some kind, in contrast to "virtual"/software sinks \since 0.9.3 */ } pa_sink_flags_t; /** Special source flags. \since 0.8 */ typedef enum pa_source_flags { PA_SOURCE_HW_VOLUME_CTRL = 1, /**< Supports hardware volume control */ PA_SOURCE_LATENCY = 2, /**< Supports latency querying */ - PA_SOURCE_HARDWARE = 4, /**< Is a hardware source of some kind, in contrast to "virtual"/software source \since 0.9.3 */ - PA_SOURCE_CAN_SUSPEND = 8 /**< Can suspend \since 0.9.7 */ + PA_SOURCE_HARDWARE = 4 /**< Is a hardware source of some kind, in contrast to "virtual"/software source \since 0.9.3 */ } pa_source_flags_t; /** A generic free() like callback prototype */ diff --git a/src/pulse/stream.c b/src/pulse/stream.c index 6d14a70a..47906a5c 100644 --- a/src/pulse/stream.c +++ b/src/pulse/stream.c @@ -423,7 +423,7 @@ static void create_stream_complete(pa_stream *s) { tv.tv_usec += LATENCY_IPOL_INTERVAL_USEC; /* every 100 ms */ pa_assert(!s->auto_timing_update_event); s->auto_timing_update_event = s->mainloop->time_new(s->mainloop, &tv, &auto_timing_update_callback, s); - } + } } void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) { @@ -497,7 +497,7 @@ void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED s->state = PA_STREAM_READY; request_auto_timing_update(s, 1); s->state = PA_STREAM_CREATING; - + } else create_stream_complete(s); @@ -540,12 +540,12 @@ static int create_stream( if (attr) s->buffer_attr = *attr; else { - /* half a second */ + /* half a second, with minimum request of 10 ms */ s->buffer_attr.tlength = pa_bytes_per_second(&s->sample_spec)/2; s->buffer_attr.maxlength = (s->buffer_attr.tlength*3)/2; - s->buffer_attr.minreq = s->buffer_attr.tlength/100; + s->buffer_attr.minreq = s->buffer_attr.tlength/50; s->buffer_attr.prebuf = s->buffer_attr.tlength - s->buffer_attr.minreq; - s->buffer_attr.fragsize = s->buffer_attr.tlength/100; + s->buffer_attr.fragsize = s->buffer_attr.tlength/50; } if (!dev) @@ -921,7 +921,7 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command, } /* First, let's complete the initialization, if necessary. */ - if (o->stream->state == PA_STREAM_CREATING) + if (o->stream->state == PA_STREAM_CREATING) create_stream_complete(o->stream); if (o->stream->latency_update_callback) diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c index bac61dc9..ec220198 100644 --- a/src/pulsecore/cli-text.c +++ b/src/pulsecore/cli-text.c @@ -111,7 +111,7 @@ char *pa_sink_list_to_string(pa_core *c) { " %c index: %u\n" "\tname: <%s>\n" "\tdriver: <%s>\n" - "\tflags: %s%s%s%s\n" + "\tflags: %s%s%s\n" "\tstate: %s\n" "\tvolume: <%s>\n" "\tmute: <%i>\n" @@ -119,7 +119,7 @@ char *pa_sink_list_to_string(pa_core *c) { "\tmonitor source: <%u>\n" "\tsample spec: <%s>\n" "\tchannel map: <%s>\n" - "\tused by: <%u>\n", + "\tused by: <%u>\n", c->default_sink_name && !strcmp(sink->name, c->default_sink_name) ? '*' : ' ', sink->index, sink->name, @@ -127,7 +127,6 @@ char *pa_sink_list_to_string(pa_core *c) { sink->flags & PA_SINK_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "", sink->flags & PA_SINK_LATENCY ? "LATENCY " : "", sink->flags & PA_SINK_HARDWARE ? "HARDWARE " : "", - sink->flags & PA_SINK_CAN_SUSPEND ? "CAN_SUSPEND " : "", state_table[pa_sink_get_state(sink)], pa_cvolume_snprint(cv, sizeof(cv), pa_sink_get_volume(sink)), !!pa_sink_get_mute(sink), @@ -171,7 +170,7 @@ char *pa_source_list_to_string(pa_core *c) { " %c index: %u\n" "\tname: <%s>\n" "\tdriver: <%s>\n" - "\tflags: %s%s%s%s\n" + "\tflags: %s%s%s\n" "\tstate: %s\n" "\tvolume: <%s>\n" "\tmute: <%u>\n" @@ -186,7 +185,6 @@ char *pa_source_list_to_string(pa_core *c) { source->flags & PA_SOURCE_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "", source->flags & PA_SOURCE_LATENCY ? "LATENCY " : "", source->flags & PA_SOURCE_HARDWARE ? "HARDWARE " : "", - source->flags & PA_SOURCE_CAN_SUSPEND ? "CAN_SUSPEND " : "", state_table[pa_source_get_state(source)], pa_cvolume_snprint(cv, sizeof(cv), pa_source_get_volume(source)), !!pa_source_get_mute(source), diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index b814f837..830960a5 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -170,9 +170,6 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state) { if (s->state == state) return 0; - if (state == PA_SINK_SUSPENDED && !(s->flags & PA_SINK_CAN_SUSPEND)) - return -1; - if ((s->state == PA_SINK_SUSPENDED && PA_SINK_OPENED(state)) || (PA_SINK_OPENED(s->state) && state == PA_SINK_SUSPENDED)) { pa_sink_input *i; diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 9745a13e..20088c74 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -145,9 +145,6 @@ static int source_set_state(pa_source *s, pa_source_state_t state) { if (s->state == state) return 0; - if (state == PA_SOURCE_SUSPENDED && !(s->flags & PA_SOURCE_CAN_SUSPEND)) - return -1; - if ((s->state == PA_SOURCE_SUSPENDED && PA_SOURCE_OPENED(state)) || (PA_SOURCE_OPENED(s->state) && state == PA_SOURCE_SUSPENDED)) { pa_source_output *o; -- cgit From 55651ec215b8359aaf3668cc37eb270847563cc3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 24 Sep 2007 16:24:23 +0000 Subject: don't count streams using the monitor source in pa_sink_used_by(), because this would disallow suspending a sink ehn an rtp stream is connected git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1895 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/cli-text.c | 12 ++++++++---- src/pulsecore/sink.c | 11 ++++++----- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c index ec220198..6683e697 100644 --- a/src/pulsecore/cli-text.c +++ b/src/pulsecore/cli-text.c @@ -119,7 +119,8 @@ char *pa_sink_list_to_string(pa_core *c) { "\tmonitor source: <%u>\n" "\tsample spec: <%s>\n" "\tchannel map: <%s>\n" - "\tused by: <%u>\n", + "\tused by: <%u>\n" + "\tlinked by: <%u>\n", c->default_sink_name && !strcmp(sink->name, c->default_sink_name) ? '*' : ' ', sink->index, sink->name, @@ -134,7 +135,8 @@ char *pa_sink_list_to_string(pa_core *c) { sink->monitor_source ? sink->monitor_source->index : PA_INVALID_INDEX, pa_sample_spec_snprint(ss, sizeof(ss), &sink->sample_spec), pa_channel_map_snprint(cm, sizeof(cm), &sink->channel_map), - pa_sink_used_by(sink)); + pa_sink_used_by(sink), + pa_sink_linked_by(sink)); if (sink->module) pa_strbuf_printf(s, "\tmodule: <%u>\n", sink->module->index); @@ -177,7 +179,8 @@ char *pa_source_list_to_string(pa_core *c) { "\tlatency: <%0.0f usec>\n" "\tsample spec: <%s>\n" "\tchannel map: <%s>\n" - "\tused by: <%u>\n", + "\tused by: <%u>\n" + "\tlinked by: <%u>\n", c->default_source_name && !strcmp(source->name, c->default_source_name) ? '*' : ' ', source->index, source->name, @@ -191,7 +194,8 @@ char *pa_source_list_to_string(pa_core *c) { (double) pa_source_get_latency(source), pa_sample_spec_snprint(ss, sizeof(ss), &source->sample_spec), pa_channel_map_snprint(cm, sizeof(cm), &source->channel_map), - pa_source_used_by(source)); + pa_source_used_by(source), + pa_source_linked_by(source)); if (source->monitor_of) pa_strbuf_printf(s, "\tmonitor_of: <%u>\n", source->monitor_of->index); diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 830960a5..733a9d9e 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -775,8 +775,11 @@ unsigned pa_sink_linked_by(pa_sink *s) { ret = pa_idxset_size(s->inputs); + /* We add in the number of streams connected to us here. Please + * not the asymmmetry to pa_sink_used_by()! */ + if (s->monitor_source) - ret += pa_source_used_by(s->monitor_source); + ret += pa_source_linked_by(s->monitor_source); return ret; } @@ -788,13 +791,11 @@ unsigned pa_sink_used_by(pa_sink *s) { pa_assert(PA_SINK_LINKED(s->state)); ret = pa_idxset_size(s->inputs); - pa_assert(ret >= s->n_corked); - ret -= s->n_corked; - if (s->monitor_source) - ret += pa_source_used_by(s->monitor_source); + /* Streams connected to our monitor source do not matter for + * pa_sink_used_by()!.*/ return ret; } -- cgit From ef020c6e8918c0481451e5640e95faf56ed453a5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 24 Sep 2007 17:14:00 +0000 Subject: fix stream corking: ignore pa_sink_input() when we are in corked state git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1896 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink-input.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 9360bee0..4a9ba6af 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -397,7 +397,7 @@ int pa_sink_input_peek(pa_sink_input *i, size_t length, pa_memchunk *chunk, pa_c pa_assert(chunk); pa_assert(volume); - if (!i->peek || !i->drop || i->thread_info.state == PA_SINK_INPUT_UNLINKED || i->thread_info.state == PA_SINK_INPUT_CORKED) + if (!i->peek || !i->drop || i->thread_info.state == PA_SINK_INPUT_CORKED) goto finish; pa_assert(i->thread_info.state == PA_SINK_INPUT_RUNNING || i->thread_info.state == PA_SINK_INPUT_DRAINED); @@ -518,6 +518,9 @@ void pa_sink_input_drop(pa_sink_input *i, size_t length) { pa_assert(pa_frame_aligned(length, &i->sink->sample_spec)); pa_assert(length > 0); + if (!i->peek || !i->drop || i->thread_info.state == PA_SINK_INPUT_CORKED) + return; + if (i->thread_info.move_silence > 0) { if (i->thread_info.move_silence >= length) { -- cgit From e37fa011ac18742303c351aee1cb2f6739e04b82 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 24 Sep 2007 21:47:22 +0000 Subject: add hooks for name/description changes of sinks/source and streams git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1897 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core.h | 8 ++++++-- src/pulsecore/sink-input.c | 5 ++++- src/pulsecore/sink.c | 5 ++++- src/pulsecore/source-output.c | 5 ++++- src/pulsecore/source.c | 5 ++++- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index c8d75800..b841c20e 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -47,22 +47,26 @@ typedef enum pa_core_hook { PA_CORE_HOOK_SINK_UNLINK, PA_CORE_HOOK_SINK_UNLINK_POST, PA_CORE_HOOK_SINK_STATE_CHANGED, + PA_CORE_HOOK_SINK_DESCRIPTION_CHANGED, PA_CORE_HOOK_SOURCE_NEW_POST, PA_CORE_HOOK_SOURCE_UNLINK, PA_CORE_HOOK_SOURCE_UNLINK_POST, PA_CORE_HOOK_SOURCE_STATE_CHANGED, + PA_CORE_HOOK_SOURCE_DESCRIPTION_CHANGED, PA_CORE_HOOK_SINK_INPUT_NEW, PA_CORE_HOOK_SINK_INPUT_PUT, PA_CORE_HOOK_SINK_INPUT_UNLINK, PA_CORE_HOOK_SINK_INPUT_UNLINK_POST, PA_CORE_HOOK_SINK_INPUT_MOVE, PA_CORE_HOOK_SINK_INPUT_MOVE_POST, + PA_CORE_HOOK_SINK_INPUT_NAME_CHANGED, PA_CORE_HOOK_SOURCE_OUTPUT_NEW, PA_CORE_HOOK_SOURCE_OUTPUT_PUT, PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK, PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK_POST, PA_CORE_HOOK_SOURCE_OUTPUT_MOVE, PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_POST, + PA_CORE_HOOK_SOURCE_OUTPUT_NAME_CHANGED, PA_CORE_HOOK_MAX } pa_core_hook_t; @@ -90,7 +94,7 @@ struct pa_core { pa_sample_spec default_sample_spec; unsigned default_n_fragments, default_fragment_size_msec; - + pa_time_event *module_auto_unload_event; pa_defer_event *module_defer_unload_event; @@ -110,7 +114,7 @@ struct pa_core { int disallow_module_loading, running_as_daemon; pa_resample_method_t resample_method; int is_system_instance; - int high_priority; + int high_priority; /* hooks */ pa_hook hooks[PA_CORE_HOOK_MAX]; diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 4a9ba6af..632cf024 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -683,7 +683,10 @@ void pa_sink_input_set_name(pa_sink_input *i, const char *name) { pa_xfree(i->name); i->name = pa_xstrdup(name); - pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); + if (PA_SINK_INPUT_LINKED(i->state)) { + pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_NAME_CHANGED], i); + pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); + } } pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i) { diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 733a9d9e..46f890de 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -764,7 +764,10 @@ void pa_sink_set_description(pa_sink *s, const char *description) { pa_xfree(n); } - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + if (PA_SINK_LINKED(s->state)) { + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_DESCRIPTION_CHANGED], s); + } } unsigned pa_sink_linked_by(pa_sink *s) { diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 1991613e..f83ca3b6 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -356,7 +356,10 @@ void pa_source_output_set_name(pa_source_output *o, const char *name) { pa_xfree(o->name); o->name = pa_xstrdup(name); - pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); + if (PA_SOURCE_OUTPUT_LINKED(o->state)) { + pa_hook_fire(&o->source->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_NAME_CHANGED], o); + pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); + } } pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o) { diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 20088c74..2106edc3 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -418,7 +418,10 @@ void pa_source_set_description(pa_source *s, const char *description) { pa_xfree(s->description); s->description = pa_xstrdup(description); - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + if (PA_SOURCE_LINKED(s->state)) { + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_DESCRIPTION_CHANGED], s); + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + } } void pa_source_set_asyncmsgq(pa_source *s, pa_asyncmsgq *q) { -- cgit From 3c75d35dd004a55753934ed328d7e037cbf8c596 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 24 Sep 2007 21:49:02 +0000 Subject: rework zeroconf service publishing, to use synchronous hooks instead of asynchronous subscription events. Don't push autoload entries anymore. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1898 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-zeroconf-publish.c | 538 +++++++++++++--------------------- 1 file changed, 198 insertions(+), 340 deletions(-) diff --git a/src/modules/module-zeroconf-publish.c b/src/modules/module-zeroconf-publish.c index 8b62ffbd..ac9d0477 100644 --- a/src/modules/module-zeroconf-publish.c +++ b/src/modules/module-zeroconf-publish.c @@ -39,7 +39,6 @@ #include #include -#include #include #include #include @@ -71,53 +70,43 @@ struct service { struct userdata *userdata; AvahiEntryGroup *entry_group; char *service_name; - char *name; - enum { UNPUBLISHED, PUBLISHED_REAL, PUBLISHED_AUTOLOAD } published ; - - struct { - int valid; - pa_namereg_type_t type; - uint32_t index; - } loaded; - - struct { - int valid; - pa_namereg_type_t type; - uint32_t index; - } autoload; + pa_object *device; }; struct userdata { pa_core *core; AvahiPoll *avahi_poll; AvahiClient *client; + pa_hashmap *services; - pa_dynarray *sink_dynarray, *source_dynarray, *autoload_dynarray; - pa_subscription *subscription; char *service_name; AvahiEntryGroup *main_entry_group; uint16_t port; + + pa_hook_slot *sink_new_slot, *source_new_slot, *sink_unlink_slot, *source_unlink_slot, *sink_changed_slot, *source_changed_slot; }; -static void get_service_data(struct userdata *u, struct service *s, pa_sample_spec *ret_ss, char **ret_description) { - pa_assert(u); +static void get_service_data(struct service *s, pa_sample_spec *ret_ss, pa_channel_map *ret_map, const char **ret_name, const char **ret_description) { pa_assert(s); - pa_assert(s->loaded.valid); pa_assert(ret_ss); pa_assert(ret_description); - if (s->loaded.type == PA_NAMEREG_SINK) { - pa_sink *sink = PA_SINK(pa_idxset_get_by_index(u->core->sinks, s->loaded.index)); - pa_sink_assert_ref(sink); + if (pa_sink_isinstance(s->device)) { + pa_sink *sink = PA_SINK(s->device); + *ret_ss = sink->sample_spec; + *ret_map = sink->channel_map; + *ret_name = sink->name; *ret_description = sink->description; - - } else if (s->loaded.type == PA_NAMEREG_SOURCE) { - pa_source *source = PA_SOURCE(pa_idxset_get_by_index(u->core->sources, s->loaded.index)); - pa_source_assert_ref(source); + + } else if (pa_source_isinstance(s->device)) { + pa_source *source = PA_SOURCE(s->device); + *ret_ss = source->sample_spec; + *ret_map = source->channel_map; + *ret_name = source->name; *ret_description = source->description; } else pa_assert_not_reached(); @@ -125,7 +114,7 @@ static void get_service_data(struct userdata *u, struct service *s, pa_sample_sp static AvahiStringList* txt_record_server_data(pa_core *c, AvahiStringList *l) { char s[128]; - + pa_core_assert_ref(c); l = avahi_string_list_add_pair(l, "server-version", PACKAGE_NAME" "PACKAGE_VERSION); @@ -136,340 +125,217 @@ static AvahiStringList* txt_record_server_data(pa_core *c, AvahiStringList *l) { return l; } -static int publish_service(struct userdata *u, struct service *s); +static int publish_service(struct service *s); static void service_entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) { struct service *s = userdata; pa_assert(s); - if (state == AVAHI_ENTRY_GROUP_COLLISION) { - char *t; + switch (state) { + + case AVAHI_ENTRY_GROUP_ESTABLISHED: + pa_log_info("Successfully established service %s.", s->service_name); + break; + + case AVAHI_ENTRY_GROUP_COLLISION: { + char *t; + + t = avahi_alternative_service_name(s->service_name); + pa_log_info("Name collision, renaming %s to %s.", s->service_name, t); + pa_xfree(s->service_name); + s->service_name = t; - t = avahi_alternative_service_name(s->service_name); - pa_xfree(s->service_name); - s->service_name = t; + publish_service(s); + break; + } + + case AVAHI_ENTRY_GROUP_FAILURE: { + pa_log("Failed to register service: %s", avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g)))); + + avahi_entry_group_free(g); + s->entry_group = NULL; + + break; + } - publish_service(s->userdata, s); + case AVAHI_ENTRY_GROUP_UNCOMMITED: + case AVAHI_ENTRY_GROUP_REGISTERING: + ; } } -static int publish_service(struct userdata *u, struct service *s) { +static void service_free(struct service *s); + +static int publish_service(struct service *s) { int r = -1; AvahiStringList *txt = NULL; + const char *description = NULL, *name = NULL; + pa_sample_spec ss; + pa_channel_map map; + char cm[PA_CHANNEL_MAP_SNPRINT_MAX]; - pa_assert(u); pa_assert(s); - if (!u->client || avahi_client_get_state(u->client) != AVAHI_CLIENT_S_RUNNING) - return 0; - - if ((s->published == PUBLISHED_REAL && s->loaded.valid) || - (s->published == PUBLISHED_AUTOLOAD && s->autoload.valid && !s->loaded.valid)) + if (!s->userdata->client || avahi_client_get_state(s->userdata->client) != AVAHI_CLIENT_S_RUNNING) return 0; - if (s->published != UNPUBLISHED) { + if (!s->entry_group) { + if (!(s->entry_group = avahi_entry_group_new(s->userdata->client, service_entry_group_callback, s))) { + pa_log("avahi_entry_group_new(): %s", avahi_strerror(avahi_client_errno(s->userdata->client))); + goto finish; + } + } else avahi_entry_group_reset(s->entry_group); - s->published = UNPUBLISHED; - } - if (s->loaded.valid || s->autoload.valid) { - pa_namereg_type_t type; + txt = txt_record_server_data(s->userdata->core, txt); - if (!s->entry_group) { - if (!(s->entry_group = avahi_entry_group_new(u->client, service_entry_group_callback, s))) { - pa_log("avahi_entry_group_new(): %s", avahi_strerror(avahi_client_errno(u->client))); - goto finish; - } - } + get_service_data(s, &ss, &map, &name, &description); + txt = avahi_string_list_add_pair(txt, "device", name); + txt = avahi_string_list_add_printf(txt, "rate=%u", ss.rate); + txt = avahi_string_list_add_printf(txt, "channels=%u", ss.channels); + txt = avahi_string_list_add_pair(txt, "format", pa_sample_format_to_string(ss.format)); + txt = avahi_string_list_add_pair(txt, "channel_map", pa_channel_map_snprint(cm, sizeof(cm), &map)); - txt = avahi_string_list_add_pair(txt, "device", s->name); - txt = txt_record_server_data(u->core, txt); - - if (s->loaded.valid) { - char *description; - pa_sample_spec ss; - - get_service_data(u, s, &ss, &description); - - txt = avahi_string_list_add_printf(txt, "rate=%u", ss.rate); - txt = avahi_string_list_add_printf(txt, "channels=%u", ss.channels); - txt = avahi_string_list_add_pair(txt, "format", pa_sample_format_to_string(ss.format)); - if (description) - txt = avahi_string_list_add_pair(txt, "description", description); - - type = s->loaded.type; - } else if (s->autoload.valid) - type = s->autoload.type; - - if (avahi_entry_group_add_service_strlst( - s->entry_group, - AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, - 0, - s->service_name, - type == PA_NAMEREG_SINK ? SERVICE_TYPE_SINK : SERVICE_TYPE_SOURCE, - NULL, - NULL, - u->port, - txt) < 0) { - - pa_log("avahi_entry_group_add_service_strlst(): %s", avahi_strerror(avahi_client_errno(u->client))); - goto finish; - } + if (avahi_entry_group_add_service_strlst( + s->entry_group, + AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, + 0, + s->service_name, + pa_sink_isinstance(s->device) ? SERVICE_TYPE_SINK : SERVICE_TYPE_SOURCE, + NULL, + NULL, + s->userdata->port, + txt) < 0) { - if (avahi_entry_group_commit(s->entry_group) < 0) { - pa_log("avahi_entry_group_commit(): %s", avahi_strerror(avahi_client_errno(u->client))); - goto finish; - } + pa_log("avahi_entry_group_add_service_strlst(): %s", avahi_strerror(avahi_client_errno(s->userdata->client))); + goto finish; + } - if (s->loaded.valid) - s->published = PUBLISHED_REAL; - else if (s->autoload.valid) - s->published = PUBLISHED_AUTOLOAD; + if (avahi_entry_group_commit(s->entry_group) < 0) { + pa_log("avahi_entry_group_commit(): %s", avahi_strerror(avahi_client_errno(s->userdata->client))); + goto finish; } r = 0; + pa_log_debug("Successfully created entry group for %s.", s->service_name); finish: - if (s->published == UNPUBLISHED) { - /* Remove this service */ - - if (s->entry_group) - avahi_entry_group_free(s->entry_group); + /* Remove this service */ + if (r < 0) + service_free(s); - pa_hashmap_remove(u->services, s->name); - pa_xfree(s->name); - pa_xfree(s->service_name); - pa_xfree(s); - } - - if (txt) - avahi_string_list_free(txt); + avahi_string_list_free(txt); return r; } -static struct service *get_service(struct userdata *u, const char *name, const char *description) { +static struct service *get_service(struct userdata *u, pa_object *device) { struct service *s; char hn[64], un[64]; + const char *n; + + pa_assert(u); + pa_object_assert_ref(device); - if ((s = pa_hashmap_get(u->services, name))) + if ((s = pa_hashmap_get(u->services, device))) return s; s = pa_xnew(struct service, 1); s->userdata = u; s->entry_group = NULL; - s->published = UNPUBLISHED; - s->name = pa_xstrdup(name); - s->loaded.valid = s->autoload.valid = 0; - s->service_name = pa_truncate_utf8(pa_sprintf_malloc("%s@%s: %s", pa_get_user_name(un, sizeof(un)), pa_get_host_name(hn, sizeof(hn)), description ? description : s->name), AVAHI_LABEL_MAX-1); - - pa_hashmap_put(u->services, s->name, s); - - return s; -} - -static int publish_sink(struct userdata *u, pa_sink *s) { - struct service *svc; - int ret; - - pa_assert(u); - pa_sink_assert_ref(s); - - svc = get_service(u, s->name, s->description); - if (svc->loaded.valid) - return publish_service(u, svc); - - svc->loaded.valid = 1; - svc->loaded.type = PA_NAMEREG_SINK; - svc->loaded.index = s->index; - - if ((ret = publish_service(u, svc)) < 0) - return ret; - - pa_dynarray_put(u->sink_dynarray, s->index, svc); - return ret; -} - -static int publish_source(struct userdata *u, pa_source *s) { - struct service *svc; - int ret; - - pa_assert(u); - pa_source_assert_ref(s); - - svc = get_service(u, s->name, s->description); - if (svc->loaded.valid) - return publish_service(u, svc); - - svc->loaded.valid = 1; - svc->loaded.type = PA_NAMEREG_SOURCE; - svc->loaded.index = s->index; + s->device = device; + + if (pa_sink_isinstance(device)) { + if (!(n = PA_SINK(device)->description)) + n = PA_SINK(device)->name; + } else { + if (!(n = PA_SOURCE(device)->description)) + n = PA_SOURCE(device)->name; + } - pa_dynarray_put(u->source_dynarray, s->index, svc); + s->service_name = pa_truncate_utf8(pa_sprintf_malloc("%s@%s: %s", + pa_get_user_name(un, sizeof(un)), + pa_get_host_name(hn, sizeof(hn)), + n), + AVAHI_LABEL_MAX-1); - if ((ret = publish_service(u, svc)) < 0) - return ret; + pa_hashmap_put(u->services, s->device, s); - pa_dynarray_put(u->sink_dynarray, s->index, svc); - return ret; + return s; } -static int publish_autoload(struct userdata *u, pa_autoload_entry *s) { - struct service *svc; - int ret; - - pa_assert(u); +static void service_free(struct service *s) { pa_assert(s); - svc = get_service(u, s->name, NULL); - if (svc->autoload.valid) - return publish_service(u, svc); - - svc->autoload.valid = 1; - svc->autoload.type = s->type; - svc->autoload.index = s->index; + pa_hashmap_remove(s->userdata->services, s->device); - if ((ret = publish_service(u, svc)) < 0) - return ret; + if (s->entry_group) { + pa_log_debug("Removing entry group for %s.", s->service_name); + avahi_entry_group_free(s->entry_group); + } - pa_dynarray_put(u->autoload_dynarray, s->index, svc); - return ret; + pa_xfree(s->service_name); + pa_xfree(s); } -static int remove_sink(struct userdata *u, uint32_t idx) { - struct service *svc; - - pa_assert(u); - pa_assert(idx != PA_INVALID_INDEX); - - if (!(svc = pa_dynarray_get(u->sink_dynarray, idx))) - return 0; - - if (!svc->loaded.valid || svc->loaded.type != PA_NAMEREG_SINK) - return 0; +static pa_hook_result_t device_new_or_changed_cb(pa_core *c, pa_object *o, struct userdata *u) { + pa_assert(c); + pa_object_assert_ref(o); - svc->loaded.valid = 0; - pa_dynarray_put(u->sink_dynarray, idx, NULL); + publish_service(get_service(u, o)); - return publish_service(u, svc); + return PA_HOOK_OK; } -static int remove_source(struct userdata *u, uint32_t idx) { - struct service *svc; - - pa_assert(u); - pa_assert(idx != PA_INVALID_INDEX); - - if (!(svc = pa_dynarray_get(u->source_dynarray, idx))) - return 0; +static pa_hook_result_t device_unlink_cb(pa_core *c, pa_object *o, struct userdata *u) { + struct service *s; - if (!svc->loaded.valid || svc->loaded.type != PA_NAMEREG_SOURCE) - return 0; + pa_assert(c); + pa_object_assert_ref(o); - svc->loaded.valid = 0; - pa_dynarray_put(u->source_dynarray, idx, NULL); + if ((s = pa_hashmap_get(u->services, o))) + service_free(s); - return publish_service(u, svc); + return PA_HOOK_OK; } -static int remove_autoload(struct userdata *u, uint32_t idx) { - struct service *svc; - - pa_assert(u); - pa_assert(idx != PA_INVALID_INDEX); - - if (!(svc = pa_dynarray_get(u->autoload_dynarray, idx))) - return 0; - - if (!svc->autoload.valid) - return 0; - - svc->autoload.valid = 0; - pa_dynarray_put(u->autoload_dynarray, idx, NULL); - - return publish_service(u, svc); -} +static int publish_main_service(struct userdata *u); -static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { +static void main_entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) { struct userdata *u = userdata; - pa_assert(u); - pa_core_assert_ref(c); - switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) - - case PA_SUBSCRIPTION_EVENT_SINK: { - if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - pa_sink *sink; - - if ((sink = PA_SINK(pa_idxset_get_by_index(c->sinks, idx)))) { - if (publish_sink(u, sink) < 0) - goto fail; - } - } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - if (remove_sink(u, idx) < 0) - goto fail; - } + switch (state) { + case AVAHI_ENTRY_GROUP_ESTABLISHED: + pa_log_info("Successfully established main service."); break; - case PA_SUBSCRIPTION_EVENT_SOURCE: + case AVAHI_ENTRY_GROUP_COLLISION: { + char *t; - if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - pa_source *source; - - if ((source = PA_SOURCE(pa_idxset_get_by_index(c->sources, idx)))) { - if (publish_source(u, source) < 0) - goto fail; - } - } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - if (remove_source(u, idx) < 0) - goto fail; - } + t = avahi_alternative_service_name(u->service_name); + pa_log_info("Name collision: renaming main service %s to %s.", u->service_name, t); + pa_xfree(u->service_name); + u->service_name = t; + publish_main_service(u); break; + } - case PA_SUBSCRIPTION_EVENT_AUTOLOAD: - if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - pa_autoload_entry *autoload; - - if ((autoload = pa_idxset_get_by_index(c->autoload_idxset, idx))) { - if (publish_autoload(u, autoload) < 0) - goto fail; - } - } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - if (remove_autoload(u, idx) < 0) - goto fail; - } + case AVAHI_ENTRY_GROUP_FAILURE: { + pa_log("Failed to register main service: %s", avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g)))); + avahi_entry_group_free(g); + u->main_entry_group = NULL; break; - } - - return; - -fail: - if (u->subscription) { - pa_subscription_free(u->subscription); - u->subscription = NULL; - } -} - -static int publish_main_service(struct userdata *u); - -static void main_entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) { - struct userdata *u = userdata; - pa_assert(u); - - if (state == AVAHI_ENTRY_GROUP_COLLISION) { - char *t; - - t = avahi_alternative_service_name(u->service_name); - pa_xfree(u->service_name); - u->service_name = t; + } - publish_main_service(u); + case AVAHI_ENTRY_GROUP_UNCOMMITED: + case AVAHI_ENTRY_GROUP_REGISTERING: + break; } } @@ -478,7 +344,7 @@ static int publish_main_service(struct userdata *u) { int r = -1; pa_assert(u); - + if (!u->main_entry_group) { if (!(u->main_entry_group = avahi_entry_group_new(u->client, main_entry_group_callback, u))) { pa_log("avahi_entry_group_new() failed: %s", avahi_strerror(avahi_client_errno(u->client))); @@ -487,7 +353,7 @@ static int publish_main_service(struct userdata *u) { } else avahi_entry_group_reset(u->main_entry_group); - txt = txt_record_server_data(u->core, NULL); + txt = txt_record_server_data(u->core, txt); if (avahi_entry_group_add_service_strlst( u->main_entry_group, @@ -520,7 +386,6 @@ fail: static int publish_all_services(struct userdata *u) { pa_sink *sink; pa_source *source; - pa_autoload_entry *autoload; int r = -1; uint32_t idx; @@ -529,17 +394,10 @@ static int publish_all_services(struct userdata *u) { pa_log_debug("Publishing services in Zeroconf"); for (sink = PA_SINK(pa_idxset_first(u->core->sinks, &idx)); sink; sink = PA_SINK(pa_idxset_next(u->core->sinks, &idx))) - if (publish_sink(u, sink) < 0) - goto fail; + publish_service(get_service(u, PA_OBJECT(sink))); for (source = PA_SOURCE(pa_idxset_first(u->core->sources, &idx)); source; source = PA_SOURCE(pa_idxset_next(u->core->sources, &idx))) - if (publish_source(u, source) < 0) - goto fail; - - if (u->core->autoload_idxset) - for (autoload = pa_idxset_first(u->core->autoload_idxset, &idx); autoload; autoload = pa_idxset_next(u->core->autoload_idxset, &idx)) - if (publish_autoload(u, autoload) < 0) - goto fail; + publish_service(get_service(u, PA_OBJECT(source))); if (publish_main_service(u) < 0) goto fail; @@ -550,7 +408,7 @@ fail: return r; } -static void unpublish_all_services(struct userdata *u, int rem) { +static void unpublish_all_services(struct userdata *u, pa_bool_t rem) { void *state = NULL; struct service *s; @@ -561,27 +419,31 @@ static void unpublish_all_services(struct userdata *u, int rem) { while ((s = pa_hashmap_iterate(u->services, &state, NULL))) { if (s->entry_group) { if (rem) { + pa_log_debug("Removing entry group for %s.", s->service_name); avahi_entry_group_free(s->entry_group); s->entry_group = NULL; - } else + } else { avahi_entry_group_reset(s->entry_group); + pa_log_debug("Resetting entry group for %s.", s->service_name); + } } - - s->published = UNPUBLISHED; } if (u->main_entry_group) { if (rem) { + pa_log_debug("Removing main entry group."); avahi_entry_group_free(u->main_entry_group); u->main_entry_group = NULL; - } else + } else { avahi_entry_group_reset(u->main_entry_group); + pa_log_debug("Resetting main entry group."); + } } } static void client_callback(AvahiClient *c, AvahiClientState state, void *userdata) { struct userdata *u = userdata; - + pa_assert(c); pa_assert(u); @@ -593,13 +455,17 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void *userda break; case AVAHI_CLIENT_S_COLLISION: - unpublish_all_services(u, 0); + pa_log_debug("Host name collision"); + unpublish_all_services(u, FALSE); break; case AVAHI_CLIENT_FAILURE: if (avahi_client_errno(c) == AVAHI_ERR_DISCONNECTED) { int error; - unpublish_all_services(u, 1); + + pa_log_debug("Avahi daemon disconnected."); + + unpublish_all_services(u, TRUE); avahi_client_free(u->client); if (!(u->client = avahi_client_new(u->avahi_poll, AVAHI_CLIENT_NO_FAIL, client_callback, u, &error))) @@ -613,7 +479,7 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void *userda } int pa__init(pa_module*m) { - + struct userdata *u; uint32_t port = PA_NATIVE_DEFAULT_PORT; pa_modargs *ma = NULL; @@ -636,15 +502,14 @@ int pa__init(pa_module*m) { u->avahi_poll = pa_avahi_poll_new(m->core->mainloop); - u->services = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - u->sink_dynarray = pa_dynarray_new(); - u->source_dynarray = pa_dynarray_new(); - u->autoload_dynarray = pa_dynarray_new(); + u->services = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - u->subscription = pa_subscription_new(m->core, - PA_SUBSCRIPTION_MASK_SINK| - PA_SUBSCRIPTION_MASK_SOURCE| - PA_SUBSCRIPTION_MASK_AUTOLOAD, subscribe_callback, u); + u->sink_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_NEW_POST], (pa_hook_cb_t) device_new_or_changed_cb, u); + u->sink_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_DESCRIPTION_CHANGED], (pa_hook_cb_t) device_new_or_changed_cb, u); + u->sink_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], (pa_hook_cb_t) device_unlink_cb, u); + u->source_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_NEW_POST], (pa_hook_cb_t) device_new_or_changed_cb, u); + u->source_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_DESCRIPTION_CHANGED], (pa_hook_cb_t) device_new_or_changed_cb, u); + u->source_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], (pa_hook_cb_t) device_unlink_cb, u); u->main_entry_group = NULL; @@ -668,21 +533,6 @@ fail: return -1; } -static void service_free(void *p, void *userdata) { - struct service *s = p; - struct userdata *u = userdata; - - pa_assert(s); - pa_assert(u); - - if (s->entry_group) - avahi_entry_group_free(s->entry_group); - - pa_xfree(s->service_name); - pa_xfree(s->name); - pa_xfree(s); -} - void pa__done(pa_module*m) { struct userdata*u; pa_assert(m); @@ -690,18 +540,27 @@ void pa__done(pa_module*m) { if (!(u = m->userdata)) return; - if (u->services) - pa_hashmap_free(u->services, service_free, u); + if (u->services) { + struct service *s; + + while ((s = pa_hashmap_get_first(u->services))) + service_free(s); - if (u->subscription) - pa_subscription_free(u->subscription); + pa_hashmap_free(u->services, NULL, NULL); + } - if (u->sink_dynarray) - pa_dynarray_free(u->sink_dynarray, NULL, NULL); - if (u->source_dynarray) - pa_dynarray_free(u->source_dynarray, NULL, NULL); - if (u->autoload_dynarray) - pa_dynarray_free(u->autoload_dynarray, NULL, NULL); + if (u->sink_new_slot) + pa_hook_slot_free(u->sink_new_slot); + if (u->source_new_slot) + pa_hook_slot_free(u->source_new_slot); + if (u->sink_changed_slot) + pa_hook_slot_free(u->sink_changed_slot); + if (u->source_changed_slot) + pa_hook_slot_free(u->source_changed_slot); + if (u->sink_unlink_slot) + pa_hook_slot_free(u->sink_unlink_slot); + if (u->source_unlink_slot) + pa_hook_slot_free(u->source_unlink_slot); if (u->main_entry_group) avahi_entry_group_free(u->main_entry_group); @@ -715,4 +574,3 @@ void pa__done(pa_module*m) { pa_xfree(u->service_name); pa_xfree(u); } - -- cgit From ac86fa1b9725d602b68410a56ebee355877f769d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 24 Sep 2007 22:41:00 +0000 Subject: fix IDLE vs. RUNNING state handling of sinks/sources when changing cork status for streams git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1899 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink-input.c | 5 +++++ src/pulsecore/source-output.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 632cf024..e99e0a08 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -233,6 +233,8 @@ static void update_n_corked(pa_sink_input *i, pa_sink_input_state_t state) { pa_assert_se(i->sink->n_corked -- >= 1); else if (i->state != PA_SINK_INPUT_CORKED && state == PA_SINK_INPUT_CORKED) i->sink->n_corked++; + + pa_sink_update_status(i->sink); } static int sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) { @@ -350,6 +352,9 @@ void pa_sink_input_put(pa_sink_input *i) { i->thread_info.volume = i->volume; i->thread_info.muted = i->muted; + if (i->state == PA_SINK_INPUT_CORKED) + i->sink->n_corked++; + pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_ADD_INPUT, i, 0, NULL); pa_sink_update_status(i->sink); diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index f83ca3b6..207e2a39 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -188,6 +188,8 @@ static int source_output_set_state(pa_source_output *o, pa_source_output_state_t else if (o->state != PA_SOURCE_OUTPUT_CORKED && state == PA_SOURCE_OUTPUT_CORKED) o->source->n_corked++; + pa_source_update_status(o->source); + o->state = state; return 0; @@ -262,6 +264,9 @@ void pa_source_output_put(pa_source_output *o) { o->thread_info.state = o->state = o->flags & PA_SOURCE_OUTPUT_START_CORKED ? PA_SOURCE_OUTPUT_CORKED : PA_SOURCE_OUTPUT_RUNNING; + if (o->state == PA_SOURCE_OUTPUT_CORKED) + o->source->n_corked++; + pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o->source), PA_SOURCE_MESSAGE_ADD_OUTPUT, o, 0, NULL); pa_source_update_status(o->source); -- cgit From f0f9df999045c202def3a46589a98bdae86127ea Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 24 Sep 2007 23:31:22 +0000 Subject: * add new state changed hook for streams * update sink->n_corked properly when moving streams git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1900 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core.h | 2 ++ src/pulsecore/sink-input.c | 8 ++++++++ src/pulsecore/source-output.c | 8 ++++++++ 3 files changed, 18 insertions(+) diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index b841c20e..dfa80f8d 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -60,6 +60,7 @@ typedef enum pa_core_hook { PA_CORE_HOOK_SINK_INPUT_MOVE, PA_CORE_HOOK_SINK_INPUT_MOVE_POST, PA_CORE_HOOK_SINK_INPUT_NAME_CHANGED, + PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED, PA_CORE_HOOK_SOURCE_OUTPUT_NEW, PA_CORE_HOOK_SOURCE_OUTPUT_PUT, PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK, @@ -67,6 +68,7 @@ typedef enum pa_core_hook { PA_CORE_HOOK_SOURCE_OUTPUT_MOVE, PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_POST, PA_CORE_HOOK_SOURCE_OUTPUT_NAME_CHANGED, + PA_CORE_HOOK_SOURCE_OUTPUT_STATE_CHANGED, PA_CORE_HOOK_MAX } pa_core_hook_t; diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index e99e0a08..ce48765a 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -262,6 +262,9 @@ static int sink_input_set_state(pa_sink_input *i, pa_sink_input_state_t state) { ssync->state = state; } + if (state != PA_SINK_INPUT_UNLINKED) + pa_hook_fire(&i->sink->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], i); + return 0; } @@ -825,6 +828,11 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest, int immediately) { pa_idxset_put(dest->inputs, i, NULL); i->sink = dest; + if (pa_sink_input_get_state(i) == PA_SINK_INPUT_CORKED) { + pa_assert_se(origin->n_corked-- >= 1); + dest->n_corked++; + } + /* Replace resampler */ if (new_resampler != i->thread_info.resampler) { if (i->thread_info.resampler) diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c index 207e2a39..2a902dc2 100644 --- a/src/pulsecore/source-output.c +++ b/src/pulsecore/source-output.c @@ -192,6 +192,9 @@ static int source_output_set_state(pa_source_output *o, pa_source_output_state_t o->state = state; + if (state != PA_SOURCE_OUTPUT_UNLINKED) + pa_hook_fire(&o->source->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_STATE_CHANGED], o); + return 0; } @@ -427,6 +430,11 @@ int pa_source_output_move_to(pa_source_output *o, pa_source *dest) { pa_idxset_put(dest->outputs, o, NULL); o->source = dest; + if (pa_source_output_get_state(o) == PA_SOURCE_OUTPUT_CORKED) { + pa_assert_se(origin->n_corked-- >= 1); + dest->n_corked++; + } + /* Replace resampler */ if (new_resampler != o->thread_info.resampler) { if (o->thread_info.resampler) -- cgit From 0e3e9e227477784a1559dd71f667c269f06e635c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 24 Sep 2007 23:32:01 +0000 Subject: only post data into the monitor source when it is not suspended git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1901 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 46f890de..38e7d632 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -482,7 +482,7 @@ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) { if (s->thread_info.state == PA_SINK_RUNNING) inputs_drop(s, info, n, result->length); - if (s->monitor_source) + if (s->monitor_source && PA_SOURCE_OPENED(pa_source_get_state(s->monitor_source))) pa_source_post(s->monitor_source, result); pa_sink_unref(s); @@ -549,7 +549,7 @@ void pa_sink_render_into(pa_sink*s, pa_memchunk *target) { if (s->thread_info.state == PA_SINK_RUNNING) inputs_drop(s, info, n, target->length); - if (s->monitor_source) + if (s->monitor_source && PA_SOURCE_OPENED(pa_source_get_state(s->monitor_source))) pa_source_post(s->monitor_source, target); pa_sink_unref(s); -- cgit From 609ad12f293eb0febebc7630c23a9978ce662211 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 24 Sep 2007 23:32:52 +0000 Subject: * decouple suspending of monitor sources and their sinks * implement resume-on-uncork git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1902 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-suspend-on-idle.c | 61 ++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 13 deletions(-) diff --git a/src/modules/module-suspend-on-idle.c b/src/modules/module-suspend-on-idle.c index 4fcb404c..5a711390 100644 --- a/src/modules/module-suspend-on-idle.c +++ b/src/modules/module-suspend-on-idle.c @@ -66,7 +66,9 @@ struct userdata { *sink_input_move_slot, *source_output_move_slot, *sink_input_move_post_slot, - *source_output_move_post_slot; + *source_output_move_post_slot, + *sink_input_state_changed_slot, + *source_output_state_changed_slot; }; struct device_info { @@ -86,13 +88,12 @@ static void timeout_cb(pa_mainloop_api*a, pa_time_event* e, const struct timeval if (d->sink && pa_sink_used_by(d->sink) <= 0 && pa_sink_get_state(d->sink) != PA_SINK_SUSPENDED) { pa_log_info("Sink %s idle for too long, suspending ...", d->sink->name); - pa_sink_suspend(d->sink, 1); - pa_source_suspend(d->sink->monitor_source, 1); + pa_sink_suspend(d->sink, TRUE); } if (d->source && pa_source_used_by(d->source) <= 0 && pa_source_get_state(d->source) != PA_SOURCE_SUSPENDED) { pa_log_info("Source %s idle for too long, suspending ...", d->source->name); - pa_source_suspend(d->source, 1); + pa_source_suspend(d->source, TRUE); } } @@ -117,16 +118,13 @@ static void resume(struct device_info *d) { d->userdata->core->mainloop->time_restart(d->time_event, NULL); if (d->sink) { - pa_sink_suspend(d->sink, 0); - pa_source_suspend(d->sink->monitor_source, 0); + pa_sink_suspend(d->sink, FALSE); pa_log_debug("Sink %s becomes busy.", d->sink->name); } if (d->source) { - pa_source_suspend(d->source, 0); - if (d->source->monitor_of) - pa_sink_suspend(d->source->monitor_of, 0); + pa_source_suspend(d->source, FALSE); pa_log_debug("Source %s becomes busy.", d->source->name); } @@ -239,6 +237,36 @@ static pa_hook_result_t source_output_move_post_hook_cb(pa_core *c, pa_source_ou return PA_HOOK_OK; } +static pa_hook_result_t sink_input_state_changed_hook_cb(pa_core *c, pa_sink_input *s, struct userdata *u) { + struct device_info *d; + pa_sink_input_state_t state; + pa_assert(c); + pa_sink_input_assert_ref(s); + pa_assert(u); + + state = pa_sink_input_get_state(s); + if (state == PA_SINK_INPUT_RUNNING || state == PA_SINK_INPUT_DRAINED) + if ((d = pa_hashmap_get(u->device_infos, s->sink))) + resume(d); + + return PA_HOOK_OK; +} + +static pa_hook_result_t source_output_state_changed_hook_cb(pa_core *c, pa_source_output *s, struct userdata *u) { + struct device_info *d; + pa_source_output_state_t state; + pa_assert(c); + pa_source_output_assert_ref(s); + pa_assert(u); + + state = pa_source_output_get_state(s); + if (state == PA_SOURCE_OUTPUT_RUNNING) + if ((d = pa_hashmap_get(u->device_infos, s->source))) + resume(d); + + return PA_HOOK_OK; +} + static pa_hook_result_t device_new_hook_cb(pa_core *c, pa_object *o, struct userdata *u) { struct device_info *d; pa_source *source; @@ -305,21 +333,22 @@ static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *o, s if (pa_sink_isinstance(o)) { pa_sink *s = PA_SINK(o); + pa_sink_state_t state = pa_sink_get_state(s); if (pa_sink_used_by(s) <= 0) { - pa_sink_state_t state = pa_sink_get_state(s); - if (state == PA_SINK_RUNNING || state == PA_SINK_IDLE) + if (PA_SINK_OPENED(state)) restart(d); + } } else if (pa_source_isinstance(o)) { pa_source *s = PA_SOURCE(o); + pa_source_state_t state = pa_source_get_state(s); if (pa_source_used_by(s) <= 0) { - pa_sink_state_t state = pa_source_get_state(s); - if (state == PA_SINK_RUNNING || state == PA_SINK_IDLE) + if (PA_SOURCE_OPENED(state)) restart(d); } } @@ -373,6 +402,8 @@ int pa__init(pa_module*m) { u->source_output_move_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE], (pa_hook_cb_t) source_output_move_hook_cb, u); u->sink_input_move_post_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_POST], (pa_hook_cb_t) sink_input_move_post_hook_cb, u); u->source_output_move_post_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_POST], (pa_hook_cb_t) source_output_move_post_hook_cb, u); + u->sink_input_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], (pa_hook_cb_t) sink_input_state_changed_hook_cb, u); + u->source_output_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_STATE_CHANGED], (pa_hook_cb_t) source_output_state_changed_hook_cb, u); pa_modargs_free(ma); @@ -419,6 +450,8 @@ void pa__done(pa_module*m) { pa_hook_slot_free(u->sink_input_move_slot); if (u->sink_input_move_post_slot) pa_hook_slot_free(u->sink_input_move_post_slot); + if (u->sink_input_state_changed_slot) + pa_hook_slot_free(u->sink_input_state_changed_slot); if (u->source_output_new_slot) pa_hook_slot_free(u->source_output_new_slot); @@ -428,6 +461,8 @@ void pa__done(pa_module*m) { pa_hook_slot_free(u->source_output_move_slot); if (u->source_output_move_post_slot) pa_hook_slot_free(u->source_output_move_post_slot); + if (u->source_output_state_changed_slot) + pa_hook_slot_free(u->source_output_state_changed_slot); while ((d = pa_hashmap_steal_first(u->device_infos))) device_info_free(d); -- cgit From 86ec4215928ae1ee0752406cf4f9fe2df77795d8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 24 Sep 2007 23:53:58 +0000 Subject: fix suspending in module-combine.c git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1903 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-combine.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 656cef92..d9c2af6d 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -450,7 +450,7 @@ static void sink_input_detach_cb(pa_sink_input *i) { pa_sink_input_assert_ref(i); pa_assert_se(o = i->userdata); - pa_log("detaching %s", i->sink->name); +/* pa_log("detaching %s", i->sink->name); */ pa_assert(o->inq_rtpoll_item); pa_rtpoll_item_free(o->inq_rtpoll_item); @@ -516,6 +516,9 @@ static int suspend(struct userdata *u) { /* Let's suspend by unlinking all streams */ + if (update_master(u, NULL) < 0) + pa_module_unload_request(u->module); + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) { if (o->sink_input) { @@ -525,9 +528,6 @@ static int suspend(struct userdata *u) { } } - if (pick_master(u, NULL) < 0) - pa_module_unload_request(u->module); - pa_log_info("Device suspended..."); return 0; -- cgit From 16872268115a52735d9dffd846f392b6c25a0b49 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 25 Sep 2007 00:45:57 +0000 Subject: fix make dist git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1904 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 9b4cb519..a92a5570 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -78,8 +78,8 @@ endif if OS_IS_WIN32 PA_THREAD_OBJS = \ pulsecore/mutex-win32.c pulsecore/mutex.h \ - pulsecore/thread-win32.c pulsecore/thread.h \ - pulsecore/semaphore-win32.c pulsecore/semaphore.h + pulsecore/thread-win32.c pulsecore/thread.h +# pulsecore/semaphore-win32.c pulsecore/semaphore.h else PA_THREAD_OBJS = \ pulsecore/mutex-posix.c pulsecore/mutex.h \ -- cgit From 5fe1589c8e258f9869e903a2d0856a8174ce9dde Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 25 Sep 2007 00:53:49 +0000 Subject: work around newest open() magic in fedora glibc git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1905 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/utils/padsp.c | 59 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/src/utils/padsp.c b/src/utils/padsp.c index 556ac2b7..299033e4 100644 --- a/src/utils/padsp.c +++ b/src/utils/padsp.c @@ -61,6 +61,10 @@ # define SIOCINQ FIONREAD #endif +/* make sure gcc doesn't redefine open and friends as macros */ +#undef open +#undef open64 + typedef enum { FD_INFO_MIXER, FD_INFO_STREAM, @@ -1436,35 +1440,23 @@ fail: return -1; } -#undef open -int open(const char *filename, int flags, ...) { - va_list args; - mode_t mode = 0; +static int real_open(const char *filename, int flags, mode_t mode) { int r, _errno = 0; debug(DEBUG_LEVEL_VERBOSE, __FILE__": open(%s)\n", filename); - va_start(args, flags); - if (flags & O_CREAT) { - if (sizeof(mode_t) < sizeof(int)) - mode = va_arg(args, int); - else - mode = va_arg(args, mode_t); - } - va_end(args); - if (!function_enter()) { LOAD_OPEN_FUNC(); return _open(filename, flags, mode); } - if (dsp_cloak_enable() && (strcmp(filename, "/dev/dsp") == 0 || strcmp(filename, "/dev/adsp") == 0)) { + if (dsp_cloak_enable() && (strcmp(filename, "/dev/dsp") == 0 || strcmp(filename, "/dev/adsp") == 0)) r = dsp_open(flags, &_errno); - } else if (mixer_cloak_enable() && strcmp(filename, "/dev/mixer") == 0) { + else if (mixer_cloak_enable() && strcmp(filename, "/dev/mixer") == 0) r = mixer_open(flags, &_errno); - } else if (sndstat_cloak_enable() && strcmp(filename, "/dev/sndstat") == 0) { + else if (sndstat_cloak_enable() && strcmp(filename, "/dev/sndstat") == 0) r = sndstat_open(flags, &_errno); - } else { + else { function_exit(); LOAD_OPEN_FUNC(); return _open(filename, flags, mode); @@ -1478,6 +1470,22 @@ int open(const char *filename, int flags, ...) { return r; } +int open(const char *filename, int flags, ...) { + va_list args; + mode_t mode = 0; + + if (flags & O_CREAT) { + va_start(args, flags); + if (sizeof(mode_t) < sizeof(int)) + mode = va_arg(args, int); + else + mode = va_arg(args, mode_t); + va_end(args); + } + + return real_open(filename, flags, mode); +} + static int mixer_ioctl(fd_info *i, unsigned long request, void*argp, int *_errno) { int ret = -1; @@ -2491,17 +2499,20 @@ int stat64(const char *pathname, struct stat64 *buf) { return 0; } -#undef open64 int open64(const char *filename, int flags, ...) { va_list args; mode_t mode = 0; debug(DEBUG_LEVEL_VERBOSE, __FILE__": open64(%s)\n", filename); - va_start(args, flags); - if (flags & O_CREAT) - mode = va_arg(args, mode_t); - va_end(args); + if (flags & O_CREAT) { + va_start(args, flags); + if (sizeof(mode_t) < sizeof(int)) + mode = va_arg(args, int); + else + mode = va_arg(args, mode_t); + va_end(args); + } if (strcmp(filename, "/dev/dsp") != 0 && strcmp(filename, "/dev/adsp") != 0 && @@ -2511,7 +2522,7 @@ int open64(const char *filename, int flags, ...) { return _open64(filename, flags, mode); } - return open(filename, flags, mode); + return real_open(filename, flags, mode); } #endif @@ -2603,7 +2614,7 @@ FILE* fopen(const char *filename, const char *mode) { if ((((mode[1] == 'b') || (mode[1] == 't')) && (mode[2] == '+')) || (mode[1] == '+')) m = O_RDWR; - if ((fd = open(filename, m)) < 0) + if ((fd = real_open(filename, m, 0)) < 0) return NULL; if (!(f = fdopen(fd, mode))) { -- cgit From a9e667bb8384c508d1edbffe2af137db91f73abd Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 25 Sep 2007 01:58:16 +0000 Subject: make sure when can shutdown PA cleanly without segfault git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1906 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-zeroconf-publish.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/module-zeroconf-publish.c b/src/modules/module-zeroconf-publish.c index ac9d0477..113686cf 100644 --- a/src/modules/module-zeroconf-publish.c +++ b/src/modules/module-zeroconf-publish.c @@ -115,7 +115,7 @@ static void get_service_data(struct service *s, pa_sample_spec *ret_ss, pa_chann static AvahiStringList* txt_record_server_data(pa_core *c, AvahiStringList *l) { char s[128]; - pa_core_assert_ref(c); + pa_assert(c); l = avahi_string_list_add_pair(l, "server-version", PACKAGE_NAME" "PACKAGE_VERSION); l = avahi_string_list_add_pair(l, "user-name", pa_get_user_name(s, sizeof(s))); -- cgit From e99bc33bcb6c3055ad3ebe6026783a5b38f9305c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 26 Sep 2007 13:33:25 +0000 Subject: fix build with compilers that lack __thread git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1907 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/thread.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/thread.h b/src/pulsecore/thread.h index 6aaf8c84..54ef320e 100644 --- a/src/pulsecore/thread.h +++ b/src/pulsecore/thread.h @@ -76,7 +76,7 @@ void *pa_tls_set(pa_tls *t, void *userdata); if (_free_cb) { \ void *p; \ if ((p = pa_tls_get(name##_tls.tls))) \ - free_cb(p); \ + _free_cb(p); \ } \ pa_tls_free(name##_tls.tls); \ } \ -- cgit From 008c7099007c9cda76a2d3bc966d2392c7b7a76d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 26 Sep 2007 22:50:08 +0000 Subject: Use Linux eventfd() if kernel supports it git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1908 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/fdsem.c | 119 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 100 insertions(+), 19 deletions(-) diff --git a/src/pulsecore/fdsem.c b/src/pulsecore/fdsem.c index c81797e0..b919ba41 100644 --- a/src/pulsecore/fdsem.c +++ b/src/pulsecore/fdsem.c @@ -25,6 +25,7 @@ #include #endif +#include #include #include @@ -35,10 +36,37 @@ #include #include +#ifdef __linux__ + +#if !defined(__NR_eventfd) && defined(__i386__) +#define __NR_eventfd 323 +#endif + +#if !defined(__NR_eventfd) && defined(__x86_64__) +#define __NR_eventfd 284 +#endif + +#if !defined(SYS_eventfd) && defined(__NR_eventfd) +#define SYS_eventfd __NR_eventfd +#endif + +#ifdef SYS_eventfd +#define HAVE_EVENTFD + +static inline long eventfd(unsigned count) { + return syscall(SYS_eventfd, count); +} + +#endif +#endif + #include "fdsem.h" struct pa_fdsem { int fds[2]; +#ifdef HAVE_EVENTFD + int efd; +#endif pa_atomic_t waiting; pa_atomic_t signalled; pa_atomic_t in_pipe; @@ -48,25 +76,38 @@ pa_fdsem *pa_fdsem_new(void) { pa_fdsem *f; f = pa_xnew(pa_fdsem, 1); - - if (pipe(f->fds) < 0) { - pa_xfree(f); - return NULL; - } - pa_make_fd_cloexec(f->fds[0]); - pa_make_fd_cloexec(f->fds[1]); +#ifdef HAVE_EVENTFD + if ((f->efd = eventfd(0)) >= 0) { + pa_make_fd_cloexec(f->efd); + f->fds[0] = f->fds[1] = -1; + + } else +#endif + { + if (pipe(f->fds) < 0) { + pa_xfree(f); + return NULL; + } + + pa_make_fd_cloexec(f->fds[0]); + pa_make_fd_cloexec(f->fds[1]); + } pa_atomic_store(&f->waiting, 0); pa_atomic_store(&f->signalled, 0); pa_atomic_store(&f->in_pipe, 0); - + return f; } void pa_fdsem_free(pa_fdsem *f) { pa_assert(f); +#ifdef HAVE_EVENTFD + if (f->efd >= 0) + pa_close(f->efd); +#endif pa_close_pipe(f->fds); pa_xfree(f); @@ -81,12 +122,24 @@ static void flush(pa_fdsem *f) { do { char x[10]; - + +#ifdef HAVE_EVENTFD + if (f->efd >= 0) { + uint64_t u; + + if ((r = read(f->efd, &u, sizeof(u))) != sizeof(u)) { + pa_assert(r < 0 && errno == EINTR); + continue; + } + r = (ssize_t) u; + } else +#endif + if ((r = read(f->fds[0], &x, sizeof(x))) <= 0) { pa_assert(r < 0 && errno == EINTR); continue; } - + } while (pa_atomic_sub(&f->in_pipe, r) > r); } @@ -98,11 +151,22 @@ void pa_fdsem_post(pa_fdsem *f) { if (pa_atomic_load(&f->waiting)) { ssize_t r; char x = 'x'; - + pa_atomic_inc(&f->in_pipe); for (;;) { - + +#ifdef HAVE_EVENTFD + if (f->efd >= 0) { + uint64_t u = 1; + + if ((r = write(f->efd, &u, sizeof(u))) != sizeof(u)) { + pa_assert(r < 0 && errno == EINTR); + continue; + } + } else +#endif + if ((r = write(f->fds[1], &x, 1)) != 1) { pa_assert(r < 0 && errno == EINTR); continue; @@ -123,16 +187,29 @@ void pa_fdsem_wait(pa_fdsem *f) { return; pa_atomic_inc(&f->waiting); - + while (!pa_atomic_cmpxchg(&f->signalled, 1, 0)) { char x[10]; ssize_t r; - + +#ifdef HAVE_EVENTFD + if (f->efd >= 0) { + uint64_t u; + + if ((r = read(f->efd, &u, sizeof(u))) != sizeof(u)) { + pa_assert(r < 0 && errno == EINTR); + continue; + } + + r = (ssize_t) u; + } else +#endif + if ((r = read(f->fds[0], &x, sizeof(x))) <= 0) { pa_assert(r < 0 && errno == EINTR); continue; } - + pa_atomic_sub(&f->in_pipe, r); } @@ -143,17 +220,21 @@ int pa_fdsem_try(pa_fdsem *f) { pa_assert(f); flush(f); - + if (pa_atomic_cmpxchg(&f->signalled, 1, 0)) return 1; return 0; } - int pa_fdsem_get(pa_fdsem *f) { pa_assert(f); - + +#ifdef HAVE_EVENTFD + if (f->efd >= 0) + return f->efd; +#endif + return f->fds[0]; } @@ -170,7 +251,7 @@ int pa_fdsem_before_poll(pa_fdsem *f) { if (pa_atomic_cmpxchg(&f->signalled, 1, 0)) { pa_assert_se(pa_atomic_dec(&f->waiting) >= 1); return -1; - } + } return 0; } -- cgit From 107f12ae3ccc95f124d2659e062f5d1f4093dc02 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 28 Sep 2007 00:29:51 +0000 Subject: speed up semaphore allocation with an flist git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1909 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/asyncmsgq.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/pulsecore/asyncmsgq.c b/src/pulsecore/asyncmsgq.c index c0917ca6..9910f651 100644 --- a/src/pulsecore/asyncmsgq.c +++ b/src/pulsecore/asyncmsgq.c @@ -40,6 +40,7 @@ #include "asyncmsgq.h" PA_STATIC_FLIST_DECLARE(asyncmsgq, 0, pa_xfree); +PA_STATIC_FLIST_DECLARE(semaphores, 0, (void(*)(void*)) pa_semaphore_free); struct asyncmsgq_item { int code; @@ -154,7 +155,11 @@ int pa_asyncmsgq_send(pa_asyncmsgq *a, pa_msgobject *object, int code, const voi i.memchunk = *chunk; } else pa_memchunk_reset(&i.memchunk); - pa_assert_se(i.semaphore = pa_semaphore_new(0)); + + if (!(i.semaphore = pa_flist_pop(PA_STATIC_FLIST_GET(semaphores)))) + i.semaphore = pa_semaphore_new(0); + + pa_assert_se(i.semaphore); /* Thus mutex makes the queue multiple-writer safe. This lock is only used on the writing side */ pa_mutex_lock(a->mutex); @@ -162,7 +167,9 @@ int pa_asyncmsgq_send(pa_asyncmsgq *a, pa_msgobject *object, int code, const voi pa_mutex_unlock(a->mutex); pa_semaphore_wait(i.semaphore); - pa_semaphore_free(i.semaphore); + + if (pa_flist_push(PA_STATIC_FLIST_GET(semaphores), i.semaphore) < 0) + pa_semaphore_free(i.semaphore); return i.ret; } @@ -192,7 +199,7 @@ int pa_asyncmsgq_get(pa_asyncmsgq *a, pa_msgobject **object, int *code, void **u *chunk = a->current->memchunk; /* pa_log_debug("Get q=%p object=%p (%s) code=%i data=%p chunk.length=%lu", (void*) a, (void*) a->current->object, a->current->object ? a->current->object->parent.type_name : NULL, a->current->code, (void*) a->current->userdata, (unsigned long) a->current->memchunk.length); */ - + return 0; } @@ -244,7 +251,7 @@ int pa_asyncmsgq_wait_for(pa_asyncmsgq *a, int code) { } while (c != code); pa_asyncmsgq_unref(a); - + return 0; } @@ -257,15 +264,15 @@ int pa_asyncmsgq_process_one(pa_asyncmsgq *a) { int ret; pa_assert(PA_REFCNT_VALUE(a) > 0); - + if (pa_asyncmsgq_get(a, &object, &code, &data, &offset, &chunk, 0) < 0) return 0; - + pa_asyncmsgq_ref(a); ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); pa_asyncmsgq_done(a, ret); pa_asyncmsgq_unref(a); - + return 1; } -- cgit From 584ca6193c41c2fbe8e0d7acf7075a0eb33b1090 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 28 Sep 2007 00:30:48 +0000 Subject: don't free silence memblocks that don't exist git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1910 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sink-input.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index ce48765a..6f654b61 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -540,9 +540,10 @@ void pa_sink_input_drop(pa_sink_input *i, size_t length) { } if (i->thread_info.move_silence <= 0) { - pa_assert(i->thread_info.silence_memblock); - pa_memblock_unref(i->thread_info.silence_memblock); - i->thread_info.silence_memblock = NULL; + if (i->thread_info.silence_memblock) { + pa_memblock_unref(i->thread_info.silence_memblock); + i->thread_info.silence_memblock = NULL; + } } if (length <= 0) -- cgit From 6d8aea724eb0011a068c9c883450418c80fda777 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 28 Sep 2007 09:23:05 +0000 Subject: Incorrectly used str2sig() instead of sig2str(). git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1911 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/core-util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 6db0870b..3defe2bc 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -639,7 +639,7 @@ const char *pa_sig2str(int sig) { { char buf[SIG2STR_MAX]; - if (str2sig(sig, buf) == 0) { + if (sig2str(sig, buf) == 0) { pa_xfree(PA_STATIC_TLS_GET(signame)); t = pa_sprintf_malloc("SIG%s", buf); PA_STATIC_TLS_SET(signame, t); -- cgit From df33b4c7b339a1c26ccbfd80e5b91637c177b378 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 28 Sep 2007 12:22:56 +0000 Subject: only do IO if we are RUNNING or IDLE, but not when we are in INIT git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1912 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-oss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 8d088997..82b5b6ce 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -849,7 +849,7 @@ static void thread_func(void *userdata) { /* Render some data and write it to the dsp */ - if (u->sink && u->sink->thread_info.state != PA_SINK_UNLINKED && u->fd >= 0 && (revents & POLLOUT)) { + if (u->sink && PA_SINK_OPENED(u->sink->thread_info.state) && (revents & POLLOUT)) { if (u->use_mmap) { @@ -939,7 +939,7 @@ static void thread_func(void *userdata) { /* Try to read some data and pass it on to the source driver */ - if (u->source && u->source->thread_info.state != PA_SOURCE_UNLINKED && u->fd >= 0 && ((revents & POLLIN))) { + if (u->source && PA_SOURCE_OPENED(u->source->thread_info.state) && ((revents & POLLIN))) { if (u->use_mmap) { -- cgit From 3cdff5f3cc79aeabedada6633ce2d779d0a21b60 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 28 Sep 2007 12:52:47 +0000 Subject: Allocate rtsigs from back to front, to avoid clashes with other libraries makeing use of rtsigs git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1913 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/rtsig.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/pulsecore/rtsig.c b/src/pulsecore/rtsig.c index 3513bedf..1af45e77 100644 --- a/src/pulsecore/rtsig.c +++ b/src/pulsecore/rtsig.c @@ -50,17 +50,17 @@ static int rtsig_start = -1, rtsig_end = -1; int pa_rtsig_get(void) { void *p; int sig; - + if ((p = pa_flist_pop(PA_STATIC_FLIST_GET(rtsig_flist)))) return PA_PTR_TO_INT(p); - sig = pa_atomic_inc(&rtsig_current); + sig = pa_atomic_dec(&rtsig_current); - pa_assert(sig >= SIGRTMIN); - pa_assert(sig >= rtsig_start); - - if (sig > rtsig_end) { - pa_atomic_dec(&rtsig_current); + pa_assert(sig <= SIGRTMAX); + pa_assert(sig <= rtsig_end); + + if (sig < rtsig_start) { + pa_atomic_inc(&rtsig_current); return -1; } @@ -73,7 +73,7 @@ int pa_rtsig_get_for_thread(void) { if ((p = PA_STATIC_TLS_GET(rtsig_tls))) return PA_PTR_TO_INT(p); - + if ((sig = pa_rtsig_get()) < 0) return -1; @@ -102,11 +102,12 @@ void pa_rtsig_configure(int start, int end) { rtsig_end = end; sigemptyset(&ss); - + for (s = rtsig_start; s <= rtsig_end; s++) pa_assert_se(sigaddset(&ss, s) == 0); - + pa_assert(pthread_sigmask(SIG_BLOCK, &ss, NULL) == 0); - - pa_atomic_store(&rtsig_current, rtsig_start); + + /* We allocate starting from the end */ + pa_atomic_store(&rtsig_current, rtsig_end); } -- cgit From f8c17861b8e528909b2d14641a2cd362fd7c4f8f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 28 Sep 2007 12:53:17 +0000 Subject: use the full range of RTSIGS for our stuff git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1914 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/main.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/daemon/main.c b/src/daemon/main.c index a660ab10..0e759d27 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -327,7 +327,7 @@ int main(int argc, char *argv[]) { struct timeval tv; #endif - + #if defined(__linux__) && defined(__OPTIMIZE__) /* Disable lazy relocations to make usage of external libraries @@ -343,7 +343,7 @@ int main(int argc, char *argv[]) { pa_assert_se(execv("/proc/self/exe", argv) == 0); } #endif - + #ifdef HAVE_GETUID real_root = getuid() == 0; suid_root = !real_root && geteuid() == 0; @@ -440,10 +440,10 @@ int main(int argc, char *argv[]) { for (i = 0; i < PA_RESAMPLER_MAX; i++) if (pa_resample_method_supported(i)) printf("%s\n", pa_resample_method_to_string(i)); - + goto finish; } - + case PA_CMD_HELP : pa_cmdline_help(argv[0]); retval = 0; @@ -482,7 +482,7 @@ int main(int argc, char *argv[]) { retval = 0; goto finish; - + default: pa_assert(conf->cmd == PA_CMD_DAEMON); } @@ -608,13 +608,13 @@ int main(int argc, char *argv[]) { #endif pa_log_info("Page size is %lu bytes", (unsigned long) PA_PAGE_SIZE); - + if (pa_rtclock_hrtimer()) pa_log_info("Fresh high-resolution timers available! Bon appetit!"); else pa_log_info("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"); - - pa_rtsig_configure(SIGRTMIN+10, SIGRTMAX); + + pa_rtsig_configure(SIGRTMIN, SIGRTMAX); pa_assert_se(mainloop = pa_mainloop_new()); @@ -659,7 +659,7 @@ int main(int argc, char *argv[]) { if (!conf->no_cpu_limit) pa_assert_se(pa_cpu_limit_init(pa_mainloop_get_api(mainloop)) == 0); - + buf = pa_strbuf_new(); if (conf->default_script_file) r = pa_cli_command_execute_file(c, conf->default_script_file, buf, &conf->fail); @@ -736,6 +736,6 @@ finish: #ifdef HAVE_DBUS dbus_shutdown(); #endif - + return retval; } -- cgit From 229afb5e2dca2ea4cf8e5f48268cd9c419ea6f4b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 28 Sep 2007 13:00:35 +0000 Subject: Move the poll() call outside the #ifdef checking for ppoll, since we want the poll in all cases. Prior to this change the check for negative return values of poll/ppoll was never actually executed when ppoll() was available git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1915 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/rtpoll.c | 121 ++++++++++++++++++++++++------------------------- 1 file changed, 60 insertions(+), 61 deletions(-) diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c index 1b523851..921619d8 100644 --- a/src/pulsecore/rtpoll.c +++ b/src/pulsecore/rtpoll.c @@ -62,9 +62,9 @@ struct pa_rtpoll { timer_t timer; #ifdef __linux__ pa_bool_t dont_use_ppoll; -#endif #endif - +#endif + PA_LLIST_HEAD(pa_rtpoll_item, items); }; @@ -81,7 +81,7 @@ struct pa_rtpoll_item { int (*before_cb)(pa_rtpoll_item *i); void (*after_cb)(pa_rtpoll_item *i); void *userdata; - + PA_LLIST_FIELDS(pa_rtpoll_item); }; @@ -99,11 +99,11 @@ pa_rtpoll *pa_rtpoll_new(void) { #ifdef __linux__ /* ppoll is broken on Linux < 2.6.16 */ p->dont_use_ppoll = FALSE; - + { struct utsname u; unsigned major, minor, micro; - + pa_assert_se(uname(&u) == 0); if (sscanf(u.release, "%u.%u.%u", &major, &minor, µ) != 3 || @@ -119,7 +119,7 @@ pa_rtpoll *pa_rtpoll_new(void) { p->rtsig = -1; sigemptyset(&p->sigset_unblocked); p->timer = (timer_t) -1; - + #endif p->n_pollfd_alloc = 32; @@ -136,7 +136,7 @@ pa_rtpoll *pa_rtpoll_new(void) { p->scan_for_dead = FALSE; p->rebuild_needed = FALSE; p->quit = FALSE; - + PA_LLIST_HEAD_INIT(pa_rtpoll_item, p->items); return p; @@ -145,7 +145,7 @@ pa_rtpoll *pa_rtpoll_new(void) { void pa_rtpoll_install(pa_rtpoll *p) { pa_assert(p); pa_assert(!p->installed); - + p->installed = 1; #ifdef HAVE_PPOLL @@ -162,7 +162,7 @@ void pa_rtpoll_install(pa_rtpoll *p) { { sigset_t ss; struct sigaction sa; - + pa_assert_se(sigemptyset(&ss) == 0); pa_assert_se(sigaddset(&ss, p->rtsig) == 0); pa_assert_se(pthread_sigmask(SIG_BLOCK, &ss, &p->sigset_unblocked) == 0); @@ -171,12 +171,12 @@ void pa_rtpoll_install(pa_rtpoll *p) { memset(&sa, 0, sizeof(sa)); sa.sa_handler = signal_handler_noop; pa_assert_se(sigemptyset(&sa.sa_mask) == 0); - + pa_assert_se(sigaction(p->rtsig, &sa, NULL) == 0); - + /* We never reset the signal handler. Why should we? */ } - + #endif } @@ -185,7 +185,7 @@ static void rtpoll_rebuild(pa_rtpoll *p) { struct pollfd *e, *t; pa_rtpoll_item *i; int ra = 0; - + pa_assert(p); p->rebuild_needed = FALSE; @@ -203,7 +203,7 @@ static void rtpoll_rebuild(pa_rtpoll *p) { if (i->n_pollfd > 0) { size_t l = i->n_pollfd * sizeof(struct pollfd); - + if (i->pollfd) memcpy(e, i->pollfd, l); else @@ -212,7 +212,7 @@ static void rtpoll_rebuild(pa_rtpoll *p) { i->pollfd = e; } else i->pollfd = NULL; - + e += i->n_pollfd; } @@ -220,7 +220,7 @@ static void rtpoll_rebuild(pa_rtpoll *p) { t = p->pollfd; p->pollfd = p->pollfd2; p->pollfd2 = t; - + if (ra) p->pollfd2 = pa_xrealloc(p->pollfd2, p->n_pollfd_alloc * sizeof(struct pollfd)); @@ -236,7 +236,7 @@ static void rtpoll_item_destroy(pa_rtpoll_item *i) { PA_LLIST_REMOVE(pa_rtpoll_item, p->items, i); p->n_pollfd_used -= i->n_pollfd; - + if (pa_flist_push(PA_STATIC_FLIST_GET(items), i) < 0) pa_xfree(i); @@ -253,22 +253,22 @@ void pa_rtpoll_free(pa_rtpoll *p) { pa_xfree(p->pollfd2); #ifdef HAVE_PPOLL - if (p->timer != (timer_t) -1) + if (p->timer != (timer_t) -1) timer_delete(p->timer); #endif - + pa_xfree(p); } static void reset_revents(pa_rtpoll_item *i) { struct pollfd *f; unsigned n; - + pa_assert(i); if (!(f = pa_rtpoll_item_get_pollfd(i, &n))) return; - + for (; n > 0; n--) f[n-1].revents = 0; } @@ -277,12 +277,12 @@ static void reset_all_revents(pa_rtpoll *p) { pa_rtpoll_item *i; pa_assert(p); - + for (i = p->items; i; i = i->next) { - + if (i->dead) continue; - + reset_revents(i); } } @@ -291,30 +291,30 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { pa_rtpoll_item *i; int r = 0; struct timespec timeout; - + pa_assert(p); pa_assert(!p->running); pa_assert(p->installed); - + p->running = TRUE; /* First, let's do some work */ for (i = p->items; i && i->priority < PA_RTPOLL_NEVER; i = i->next) { int k; - + if (i->dead) continue; - + if (!i->work_cb) continue; if (p->quit) goto finish; - + if ((k = i->work_cb(i)) != 0) { if (k < 0) r = k; - + goto finish; } } @@ -322,10 +322,10 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { /* Now let's prepare for entering the sleep */ for (i = p->items; i && i->priority < PA_RTPOLL_NEVER; i = i->next) { int k = 0; - + if (i->dead) continue; - + if (!i->before_cb) continue; @@ -334,10 +334,10 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { /* Hmm, this one doesn't let us enter the poll, so rewind everything */ for (i = i->prev; i; i = i->prev) { - + if (i->dead) continue; - + if (!i->after_cb) continue; @@ -346,7 +346,7 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { if (k < 0) r = k; - + goto finish; } } @@ -367,7 +367,7 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { else pa_timespec_store(&timeout, pa_timespec_diff(&p->next_elapse, &now)); } - + /* OK, now let's sleep */ #ifdef HAVE_PPOLL @@ -379,17 +379,16 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { else #endif -#else - r = poll(p->pollfd, p->n_pollfd_used, p->timer_enabled > 0 ? (timeout.tv_sec*1000) + (timeout.tv_nsec / 1000000) : -1); #endif + r = poll(p->pollfd, p->n_pollfd_used, p->timer_enabled > 0 ? (timeout.tv_sec*1000) + (timeout.tv_nsec / 1000000) : -1); if (r < 0) { - reset_all_revents(p); - if (errno == EAGAIN || errno == EINTR) r = 0; else pa_log_error("poll(): %s", pa_cstrerror(errno)); + + reset_all_revents(p); } if (p->timer_enabled) { @@ -422,12 +421,12 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { finish: p->running = FALSE; - + if (p->scan_for_dead) { pa_rtpoll_item *n; p->scan_for_dead = FALSE; - + for (i = p->items; i; i = n) { n = i->next; @@ -447,7 +446,7 @@ static void update_timer(pa_rtpoll *p) { #ifdef __linux__ if (!p->dont_use_ppoll) { #endif - + if (p->timer == (timer_t) -1) { struct sigevent se; @@ -473,7 +472,7 @@ static void update_timer(pa_rtpoll *p) { * "disarming" */ if (its.it_value.tv_sec == 0) its.it_value.tv_nsec = 1; - + if (p->period > 0) pa_timespec_store(&its.it_interval, p->period); } @@ -484,18 +483,18 @@ static void update_timer(pa_rtpoll *p) { #ifdef __linux__ } #endif - + #endif } void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timespec *ts) { pa_assert(p); pa_assert(ts); - + p->next_elapse = *ts; p->period = 0; p->timer_enabled = TRUE; - + update_timer(p); } @@ -533,7 +532,7 @@ void pa_rtpoll_set_timer_disabled(pa_rtpoll *p) { pa_rtpoll_item *pa_rtpoll_item_new(pa_rtpoll *p, pa_rtpoll_priority_t prio, unsigned n_fds) { pa_rtpoll_item *i, *j, *l = NULL; - + pa_assert(p); if (!(i = pa_flist_pop(PA_STATIC_FLIST_GET(items)))) @@ -582,20 +581,20 @@ void pa_rtpoll_item_free(pa_rtpoll_item *i) { struct pollfd *pa_rtpoll_item_get_pollfd(pa_rtpoll_item *i, unsigned *n_fds) { pa_assert(i); - if (i->n_pollfd > 0) + if (i->n_pollfd > 0) if (i->rtpoll->rebuild_needed) rtpoll_rebuild(i->rtpoll); - + if (n_fds) *n_fds = i->n_pollfd; - + return i->pollfd; } void pa_rtpoll_item_set_before_callback(pa_rtpoll_item *i, int (*before_cb)(pa_rtpoll_item *i)) { pa_assert(i); pa_assert(i->priority < PA_RTPOLL_NEVER); - + i->before_cb = before_cb; } @@ -635,7 +634,7 @@ static int fdsem_before(pa_rtpoll_item *i) { static void fdsem_after(pa_rtpoll_item *i) { pa_assert(i); - + pa_assert((i->pollfd[0].revents & ~POLLIN) == 0); pa_fdsem_after_poll(i->userdata); } @@ -643,7 +642,7 @@ static void fdsem_after(pa_rtpoll_item *i) { pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_fdsem *f) { pa_rtpoll_item *i; struct pollfd *pollfd; - + pa_assert(p); pa_assert(f); @@ -653,7 +652,7 @@ pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_rtpoll_priority_t prio pollfd->fd = pa_fdsem_get(f); pollfd->events = POLLIN; - + i->before_cb = fdsem_before; i->after_cb = fdsem_after; i->userdata = f; @@ -663,7 +662,7 @@ pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_rtpoll_priority_t prio static int asyncmsgq_before(pa_rtpoll_item *i) { pa_assert(i); - + if (pa_asyncmsgq_before_poll(i->userdata) < 0) return 1; /* 1 means immediate restart of the loop */ @@ -672,7 +671,7 @@ static int asyncmsgq_before(pa_rtpoll_item *i) { static void asyncmsgq_after(pa_rtpoll_item *i) { pa_assert(i); - + pa_assert((i->pollfd[0].revents & ~POLLIN) == 0); pa_asyncmsgq_after_poll(i->userdata); } @@ -688,7 +687,7 @@ static int asyncmsgq_work(pa_rtpoll_item *i) { if (pa_asyncmsgq_get(i->userdata, &object, &code, &data, &offset, &chunk, 0) == 0) { int ret; - + if (!object && code == PA_MESSAGE_SHUTDOWN) { pa_asyncmsgq_done(i->userdata, 0); pa_rtpoll_quit(i->rtpoll); @@ -698,7 +697,7 @@ static int asyncmsgq_work(pa_rtpoll_item *i) { ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk); pa_asyncmsgq_done(i->userdata, ret); return 1; - } + } return 0; } @@ -706,7 +705,7 @@ static int asyncmsgq_work(pa_rtpoll_item *i) { pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_asyncmsgq *q) { pa_rtpoll_item *i; struct pollfd *pollfd; - + pa_assert(p); pa_assert(q); @@ -715,7 +714,7 @@ pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq(pa_rtpoll *p, pa_rtpoll_priority_t pollfd = pa_rtpoll_item_get_pollfd(i, NULL); pollfd->fd = pa_asyncmsgq_get_fd(q); pollfd->events = POLLIN; - + i->before_cb = asyncmsgq_before; i->after_cb = asyncmsgq_after; i->work_cb = asyncmsgq_work; -- cgit From 33f2f497de3c1a99a05cc20172a7b03b38a084e1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 28 Sep 2007 13:02:28 +0000 Subject: rework module-combine once again. We now run the data generation always in a seperate thread. This should help use to avoid all the awful race conditions we had in previously git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1916 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-combine.c | 544 +++++++++++++++++-------------------------- 1 file changed, 208 insertions(+), 336 deletions(-) diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index d9c2af6d..447f41cb 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -84,11 +84,12 @@ static const char* const valid_modargs[] = { struct output { struct userdata *userdata; + pa_sink *sink; pa_sink_input *sink_input; - pa_asyncmsgq *inq, /* Message queue from the master to this sink input */ - *outq; /* Message queue from this sink input to the master */ + pa_asyncmsgq *inq, /* Message queue from the sink thread to this sink input */ + *outq; /* Message queue from this sink input to the sink thread */ pa_rtpoll_item *inq_rtpoll_item, *outq_rtpoll_item; pa_memblockq *memblockq; @@ -107,35 +108,33 @@ struct userdata { pa_thread_mq thread_mq; pa_rtpoll *rtpoll; - struct output *master; - pa_time_event *time_event; uint32_t adjust_time; - int automatic; + pa_bool_t automatic; size_t block_size; - struct timespec timestamp; - pa_hook_slot *sink_new_slot, *sink_unlink_slot, *sink_state_changed_slot; pa_resample_method_t resample_method; struct timespec adjust_timestamp; + struct output *master; pa_idxset* outputs; /* managed in main context */ struct { - PA_LLIST_HEAD(struct output, outputs); /* managed in IO thread context */ - struct output *master; + PA_LLIST_HEAD(struct output, active_outputs); /* managed in IO thread context */ + pa_atomic_t running; /* we cache that value here, so that every thread can query it cheaply */ + struct timespec timestamp; + pa_bool_t in_null_mode; } thread_info; }; enum { SINK_MESSAGE_ADD_OUTPUT = PA_SINK_MESSAGE_MAX, SINK_MESSAGE_REMOVE_OUTPUT, - SINK_MESSAGE_NEED, - SINK_MESSAGE_SET_MASTER + SINK_MESSAGE_NEED }; enum { @@ -143,9 +142,9 @@ enum { }; static void output_free(struct output *o); -static int output_create_sink_input(struct userdata *u, struct output *o); -static int update_master(struct userdata *u, struct output *o); -static int pick_master(struct userdata *u, struct output *except); +static int output_create_sink_input(struct output *o); +static void update_master(struct userdata *u, struct output *o); +static void pick_master(struct userdata *u, struct output *except); static void adjust_rates(struct userdata *u) { struct output *o; @@ -159,22 +158,25 @@ static void adjust_rates(struct userdata *u) { if (pa_idxset_size(u->outputs) <= 0) return; + if (!u->master) + return; + if (!PA_SINK_OPENED(pa_sink_get_state(u->sink))) return; for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) { - uint32_t sink_latency; + pa_usec_t sink_latency; if (!o->sink_input || !PA_SINK_OPENED(pa_sink_get_state(o->sink))) continue; - sink_latency = o->sink_input->sink ? pa_sink_get_latency(o->sink_input->sink) : 0; + sink_latency = pa_sink_get_latency(o->sink); o->total_latency = sink_latency + pa_sink_input_get_latency(o->sink_input); if (sink_latency > max_sink_latency) max_sink_latency = sink_latency; - if (o->total_latency < min_total_latency) + if (min_total_latency == (pa_usec_t) -1 || o->total_latency < min_total_latency) min_total_latency = o->total_latency; } @@ -184,7 +186,7 @@ static void adjust_rates(struct userdata *u) { target_latency = max_sink_latency > min_total_latency ? max_sink_latency : min_total_latency; pa_log_info("[%s] target latency is %0.0f usec.", u->sink->name, (float) target_latency); - pa_log_info("[%s] master is %s", u->sink->name, u->master->sink->description); + pa_log_info("[%s] master %s latency %0.0f usec.", u->sink->name, u->master->sink->name, (float) u->master->total_latency); base_rate = u->sink->sample_spec.rate; @@ -195,9 +197,9 @@ static void adjust_rates(struct userdata *u) { continue; if (o->total_latency < target_latency) - r -= (uint32_t) (((((double) target_latency - o->total_latency))/u->adjust_time)*r/ 1000000); + r -= (uint32_t) (((((double) target_latency - o->total_latency))/u->adjust_time)*r/PA_USEC_PER_SEC); else if (o->total_latency > target_latency) - r += (uint32_t) (((((double) o->total_latency - target_latency))/u->adjust_time)*r/ 1000000); + r += (uint32_t) (((((double) o->total_latency - target_latency))/u->adjust_time)*r/PA_USEC_PER_SEC); if (r < (uint32_t) (base_rate*0.9) || r > (uint32_t) (base_rate*1.1)) { pa_log_warn("[%s] sample rates too different, not adjusting (%u vs. %u).", o->sink_input->name, base_rate, r); @@ -231,36 +233,46 @@ static void thread_func(void *userdata) { pa_log_debug("Thread starting up"); + if (u->core->high_priority) + pa_make_realtime(); + pa_thread_mq_install(&u->thread_mq); pa_rtpoll_install(u->rtpoll); - pa_rtclock_get(&u->timestamp); - - /* This is only run when we are in NULL mode, to make sure that - * playback doesn't stop. In all other cases we hook our stuff - * into the master sink. */ + pa_rtclock_get(&u->thread_info.timestamp); + u->thread_info.in_null_mode = FALSE; for (;;) { int ret; - /* Render some data and drop it immediately */ - if (u->sink->thread_info.state == PA_SINK_RUNNING) { + /* If no outputs are connected, render some data and drop it immediately. */ + if (u->sink->thread_info.state == PA_SINK_RUNNING && !u->thread_info.active_outputs) { struct timespec now; pa_rtclock_get(&now); - if (pa_timespec_cmp(&u->timestamp, &now) <= 0) { + if (!u->thread_info.in_null_mode || pa_timespec_cmp(&u->thread_info.timestamp, &now) <= 0) { pa_sink_skip(u->sink, u->block_size); - pa_timespec_add(&u->timestamp, pa_bytes_to_usec(u->block_size, &u->sink->sample_spec)); + + if (!u->thread_info.in_null_mode) + u->thread_info.timestamp = now; + + pa_timespec_add(&u->thread_info.timestamp, pa_bytes_to_usec(u->block_size, &u->sink->sample_spec)); } - pa_rtpoll_set_timer_absolute(u->rtpoll, &u->timestamp); - } else + pa_rtpoll_set_timer_absolute(u->rtpoll, &u->thread_info.timestamp); + u->thread_info.in_null_mode = TRUE; + + } else { pa_rtpoll_set_timer_disabled(u->rtpoll); + u->thread_info.in_null_mode = FALSE; + } /* Hmm, nothing to do. Let's sleep */ - if ((ret = pa_rtpoll_run(u->rtpoll, 1)) < 0) + if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0) { + pa_log_info("pa_rtpoll_run() = %i", ret); goto fail; + } if (ret == 0) goto finish; @@ -281,12 +293,13 @@ static void render_memblock(struct userdata *u, struct output *o, size_t length) pa_assert(u); pa_assert(o); - if (!PA_SINK_OPENED(u->sink->thread_info.state)) - return; + /* We are run by the sink thread, on behalf of an output (o). The + * other output is waiting for us, hence it is safe to access its + * mainblockq and asyncmsgq directly. */ - /* We are run by the master output (u->master), possibly on behalf - * of another output (o). The other output is waiting for us, - * hence it is safe to access its mainblockq directly. */ + /* If we are not running, we cannot produce any data */ + if (!pa_atomic_load(&u->thread_info.running)) + return; /* Maybe there's some data in the requesting output's queue * now? */ @@ -302,19 +315,16 @@ static void render_memblock(struct userdata *u, struct output *o, size_t length) pa_sink_render(u->sink, length, &chunk); /* OK, let's send this data to the other threads */ - for (j = o->userdata->thread_info.outputs; j; j = j->next) + for (j = u->thread_info.active_outputs; j; j = j->next) /* Send to other outputs, which are not the requesting - * one, and not the master */ + * one */ - if (j != o && j != u->thread_info.master && j->sink_input) + if (j != o) pa_asyncmsgq_post(j->inq, PA_MSGOBJECT(j->sink_input), SINK_INPUT_MESSAGE_POST, NULL, 0, &chunk, NULL); - /* Now push it into the master queue */ - pa_memblockq_push_align(u->thread_info.master->memblockq, &chunk); - - /* And into the requesting output's queue */ - if (o != u->thread_info.master) + /* And place it directly into the requesting output's queue */ + if (o) pa_memblockq_push_align(o->memblockq, &chunk); pa_memblock_unref(chunk.memblock); @@ -337,16 +347,8 @@ static void request_memblock(struct output *o, size_t length) { if (pa_memblockq_is_readable(o->memblockq)) return; - /* OK, we need to prepare new data */ - - if (o == o->userdata->thread_info.master) - /* OK, we're the master, so let's render some data */ - render_memblock(o->userdata, o, length); - - else - /* We're not the master, we need to ask the master to do the - * rendering for us */ - + /* OK, we need to prepare new data, but only if the sink is actually running */ + if (pa_atomic_load(&o->userdata->thread_info.running)) pa_asyncmsgq_send(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_NEED, o, length, NULL); } @@ -360,7 +362,7 @@ static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chun /* If necessary, get some new data */ request_memblock(o, length); - return pa_memblockq_peek(o->memblockq, chunk); + return pa_memblockq_peek(o->memblockq, chunk); } /* Called from I/O thread context */ @@ -374,49 +376,6 @@ static void sink_input_drop_cb(pa_sink_input *i, size_t length) { pa_memblockq_drop(o->memblockq, length); } -/* Called from I/O thread context for the master */ -static void create_master_rtpolls(struct userdata *u) { - struct output *k; - - pa_assert(u); - - pa_assert(!u->master->outq_rtpoll_item); - - /* Set up the queues from the outputs to the master */ - for (k = u->thread_info.outputs; k; k = k->next) { - - pa_assert(!k->outq_rtpoll_item); - - if (k == u->master) - continue; - - k->outq_rtpoll_item = pa_rtpoll_item_new_asyncmsgq( - u->master->sink->rtpoll, - PA_RTPOLL_EARLY+1, /* This one has a slightly lower priority than the normal message handling */ - k->outq); - } -} - -/* Called from I/O thread context for the master */ -static void free_master_rtpolls(struct userdata *u) { - struct output *k; - - pa_assert(!u->master->outq_rtpoll_item); - - for (k = u->thread_info.outputs; k; k = k->next) { - - if (k == u->master) - continue; - - if (k->outq_rtpoll_item) { - pa_rtpoll_item_free(k->outq_rtpoll_item); - k->outq_rtpoll_item = NULL; - } - - pa_assert(!k->outq_rtpoll_item); - } -} - /* Called from I/O thread context */ static void sink_input_attach_cb(pa_sink_input *i) { struct output *o; @@ -424,22 +383,11 @@ static void sink_input_attach_cb(pa_sink_input *i) { pa_sink_input_assert_ref(i); pa_assert_se(o = i->userdata); - if (o->userdata->thread_info.master == o) { - create_master_rtpolls(o->userdata); - - /* Calling these two functions here is safe, because both - * threads that might access this sink are known to be - * waiting for us. */ - pa_sink_set_asyncmsgq(o->userdata->sink, i->sink->asyncmsgq); - pa_sink_set_rtpoll(o->userdata->sink, i->sink->rtpoll); - pa_sink_attach_within_thread(o->userdata->sink); - } - - /* Set up the queues from the inputs to the master */ + /* Set up the queue from the sink thread to us */ pa_assert(!o->inq_rtpoll_item); o->inq_rtpoll_item = pa_rtpoll_item_new_asyncmsgq( i->sink->rtpoll, - PA_RTPOLL_NORMAL, /* This one has a lower priority than the normal message handling */ + PA_RTPOLL_LATE, /* This one is not that important, since we check for data in _peek() anyway. */ o->inq); } @@ -450,16 +398,10 @@ static void sink_input_detach_cb(pa_sink_input *i) { pa_sink_input_assert_ref(i); pa_assert_se(o = i->userdata); -/* pa_log("detaching %s", i->sink->name); */ - + /* Shut down the queue from the sink thread to us */ pa_assert(o->inq_rtpoll_item); pa_rtpoll_item_free(o->inq_rtpoll_item); o->inq_rtpoll_item = NULL; - - if (o->userdata->thread_info.master == o) { - pa_sink_detach_within_thread(o->userdata->sink); - free_master_rtpolls(o->userdata); - } } /* Called from main context */ @@ -467,14 +409,10 @@ static void sink_input_kill_cb(pa_sink_input *i) { struct output *o; pa_sink_input_assert_ref(i); - o = i->userdata; - pa_assert(o); - - pa_sink_input_unlink(o->sink_input); - pa_sink_input_unref(o->sink_input); - o->sink_input = NULL; + pa_assert(o = i->userdata); pa_module_unload_request(o->userdata->module); + output_free(o); } /* Called from thread context */ @@ -493,7 +431,7 @@ static int sink_input_process_msg(pa_msgobject *obj, int code, void *data, int64 break; } - case SINK_INPUT_MESSAGE_POST: { + case SINK_INPUT_MESSAGE_POST: if (PA_SINK_OPENED(o->sink_input->sink->thread_info.state)) pa_memblockq_push_align(o->memblockq, chunk); @@ -501,66 +439,78 @@ static int sink_input_process_msg(pa_msgobject *obj, int code, void *data, int64 pa_memblockq_flush(o->memblockq); break; - } } return pa_sink_input_process_msg(obj, code, data, offset, chunk); } /* Called from main context */ -static int suspend(struct userdata *u) { +static void disable_output(struct output *o) { + pa_assert(o); + + if (!o->sink_input) + return; + + pa_asyncmsgq_send(o->userdata->sink->asyncmsgq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_REMOVE_OUTPUT, o, 0, NULL); + pa_sink_input_unlink(o->sink_input); + pa_sink_input_unref(o->sink_input); + o->sink_input = NULL; + +} + +/* Called from main context */ +static void enable_output(struct output *o) { + pa_assert(o); + + if (o->sink_input) + return; + + if (output_create_sink_input(o) >= 0) { + + pa_memblockq_flush(o->memblockq); + + pa_sink_input_put(o->sink_input); + + if (o->userdata->sink && PA_SINK_LINKED(pa_sink_get_state(o->userdata->sink))) + pa_asyncmsgq_send(o->userdata->sink->asyncmsgq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_ADD_OUTPUT, o, 0, NULL); + } +} + +/* Called from main context */ +static void suspend(struct userdata *u) { struct output *o; uint32_t idx; pa_assert(u); /* Let's suspend by unlinking all streams */ + for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) + disable_output(o); - if (update_master(u, NULL) < 0) - pa_module_unload_request(u->module); - - for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) { - - if (o->sink_input) { - pa_sink_input_unlink(o->sink_input); - pa_sink_input_unref(o->sink_input); - o->sink_input = NULL; - } - } + pick_master(u, NULL); pa_log_info("Device suspended..."); - - return 0; } /* Called from main context */ -static int unsuspend(struct userdata *u) { +static void unsuspend(struct userdata *u) { struct output *o; uint32_t idx; pa_assert(u); /* Let's resume */ - for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) { - pa_sink_suspend(o->sink, 0); + pa_sink_suspend(o->sink, FALSE); - if (PA_SINK_OPENED(pa_sink_get_state(o->sink))) { - if (output_create_sink_input(u, o) < 0) - output_free(o); - } + if (PA_SINK_OPENED(pa_sink_get_state(o->sink))) + enable_output(o); } - if (pick_master(u, NULL) < 0) - pa_module_unload_request(u->module); - - for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) - if (o->sink_input && pa_sink_get_state(o->sink_input) == PA_SINK_INPUT_INIT) - pa_sink_input_put(o->sink_input); + pick_master(u, NULL); pa_log_info("Resumed successfully..."); - return 0; } /* Called from main context */ @@ -577,18 +527,14 @@ static int sink_set_state(pa_sink *sink, pa_sink_state_t state) { case PA_SINK_SUSPENDED: pa_assert(PA_SINK_OPENED(pa_sink_get_state(u->sink))); - if (suspend(u) < 0) - return -1; - + suspend(u); break; case PA_SINK_IDLE: case PA_SINK_RUNNING: - if (pa_sink_get_state(u->sink) == PA_SINK_SUSPENDED) { - if (unsuspend(u) < 0) - return -1; - } + if (pa_sink_get_state(u->sink) == PA_SINK_SUSPENDED) + unsuspend(u); break; @@ -607,67 +553,41 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse switch (code) { case PA_SINK_MESSAGE_SET_STATE: - - if ((pa_sink_state_t) PA_PTR_TO_UINT(data) == PA_SINK_RUNNING) { - /* Only useful when running in NULL mode, i.e. when no - * master sink is attached */ - pa_rtclock_get(&u->timestamp); - } - + pa_atomic_store(&u->thread_info.running, PA_PTR_TO_UINT(data) == PA_SINK_RUNNING); break; - case PA_SINK_MESSAGE_GET_LATENCY: { - struct timespec now; + case PA_SINK_MESSAGE_GET_LATENCY: /* This code will only be called when running in NULL - * mode, i.e. when no master sink is attached. See + * mode, i.e. when no output is attached. See * sink_get_latency_cb() below */ - pa_rtclock_get(&now); - if (pa_timespec_cmp(&u->timestamp, &now) > 0) - *((pa_usec_t*) data) = 0; - else - *((pa_usec_t*) data) = pa_timespec_diff(&u->timestamp, &now); - break; - } - - case SINK_MESSAGE_SET_MASTER: - - if (u->thread_info.master && data != u->thread_info.master) { - - if (u->thread_info.master->sink_input->thread_info.attached) - free_master_rtpolls(u); + if (u->thread_info.in_null_mode) { + struct timespec now; + if (pa_timespec_cmp(&u->thread_info.timestamp, pa_rtclock_get(&now)) > 0) { + *((pa_usec_t*) data) = pa_timespec_diff(&u->thread_info.timestamp, &now); + break; + } } - if ((u->thread_info.master = data)) { - - /* There's now a master, and we're being executed in - * its thread, let's register the asyncmsgqs from other - * outputs to us */ - - if (u->thread_info.master->sink_input->thread_info.attached) - create_master_rtpolls(u); + *((pa_usec_t*) data) = 0; - } - - return 0; + break; case SINK_MESSAGE_ADD_OUTPUT: { struct output *op = data; - PA_LLIST_PREPEND(struct output, u->thread_info.outputs, op); + PA_LLIST_PREPEND(struct output, u->thread_info.active_outputs, op); pa_assert(!op->outq_rtpoll_item); - if (op != u->thread_info.master) { - /* Create pa_asyncmsgq to master */ + /* Create pa_asyncmsgq to the sink thread */ - op->outq_rtpoll_item = pa_rtpoll_item_new_asyncmsgq( - u->thread_info.master->sink->rtpoll, - PA_RTPOLL_EARLY+1, /* This one has a slightly lower priority than the normal message handling */ - op->outq); - } + op->outq_rtpoll_item = pa_rtpoll_item_new_asyncmsgq( + u->rtpoll, + PA_RTPOLL_EARLY-1, /* This item is very important */ + op->outq); return 0; } @@ -675,14 +595,13 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse case SINK_MESSAGE_REMOVE_OUTPUT: { struct output *op = data; - PA_LLIST_REMOVE(struct output, u->thread_info.outputs, op); + PA_LLIST_REMOVE(struct output, u->thread_info.active_outputs, op); - /* Remove the q that leads from this output to the master output */ + /* Remove the q that leads from this output to the sink thread */ - if (op->outq_rtpoll_item) { - pa_rtpoll_item_free(op->outq_rtpoll_item); - op->outq_rtpoll_item = NULL; - } + pa_assert(op->outq_rtpoll_item); + pa_rtpoll_item_free(op->outq_rtpoll_item); + op->outq_rtpoll_item = NULL; return 0; } @@ -700,8 +619,7 @@ static pa_usec_t sink_get_latency_cb(pa_sink *s) { struct userdata *u; pa_sink_assert_ref(s); - u = s->userdata; - pa_assert(u); + pa_assert_se(u = s->userdata); if (u->master) { /* If we have a master sink, we just return the latency of it @@ -712,10 +630,10 @@ static pa_usec_t sink_get_latency_cb(pa_sink *s) { return pa_sink_input_get_latency(u->master->sink_input) + - pa_sink_get_latency(u->master->sink_input->sink); + pa_sink_get_latency(u->master->sink); } else { - pa_usec_t usec; + pa_usec_t usec = 0; /* We have no master, hence let's ask our own thread which * implements the NULL sink */ @@ -759,94 +677,50 @@ static void update_description(struct userdata *u) { pa_xfree(t); } -static int update_master(struct userdata *u, struct output *o) { +static void update_master(struct userdata *u, struct output *o) { pa_assert(u); - /* Make sure everything is detached from the old thread before we move our stuff to a new thread */ - if (u->sink && PA_SINK_LINKED(pa_sink_get_state(u->sink))) { - pa_sink_detach(u->sink); - pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_SET_MASTER, NULL, 0, NULL); - } else - u->thread_info.master = NULL; - - if (o) { - /* If we have a master sink we run our own sink in its thread */ - - pa_assert(o->sink_input); - pa_assert(PA_SINK_OPENED(pa_sink_get_state(o->sink))); - - if (u->thread) { - /* If we previously were in NULL mode, let's kill the thread */ - pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); - pa_thread_free(u->thread); - u->thread = NULL; - - pa_assert(u->rtpoll); - pa_rtpoll_free(u->rtpoll); - u->rtpoll = NULL; - } - - pa_sink_set_asyncmsgq(u->sink, o->sink->asyncmsgq); - pa_sink_set_rtpoll(u->sink, o->sink->rtpoll); - u->master = o; + if (u->master == o) + return; + if ((u->master = o)) pa_log_info("Master sink is now '%s'", o->sink_input->sink->name); - - } else { - - /* We have no master sink, let's create our own thread */ - - pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); - u->master = NULL; - - if (!u->thread) { - pa_assert(!u->rtpoll); - - u->rtpoll = pa_rtpoll_new(); - pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); - - pa_sink_set_rtpoll(u->sink, u->rtpoll); - - if (!(u->thread = pa_thread_new(thread_func, u))) { - pa_log("Failed to create thread."); - return -1; - } - } - - pa_log_info("No suitable master sink found, going to NULL mode\n"); - } - - /* Now attach everything again */ - if (u->sink && PA_SINK_LINKED(pa_sink_get_state(u->sink))) { - pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_SET_MASTER, u->master, 0, NULL); - pa_sink_attach(u->sink); - } else - u->thread_info.master = u->master; - - return 0; + else + pa_log_info("No master selected, lacking suitable outputs."); } -static int pick_master(struct userdata *u, struct output *except) { +static void pick_master(struct userdata *u, struct output *except) { struct output *o; uint32_t idx; pa_assert(u); - if (u->master && u->master != except && u->master->sink_input && PA_SINK_OPENED(pa_sink_get_state(u->master->sink))) - return update_master(u, u->master); + if (u->master && + u->master != except && + u->master->sink_input && + PA_SINK_OPENED(pa_sink_get_state(u->master->sink))) { + update_master(u, u->master); + return; + } for (o = pa_idxset_first(u->outputs, &idx); o; o = pa_idxset_next(u->outputs, &idx)) - if (o != except && o->sink_input && PA_SINK_OPENED(pa_sink_get_state(o->sink))) - return update_master(u, o); + if (o != except && + o->sink_input && + PA_SINK_OPENED(pa_sink_get_state(o->sink))) { + update_master(u, o); + return; + } - return update_master(u, NULL); + update_master(u, NULL); } -static int output_create_sink_input(struct userdata *u, struct output *o) { +static int output_create_sink_input(struct output *o) { pa_sink_input_new_data data; char *t; - pa_assert(u); - pa_assert(!o->sink_input); + pa_assert(o); + + if (o->sink_input) + return 0; t = pa_sprintf_malloc("Simultaneous output on %s", o->sink->description); @@ -854,12 +728,12 @@ static int output_create_sink_input(struct userdata *u, struct output *o) { data.sink = o->sink; data.driver = __FILE__; data.name = t; - pa_sink_input_new_data_set_sample_spec(&data, &u->sink->sample_spec); - pa_sink_input_new_data_set_channel_map(&data, &u->sink->channel_map); - data.module = u->module; - data.resample_method = u->resample_method; + pa_sink_input_new_data_set_sample_spec(&data, &o->userdata->sink->sample_spec); + pa_sink_input_new_data_set_channel_map(&data, &o->userdata->sink->channel_map); + data.module = o->userdata->module; + data.resample_method = o->userdata->resample_method; - o->sink_input = pa_sink_input_new(u->core, &data, PA_SINK_INPUT_VARIABLE_RATE|PA_SINK_INPUT_DONT_MOVE); + o->sink_input = pa_sink_input_new(o->userdata->core, &data, PA_SINK_INPUT_VARIABLE_RATE|PA_SINK_INPUT_DONT_MOVE); pa_xfree(t); @@ -874,6 +748,7 @@ static int output_create_sink_input(struct userdata *u, struct output *o) { o->sink_input->kill = sink_input_kill_cb; o->sink_input->userdata = o; + return 0; } @@ -901,29 +776,38 @@ static struct output *output_new(struct userdata *u, pa_sink *sink) { 0, NULL); - pa_assert_se(pa_idxset_put(u->outputs, o, NULL) == 0); - update_description(u); - if (u->sink && PA_SINK_LINKED(pa_sink_get_state(u->sink))) pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_ADD_OUTPUT, o, 0, NULL); - else - PA_LLIST_PREPEND(struct output, u->thread_info.outputs, o); + else { + /* If the sink is not yet started, we need to do the activation ourselves */ + PA_LLIST_PREPEND(struct output, u->thread_info.active_outputs, o); + + o->outq_rtpoll_item = pa_rtpoll_item_new_asyncmsgq( + u->rtpoll, + PA_RTPOLL_EARLY-1, /* This item is very important */ + o->outq); + } if (PA_SINK_OPENED(pa_sink_get_state(u->sink)) || pa_sink_get_state(u->sink) == PA_SINK_INIT) { - pa_sink_suspend(sink, 0); + pa_sink_suspend(sink, FALSE); if (PA_SINK_OPENED(pa_sink_get_state(sink))) - if (output_create_sink_input(u, o) < 0) + if (output_create_sink_input(o) < 0) goto fail; } + + update_description(u); + return o; fail: if (o) { + pa_idxset_remove_by_data(u->outputs, o, NULL); + if (o->sink_input) { pa_sink_input_unlink(o->sink_input); pa_sink_input_unref(o->sink_input); @@ -962,12 +846,11 @@ static pa_hook_result_t sink_new_hook_cb(pa_core *c, pa_sink *s, struct userdata return PA_HOOK_OK; } - if (pick_master(u, NULL) < 0) - pa_module_unload_request(u->module); - if (o->sink_input) pa_sink_input_put(o->sink_input); + pick_master(u, NULL); + return PA_HOOK_OK; } @@ -1014,24 +897,13 @@ static pa_hook_result_t sink_state_changed_hook_cb(pa_core *c, pa_sink *s, struc state = pa_sink_get_state(s); if (PA_SINK_OPENED(state) && PA_SINK_OPENED(pa_sink_get_state(u->sink)) && !o->sink_input) { - output_create_sink_input(u, o); - - if (pick_master(u, NULL) < 0) - pa_module_unload_request(u->module); - - if (o->sink_input) - pa_sink_input_put(o->sink_input); + enable_output(o); + pick_master(u, NULL); } if (state == PA_SINK_SUSPENDED && o->sink_input) { - pa_sink_input_unlink(o->sink_input); - pa_sink_input_unref(o->sink_input); - o->sink_input = NULL; - - pa_memblockq_flush(o->memblockq); - - if (pick_master(u, o) < 0) - pa_module_unload_request(u->module); + disable_output(o); + pick_master(u, o); } return PA_HOOK_OK; @@ -1067,16 +939,20 @@ int pa__init(pa_module*m) { u->module = m; m->userdata = u; u->sink = NULL; - u->thread_info.master = u->master = NULL; + u->master = NULL; u->time_event = NULL; u->adjust_time = DEFAULT_ADJUST_TIME; pa_thread_mq_init(&u->thread_mq, m->core->mainloop); - u->rtpoll = NULL; + u->rtpoll = pa_rtpoll_new(); u->thread = NULL; - PA_LLIST_HEAD_INIT(struct output, u->thread_info.outputs); u->resample_method = resample_method; u->outputs = pa_idxset_new(NULL, NULL); pa_timespec_reset(&u->adjust_timestamp); + u->sink_new_slot = u->sink_unlink_slot = u->sink_state_changed_slot = NULL; + PA_LLIST_HEAD_INIT(struct output, u->thread_info.active_outputs); + pa_atomic_store(&u->thread_info.running, FALSE); + u->thread_info.in_null_mode = FALSE; + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); if (pa_modargs_get_value_u32(ma, "adjust_time", &u->adjust_time) < 0) { pa_log("Failed to parse adjust_time value"); @@ -1097,11 +973,11 @@ int pa__init(pa_module*m) { } ss = master_sink->sample_spec; - u->automatic = 0; + u->automatic = FALSE; } else { master_sink = NULL; ss = m->core->default_sample_spec; - u->automatic = 1; + u->automatic = TRUE; } if ((pa_modargs_get_sample_spec(ma, &ss) < 0)) { @@ -1137,6 +1013,8 @@ int pa__init(pa_module*m) { u->sink->flags = PA_SINK_LATENCY; pa_sink_set_module(u->sink, m); pa_sink_set_description(u->sink, "Simultaneous output"); + pa_sink_set_rtpoll(u->sink, u->rtpoll); + pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); u->block_size = pa_bytes_per_second(&ss) / 20; /* 50 ms */ if (u->block_size <= 0) @@ -1200,8 +1078,12 @@ int pa__init(pa_module*m) { u->sink_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], (pa_hook_cb_t) sink_unlink_hook_cb, u); u->sink_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], (pa_hook_cb_t) sink_state_changed_hook_cb, u); - if (pick_master(u, NULL) < 0) + pick_master(u, NULL); + + if (!(u->thread = pa_thread_new(thread_func, u))) { + pa_log("Failed to create thread."); goto fail; + } /* Activate the sink and the sink inputs */ pa_sink_put(u->sink); @@ -1234,22 +1116,12 @@ fail: static void output_free(struct output *o) { pa_assert(o); - /* Make sure the master points to a different output */ - if (pick_master(o->userdata, o) < 0) - pa_module_unload_request(o->userdata->module); + pick_master(o->userdata, o); - if (o->userdata->sink && PA_SINK_LINKED(pa_sink_get_state(o->userdata->sink))) - pa_asyncmsgq_send(o->userdata->sink->asyncmsgq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_REMOVE_OUTPUT, o, 0, NULL); - else - PA_LLIST_REMOVE(struct output, o->userdata->thread_info.outputs, o); + disable_output(o); pa_assert_se(pa_idxset_remove_by_data(o->userdata->outputs, o, NULL)); - if (o->sink_input) { - pa_sink_input_unlink(o->sink_input); - pa_sink_input_unref(o->sink_input); - } - update_description(o->userdata); if (o->inq_rtpoll_item) @@ -1288,9 +1160,6 @@ void pa__done(pa_module*m) { if (u->sink_state_changed_slot) pa_hook_slot_free(u->sink_state_changed_slot); - if (u->sink) - pa_sink_unlink(u->sink); - if (u->outputs) { while ((o = pa_idxset_first(u->outputs, NULL))) output_free(o); @@ -1298,6 +1167,9 @@ void pa__done(pa_module*m) { pa_idxset_free(u->outputs, NULL, NULL); } + if (u->sink) + pa_sink_unlink(u->sink); + if (u->thread) { pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); pa_thread_free(u->thread); -- cgit From 67b899acc915a3d01623a7d517f81eab7231d11d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 28 Sep 2007 13:15:11 +0000 Subject: treat timer_enabled like a real, grown-up boolean variable git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1917 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/rtpoll.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c index 921619d8..de0ffa4f 100644 --- a/src/pulsecore/rtpoll.c +++ b/src/pulsecore/rtpoll.c @@ -374,13 +374,13 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { #ifdef __linux__ if (!p->dont_use_ppoll) #endif - r = ppoll(p->pollfd, p->n_pollfd_used, p->timer_enabled > 0 ? &timeout : NULL, p->rtsig < 0 ? NULL : &p->sigset_unblocked); + r = ppoll(p->pollfd, p->n_pollfd_used, p->timer_enabled ? &timeout : NULL, p->rtsig < 0 ? NULL : &p->sigset_unblocked); #ifdef __linux__ else #endif #endif - r = poll(p->pollfd, p->n_pollfd_used, p->timer_enabled > 0 ? (timeout.tv_sec*1000) + (timeout.tv_nsec / 1000000) : -1); + r = poll(p->pollfd, p->n_pollfd_used, p->timer_enabled ? (timeout.tv_sec*1000) + (timeout.tv_nsec / 1000000) : -1); if (r < 0) { if (errno == EAGAIN || errno == EINTR) @@ -403,7 +403,7 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { pa_timespec_add(&p->next_elapse, (pa_timespec_diff(&now, &p->next_elapse) / p->period + 1) * p->period); } else - p->timer_enabled = 0; + p->timer_enabled = FALSE; } /* Let's tell everyone that we left the sleep */ -- cgit From bdf97468f34407674d191f216febb1987adb16f6 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 28 Sep 2007 14:01:25 +0000 Subject: Update module-solaris to new structure. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1918 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 14 +- src/modules/module-solaris.c | 688 ++++++++++++++++++++++++------------------- 2 files changed, 395 insertions(+), 307 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index a92a5570..e1d210b0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1005,10 +1005,10 @@ modlibexec_LTLIBRARIES += \ module-alsa-source.la endif -#if HAVE_SOLARIS -#modlibexec_LTLIBRARIES += \ -# module-solaris.la -#endif +if HAVE_SOLARIS +modlibexec_LTLIBRARIES += \ + module-solaris.la +endif if HAVE_AVAHI modlibexec_LTLIBRARIES += \ @@ -1285,9 +1285,9 @@ module_alsa_source_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) # Solaris -#module_solaris_la_SOURCES = modules/module-solaris.c -#module_solaris_la_LDFLAGS = -module -avoid-version -#module_solaris_la_LIBADD = $(AM_LIBADD) libiochannel.la +module_solaris_la_SOURCES = modules/module-solaris.c +module_solaris_la_LDFLAGS = -module -avoid-version +module_solaris_la_LIBADD = $(AM_LIBADD) libiochannel.la # Avahi diff --git a/src/modules/module-solaris.c b/src/modules/module-solaris.c index c8ff7705..a8a94712 100644 --- a/src/modules/module-solaris.c +++ b/src/modules/module-solaris.c @@ -4,7 +4,7 @@ This file is part of PulseAudio. Copyright 2006 Lennart Poettering - Copyright 2006 Pierre Ossman for Cendio AB + Copyright 2006-2007 Pierre Ossman for Cendio AB PulseAudio is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published @@ -57,6 +57,9 @@ #include #include #include +#include +#include +#include #include "module-solaris-symdef.h" @@ -75,12 +78,14 @@ PA_MODULE_USAGE( "channel_map=") struct userdata { + pa_core *core; pa_sink *sink; pa_source *source; - pa_iochannel *io; - pa_core *core; - pa_time_event *timer; - pa_usec_t poll_timeout; + + pa_thread *thread; + pa_thread_mq thread_mq; + pa_rtpoll *rtpoll; + pa_signal_event *sig; pa_memchunk memchunk; @@ -90,9 +95,9 @@ struct userdata { uint32_t frame_size; uint32_t buffer_size; unsigned int written_bytes, read_bytes; - int sink_underflow; int fd; + pa_rtpoll_item *rtpoll_item; pa_module *module; }; @@ -114,309 +119,357 @@ static const char* const valid_modargs[] = { #define DEFAULT_SOURCE_NAME "solaris_input" #define DEFAULT_DEVICE "/dev/audio" -#define CHUNK_SIZE 2048 - -static void update_usage(struct userdata *u) { - pa_module_set_used(u->module, - (u->sink ? pa_sink_used_by(u->sink) : 0) + - (u->source ? pa_source_used_by(u->source) : 0)); -} - -static void do_write(struct userdata *u) { - audio_info_t info; +static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { + struct userdata *u = PA_SINK(o)->userdata; int err; - size_t len; - ssize_t r; + audio_info_t info; - assert(u); + switch (code) { + case PA_SINK_MESSAGE_GET_LATENCY: { + pa_usec_t r = 0; - /* We cannot check pa_iochannel_is_writable() because of our buffer hack */ - if (!u->sink) - return; + if (u->fd >= 0) { - update_usage(u); + err = ioctl(u->fd, AUDIO_GETINFO, &info); + pa_assert(err >= 0); - err = ioctl(u->fd, AUDIO_GETINFO, &info); - assert(err >= 0); + r += pa_bytes_to_usec(u->written_bytes, &PA_SINK(o)->sample_spec); + r -= pa_bytes_to_usec(info.play.samples * u->frame_size, &PA_SINK(o)->sample_spec); - /* - * Since we cannot modify the size of the output buffer we fake it - * by not filling it more than u->buffer_size. - */ - len = u->buffer_size; - len -= u->written_bytes - (info.play.samples * u->frame_size); + if (u->memchunk.memblock) + r += pa_bytes_to_usec(u->memchunk.length, &PA_SINK(o)->sample_spec); + } - /* The sample counter can sometimes go backwards :( */ - if (len > u->buffer_size) - len = 0; + *((pa_usec_t*) data) = r; - if (!u->sink_underflow && (len == u->buffer_size)) - pa_log_debug("Solaris buffer underflow!"); + return 0; + } - len -= len % u->frame_size; + case PA_SINK_MESSAGE_SET_VOLUME: + if (u->fd >= 0) { + AUDIO_INITINFO(&info); + + info.play.gain = pa_cvolume_avg((pa_cvolume*)data) * AUDIO_MAX_GAIN / PA_VOLUME_NORM; + assert(info.play.gain <= AUDIO_MAX_GAIN); + + if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) { + if (errno == EINVAL) + pa_log("AUDIO_SETINFO: Unsupported volume."); + else + pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); + } else { + return 0; + } + } + break; - if (len == 0) - return; + case PA_SINK_MESSAGE_GET_VOLUME: + if (u->fd >= 0) { + err = ioctl(u->fd, AUDIO_GETINFO, &info); + assert(err >= 0); - if (!u->memchunk.length) { - if (pa_sink_render(u->sink, len, &u->memchunk) < 0) { - u->sink_underflow = 1; - return; - } - } + pa_cvolume_set((pa_cvolume*) data, ((pa_cvolume*) data)->channels, + info.play.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN); - u->sink_underflow = 0; + return 0; + } + break; - assert(u->memchunk.memblock); - assert(u->memchunk.memblock->data); - assert(u->memchunk.length); + case PA_SINK_MESSAGE_SET_MUTE: + if (u->fd >= 0) { + AUDIO_INITINFO(&info); - if (u->memchunk.length < len) { - len = u->memchunk.length; - len -= len % u->frame_size; - assert(len); - } + info.output_muted = !!PA_PTR_TO_UINT(data); - if ((r = pa_iochannel_write(u->io, - (uint8_t*) u->memchunk.memblock->data + u->memchunk.index, len)) < 0) { - pa_log("write() failed: %s", pa_cstrerror(errno)); - return; - } + if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) + pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); + else + return 0; + } + break; - assert(r % u->frame_size == 0); + case PA_SINK_MESSAGE_GET_MUTE: + if (u->fd >= 0) { + err = ioctl(u->fd, AUDIO_GETINFO, &info); + pa_assert(err >= 0); - u->memchunk.index += r; - u->memchunk.length -= r; + *(int*)data = !!info.output_muted; - if (u->memchunk.length <= 0) { - pa_memblock_unref(u->memchunk.memblock); - u->memchunk.memblock = NULL; + return 0; + } + break; } - u->written_bytes += r; + return pa_sink_process_msg(o, code, data, offset, chunk); } -static void do_read(struct userdata *u) { - pa_memchunk memchunk; +static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { + struct userdata *u = PA_SOURCE(o)->userdata; int err; - size_t l; - ssize_t r; - assert(u); + audio_info_t info; - if (!u->source || !pa_iochannel_is_readable(u->io)) - return; + switch (code) { + case PA_SOURCE_MESSAGE_GET_LATENCY: { + pa_usec_t r = 0; - update_usage(u); + if (u->fd) { + err = ioctl(u->fd, AUDIO_GETINFO, &info); + pa_assert(err >= 0); - err = ioctl(u->fd, I_NREAD, &l); - assert(err >= 0); + r += pa_bytes_to_usec(info.record.samples * u->frame_size, &PA_SOURCE(o)->sample_spec); + r -= pa_bytes_to_usec(u->read_bytes, &PA_SOURCE(o)->sample_spec); + } - /* This is to make sure it fits in the memory pool. Also, a page - should be the most efficient transfer size. */ - if (l > u->page_size) - l = u->page_size; + *((pa_usec_t*) data) = r; - memchunk.memblock = pa_memblock_new(u->core->mempool, l); - assert(memchunk.memblock); - if ((r = pa_iochannel_read(u->io, memchunk.memblock->data, memchunk.memblock->length)) < 0) { - pa_memblock_unref(memchunk.memblock); - if (errno != EAGAIN) - pa_log("read() failed: %s", pa_cstrerror(errno)); - return; - } + return 0; + } - assert(r <= (ssize_t) memchunk.memblock->length); - memchunk.length = memchunk.memblock->length = r; - memchunk.index = 0; + case PA_SOURCE_MESSAGE_SET_VOLUME: + if (u->fd >= 0) { + AUDIO_INITINFO(&info); + + info.record.gain = pa_cvolume_avg((pa_cvolume*) data) * AUDIO_MAX_GAIN / PA_VOLUME_NORM; + assert(info.record.gain <= AUDIO_MAX_GAIN); + + if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) { + if (errno == EINVAL) + pa_log("AUDIO_SETINFO: Unsupported volume."); + else + pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); + } else { + return 0; + } + } + break; - pa_source_post(u->source, &memchunk); - pa_memblock_unref(memchunk.memblock); + case PA_SOURCE_MESSAGE_GET_VOLUME: + if (u->fd >= 0) { + err = ioctl(u->fd, AUDIO_GETINFO, &info); + pa_assert(err >= 0); - u->read_bytes += r; -} + pa_cvolume_set((pa_cvolume*) data, ((pa_cvolume*) data)->channels, + info.record.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN); -static void io_callback(pa_iochannel *io, void*userdata) { - struct userdata *u = userdata; - assert(u); - do_write(u); - do_read(u); -} + return 0; + } + break; + } -static void timer_cb(pa_mainloop_api*a, pa_time_event *e, const struct timeval *tv, void *userdata) { - struct userdata *u = userdata; - struct timeval ntv; + return pa_source_process_msg(o, code, data, offset, chunk); +} - assert(u); +static void clear_underflow(struct userdata *u) +{ + audio_info_t info; - do_write(u); + AUDIO_INITINFO(&info); - pa_gettimeofday(&ntv); - pa_timeval_add(&ntv, u->poll_timeout); + info.play.error = 0; - a->time_restart(e, &ntv); + if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) + pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); } -static void sig_callback(pa_mainloop_api *api, pa_signal_event*e, int sig, void *userdata) { - struct userdata *u = userdata; - pa_cvolume old_vol; +static void clear_overflow(struct userdata *u) +{ + audio_info_t info; - assert(u); + AUDIO_INITINFO(&info); - if (u->sink) { - assert(u->sink->get_hw_volume); - memcpy(&old_vol, &u->sink->hw_volume, sizeof(pa_cvolume)); - if (u->sink->get_hw_volume(u->sink) < 0) - return; - if (memcmp(&old_vol, &u->sink->hw_volume, sizeof(pa_cvolume)) != 0) { - pa_subscription_post(u->sink->core, - PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, - u->sink->index); - } - } + info.record.error = 0; - if (u->source) { - assert(u->source->get_hw_volume); - memcpy(&old_vol, &u->source->hw_volume, sizeof(pa_cvolume)); - if (u->source->get_hw_volume(u->source) < 0) - return; - if (memcmp(&old_vol, &u->source->hw_volume, sizeof(pa_cvolume)) != 0) { - pa_subscription_post(u->source->core, - PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, - u->source->index); - } - } + if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) + pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); } -static pa_usec_t sink_get_latency_cb(pa_sink *s) { - pa_usec_t r = 0; - audio_info_t info; - int err; - struct userdata *u = s->userdata; - assert(s && u && u->sink); +static void thread_func(void *userdata) { + struct userdata *u = userdata; + unsigned short revents = 0; + int ret; - err = ioctl(u->fd, AUDIO_GETINFO, &info); - assert(err >= 0); + pa_assert(u); - r += pa_bytes_to_usec(u->written_bytes, &s->sample_spec); - r -= pa_bytes_to_usec(info.play.samples * u->frame_size, &s->sample_spec); + pa_log_debug("Thread starting up"); - if (u->memchunk.memblock) - r += pa_bytes_to_usec(u->memchunk.length, &s->sample_spec); + if (u->core->high_priority) + pa_make_realtime(); - return r; -} + pa_thread_mq_install(&u->thread_mq); + pa_rtpoll_install(u->rtpoll); -static pa_usec_t source_get_latency_cb(pa_source *s) { - pa_usec_t r = 0; - struct userdata *u = s->userdata; - audio_info_t info; - int err; - assert(s && u && u->source); + for (;;) { + /* Render some data and write it to the dsp */ - err = ioctl(u->fd, AUDIO_GETINFO, &info); - assert(err >= 0); + if (u->sink && PA_SINK_OPENED(u->sink->thread_info.state)) { + audio_info_t info; + int err; + size_t len; - r += pa_bytes_to_usec(info.record.samples * u->frame_size, &s->sample_spec); - r -= pa_bytes_to_usec(u->read_bytes, &s->sample_spec); + err = ioctl(u->fd, AUDIO_GETINFO, &info); + pa_assert(err >= 0); - return r; -} + /* + * Since we cannot modify the size of the output buffer we fake it + * by not filling it more than u->buffer_size. + */ + len = u->buffer_size; + len -= u->written_bytes - (info.play.samples * u->frame_size); -static int sink_get_hw_volume_cb(pa_sink *s) { - struct userdata *u = s->userdata; - audio_info_t info; - int err; + /* The sample counter can sometimes go backwards :( */ + if (len > u->buffer_size) + len = 0; - err = ioctl(u->fd, AUDIO_GETINFO, &info); - assert(err >= 0); + if (info.play.error) { + pa_log_debug("Solaris buffer underflow!"); + clear_underflow(u); + } - pa_cvolume_set(&s->hw_volume, s->hw_volume.channels, - info.play.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN); + len -= len % u->frame_size; - return 0; -} + while (len) { + void *p; + ssize_t r; -static int sink_set_hw_volume_cb(pa_sink *s) { - struct userdata *u = s->userdata; - audio_info_t info; + if (!u->memchunk.length) + pa_sink_render(u->sink, len, &u->memchunk); - AUDIO_INITINFO(&info); + pa_assert(u->memchunk.length); - info.play.gain = pa_cvolume_avg(&s->hw_volume) * AUDIO_MAX_GAIN / PA_VOLUME_NORM; - assert(info.play.gain <= AUDIO_MAX_GAIN); + p = pa_memblock_acquire(u->memchunk.memblock); + r = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length, NULL); + pa_memblock_release(u->memchunk.memblock); - if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) { - if (errno == EINVAL) - pa_log("AUDIO_SETINFO: Unsupported volume."); - else - pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); - return -1; - } + if (r < 0) { + if (errno == EINTR) + continue; + else if (errno != EAGAIN) { + pa_log("Failed to read data from DSP: %s", pa_cstrerror(errno)); + goto fail; + } + } else { + pa_assert(r % u->frame_size == 0); - return 0; -} + u->memchunk.index += r; + u->memchunk.length -= r; -static int sink_get_hw_mute_cb(pa_sink *s) { - struct userdata *u = s->userdata; - audio_info_t info; - int err; + if (u->memchunk.length <= 0) { + pa_memblock_unref(u->memchunk.memblock); + pa_memchunk_reset(&u->memchunk); + } - err = ioctl(u->fd, AUDIO_GETINFO, &info); - assert(err >= 0); + len -= r; + u->written_bytes += r; + } + } + } - s->hw_muted = !!info.output_muted; + /* Try to read some data and pass it on to the source driver */ + + if (u->source && PA_SOURCE_OPENED(u->source->thread_info.state) && ((revents & POLLIN))) { + pa_memchunk memchunk; + int err; + size_t l; + void *p; + ssize_t r; + audio_info_t info; + + err = ioctl(u->fd, AUDIO_GETINFO, &info); + pa_assert(err >= 0); + + if (info.record.error) { + pa_log_debug("Solaris buffer overflow!"); + clear_overflow(u); + } + + err = ioctl(u->fd, I_NREAD, &l); + pa_assert(err >= 0); + + if (l > 0) { + /* This is to make sure it fits in the memory pool. Also, a page + should be the most efficient transfer size. */ + if (l > u->page_size) + l = u->page_size; + + memchunk.memblock = pa_memblock_new(u->core->mempool, l); + pa_assert(memchunk.memblock); + + p = pa_memblock_acquire(memchunk.memblock); + r = pa_read(u->fd, p, l, NULL); + pa_memblock_release(memchunk.memblock); + + if (r < 0) { + pa_memblock_unref(memchunk.memblock); + if (errno != EAGAIN) { + pa_log("Failed to read data from DSP: %s", pa_cstrerror(errno)); + goto fail; + } + } else { + memchunk.index = 0; + memchunk.length = r; + + pa_source_post(u->source, &memchunk); + pa_memblock_unref(memchunk.memblock); + + u->read_bytes += r; + + revents &= ~POLLIN; + } + } + } - return 0; -} + if (u->fd >= 0) { + struct pollfd *pollfd; -static int sink_set_hw_mute_cb(pa_sink *s) { - struct userdata *u = s->userdata; - audio_info_t info; + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + pollfd->events = + ((u->source && PA_SOURCE_OPENED(u->source->thread_info.state)) ? POLLIN : 0); + } - AUDIO_INITINFO(&info); + /* Hmm, nothing to do. Let's sleep */ + if ((ret = pa_rtpoll_run(u->rtpoll, 1)) < 0) + goto fail; - info.output_muted = !!s->hw_muted; + if (ret == 0) + goto finish; - if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) { - pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); - return -1; - } + if (u->fd >= 0) { + struct pollfd *pollfd; - return 0; -} + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); -static int source_get_hw_volume_cb(pa_source *s) { - struct userdata *u = s->userdata; - audio_info_t info; - int err; + if (pollfd->revents & ~(POLLOUT|POLLIN)) { + pa_log("DSP shutdown."); + goto fail; + } - err = ioctl(u->fd, AUDIO_GETINFO, &info); - assert(err >= 0); + revents = pollfd->revents; + } else + revents = 0; + } - pa_cvolume_set(&s->hw_volume, s->hw_volume.channels, - info.record.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN); +fail: + /* We have to continue processing messages until we receive the + * SHUTDOWN message */ + pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); + pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); - return 0; +finish: + pa_log_debug("Thread shutting down"); } -static int source_set_hw_volume_cb(pa_source *s) { - struct userdata *u = s->userdata; - audio_info_t info; - - AUDIO_INITINFO(&info); +static void sig_callback(pa_mainloop_api *api, pa_signal_event*e, int sig, void *userdata) { + struct userdata *u = userdata; - info.record.gain = pa_cvolume_avg(&s->hw_volume) * AUDIO_MAX_GAIN / PA_VOLUME_NORM; - assert(info.record.gain <= AUDIO_MAX_GAIN); + assert(u); - if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) { - if (errno == EINVAL) - pa_log("AUDIO_SETINFO: Unsupported volume."); - else - pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno)); - return -1; + if (u->sink) { + pa_sink_get_volume(u->sink); + pa_sink_get_mute(u->sink); } - return 0; + if (u->source) + pa_source_get_volume(u->source); } static int pa_solaris_auto_format(int fd, int mode, pa_sample_spec *ss) { @@ -490,6 +543,7 @@ static int pa_solaris_set_buffer(int fd, int buffer_size) { AUDIO_INITINFO(&info); + info.play.buffer_size = buffer_size; info.record.buffer_size = buffer_size; if (ioctl(fd, AUDIO_SETINFO, &info) < 0) { @@ -503,7 +557,7 @@ static int pa_solaris_set_buffer(int fd, int buffer_size) { return 0; } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module *m) { struct userdata *u = NULL; const char *p; int fd = -1; @@ -513,9 +567,10 @@ int pa__init(pa_core *c, pa_module*m) { pa_sample_spec ss; pa_channel_map map; pa_modargs *ma = NULL; - struct timeval tv; char *t; - assert(c && m); + struct pollfd *pollfd; + + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("failed to parse module arguments."); @@ -540,7 +595,7 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - ss = c->default_sample_spec; + ss = m->core->default_sample_spec; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) { pa_log("failed to parse sample specification"); goto fail; @@ -554,52 +609,15 @@ int pa__init(pa_core *c, pa_module*m) { if (pa_solaris_auto_format(fd, mode, &ss) < 0) goto fail; - if ((mode != O_WRONLY) && (buffer_size >= 1)) - if (pa_solaris_set_buffer(fd, buffer_size) < 0) - goto fail; + if (pa_solaris_set_buffer(fd, buffer_size) < 0) + goto fail; u = pa_xmalloc(sizeof(struct userdata)); - u->core = c; + u->core = m->core; - if (mode != O_WRONLY) { - u->source = pa_source_new(c, __FILE__, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME), 0, &ss, &map); - assert(u->source); - u->source->userdata = u; - u->source->get_latency = source_get_latency_cb; - u->source->get_hw_volume = source_get_hw_volume_cb; - u->source->set_hw_volume = source_set_hw_volume_cb; - pa_source_set_owner(u->source, m); - pa_source_set_description(u->source, t = pa_sprintf_malloc("Solaris PCM on '%s'", p)); - pa_xfree(t); - u->source->is_hardware = 1; - } else - u->source = NULL; - - if (mode != O_RDONLY) { - u->sink = pa_sink_new(c, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map); - assert(u->sink); - u->sink->get_latency = sink_get_latency_cb; - u->sink->get_hw_volume = sink_get_hw_volume_cb; - u->sink->set_hw_volume = sink_set_hw_volume_cb; - u->sink->get_hw_mute = sink_get_hw_mute_cb; - u->sink->set_hw_mute = sink_set_hw_mute_cb; - u->sink->userdata = u; - pa_sink_set_owner(u->sink, m); - pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Solaris PCM on '%s'", p)); - pa_xfree(t); - u->sink->is_hardware = 1; - } else - u->sink = NULL; - - assert(u->source || u->sink); - - u->io = pa_iochannel_new(c->mainloop, u->source ? fd : -1, u->sink ? fd : 0); - assert(u->io); - pa_iochannel_set_callback(u->io, io_callback, u); u->fd = fd; - u->memchunk.memblock = NULL; - u->memchunk.length = 0; + pa_memchunk_reset(&u->memchunk); /* We use this to get a reasonable chunk size */ u->page_size = PA_PAGE_SIZE; @@ -610,37 +628,91 @@ int pa__init(pa_core *c, pa_module*m) { u->written_bytes = 0; u->read_bytes = 0; - u->sink_underflow = 1; - u->module = m; m->userdata = u; - u->poll_timeout = pa_bytes_to_usec(u->buffer_size / 10, &ss); + pa_thread_mq_init(&u->thread_mq, m->core->mainloop); + + u->rtpoll = pa_rtpoll_new(); + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); + + pa_rtpoll_set_timer_periodic(u->rtpoll, pa_bytes_to_usec(u->buffer_size / 10, &ss)); - pa_gettimeofday(&tv); - pa_timeval_add(&tv, u->poll_timeout); + u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1); + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + pollfd->fd = fd; + pollfd->events = 0; + pollfd->revents = 0; - u->timer = c->mainloop->time_new(c->mainloop, &tv, timer_cb, u); - assert(u->timer); + if (mode != O_WRONLY) { + u->source = pa_source_new(m->core, __FILE__, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME), 0, &ss, &map); + pa_assert(u->source); + + u->source->userdata = u; + u->source->parent.process_msg = source_process_msg; + + pa_source_set_module(u->source, m); + pa_source_set_description(u->source, t = pa_sprintf_malloc("Solaris PCM on '%s'", p)); + pa_xfree(t); + pa_source_set_asyncmsgq(u->source, u->thread_mq.inq); + pa_source_set_rtpoll(u->source, u->rtpoll); + + u->source->flags = PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY|PA_SOURCE_HW_VOLUME_CTRL; + u->source->refresh_volume = 1; + } else + u->source = NULL; + + if (mode != O_RDONLY) { + u->sink = pa_sink_new(m->core, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map); + pa_assert(u->sink); + + u->sink->userdata = u; + u->sink->parent.process_msg = sink_process_msg; + + pa_sink_set_module(u->sink, m); + pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Solaris PCM on '%s'", p)); + pa_xfree(t); + pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); + pa_sink_set_rtpoll(u->sink, u->rtpoll); + + u->sink->flags = PA_SINK_HARDWARE|PA_SINK_LATENCY|PA_SINK_HW_VOLUME_CTRL; + u->sink->refresh_volume = 1; + u->sink->refresh_mute = 1; + } else + u->sink = NULL; + + pa_assert(u->source || u->sink); u->sig = pa_signal_new(SIGPOLL, sig_callback, u); - assert(u->sig); + pa_assert(u->sig); ioctl(u->fd, I_SETSIG, S_MSG); - pa_modargs_free(ma); + if (!(u->thread = pa_thread_new(thread_func, u))) { + pa_log("Failed to create thread."); + goto fail; + } /* Read mixer settings */ if (u->source) - source_get_hw_volume_cb(u->source); + pa_asyncmsgq_send(u->thread_mq.inq, PA_MSGOBJECT(u->source), PA_SOURCE_MESSAGE_GET_VOLUME, &u->source->volume, 0, NULL); if (u->sink) { - sink_get_hw_volume_cb(u->sink); - sink_get_hw_mute_cb(u->sink); + pa_asyncmsgq_send(u->thread_mq.inq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_GET_VOLUME, &u->sink->volume, 0, NULL); + pa_asyncmsgq_send(u->thread_mq.inq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_GET_MUTE, &u->sink->muted, 0, NULL); } + if (u->sink) + pa_sink_put(u->sink); + if (u->source) + pa_source_put(u->source); + + pa_modargs_free(ma); + return 0; fail: - if (fd >= 0) + if (u) + pa__done(m); + else if (fd >= 0) close(fd); if (ma) @@ -649,31 +721,47 @@ fail: return -1; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module *m) { struct userdata *u; - assert(c && m); + + pa_assert(m); if (!(u = m->userdata)) return; - if (u->timer) - c->mainloop->time_free(u->timer); ioctl(u->fd, I_SETSIG, 0); pa_signal_free(u->sig); - if (u->memchunk.memblock) - pa_memblock_unref(u->memchunk.memblock); + if (u->sink) + pa_sink_unlink(u->sink); - if (u->sink) { - pa_sink_disconnect(u->sink); - pa_sink_unref(u->sink); + if (u->source) + pa_source_unlink(u->source); + + if (u->thread) { + pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); + pa_thread_free(u->thread); } - if (u->source) { - pa_source_disconnect(u->source); + pa_thread_mq_done(&u->thread_mq); + + if (u->sink) + pa_sink_unref(u->sink); + + if (u->source) pa_source_unref(u->source); - } - pa_iochannel_free(u->io); + if (u->memchunk.memblock) + pa_memblock_unref(u->memchunk.memblock); + + if (u->rtpoll_item) + pa_rtpoll_item_free(u->rtpoll_item); + + if (u->rtpoll) + pa_rtpoll_free(u->rtpoll); + + if (u->fd >= 0) + close(u->fd); + pa_xfree(u); } -- cgit From dbcd086332a654db9913638719073a899b07db81 Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Sun, 30 Sep 2007 13:19:26 +0000 Subject: Fixed PA_GCC_CONST definition. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1919 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/gccmacro.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/gccmacro.h b/src/pulsecore/gccmacro.h index d211c2e7..e9f0d093 100644 --- a/src/pulsecore/gccmacro.h +++ b/src/pulsecore/gccmacro.h @@ -70,9 +70,9 @@ #ifndef PA_GCC_CONST #ifdef __GNUCC__ -#define PA_GCC_CONST __attribute__ ((pure)) +#define PA_GCC_CONST __attribute__ ((const)) #else -/** This function's return value depends only the arguments list (stricter version of PA_GCC_CONST) **/ +/** This function's return value depends only the arguments list (stricter version of PA_GCC_PURE) **/ #define PA_GCC_CONST #endif #endif -- cgit From abd692e1ba07df525e9ef23ea1aff3ccff404ca3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 1 Oct 2007 00:16:24 +0000 Subject: fix silence initializer for alaw and ulaw git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1920 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sample-util.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c index bc83ac6f..fee22c77 100644 --- a/src/pulsecore/sample-util.c +++ b/src/pulsecore/sample-util.c @@ -104,9 +104,11 @@ void pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) { c = 0; break; case PA_SAMPLE_ALAW: - case PA_SAMPLE_ULAW: - c = 80; + c = 0xd5; break; + case PA_SAMPLE_ULAW: + c = 0xff; + breaK; default: pa_assert_not_reached(); } -- cgit From 9d34a1e18b33330717caca6c25345ccb061cd7ea Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 1 Oct 2007 00:44:29 +0000 Subject: fix trivial typo git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1921 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sample-util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c index fee22c77..56d89c8c 100644 --- a/src/pulsecore/sample-util.c +++ b/src/pulsecore/sample-util.c @@ -108,7 +108,7 @@ void pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) { break; case PA_SAMPLE_ULAW: c = 0xff; - breaK; + break; default: pa_assert_not_reached(); } -- cgit From d6a22032078bcb260eb2e0dd2ca36235c5251115 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 1 Oct 2007 16:39:04 +0000 Subject: Fix race condition between IO thread creation and pa_sink_put(). Move activation of rtpoll fds when we change the state INIT->IDLE. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1922 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-alsa-sink.c | 8 +- src/modules/module-alsa-source.c | 12 +-- src/modules/module-ladspa-sink.c | 2 +- src/modules/module-oss.c | 176 +++++++++++++++++++++++++-------------- src/modules/module-remap-sink.c | 2 +- src/pulsecore/sink.c | 32 +++---- src/pulsecore/source.c | 28 +++---- 7 files changed, 158 insertions(+), 102 deletions(-) diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 0489fa87..bb78bca2 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -450,6 +450,11 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse case PA_SINK_IDLE: case PA_SINK_RUNNING: + if (u->sink->thread_info.state == PA_SINK_INIT) { + if (build_pollfd(u) < 0) + return -1; + } + if (u->sink->thread_info.state == PA_SINK_SUSPENDED) { if (unsuspend(u) < 0) return -1; @@ -604,9 +609,6 @@ static void thread_func(void *userdata) { pa_thread_mq_install(&u->thread_mq); pa_rtpoll_install(u->rtpoll); - if (build_pollfd(u) < 0) - goto fail; - for (;;) { int ret; diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index de019ffb..0f19a4ae 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -437,6 +437,13 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off case PA_SOURCE_IDLE: case PA_SOURCE_RUNNING: + if (u->source->thread_info.state == PA_SOURCE_INIT) { + if (build_pollfd(u) < 0) + return -1; + + snd_pcm_start(u->pcm_handle); + } + if (u->source->thread_info.state == PA_SOURCE_SUSPENDED) { if (unsuspend(u) < 0) return -1; @@ -591,11 +598,6 @@ static void thread_func(void *userdata) { pa_thread_mq_install(&u->thread_mq); pa_rtpoll_install(u->rtpoll); - if (build_pollfd(u) < 0) - goto fail; - - snd_pcm_start(u->pcm_handle); - for (;;) { int ret; diff --git a/src/modules/module-ladspa-sink.c b/src/modules/module-ladspa-sink.c index 9f771c6b..29ca89f0 100644 --- a/src/modules/module-ladspa-sink.c +++ b/src/modules/module-ladspa-sink.c @@ -114,7 +114,7 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state) { pa_sink_assert_ref(s); pa_assert_se(u = s->userdata); - if (PA_SINK_LINKED(state) && u->sink_input) + if (PA_SINK_LINKED(state) && u->sink_input && PA_SINK_INPUT_LINKED(pa_sink_input_get_state(u->sink_input))) pa_sink_input_cork(u->sink_input, state == PA_SINK_SUSPENDED); return 0; diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 82b5b6ce..cb975fd7 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -110,10 +110,10 @@ struct userdata { size_t frame_size; uint32_t in_fragment_size, out_fragment_size, in_nfrags, out_nfrags, in_hwbuf_size, out_hwbuf_size; - int use_getospace, use_getispace; - int use_getodelay; + pa_bool_t use_getospace, use_getispace; + pa_bool_t use_getodelay; - int sink_suspended, source_suspended; + pa_bool_t sink_suspended, source_suspended; int fd; int mode; @@ -123,7 +123,7 @@ struct userdata { int nfrags, frag_size; - int use_mmap; + pa_bool_t use_mmap; unsigned out_mmap_current, in_mmap_current; void *in_mmap, *out_mmap; pa_memblock **in_mmap_memblocks, **out_mmap_memblocks; @@ -149,7 +149,7 @@ static const char* const valid_modargs[] = { NULL }; -static void trigger(struct userdata *u, int quick) { +static void trigger(struct userdata *u, pa_bool_t quick) { int enable_bits = 0, zero = 0; pa_assert(u); @@ -157,7 +157,7 @@ static void trigger(struct userdata *u, int quick) { if (u->fd < 0) return; -/* pa_log_debug("trigger"); */ + pa_log_debug("trigger"); if (u->source && PA_SOURCE_OPENED(u->source->thread_info.state)) enable_bits |= PCM_ENABLE_INPUT; @@ -165,6 +165,9 @@ static void trigger(struct userdata *u, int quick) { if (u->sink && PA_SINK_OPENED(u->sink->thread_info.state)) enable_bits |= PCM_ENABLE_OUTPUT; + pa_log_debug("trigger: %i", enable_bits); + + if (u->use_mmap) { if (!quick) @@ -327,6 +330,8 @@ static int mmap_read(struct userdata *u) { return -1; } +/* pa_log("... %i", info.blocks); */ + info.blocks += u->in_mmap_saved_nfrags; u->in_mmap_saved_nfrags = 0; @@ -438,6 +443,22 @@ static pa_usec_t io_source_get_latency(struct userdata *u) { return r; } +static void build_pollfd(struct userdata *u) { + struct pollfd *pollfd; + + pa_assert(u); + pa_assert(u->fd >= 0); + + if (u->rtpoll_item) + pa_rtpoll_item_free(u->rtpoll_item); + + u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1); + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + pollfd->fd = u->fd; + pollfd->events = 0; + pollfd->revents = 0; +} + static int suspend(struct userdata *u) { pa_assert(u); pa_assert(u->fd >= 0); @@ -493,7 +514,6 @@ static int unsuspend(struct userdata *u) { int frag_size, in_frag_size, out_frag_size; int in_nfrags, out_nfrags; struct audio_buf_info info; - struct pollfd *pollfd; pa_assert(u); pa_assert(u->fd < 0); @@ -575,11 +595,7 @@ static int unsuspend(struct userdata *u) { pa_assert(!u->rtpoll_item); - u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1); - pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); - pollfd->fd = u->fd; - pollfd->events = 0; - pollfd->revents = 0; + build_pollfd(u); if (u->sink) pa_sink_get_volume(u->sink); @@ -598,7 +614,8 @@ fail: static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { struct userdata *u = PA_SINK(o)->userdata; - int do_trigger = 0, ret, quick = 1; + int ret; + pa_bool_t do_trigger = FALSE, quick = TRUE; switch (code) { @@ -629,28 +646,33 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse return -1; } - do_trigger = 1; + do_trigger = TRUE; - u->sink_suspended = 1; + u->sink_suspended = TRUE; break; case PA_SINK_IDLE: case PA_SINK_RUNNING: + if (u->sink->thread_info.state == PA_SINK_INIT) { + do_trigger = TRUE; + quick = u->source && PA_SOURCE_OPENED(u->source->thread_info.state); + } + if (u->sink->thread_info.state == PA_SINK_SUSPENDED) { if (!u->source || u->source_suspended) { if (unsuspend(u) < 0) return -1; - quick = 0; + quick = FALSE; } - do_trigger = 1; + do_trigger = TRUE; u->out_mmap_current = 0; u->out_mmap_saved_nfrags = 0; - u->sink_suspended = 0; + u->sink_suspended = FALSE; } break; @@ -674,7 +696,8 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { struct userdata *u = PA_SOURCE(o)->userdata; - int do_trigger = 0, ret, quick = 1; + int ret; + int do_trigger = FALSE, quick = TRUE; switch (code) { @@ -703,28 +726,33 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off return -1; } - do_trigger = 1; + do_trigger = TRUE; - u->source_suspended = 1; + u->source_suspended = TRUE; break; case PA_SOURCE_IDLE: case PA_SOURCE_RUNNING: + if (u->source->thread_info.state == PA_SOURCE_INIT) { + do_trigger = TRUE; + quick = u->sink && PA_SINK_OPENED(u->sink->thread_info.state); + } + if (u->source->thread_info.state == PA_SOURCE_SUSPENDED) { if (!u->sink || u->sink_suspended) { if (unsuspend(u) < 0) return -1; - quick = 0; + quick = FALSE; } - do_trigger = 1; + do_trigger = TRUE; u->in_mmap_current = 0; u->in_mmap_saved_nfrags = 0; - u->source_suspended = 0; + u->source_suspended = FALSE; } break; @@ -840,8 +868,6 @@ static void thread_func(void *userdata) { pa_thread_mq_install(&u->thread_mq); pa_rtpoll_install(u->rtpoll); - trigger(u, 0); - for (;;) { int ret; @@ -849,7 +875,7 @@ static void thread_func(void *userdata) { /* Render some data and write it to the dsp */ - if (u->sink && PA_SINK_OPENED(u->sink->thread_info.state) && (revents & POLLOUT)) { + if (u->sink && PA_SINK_OPENED(u->sink->thread_info.state) && ((revents & POLLOUT) || u->use_mmap || u->use_getospace)) { if (u->use_mmap) { @@ -863,7 +889,7 @@ static void thread_func(void *userdata) { } else { ssize_t l; - int loop = 0; + pa_bool_t loop = FALSE, work_done = FALSE; l = u->out_fragment_size; @@ -872,21 +898,35 @@ static void thread_func(void *userdata) { if (ioctl(u->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) { pa_log_info("Device doesn't support SNDCTL_DSP_GETOSPACE: %s", pa_cstrerror(errno)); - u->use_getospace = 0; + u->use_getospace = FALSE; } else { - if (info.bytes >= l) { - l = (info.bytes/l)*l; - loop = 1; - } + l = info.bytes; + + /* We loop only if GETOSPACE worked and we + * actually *know* that we can write more than + * one fragment at a time */ + loop = TRUE; } } - do { + /* Round down to multiples of the fragment size, + * because OSS needs that (at least some versions + * do) */ + l = (l/u->out_fragment_size) * u->out_fragment_size; + + /* Hmm, so poll() signalled us that we can read + * something, but GETOSPACE told us there was nothing? + * Hmm, make the best of it, try to read some data, to + * avoid spinning forever. */ + if (l <= 0 && (revents & POLLOUT)) { + l = u->out_fragment_size; + loop = FALSE; + } + + while (l > 0) { void *p; ssize_t t; - pa_assert(l > 0); - if (u->memchunk.length <= 0) pa_sink_render(u->sink, l, &u->memchunk); @@ -929,17 +969,21 @@ static void thread_func(void *userdata) { l -= t; revents &= ~POLLOUT; + work_done = TRUE; } - } while (loop && l > 0); + if (!loop) + break; + } - continue; + if (work_done) + continue; } } - /* Try to read some data and pass it on to the source driver */ + /* Try to read some data and pass it on to the source driver. */ - if (u->source && PA_SOURCE_OPENED(u->source->thread_info.state) && ((revents & POLLIN))) { + if (u->source && PA_SOURCE_OPENED(u->source->thread_info.state) && ((revents & POLLIN) || u->use_mmap || u->use_getispace)) { if (u->use_mmap) { @@ -956,7 +1000,7 @@ static void thread_func(void *userdata) { void *p; ssize_t l; pa_memchunk memchunk; - int loop = 0; + pa_bool_t loop = FALSE, work_done = FALSE; l = u->in_fragment_size; @@ -965,16 +1009,21 @@ static void thread_func(void *userdata) { if (ioctl(u->fd, SNDCTL_DSP_GETISPACE, &info) < 0) { pa_log_info("Device doesn't support SNDCTL_DSP_GETISPACE: %s", pa_cstrerror(errno)); - u->use_getispace = 0; + u->use_getispace = FALSE; } else { - if (info.bytes >= l) { - l = (info.bytes/l)*l; - loop = 1; - } + l = info.bytes; + loop = TRUE; } } - do { + l = (l/u->in_fragment_size) * u->in_fragment_size; + + if (l <= 0 && (revents & POLLIN)) { + l = u->in_fragment_size; + loop = FALSE; + } + + while (l > 0) { ssize_t t, k; pa_assert(l > 0); @@ -1023,18 +1072,25 @@ static void thread_func(void *userdata) { l -= t; revents &= ~POLLIN; + work_done = TRUE; } - } while (loop && l > 0); - continue; + if (!loop) + break; + } + + if (work_done) + continue; } } -/* pa_log("loop2"); */ +/* pa_log("loop2 revents=%i", revents); */ - if (u->fd >= 0) { + if (u->rtpoll_item) { struct pollfd *pollfd; + pa_assert(u->fd >= 0); + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); pollfd->events = ((u->source && PA_SOURCE_OPENED(u->source->thread_info.state)) ? POLLIN : 0) | @@ -1042,13 +1098,13 @@ static void thread_func(void *userdata) { } /* Hmm, nothing to do. Let's sleep */ - if ((ret = pa_rtpoll_run(u->rtpoll, 1)) < 0) + if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0) goto fail; if (ret == 0) goto finish; - if (u->fd >= 0) { + if (u->rtpoll_item) { struct pollfd *pollfd; pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); @@ -1088,7 +1144,6 @@ int pa__init(pa_module*m) { char hwdesc[64], *t; const char *name; int namereg_fail; - struct pollfd *pollfd; pa_assert(m); @@ -1180,11 +1235,8 @@ int pa__init(pa_module*m) { pa_thread_mq_init(&u->thread_mq, m->core->mainloop); u->rtpoll = pa_rtpoll_new(); pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); - u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1); - pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); - pollfd->fd = fd; - pollfd->events = 0; - pollfd->revents = 0; + u->rtpoll_item = NULL; + build_pollfd(u); if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) >= 0) { pa_log_info("Input -- %u fragments of size %u.", info.fragstotal, info.fragsize); @@ -1244,7 +1296,7 @@ int pa__init(pa_module*m) { use_mmap ? " via DMA" : "")); pa_xfree(t); u->source->flags = PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY; - u->source->refresh_volume = 1; + u->source->refresh_volume = TRUE; if (use_mmap) u->in_mmap_memblocks = pa_xnew0(pa_memblock*, u->in_nfrags); @@ -1261,7 +1313,7 @@ int pa__init(pa_module*m) { goto go_on; } else { pa_log_warn("mmap(PROT_WRITE) failed, reverting to non-mmap mode: %s", pa_cstrerror(errno)); - u->use_mmap = use_mmap = 0; + u->use_mmap = (use_mmap = FALSE); u->out_mmap = NULL; } } else { @@ -1299,7 +1351,7 @@ int pa__init(pa_module*m) { use_mmap ? " via DMA" : "")); pa_xfree(t); u->sink->flags = PA_SINK_HARDWARE|PA_SINK_LATENCY; - u->sink->refresh_volume = 1; + u->sink->refresh_volume = TRUE; if (use_mmap) u->out_mmap_memblocks = pa_xnew0(pa_memblock*, u->out_nfrags); diff --git a/src/modules/module-remap-sink.c b/src/modules/module-remap-sink.c index d712a045..e863c0c3 100644 --- a/src/modules/module-remap-sink.c +++ b/src/modules/module-remap-sink.c @@ -100,7 +100,7 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state) { pa_sink_assert_ref(s); pa_assert_se(u = s->userdata); - if (PA_SINK_LINKED(state) && u->sink_input) + if (PA_SINK_LINKED(state) && u->sink_input && PA_SINK_INPUT_LINKED(pa_sink_input_get_state(u->sink_input))) pa_sink_input_cork(u->sink_input, state == PA_SINK_SUSPENDED); return 0; diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 38e7d632..dccb34cc 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -147,21 +147,6 @@ pa_sink* pa_sink_new( return s; } -void pa_sink_put(pa_sink* s) { - pa_sink_assert_ref(s); - - pa_assert(s->state == PA_SINK_INIT); - pa_assert(s->asyncmsgq); - pa_assert(s->rtpoll); - - s->thread_info.state = s->state = PA_SINK_IDLE; - - pa_source_put(s->monitor_source); - - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index); - pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_NEW_POST], s); -} - static int sink_set_state(pa_sink *s, pa_sink_state_t state) { int ret; @@ -196,6 +181,21 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state) { return 0; } +void pa_sink_put(pa_sink* s) { + pa_sink_assert_ref(s); + + pa_assert(s->state == PA_SINK_INIT); + pa_assert(s->asyncmsgq); + pa_assert(s->rtpoll); + + pa_assert_se(sink_set_state(s, PA_SINK_IDLE) == 0); + + pa_source_put(s->monitor_source); + + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_NEW_POST], s); +} + void pa_sink_unlink(pa_sink* s) { pa_bool_t linked; pa_sink_input *i, *j = NULL; @@ -806,7 +806,7 @@ unsigned pa_sink_used_by(pa_sink *s) { int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) { pa_sink *s = PA_SINK(o); pa_sink_assert_ref(s); - pa_assert(PA_SINK_LINKED(s->thread_info.state)); + pa_assert(s->thread_info.state != PA_SINK_UNLINKED); switch ((pa_sink_message_t) code) { diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c index 2106edc3..9a6902ae 100644 --- a/src/pulsecore/source.c +++ b/src/pulsecore/source.c @@ -124,19 +124,6 @@ pa_source* pa_source_new( return s; } -void pa_source_put(pa_source *s) { - pa_source_assert_ref(s); - - pa_assert(s->state == PA_SINK_INIT); - pa_assert(s->rtpoll); - pa_assert(s->asyncmsgq); - - s->thread_info.state = s->state = PA_SOURCE_IDLE; - - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index); - pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_NEW_POST], s); -} - static int source_set_state(pa_source *s, pa_source_state_t state) { int ret; @@ -171,6 +158,19 @@ static int source_set_state(pa_source *s, pa_source_state_t state) { return 0; } +void pa_source_put(pa_source *s) { + pa_source_assert_ref(s); + + pa_assert(s->state == PA_SINK_INIT); + pa_assert(s->rtpoll); + pa_assert(s->asyncmsgq); + + pa_assert_se(source_set_state(s, PA_SOURCE_IDLE) == 0); + + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_NEW_POST], s); +} + void pa_source_unlink(pa_source *s) { pa_bool_t linked; pa_source_output *o, *j = NULL; @@ -460,7 +460,7 @@ unsigned pa_source_used_by(pa_source *s) { int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_t offset, pa_memchunk *chunk) { pa_source *s = PA_SOURCE(object); pa_source_assert_ref(s); - pa_assert(PA_SOURCE_LINKED(s->thread_info.state)); + pa_assert(s->thread_info.state != PA_SOURCE_UNLINKED); switch ((pa_source_message_t) code) { case PA_SOURCE_MESSAGE_ADD_OUTPUT: { -- cgit From 2e780e88c219fdd63f8b0f4c835c7d0500b88910 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 1 Oct 2007 16:41:50 +0000 Subject: Move request size handling into pa_memblockq, function pa_memblockq_pop_missing() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1923 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/memblockq.c | 135 +++++++++++++++++++++++++++++++++++----------- src/pulsecore/memblockq.h | 4 ++ 2 files changed, 108 insertions(+), 31 deletions(-) diff --git a/src/pulsecore/memblockq.c b/src/pulsecore/memblockq.c index ecdf45b6..a46155a9 100644 --- a/src/pulsecore/memblockq.c +++ b/src/pulsecore/memblockq.c @@ -47,15 +47,17 @@ struct list_item { }; PA_STATIC_FLIST_DECLARE(list_items, 0, pa_xfree); - + struct pa_memblockq { struct list_item *blocks, *blocks_tail; unsigned n_blocks; size_t maxlength, tlength, base, prebuf, minreq; int64_t read_index, write_index; - int in_prebuf; + pa_bool_t in_prebuf; pa_memblock *silence; pa_mcalign *mcalign; + int64_t missing; + size_t requested; }; pa_memblockq* pa_memblockq_new( @@ -109,6 +111,9 @@ pa_memblockq* pa_memblockq_new( bq->silence = silence ? pa_memblock_ref(silence) : NULL; bq->mcalign = NULL; + bq->missing = bq->tlength; + bq->requested = 0; + return bq; } @@ -116,7 +121,7 @@ void pa_memblockq_free(pa_memblockq* bq) { pa_assert(bq); pa_memblockq_flush(bq); - + if (bq->silence) pa_memblock_unref(bq->silence); @@ -150,7 +155,7 @@ static void drop_block(pa_memblockq *bq, struct list_item *q) { bq->n_blocks--; } -static int can_push(pa_memblockq *bq, size_t l) { +static pa_bool_t can_push(pa_memblockq *bq, size_t l) { int64_t end; pa_assert(bq); @@ -161,7 +166,7 @@ static int can_push(pa_memblockq *bq, size_t l) { if (l > d) l -= d; else - return 1; + return TRUE; } end = bq->blocks_tail ? bq->blocks_tail->index + bq->blocks_tail->chunk.length : 0; @@ -169,15 +174,15 @@ static int can_push(pa_memblockq *bq, size_t l) { /* Make sure that the list doesn't get too long */ if (bq->write_index + (int64_t)l > end) if (bq->write_index + l - bq->read_index > bq->maxlength) - return 0; + return FALSE; - return 1; + return TRUE; } int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { - struct list_item *q, *n; pa_memchunk chunk; + int64_t old, delta; pa_assert(bq); pa_assert(uchunk); @@ -191,6 +196,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { if (!can_push(bq, uchunk->length)) return -1; + old = bq->write_index; chunk = *uchunk; if (bq->read_index > bq->write_index) { @@ -207,7 +213,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { } else { /* We drop the incoming data completely */ bq->write_index += chunk.length; - return 0; + goto finish; } } @@ -245,7 +251,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { /* Create a new list entry for the end of thie memchunk */ if (!(p = pa_flist_pop(PA_STATIC_FLIST_GET(list_items)))) p = pa_xnew(struct list_item, 1); - + p->chunk = q->chunk; pa_memblock_ref(p->chunk.memblock); @@ -308,15 +314,14 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { q->chunk.length += chunk.length; bq->write_index += chunk.length; - return 0; + goto finish; } } else pa_assert(!bq->blocks || (bq->write_index + (int64_t)chunk.length <= bq->blocks->index)); - if (!(n = pa_flist_pop(PA_STATIC_FLIST_GET(list_items)))) n = pa_xnew(struct list_item, 1); - + n->chunk = chunk; pa_memblock_ref(n->chunk.memblock); n->index = bq->write_index; @@ -336,27 +341,42 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { bq->blocks = n; bq->n_blocks++; + +finish: + + delta = bq->write_index - old; + + if (delta >= bq->requested) { + delta -= bq->requested; + bq->requested = 0; + } else { + bq->requested -= delta; + delta = 0; + } + + bq->missing -= delta; + return 0; } -static int memblockq_check_prebuf(pa_memblockq *bq) { +static pa_bool_t memblockq_check_prebuf(pa_memblockq *bq) { pa_assert(bq); - + if (bq->in_prebuf) { - + if (pa_memblockq_get_length(bq) < bq->prebuf) - return 1; + return TRUE; - bq->in_prebuf = 0; - return 0; + bq->in_prebuf = FALSE; + return FALSE; } else { if (bq->prebuf > 0 && bq->read_index >= bq->write_index) { - bq->in_prebuf = 1; - return 1; + bq->in_prebuf = TRUE; + return TRUE; } - return 0; + return FALSE; } } @@ -409,15 +429,18 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) { } void pa_memblockq_drop(pa_memblockq *bq, size_t length) { + int64_t old, delta; pa_assert(bq); pa_assert(length % bq->base == 0); - + + old = bq->read_index; + while (length > 0) { /* Do not drop any data when we are in prebuffering mode */ if (memblockq_check_prebuf(bq)) break; - + if (bq->blocks) { size_t d; @@ -462,6 +485,9 @@ void pa_memblockq_drop(pa_memblockq *bq, size_t length) { break; } } + + delta = bq->read_index - old; + bq->missing += delta; } int pa_memblockq_is_readable(pa_memblockq *bq) { @@ -493,6 +519,7 @@ size_t pa_memblockq_missing(pa_memblockq *bq) { return 0; l = bq->tlength - l; + return l >= bq->minreq ? l : 0; } @@ -503,27 +530,43 @@ size_t pa_memblockq_get_minreq(pa_memblockq *bq) { } void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek) { + int64_t old, delta; pa_assert(bq); + old = bq->write_index; + switch (seek) { case PA_SEEK_RELATIVE: bq->write_index += offset; - return; + break; case PA_SEEK_ABSOLUTE: bq->write_index = offset; - return; + break; case PA_SEEK_RELATIVE_ON_READ: bq->write_index = bq->read_index + offset; - return; + break; case PA_SEEK_RELATIVE_END: bq->write_index = (bq->blocks_tail ? bq->blocks_tail->index + (int64_t) bq->blocks_tail->chunk.length : bq->read_index) + offset; - return; + break; + default: + pa_assert_not_reached(); } - pa_assert_not_reached(); + delta = bq->write_index - old; + + if (delta >= bq->requested) { + delta -= bq->requested; + bq->requested = 0; + } else if (delta >= 0) { + bq->requested -= delta; + delta = 0; + } + + bq->missing -= delta; } void pa_memblockq_flush(pa_memblockq *bq) { + int64_t old, delta; pa_assert(bq); while (bq->blocks) @@ -531,9 +574,22 @@ void pa_memblockq_flush(pa_memblockq *bq) { pa_assert(bq->n_blocks == 0); + old = bq->write_index; bq->write_index = bq->read_index; pa_memblockq_prebuf_force(bq); + + delta = bq->write_index - old; + + if (delta > bq->requested) { + delta -= bq->requested; + bq->requested = 0; + } else if (delta >= 0) { + bq->requested -= delta; + delta = 0; + } + + bq->missing -= delta; } size_t pa_memblockq_get_tlength(pa_memblockq *bq) { @@ -594,14 +650,14 @@ void pa_memblockq_shorten(pa_memblockq *bq, size_t length) { void pa_memblockq_prebuf_disable(pa_memblockq *bq) { pa_assert(bq); - bq->in_prebuf = 0; + bq->in_prebuf = FALSE; } void pa_memblockq_prebuf_force(pa_memblockq *bq) { pa_assert(bq); if (!bq->in_prebuf && bq->prebuf > 0) - bq->in_prebuf = 1; + bq->in_prebuf = TRUE; } size_t pa_memblockq_get_maxlength(pa_memblockq *bq) { @@ -615,3 +671,20 @@ size_t pa_memblockq_get_prebuf(pa_memblockq *bq) { return bq->prebuf; } + +size_t pa_memblockq_pop_missing(pa_memblockq *bq) { + size_t l; + + pa_assert(bq); + +/* pa_log("pop: %lli", bq->missing); */ + + if (bq->missing <= 0) + return 0; + + l = (size_t) bq->missing; + bq->missing = 0; + bq->requested += l; + + return l; +} diff --git a/src/pulsecore/memblockq.h b/src/pulsecore/memblockq.h index 5eb23aac..8c3e70fc 100644 --- a/src/pulsecore/memblockq.h +++ b/src/pulsecore/memblockq.h @@ -103,6 +103,10 @@ size_t pa_memblockq_get_length(pa_memblockq *bq); /* Return how many bytes are missing in queue to the specified fill amount */ size_t pa_memblockq_missing(pa_memblockq *bq); +/* Return the number of bytes that are missing since the last call to + * this function, reset the internal counter to 0. */ +size_t pa_memblockq_pop_missing(pa_memblockq *bq); + /* Returns the minimal request value */ size_t pa_memblockq_get_minreq(pa_memblockq *bq); -- cgit From 7c1768d4d1a61b998811c5044e16525b05cd88b0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 1 Oct 2007 16:42:59 +0000 Subject: update native protocol to make use of pa_memblockq_pop_missing git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1924 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-native.c | 177 ++++++++++++++++++++-------------------- 1 file changed, 89 insertions(+), 88 deletions(-) diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index c282c177..9ae0f083 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -80,7 +80,7 @@ typedef struct record_stream { connection *connection; uint32_t index; - + pa_source_output *source_output; pa_memblockq *memblockq; size_t fragment_size; @@ -92,10 +92,10 @@ typedef struct output_stream { typedef struct playback_stream { output_stream parent; - + connection *connection; uint32_t index; - + pa_sink_input *sink_input; pa_memblockq *memblockq; int drain_request; @@ -104,7 +104,7 @@ typedef struct playback_stream { int underrun; pa_atomic_t missing; - size_t last_missing; + size_t minreq; /* Only updated after SINK_INPUT_MESSAGE_UPDATE_LATENCY */ int64_t read_index, write_index; @@ -113,10 +113,10 @@ typedef struct playback_stream { typedef struct upload_stream { output_stream parent; - + connection *connection; uint32_t index; - + pa_memchunk memchunk; size_t length; char *name; @@ -126,7 +126,7 @@ typedef struct upload_stream { struct connection { pa_msgobject parent; - + int authorized; uint32_t version; pa_protocol_native *protocol; @@ -299,7 +299,7 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = { [PA_COMMAND_SUSPEND_SINK] = command_suspend, [PA_COMMAND_SUSPEND_SOURCE] = command_suspend, - + [PA_COMMAND_CORK_PLAYBACK_STREAM] = command_cork_playback_stream, [PA_COMMAND_FLUSH_PLAYBACK_STREAM] = command_trigger_or_flush_or_prebuf_playback_stream, [PA_COMMAND_TRIGGER_PLAYBACK_STREAM] = command_trigger_or_flush_or_prebuf_playback_stream, @@ -360,7 +360,7 @@ static upload_stream* upload_stream_new( const char *name, size_t length) { upload_stream *s; - + pa_assert(c); pa_assert(ss); pa_assert(name); @@ -376,7 +376,7 @@ static upload_stream* upload_stream_new( s->length = length; pa_idxset_put(c->output_streams, s, &s->index); - + return s; } @@ -394,7 +394,7 @@ static void record_stream_unlink(record_stream *s) { pa_assert_se(pa_idxset_remove_by_data(s->connection->record_streams, s, NULL) == s); s->connection = NULL; - record_stream_unref(s); + record_stream_unref(s); } static void record_stream_free(pa_object *o) { @@ -402,7 +402,7 @@ static void record_stream_free(pa_object *o) { pa_assert(s); record_stream_unlink(s); - + pa_memblockq_free(s->memblockq); pa_xfree(s); } @@ -413,11 +413,11 @@ static int record_stream_process_msg(pa_msgobject *o, int code, void*userdata, i if (!s->connection) return -1; - + switch (code) { - + case RECORD_STREAM_MESSAGE_POST_DATA: - + if (pa_memblockq_push_align(s->memblockq, chunk) < 0) { /* pa_log_warn("Failed to push data into output queue."); */ return -1; @@ -512,7 +512,7 @@ static void playback_stream_unlink(playback_stream *s) { pa_assert_se(pa_idxset_remove_by_data(s->connection->output_streams, s, NULL) == s); s->connection = NULL; - playback_stream_unref(s); + playback_stream_unref(s); } static void playback_stream_free(pa_object* o) { @@ -520,7 +520,7 @@ static void playback_stream_free(pa_object* o) { pa_assert(s); playback_stream_unlink(s); - + pa_memblockq_free(s->memblockq); pa_xfree(s); } @@ -535,23 +535,26 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata, switch (code) { case PLAYBACK_STREAM_MESSAGE_REQUEST_DATA: { pa_tagstruct *t; - int32_t l = 0; + uint32_t l = 0; for (;;) { int32_t k; - + if ((k = pa_atomic_load(&s->missing)) <= 0) break; l += k; - + + if (l < s->minreq) + break; + if (pa_atomic_sub(&s->missing, k) <= k) break; } - if (l <= 0) + if (l < s->minreq) break; - + t = pa_tagstruct_new(NULL, 0); pa_tagstruct_putu32(t, PA_COMMAND_REQUEST); pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ @@ -689,16 +692,16 @@ static playback_stream* playback_stream_new( *tlength = (uint32_t) pa_memblockq_get_tlength(s->memblockq); *prebuf = (uint32_t) pa_memblockq_get_prebuf(s->memblockq); *minreq = (uint32_t) pa_memblockq_get_minreq(s->memblockq); - *missing = (uint32_t) pa_memblockq_missing(s->memblockq); - + *missing = (uint32_t) pa_memblockq_pop_missing(s->memblockq); + + s->minreq = pa_memblockq_get_minreq(s->memblockq); pa_atomic_store(&s->missing, 0); - s->last_missing = *missing; s->drain_request = 0; pa_idxset_put(c->output_streams, s, &s->index); pa_sink_input_put(s->sink_input); - + return s; } @@ -708,9 +711,9 @@ static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int6 if (!c->protocol) return -1; - + switch (code) { - + case CONNECTION_MESSAGE_REVOKE: pa_pstream_send_revoke(c->pstream, PA_PTR_TO_UINT(userdata)); break; @@ -751,7 +754,7 @@ static void connection_unlink(connection *c) { c->protocol->core->mainloop->time_free(c->auth_timeout_event); c->auth_timeout_event = NULL; } - + pa_assert_se(pa_idxset_remove_by_data(c->protocol->connections, c, NULL) == c); c->protocol = NULL; connection_unref(c); @@ -759,11 +762,11 @@ static void connection_unlink(connection *c) { static void connection_free(pa_object *o) { connection *c = CONNECTION(o); - + pa_assert(c); connection_unlink(c); - + pa_idxset_free(c->record_streams, NULL, NULL); pa_idxset_free(c->output_streams, NULL, NULL); @@ -776,23 +779,19 @@ static void connection_free(pa_object *o) { /* Called from thread context */ static void request_bytes(playback_stream *s) { - size_t new_missing, delta, previous_missing; - size_t minreq; + size_t m, previous_missing; playback_stream_assert_ref(s); - new_missing = pa_memblockq_missing(s->memblockq); - delta = new_missing > s->last_missing ? new_missing - s->last_missing : 0; - s->last_missing = new_missing; + m = pa_memblockq_pop_missing(s->memblockq); - if (delta <= 0) + if (m <= 0) return; -/* pa_log("request_bytes(%u)", delta); */ - minreq = pa_memblockq_get_minreq(s->memblockq); +/* pa_log("request_bytes(%u)", m); */ - previous_missing = pa_atomic_add(&s->missing, delta); - if (previous_missing < minreq && previous_missing+delta >= minreq) { + previous_missing = pa_atomic_add(&s->missing, m); + if (previous_missing < s->minreq && previous_missing+m >= s->minreq) { pa_assert(pa_thread_mq_get()); pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL); } @@ -821,7 +820,7 @@ static void send_memblock(connection *c) { schunk.length = r->fragment_size; pa_pstream_send_memblock(c->pstream, r->index, 0, PA_SEEK_RELATIVE, &schunk); - + pa_memblockq_drop(r->memblockq, schunk.length); pa_memblock_unref(schunk.memblock); @@ -865,7 +864,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int switch (code) { - case SINK_INPUT_MESSAGE_SEEK: + case SINK_INPUT_MESSAGE_SEEK: pa_memblockq_seek(s->memblockq, offset, PA_PTR_TO_UINT(userdata)); request_bytes(s); return 0; @@ -873,6 +872,8 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int case SINK_INPUT_MESSAGE_POST_DATA: { pa_assert(chunk); +/* pa_log("sink input post: %u", chunk->length); */ + if (pa_memblockq_push_align(s->memblockq, chunk) < 0) { pa_log_warn("Failed to push data into queue"); @@ -904,7 +905,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int case SINK_INPUT_MESSAGE_FLUSH: case SINK_INPUT_MESSAGE_PREBUF_FORCE: case SINK_INPUT_MESSAGE_TRIGGER: { - + pa_sink_input *isync; void (*func)(pa_memblockq *bq); @@ -912,11 +913,11 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int case SINK_INPUT_MESSAGE_FLUSH: func = pa_memblockq_flush; break; - + case SINK_INPUT_MESSAGE_PREBUF_FORCE: func = pa_memblockq_prebuf_force; break; - + case SINK_INPUT_MESSAGE_TRIGGER: func = pa_memblockq_prebuf_disable; break; @@ -924,7 +925,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int default: pa_assert_not_reached(); } - + func(s->memblockq); s->underrun = 0; request_bytes(s); @@ -943,17 +944,17 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int ssync->underrun = 0; request_bytes(ssync); } - + return 0; } - case SINK_INPUT_MESSAGE_UPDATE_LATENCY: + case SINK_INPUT_MESSAGE_UPDATE_LATENCY: s->read_index = pa_memblockq_get_read_index(s->memblockq); s->write_index = pa_memblockq_get_write_index(s->memblockq); s->resampled_chunk_length = s->sink_input->thread_info.resampled_chunk.memblock ? s->sink_input->thread_info.resampled_chunk.length : 0; return 0; - + case PA_SINK_INPUT_MESSAGE_SET_STATE: pa_memblockq_prebuf_force(s->memblockq); @@ -993,7 +994,7 @@ static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chun return -1; } -/* pa_log("peek: %u", chunk->length); */ +/* pa_log("peek: %u", chunk->length); */ request_bytes(s); @@ -1018,7 +1019,7 @@ static void sink_input_drop_cb(pa_sink_input *i, size_t length) { request_bytes(s); -/* pa_log("after_drop: %u %u", pa_memblockq_get_length(s->memblockq), pa_memblockq_is_readable(s->memblockq)); */ +/* pa_log("after_drop: %u %u", pa_memblockq_get_length(s->memblockq), pa_memblockq_is_readable(s->memblockq)); */ } static void sink_input_kill_cb(pa_sink_input *i) { @@ -1103,7 +1104,7 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC pa_sink *sink = NULL; pa_cvolume volume; int corked; - + connection_assert_ref(c); pa_assert(t); @@ -1156,7 +1157,7 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC pa_tagstruct_putu32(reply, missing); /* pa_log("initial request is %u", missing); */ - + if (c->version >= 9) { /* Since 0.9 we support sending the buffer metrics back to the client */ @@ -1185,25 +1186,25 @@ static void command_delete_stream(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t comma CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); switch (command) { - + case PA_COMMAND_DELETE_PLAYBACK_STREAM: { playback_stream *s; if (!(s = pa_idxset_get_by_index(c->output_streams, channel)) || !playback_stream_isinstance(s)) { pa_pstream_send_error(c->pstream, tag, PA_ERR_EXIST); return; } - + playback_stream_unlink(s); break; } - + case PA_COMMAND_DELETE_RECORD_STREAM: { record_stream *s; if (!(s = pa_idxset_get_by_index(c->record_streams, channel))) { pa_pstream_send_error(c->pstream, tag, PA_ERR_EXIST); return; } - + record_stream_unlink(s); break; } @@ -1215,7 +1216,7 @@ static void command_delete_stream(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t comma pa_pstream_send_error(c->pstream, tag, PA_ERR_EXIST); return; } - + upload_stream_unlink(s); break; } @@ -1294,7 +1295,7 @@ static void command_exit(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t connection_assert_ref(c); pa_assert(t); - + if (!pa_tagstruct_eof(t)) { protocol_error(c); return; @@ -1427,7 +1428,7 @@ static void command_lookup(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uin connection *c = CONNECTION(userdata); const char *name; uint32_t idx = PA_IDXSET_INVALID; - + connection_assert_ref(c); pa_assert(t); @@ -1532,12 +1533,12 @@ static void command_get_playback_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); CHECK_VALIDITY(c->pstream, playback_stream_isinstance(s), tag, PA_ERR_NOENTITY); CHECK_VALIDITY(c->pstream, pa_asyncmsgq_send(s->sink_input->sink->asyncmsgq, PA_MSGOBJECT(s->sink_input), SINK_INPUT_MESSAGE_UPDATE_LATENCY, s, 0, NULL) == 0, tag, PA_ERR_NOENTITY) - + reply = reply_new(tag); - + latency = pa_sink_get_latency(s->sink_input->sink); - latency += pa_bytes_to_usec(s->resampled_chunk_length, &s->sink_input->sample_spec); - + latency += pa_bytes_to_usec(s->resampled_chunk_length, &s->sink_input->sample_spec); + pa_tagstruct_put_usec(reply, latency); pa_tagstruct_put_usec(reply, 0); @@ -1792,7 +1793,7 @@ static void sink_input_fill_tagstruct(connection *c, pa_tagstruct *t, pa_sink_in pa_tagstruct_puts(t, pa_resample_method_to_string(pa_sink_input_get_resample_method(s))); pa_tagstruct_puts(t, s->driver); if (c->version >= 11) - pa_tagstruct_put_boolean(t, pa_sink_input_get_mute(s)); + pa_tagstruct_put_boolean(t, pa_sink_input_get_mute(s)); } static void source_output_fill_tagstruct(pa_tagstruct *t, pa_source_output *s) { @@ -1815,7 +1816,7 @@ static void source_output_fill_tagstruct(pa_tagstruct *t, pa_source_output *s) { static void scache_fill_tagstruct(pa_tagstruct *t, pa_scache_entry *e) { pa_assert(t); pa_assert(e); - + pa_tagstruct_putu32(t, e->index); pa_tagstruct_puts(t, e->name); pa_tagstruct_put_cvolume(t, &e->volume); @@ -2073,7 +2074,7 @@ static void command_set_volume( CHECK_VALIDITY(c->pstream, pa_cvolume_valid(&volume), tag, PA_ERR_INVALID); switch (command) { - + case PA_COMMAND_SET_SINK_VOLUME: if (idx != PA_INVALID_INDEX) sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx); @@ -2087,7 +2088,7 @@ static void command_set_volume( else source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1); break; - + case PA_COMMAND_SET_SINK_INPUT_VOLUME: si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx); break; @@ -2139,7 +2140,7 @@ static void command_set_mute( CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID); switch (command) { - + case PA_COMMAND_SET_SINK_MUTE: if (idx != PA_INVALID_INDEX) @@ -2227,7 +2228,7 @@ static void command_trigger_or_flush_or_prebuf_playback_stream(PA_GCC_UNUSED pa_ case PA_COMMAND_FLUSH_PLAYBACK_STREAM: pa_asyncmsgq_send(s->sink_input->sink->asyncmsgq, PA_MSGOBJECT(s->sink_input), SINK_INPUT_MESSAGE_FLUSH, NULL, 0, NULL); break; - + case PA_COMMAND_PREBUF_PLAYBACK_STREAM: pa_asyncmsgq_send(s->sink_input->sink->asyncmsgq, PA_MSGOBJECT(s->sink_input), SINK_INPUT_MESSAGE_PREBUF_FORCE, NULL, 0, NULL); break; @@ -2275,7 +2276,7 @@ static void command_flush_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_U connection_assert_ref(c); pa_assert(t); - + if (pa_tagstruct_getu32(t, &idx) < 0 || !pa_tagstruct_eof(t)) { protocol_error(c); @@ -2405,7 +2406,7 @@ static void command_load_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED ui connection_assert_ref(c); pa_assert(t); - + if (pa_tagstruct_gets(t, &name) < 0 || pa_tagstruct_gets(t, &argument) < 0 || !pa_tagstruct_eof(t)) { @@ -2562,7 +2563,7 @@ static void command_get_autoload_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNU static void command_get_autoload_info_list(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { connection *c = CONNECTION(userdata); pa_tagstruct *reply; - + connection_assert_ref(c); pa_assert(t); @@ -2680,7 +2681,7 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa if (idx != PA_INVALID_INDEX) sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx); - else + else sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK, 1); CHECK_VALIDITY(c->pstream, sink, tag, PA_ERR_NOENTITY); @@ -2693,9 +2694,9 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa } else { pa_assert(command == PA_COMMAND_SUSPEND_SOURCE); - + if (idx == PA_INVALID_INDEX && name && !*name) { - + if (pa_source_suspend_all(c->protocol->core, b) < 0) { pa_pstream_send_error(c->pstream, tag, PA_ERR_INVALID); return; @@ -2708,7 +2709,7 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa source = pa_idxset_get_by_index(c->protocol->core->sources, idx); else source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1); - + CHECK_VALIDITY(c->pstream, source, tag, PA_ERR_NOENTITY); if (pa_source_suspend(source, b) < 0) { @@ -2739,7 +2740,7 @@ static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_c static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata) { connection *c = CONNECTION(userdata); output_stream *stream; - + pa_assert(p); pa_assert(chunk); connection_assert_ref(c); @@ -2752,12 +2753,12 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o if (playback_stream_isinstance(stream)) { playback_stream *ps = PLAYBACK_STREAM(stream); - + if (seek != PA_SEEK_RELATIVE || offset != 0) pa_asyncmsgq_post(ps->sink_input->sink->asyncmsgq, PA_MSGOBJECT(ps->sink_input), SINK_INPUT_MESSAGE_SEEK, PA_UINT_TO_PTR(seek), offset, NULL, NULL); - + pa_asyncmsgq_post(ps->sink_input->sink->asyncmsgq, PA_MSGOBJECT(ps->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, 0, chunk, NULL); - + } else { upload_stream *u = UPLOAD_STREAM(stream); size_t l; @@ -2799,7 +2800,7 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o static void pstream_die_callback(pa_pstream *p, void *userdata) { connection *c = CONNECTION(userdata); - + pa_assert(p); connection_assert_ref(c); @@ -2818,7 +2819,7 @@ static void pstream_drain_callback(pa_pstream *p, void *userdata) { static void pstream_revoke_callback(pa_pstream *p, uint32_t block_id, void *userdata) { pa_thread_mq *q; - + if (!(q = pa_thread_mq_get())) pa_pstream_send_revoke(p, block_id); else @@ -2827,7 +2828,7 @@ static void pstream_revoke_callback(pa_pstream *p, uint32_t block_id, void *user static void pstream_release_callback(pa_pstream *p, uint32_t block_id, void *userdata) { pa_thread_mq *q; - + if (!(q = pa_thread_mq_get())) pa_pstream_send_release(p, block_id); else @@ -2838,7 +2839,7 @@ static void pstream_release_callback(pa_pstream *p, uint32_t block_id, void *use static void client_kill_cb(pa_client *c) { pa_assert(c); - + connection_unlink(CONNECTION(c->userdata)); } @@ -2846,7 +2847,7 @@ static void client_kill_cb(pa_client *c) { static void auth_timeout(pa_mainloop_api*m, pa_time_event *e, const struct timeval *tv, void *userdata) { connection *c = CONNECTION(userdata); - + pa_assert(m); pa_assert(tv); connection_assert_ref(c); @@ -3075,7 +3076,7 @@ pa_protocol_native* pa_protocol_native_new_iochannel( pa_iochannel *io, pa_module *m, pa_modargs *ma) { - + pa_protocol_native *p; if (!(p = protocol_new_internal(core, m, ma))) -- cgit From ef8812e89bb867f127813e1b193589a52f0f2073 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 3 Oct 2007 14:41:21 +0000 Subject: Replace all references to sys/poll.h with poll.h as that's what POSIX defines. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1925 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 5 +---- src/pulse/mainloop.c | 4 ++-- src/pulse/thread-mainloop.c | 4 ++-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index 0da52533..b22a990d 100644 --- a/configure.ac +++ b/configure.ac @@ -185,7 +185,7 @@ AC_HEADER_STDC # POSIX AC_CHECK_HEADERS([arpa/inet.h glob.h grp.h netdb.h netinet/in.h \ - netinet/in_systm.h netinet/tcp.h pwd.h sched.h \ + netinet/in_systm.h netinet/tcp.h poll.h pwd.h sched.h \ sys/mman.h sys/resource.h sys/select.h sys/socket.h sys/wait.h \ syslog.h sys/dl.h dlfcn.h]) AC_CHECK_HEADERS([netinet/ip.h], [], [], @@ -203,9 +203,6 @@ AC_CHECK_HEADERS([sys/un.h], [HAVE_AF_UNIX=1], [HAVE_AF_UNIX=0]) AM_CONDITIONAL(HAVE_REGEX, test "x$HAVE_REGEX" = "x1") AM_CONDITIONAL(HAVE_AF_UNIX, test "x$HAVE_AF_UNIX" = "x1") -# XPG4-UNIX -AC_CHECK_HEADERS([sys/poll.h]) - # Linux AC_CHECK_HEADERS([linux/input.h], [HAVE_EVDEV=1], [HAVE_EVDEV=0]) diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index bab8eb5c..ad4e4e97 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -34,8 +34,8 @@ #include #include -#ifdef HAVE_SYS_POLL_H -#include +#ifdef HAVE_POLL_H +#include #else #include #endif diff --git a/src/pulse/thread-mainloop.c b/src/pulse/thread-mainloop.c index 30685705..9dd47ae3 100644 --- a/src/pulse/thread-mainloop.c +++ b/src/pulse/thread-mainloop.c @@ -29,8 +29,8 @@ #include #include -#ifdef HAVE_SYS_POLL_H -#include +#ifdef HAVE_POLL_H +#include #else #include #endif -- cgit From 8dcc1fa6161c2a507d008a50a6d7f5170ce54a14 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 3 Oct 2007 14:43:56 +0000 Subject: Adapt rtpoll and friends to Windows by replacing timespec with timeval and add a fallback when clock_gettime() isn't available. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1926 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 7 ++- src/modules/module-combine.c | 18 +++--- src/modules/module-null-sink.c | 14 ++--- src/pulsecore/rtclock.c | 129 ++++++++++------------------------------- src/pulsecore/rtclock.h | 19 ++---- src/pulsecore/rtpoll.c | 45 ++++++++------ src/pulsecore/rtpoll.h | 3 +- 7 files changed, 83 insertions(+), 152 deletions(-) diff --git a/configure.ac b/configure.ac index b22a990d..152cd51a 100644 --- a/configure.ac +++ b/configure.ac @@ -271,9 +271,10 @@ AC_CHECK_FUNCS([lrintf strtof]) AC_FUNC_FORK AC_FUNC_GETGROUPS AC_FUNC_SELECT_ARGTYPES -AC_CHECK_FUNCS([chmod chown getaddrinfo getgrgid_r getpwuid_r gettimeofday \ - getuid inet_ntop inet_pton nanosleep pipe posix_fadvise posix_madvise \ - posix_memalign setpgid setsid shm_open sigaction sleep sysconf]) +AC_CHECK_FUNCS([chmod chown clock_gettime getaddrinfo getgrgid_r \ + getpwuid_r gettimeofday getuid inet_ntop inet_pton mlock nanosleep \ + pipe posix_fadvise posix_madvise posix_memalign setpgid setsid shm_open \ + sigaction sleep sysconf]) AC_CHECK_FUNCS([mkfifo], [HAVE_MKFIFO=1], [HAVE_MKFIFO=0]) AM_CONDITIONAL(HAVE_MKFIFO, test "x$HAVE_MKFIFO" = "x1") diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 447f41cb..665bf9dd 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -118,7 +118,7 @@ struct userdata { pa_resample_method_t resample_method; - struct timespec adjust_timestamp; + struct timeval adjust_timestamp; struct output *master; pa_idxset* outputs; /* managed in main context */ @@ -126,7 +126,7 @@ struct userdata { struct { PA_LLIST_HEAD(struct output, active_outputs); /* managed in IO thread context */ pa_atomic_t running; /* we cache that value here, so that every thread can query it cheaply */ - struct timespec timestamp; + struct timeval timestamp; pa_bool_t in_null_mode; } thread_info; }; @@ -247,17 +247,17 @@ static void thread_func(void *userdata) { /* If no outputs are connected, render some data and drop it immediately. */ if (u->sink->thread_info.state == PA_SINK_RUNNING && !u->thread_info.active_outputs) { - struct timespec now; + struct timeval now; pa_rtclock_get(&now); - if (!u->thread_info.in_null_mode || pa_timespec_cmp(&u->thread_info.timestamp, &now) <= 0) { + if (!u->thread_info.in_null_mode || pa_timeval_cmp(&u->thread_info.timestamp, &now) <= 0) { pa_sink_skip(u->sink, u->block_size); if (!u->thread_info.in_null_mode) u->thread_info.timestamp = now; - pa_timespec_add(&u->thread_info.timestamp, pa_bytes_to_usec(u->block_size, &u->sink->sample_spec)); + pa_timeval_add(&u->thread_info.timestamp, pa_bytes_to_usec(u->block_size, &u->sink->sample_spec)); } pa_rtpoll_set_timer_absolute(u->rtpoll, &u->thread_info.timestamp); @@ -563,10 +563,10 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse * sink_get_latency_cb() below */ if (u->thread_info.in_null_mode) { - struct timespec now; + struct timeval now; - if (pa_timespec_cmp(&u->thread_info.timestamp, pa_rtclock_get(&now)) > 0) { - *((pa_usec_t*) data) = pa_timespec_diff(&u->thread_info.timestamp, &now); + if (pa_timeval_cmp(&u->thread_info.timestamp, pa_rtclock_get(&now)) > 0) { + *((pa_usec_t*) data) = pa_timeval_diff(&u->thread_info.timestamp, &now); break; } } @@ -947,7 +947,7 @@ int pa__init(pa_module*m) { u->thread = NULL; u->resample_method = resample_method; u->outputs = pa_idxset_new(NULL, NULL); - pa_timespec_reset(&u->adjust_timestamp); + memset(&u->adjust_timestamp, 0, sizeof(u->adjust_timestamp)); u->sink_new_slot = u->sink_unlink_slot = u->sink_state_changed_slot = NULL; PA_LLIST_HEAD_INIT(struct output, u->thread_info.active_outputs); pa_atomic_store(&u->thread_info.running, FALSE); diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index 04df239d..d993988e 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -75,7 +75,7 @@ struct userdata { size_t block_size; - struct timespec timestamp; + struct timeval timestamp; }; static const char* const valid_modargs[] = { @@ -100,14 +100,14 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse break; case PA_SINK_MESSAGE_GET_LATENCY: { - struct timespec now; + struct timeval now; pa_rtclock_get(&now); - if (pa_timespec_cmp(&u->timestamp, &now) > 0) + if (pa_timeval_cmp(&u->timestamp, &now) > 0) *((pa_usec_t*) data) = 0; else - *((pa_usec_t*) data) = pa_timespec_diff(&u->timestamp, &now); + *((pa_usec_t*) data) = pa_timeval_diff(&u->timestamp, &now); break; } } @@ -132,13 +132,13 @@ static void thread_func(void *userdata) { /* Render some data and drop it immediately */ if (u->sink->thread_info.state == PA_SINK_RUNNING) { - struct timespec now; + struct timeval now; pa_rtclock_get(&now); - if (pa_timespec_cmp(&u->timestamp, &now) <= 0) { + if (pa_timeval_cmp(&u->timestamp, &now) <= 0) { pa_sink_skip(u->sink, u->block_size); - pa_timespec_add(&u->timestamp, pa_bytes_to_usec(u->block_size, &u->sink->sample_spec)); + pa_timeval_add(&u->timestamp, pa_bytes_to_usec(u->block_size, &u->sink->sample_spec)); } pa_rtpoll_set_timer_absolute(u->rtpoll, &u->timestamp); diff --git a/src/pulsecore/rtclock.c b/src/pulsecore/rtclock.c index 7dd83b3f..0d983f83 100644 --- a/src/pulsecore/rtclock.c +++ b/src/pulsecore/rtclock.c @@ -35,123 +35,48 @@ #include "rtclock.h" -struct timespec *pa_timespec_store(struct timespec *a, pa_usec_t u) { - pa_assert(a); +pa_usec_t pa_rtclock_age(const struct timeval *tv) { + struct timeval now; + pa_assert(tv); - a->tv_sec = u / PA_USEC_PER_SEC; - - u -= (pa_usec_t) a->tv_sec * PA_USEC_PER_SEC; - - a->tv_nsec = u * 1000; - - return a; -} - -struct timespec *pa_timespec_reset(struct timespec *a) { - pa_assert(a); - - a->tv_sec = a->tv_nsec = 0; - return a; -} - -pa_usec_t pa_timespec_load(struct timespec *ts) { - pa_assert(ts); - - return (pa_usec_t) ts->tv_sec * PA_USEC_PER_SEC + (pa_usec_t) (ts->tv_nsec / 1000); -} - -pa_usec_t pa_timespec_diff(const struct timespec *a, const struct timespec *b) { - pa_usec_t r; - - pa_assert(a); - pa_assert(b); - - /* Check which whan is the earlier time and swap the two arguments if required. */ - if (pa_timespec_cmp(a, b) < 0) { - const struct timespec *c; - c = a; - a = b; - b = c; - } - - /* Calculate the second difference*/ - r = ((pa_usec_t) a->tv_sec - b->tv_sec) * PA_USEC_PER_SEC; - - /* Calculate the microsecond difference */ - if (a->tv_nsec > b->tv_nsec) - r += (pa_usec_t) ((a->tv_nsec - b->tv_nsec) / 1000); - else if (a->tv_nsec < b->tv_nsec) - r -= (pa_usec_t) ((b->tv_nsec - a->tv_nsec) / 1000); - - return r; -} - -int pa_timespec_cmp(const struct timespec *a, const struct timespec *b) { - pa_assert(a); - pa_assert(b); - - if (a->tv_sec < b->tv_sec) - return -1; - - if (a->tv_sec > b->tv_sec) - return 1; - - if (a->tv_nsec < b->tv_nsec) - return -1; - - if (a->tv_nsec > b->tv_nsec) - return 1; - - return 0; + return pa_timeval_diff(pa_rtclock_get(&now), tv); } -struct timespec* pa_timespec_add(struct timespec *ts, pa_usec_t v) { - unsigned long secs; - pa_assert(ts); - - secs = (unsigned long) (v/PA_USEC_PER_SEC); - ts->tv_sec += secs; - v -= ((pa_usec_t) secs) * PA_USEC_PER_SEC; - - ts->tv_nsec += (long) (v*1000); - - /* Normalize */ - while (ts->tv_nsec >= PA_NSEC_PER_SEC) { - ts->tv_sec++; - ts->tv_nsec -= PA_NSEC_PER_SEC; - } - - return ts; -} - -pa_usec_t pa_rtclock_age(const struct timespec *ts) { - struct timespec now; - pa_assert(ts); - - return pa_timespec_diff(pa_rtclock_get(&now), ts); -} - -struct timespec *pa_rtclock_get(struct timespec *ts) { +struct timeval *pa_rtclock_get(struct timeval *tv) { +#ifdef HAVE_CLOCK_GETTIME static int no_monotonic = 0; + struct timespec ts; /* No locking or atomic ops for no_monotonic here */ - - pa_assert(ts); if (!no_monotonic) { #ifdef CLOCK_MONOTONIC - if (clock_gettime(CLOCK_MONOTONIC, ts) >= 0) - return ts; + if (clock_gettime(CLOCK_MONOTONIC, &ts) >= 0) + goto out; #endif no_monotonic = 1; } pa_assert_se(clock_gettime(CLOCK_REALTIME, ts) == 0); - return ts; + +out: + pa_assert(tv); + + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec / 1000; + + return tv; + +#else /* HAVE_CLOCK_GETTIME */ + + return pa_gettimeofday(tv); + +#endif } int pa_rtclock_hrtimer(void) { +#ifdef HAVE_CLOCK_GETTIME struct timespec ts; #ifdef CLOCK_MONOTONIC @@ -161,5 +86,11 @@ int pa_rtclock_hrtimer(void) { pa_assert_se(clock_getres(CLOCK_REALTIME, &ts) == 0); return ts.tv_sec == 0 && ts.tv_nsec <= PA_HRTIMER_THRESHOLD_USEC*1000; + +#else /* HAVE_CLOCK_GETTIME */ + + return 0; + +#endif } diff --git a/src/pulsecore/rtclock.h b/src/pulsecore/rtclock.h index cfc968f8..0d232a04 100644 --- a/src/pulsecore/rtclock.h +++ b/src/pulsecore/rtclock.h @@ -24,25 +24,14 @@ USA. ***/ -#include -#include +struct timeval; -#include +/* Something like pulse/timeval.h but based on CLOCK_MONOTONIC */ -/* Something like pulse/timeval.h but based on CLOCK_MONOTONIC and - * timespec instead of timeval */ - -struct timespec *pa_rtclock_get(struct timespec *ts); -pa_usec_t pa_rtclock_age(const struct timespec *tv); +struct timeval *pa_rtclock_get(struct timeval *ts); +pa_usec_t pa_rtclock_age(const struct timeval *tv); int pa_rtclock_hrtimer(void); -struct timespec *pa_timespec_store(struct timespec *a, pa_usec_t u); -struct timespec *pa_timespec_reset(struct timespec *a); -pa_usec_t pa_timespec_load(struct timespec *tv); -struct timespec *pa_timespec_add(struct timespec *tv, pa_usec_t t); -pa_usec_t pa_timespec_diff(const struct timespec *a, const struct timespec *b); -int pa_timespec_cmp(const struct timespec *a, const struct timespec *b); - /* timer with a resolution better than this are considered high-resolution */ #define PA_HRTIMER_THRESHOLD_USEC 10 diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c index de0ffa4f..c81fcd11 100644 --- a/src/pulsecore/rtpoll.c +++ b/src/pulsecore/rtpoll.c @@ -26,14 +26,24 @@ #include #endif -#include #include #include #include #include #include +#ifdef __linux__ +#include +#endif + +#ifdef HAVE_POLL_H +#include +#else +#include +#endif + #include +#include #include #include @@ -43,6 +53,8 @@ #include #include +#include + #include "rtpoll.h" struct pa_rtpoll { @@ -50,7 +62,7 @@ struct pa_rtpoll { unsigned n_pollfd_alloc, n_pollfd_used; pa_bool_t timer_enabled; - struct timespec next_elapse; + struct timeval next_elapse; pa_usec_t period; pa_bool_t scan_for_dead; @@ -290,7 +302,7 @@ static void reset_all_revents(pa_rtpoll *p) { int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { pa_rtpoll_item *i; int r = 0; - struct timespec timeout; + struct timeval timeout; pa_assert(p); pa_assert(!p->running); @@ -357,15 +369,14 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { /* Calculate timeout */ if (!wait || p->quit) { timeout.tv_sec = 0; - timeout.tv_nsec = 0; + timeout.tv_usec = 0; } else if (p->timer_enabled) { - struct timespec now; + struct timeval now; pa_rtclock_get(&now); - if (pa_timespec_cmp(&p->next_elapse, &now) <= 0) - memset(&timeout, 0, sizeof(timeout)); - else - pa_timespec_store(&timeout, pa_timespec_diff(&p->next_elapse, &now)); + memset(&timeout, 0, sizeof(timeout)); + if (pa_timeval_cmp(&p->next_elapse, &now) > 0) + pa_timeval_add(&timeout, pa_timeval_diff(&p->next_elapse, &now)); } /* OK, now let's sleep */ @@ -380,7 +391,7 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { #endif #endif - r = poll(p->pollfd, p->n_pollfd_used, p->timer_enabled ? (timeout.tv_sec*1000) + (timeout.tv_nsec / 1000000) : -1); + r = poll(p->pollfd, p->n_pollfd_used, p->timer_enabled ? (timeout.tv_sec*1000) + (timeout.tv_usec / 1000) : -1); if (r < 0) { if (errno == EAGAIN || errno == EINTR) @@ -393,14 +404,14 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { if (p->timer_enabled) { if (p->period > 0) { - struct timespec now; + struct timeval now; pa_rtclock_get(&now); - pa_timespec_add(&p->next_elapse, p->period); + pa_timeval_add(&p->next_elapse, p->period); /* Guarantee that the next timeout will happen in the future */ - if (pa_timespec_cmp(&p->next_elapse, &now) < 0) - pa_timespec_add(&p->next_elapse, (pa_timespec_diff(&now, &p->next_elapse) / p->period + 1) * p->period); + if (pa_timeval_cmp(&p->next_elapse, &now) < 0) + pa_timeval_add(&p->next_elapse, (pa_timeval_diff(&now, &p->next_elapse) / p->period + 1) * p->period); } else p->timer_enabled = FALSE; @@ -487,7 +498,7 @@ static void update_timer(pa_rtpoll *p) { #endif } -void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timespec *ts) { +void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timeval *ts) { pa_assert(p); pa_assert(ts); @@ -503,7 +514,7 @@ void pa_rtpoll_set_timer_periodic(pa_rtpoll *p, pa_usec_t usec) { p->period = usec; pa_rtclock_get(&p->next_elapse); - pa_timespec_add(&p->next_elapse, usec); + pa_timeval_add(&p->next_elapse, usec); p->timer_enabled = TRUE; update_timer(p); @@ -514,7 +525,7 @@ void pa_rtpoll_set_timer_relative(pa_rtpoll *p, pa_usec_t usec) { p->period = 0; pa_rtclock_get(&p->next_elapse); - pa_timespec_add(&p->next_elapse, usec); + pa_timeval_add(&p->next_elapse, usec); p->timer_enabled = TRUE; update_timer(p); diff --git a/src/pulsecore/rtpoll.h b/src/pulsecore/rtpoll.h index a1242b38..d38d0864 100644 --- a/src/pulsecore/rtpoll.h +++ b/src/pulsecore/rtpoll.h @@ -24,7 +24,6 @@ USA. ***/ -#include #include #include @@ -75,7 +74,7 @@ void pa_rtpoll_install(pa_rtpoll *p); * cleanly. */ int pa_rtpoll_run(pa_rtpoll *f, pa_bool_t wait); -void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timespec *ts); +void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timeval *ts); void pa_rtpoll_set_timer_periodic(pa_rtpoll *p, pa_usec_t usec); void pa_rtpoll_set_timer_relative(pa_rtpoll *p, pa_usec_t usec); void pa_rtpoll_set_timer_disabled(pa_rtpoll *p); -- cgit From ce74146a817481c95942f4afee73d918ba82427d Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 3 Oct 2007 14:46:36 +0000 Subject: Add stubs when RT signals aren't available. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1927 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/rtsig.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/pulsecore/rtsig.c b/src/pulsecore/rtsig.c index 1af45e77..bfc49c88 100644 --- a/src/pulsecore/rtsig.c +++ b/src/pulsecore/rtsig.c @@ -36,6 +36,8 @@ #include "rtsig.h" +#ifdef SIGRTMIN + static void _free_rtsig(void *p) { pa_rtsig_put(PA_PTR_TO_INT(p)); } @@ -111,3 +113,21 @@ void pa_rtsig_configure(int start, int end) { /* We allocate starting from the end */ pa_atomic_store(&rtsig_current, rtsig_end); } + +#else /* SIGRTMIN */ + +int pa_rtsig_get(void) { + return -1; +} + +int pa_rtsig_get_for_thread(void) { + return -1; +} + +void pa_rtsig_put(int sig) { +} + +void pa_rtsig_configure(int start, int end) { +} + +#endif /* SIGRTMIN */ -- cgit From cef65632734caf00fbf1b0e44672d0e3c533c52f Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 3 Oct 2007 14:47:26 +0000 Subject: Assorted minor Windows compatibility fixes for recent code updates. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1928 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 1 + libltdl/config.h | 30 +++++++++++++------------- src/Makefile.am | 4 ++-- src/pulsecore/authkey.c | 4 ++++ src/pulsecore/core-util.c | 45 +++++++++++++++++++++++++++++++++++++-- src/pulsecore/fdsem.c | 7 ++++++ src/pulsecore/ioline.c | 1 + src/pulsecore/mutex-win32.c | 2 +- src/pulsecore/once.c | 2 -- src/pulsecore/pid.c | 5 ++++- src/pulsecore/rtsig.h | 3 --- src/pulsecore/sound-file-stream.c | 6 +++++- src/pulsecore/sound-file.c | 6 +++++- src/pulsecore/thread-win32.c | 19 +++++++---------- src/pulsecore/winsock.h | 2 ++ 15 files changed, 98 insertions(+), 39 deletions(-) diff --git a/configure.ac b/configure.ac index 152cd51a..cf9069a1 100644 --- a/configure.ac +++ b/configure.ac @@ -219,6 +219,7 @@ AC_CHECK_HEADERS([windows.h winsock2.h ws2tcpip.h]) # Other AC_CHECK_HEADERS([sys/ioctl.h]) AC_CHECK_HEADERS([byteswap.h]) +AC_CHECK_HEADERS([sys/syscall.h]) #### Typdefs, structures, etc. #### diff --git a/libltdl/config.h b/libltdl/config.h index a04820a7..a4186d9a 100644 --- a/libltdl/config.h +++ b/libltdl/config.h @@ -2,22 +2,22 @@ /* config-h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the `argz_append' function. */ -#define HAVE_ARGZ_APPEND 1 +/* #undef HAVE_ARGZ_APPEND */ /* Define to 1 if you have the `argz_create_sep' function. */ -#define HAVE_ARGZ_CREATE_SEP 1 +/* #undef HAVE_ARGZ_CREATE_SEP */ /* Define to 1 if you have the header file. */ -#define HAVE_ARGZ_H 1 +/* #undef HAVE_ARGZ_H */ /* Define to 1 if you have the `argz_insert' function. */ -#define HAVE_ARGZ_INSERT 1 +/* #undef HAVE_ARGZ_INSERT */ /* Define to 1 if you have the `argz_next' function. */ -#define HAVE_ARGZ_NEXT 1 +/* #undef HAVE_ARGZ_NEXT */ /* Define to 1 if you have the `argz_stringify' function. */ -#define HAVE_ARGZ_STRINGIFY 1 +/* #undef HAVE_ARGZ_STRINGIFY */ /* Define to 1 if you have the header file. */ #define HAVE_ASSERT_H 1 @@ -42,10 +42,10 @@ /* #undef HAVE_DLD_H */ /* Define to 1 if you have the `dlerror' function. */ -#define HAVE_DLERROR 1 +/* #undef HAVE_DLERROR */ /* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H 1 +/* #undef HAVE_DLFCN_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_DL_H */ @@ -57,7 +57,7 @@ #define HAVE_ERRNO_H 1 /* Define to 1 if the system has the type `error_t'. */ -#define HAVE_ERROR_T 1 +/* #undef HAVE_ERROR_T */ /* Define to 1 if you have the `index' function. */ /* #undef HAVE_INDEX */ @@ -66,7 +66,7 @@ #define HAVE_INTTYPES_H 1 /* Define if you have the libdl library or equivalent. */ -#define HAVE_LIBDL 1 +/* #undef HAVE_LIBDL */ /* Define to 1 if you have the header file. */ /* #undef HAVE_MACH_O_DYLD_H */ @@ -146,7 +146,7 @@ #define HAVE_UNISTD_H 1 /* Define if the OS needs help to load dependent libraries for dlopen(). */ -/* #undef LTDL_DLOPEN_DEPLIBS */ +#define LTDL_DLOPEN_DEPLIBS 1 /* Define to the sub-directory in which libtool stores uninstalled libraries. */ @@ -154,13 +154,13 @@ /* Define to the name of the environment variable that determines the dynamic library search path. */ -#define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH" +#define LTDL_SHLIBPATH_VAR "PATH" /* Define to the extension used for shared libraries, say, ".so". */ -#define LTDL_SHLIB_EXT ".so" +#define LTDL_SHLIB_EXT ".dll" /* Define to the system default library search path. */ -#define LTDL_SYSSEARCHPATH "/lib:/usr/lib:/usr/lib/atlas:/usr/local/lib:/lib/i486-linux-gnu:/usr/lib/i486-linux-gnu:/usr/local/lib" +#define LTDL_SYSSEARCHPATH "/lib:/usr/lib" /* Define if dlsym() requires a leading underscore in symbol names. */ /* #undef NEED_USCORE */ @@ -187,7 +187,7 @@ /* #undef const */ /* Define to a type to use for `error_t' if it is not otherwise available. */ -/* #undef error_t */ +#define error_t int /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ diff --git a/src/Makefile.am b/src/Makefile.am index e1d210b0..98e78745 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -78,8 +78,8 @@ endif if OS_IS_WIN32 PA_THREAD_OBJS = \ pulsecore/mutex-win32.c pulsecore/mutex.h \ - pulsecore/thread-win32.c pulsecore/thread.h -# pulsecore/semaphore-win32.c pulsecore/semaphore.h + pulsecore/thread-win32.c pulsecore/thread.h \ + pulsecore/semaphore-win32.c pulsecore/semaphore.h else PA_THREAD_OBJS = \ pulsecore/mutex-posix.c pulsecore/mutex.h \ diff --git a/src/pulsecore/authkey.c b/src/pulsecore/authkey.c index 4d9bfd3a..d422d6a2 100644 --- a/src/pulsecore/authkey.c +++ b/src/pulsecore/authkey.c @@ -71,6 +71,10 @@ static int generate(int fd, void *ret_data, size_t length) { #define O_BINARY 0 #endif +#ifndef O_NOCTTY +#define O_NOCTTY 0 +#endif + /* Load an euthorization cookie from file fn and store it in data. If * the cookie file doesn't exist, create it */ static int load(const char *fn, void *data, size_t length) { diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 3defe2bc..a644b664 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -653,13 +653,21 @@ const char *pa_sig2str(int sig) { case SIGHUP: return "SIGHUP"; #endif case SIGINT: return "SIGINT"; +#ifdef SIGQUIT case SIGQUIT: return "SIGQUIT"; +#endif case SIGILL: return "SIGULL"; +#ifdef SIGTRAP case SIGTRAP: return "SIGTRAP"; +#endif case SIGABRT: return "SIGABRT"; +#ifdef SIGBUS case SIGBUS: return "SIGBUS"; +#endif case SIGFPE: return "SIGFPE"; +#ifdef SIGKILL case SIGKILL: return "SIGKILL"; +#endif #ifdef SIGUSR1 case SIGUSR1: return "SIGUSR1"; #endif @@ -670,30 +678,58 @@ const char *pa_sig2str(int sig) { #ifdef SIGPIPE case SIGPIPE: return "SIGPIPE"; #endif +#ifdef SIGALRM case SIGALRM: return "SIGALRM"; +#endif case SIGTERM: return "SIGTERM"; +#ifdef SIGSTKFLT case SIGSTKFLT: return "SIGSTKFLT"; +#endif #ifdef SIGCHLD case SIGCHLD: return "SIGCHLD"; #endif +#ifdef SIGCONT case SIGCONT: return "SIGCONT"; +#endif +#ifdef SIGSTOP case SIGSTOP: return "SIGSTOP"; +#endif +#ifdef SIGTSTP case SIGTSTP: return "SIGTSTP"; +#endif +#ifdef SIGTTIN case SIGTTIN: return "SIGTTIN"; +#endif +#ifdef SIGTTOU case SIGTTOU: return "SIGTTOU"; +#endif +#ifdef SIGURG case SIGURG: return "SIGURG"; +#endif #ifdef SIGXCPU case SIGXCPU: return "SIGXCPU"; #endif #ifdef SIGXFSZ case SIGXFSZ: return "SIGXFSZ"; #endif +#ifdef SIGVTALRM case SIGVTALRM: return "SIGVTALRM"; +#endif +#ifdef SIGPROF case SIGPROF: return "SIGPROF"; +#endif +#ifdef SIGWINCH case SIGWINCH: return "SIGWINCH"; +#endif +#ifdef SIGIO case SIGIO: return "SIGIO"; +#endif +#ifdef SIGPWR case SIGPWR: return "SIGPWR"; +#endif +#ifdef SIGSYS case SIGSYS: return "SIGSYS"; +#endif } #ifdef SIGRTMIN @@ -943,7 +979,10 @@ int pa_lock_lockfile(const char *fn) { for (;;) { struct stat st; - if ((fd = open(fn, O_CREAT|O_RDWR|O_NOCTTY + if ((fd = open(fn, O_CREAT|O_RDWR +#ifdef O_NOCTTY + |O_NOCTTY +#endif #ifdef O_NOFOLLOW |O_NOFOLLOW #endif @@ -1431,6 +1470,7 @@ void *pa_will_need(const void *p, size_t l) { pa_log_debug("posix_madvise() failed (or doesn't exist), trying mlock(): %s", pa_cstrerror(r)); +#ifdef HAVE_MLOCK while (size > 0 && bs > 0) { if (bs > size) @@ -1446,9 +1486,10 @@ void *pa_will_need(const void *p, size_t l) { a = (const uint8_t*) a + bs; size -= bs; } +#endif if (bs <= 0) - pa_log_debug("mlock() failed too, giving up: %s", pa_cstrerror(errno)); + pa_log_debug("mlock() failed too (or doesn't exist), giving up: %s", pa_cstrerror(errno)); else pa_log_debug("mlock() worked fine!"); diff --git a/src/pulsecore/fdsem.c b/src/pulsecore/fdsem.c index b919ba41..927bf00c 100644 --- a/src/pulsecore/fdsem.c +++ b/src/pulsecore/fdsem.c @@ -25,7 +25,10 @@ #include #endif +#ifdef HAVE_SYS_SYSCALL_H #include +#endif + #include #include @@ -36,6 +39,10 @@ #include #include +#ifndef HAVE_PIPE +#include +#endif + #ifdef __linux__ #if !defined(__NR_eventfd) && defined(__i386__) diff --git a/src/pulsecore/ioline.c b/src/pulsecore/ioline.c index a3627003..efb50722 100644 --- a/src/pulsecore/ioline.c +++ b/src/pulsecore/ioline.c @@ -32,6 +32,7 @@ #include +#include #include #include #include diff --git a/src/pulsecore/mutex-win32.c b/src/pulsecore/mutex-win32.c index 1f16e24c..77d63d15 100644 --- a/src/pulsecore/mutex-win32.c +++ b/src/pulsecore/mutex-win32.c @@ -40,7 +40,7 @@ struct pa_cond { pa_hashmap *wait_events; }; -pa_mutex* pa_mutex_new(int recursive) { +pa_mutex* pa_mutex_new(pa_bool_t recursive, pa_bool_t inherit_priority) { pa_mutex *m; m = pa_xnew(pa_mutex, 1); diff --git a/src/pulsecore/once.c b/src/pulsecore/once.c index 4f6e5b62..198bd41e 100644 --- a/src/pulsecore/once.c +++ b/src/pulsecore/once.c @@ -25,8 +25,6 @@ #include #endif -#include - #include #include diff --git a/src/pulsecore/pid.c b/src/pulsecore/pid.c index 38d26814..55ff2088 100644 --- a/src/pulsecore/pid.c +++ b/src/pulsecore/pid.c @@ -88,7 +88,10 @@ static int open_pid_file(const char *fn, int mode) { for (;;) { struct stat st; - if ((fd = open(fn, mode|O_NOCTTY + if ((fd = open(fn, mode +#ifdef O_NOCTTY + |O_NOCTTY +#endif #ifdef O_NOFOLLOW |O_NOFOLLOW #endif diff --git a/src/pulsecore/rtsig.h b/src/pulsecore/rtsig.h index 48f5f050..7830d272 100644 --- a/src/pulsecore/rtsig.h +++ b/src/pulsecore/rtsig.h @@ -24,9 +24,6 @@ USA. ***/ -#include -#include - /* Return the next unused POSIX Realtime signals */ int pa_rtsig_get(void); diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c index 6c70c4f1..d9f11a26 100644 --- a/src/pulsecore/sound-file-stream.c +++ b/src/pulsecore/sound-file-stream.c @@ -244,7 +244,11 @@ int pa_play_file( memset(&sfinfo, 0, sizeof(sfinfo)); - if ((fd = open(fname, O_RDONLY|O_NOCTTY)) < 0) { + if ((fd = open(fname, O_RDONLY +#ifdef O_NOCTTY + |O_NOCTTY +#endif + )) < 0) { pa_log("Failed to open file %s: %s", fname, pa_cstrerror(errno)); goto fail; } diff --git a/src/pulsecore/sound-file.c b/src/pulsecore/sound-file.c index b1c509f2..50352930 100644 --- a/src/pulsecore/sound-file.c +++ b/src/pulsecore/sound-file.c @@ -63,7 +63,11 @@ int pa_sound_file_load( pa_memchunk_reset(chunk); memset(&sfinfo, 0, sizeof(sfinfo)); - if ((fd = open(fname, O_RDONLY|O_NOCTTY)) < 0) { + if ((fd = open(fname, O_RDONLY +#ifdef O_NOCTTY + |O_NOCTTY +#endif + )) < 0) { pa_log("Failed to open file %s: %s", fname, pa_cstrerror(errno)); goto finish; } diff --git a/src/pulsecore/thread-win32.c b/src/pulsecore/thread-win32.c index 46d273b4..cad1420a 100644 --- a/src/pulsecore/thread-win32.c +++ b/src/pulsecore/thread-win32.c @@ -53,9 +53,8 @@ struct pa_tls_monitor { }; static pa_tls *thread_tls; -static pa_once_t thread_tls_once = PA_ONCE_INIT; +static pa_once thread_tls_once = PA_ONCE_INIT; static pa_tls *monitor_tls; -static pa_once_t monitor_tls_once = PA_ONCE_INIT; static void thread_tls_once_func(void) { thread_tls = pa_tls_new(NULL); @@ -66,7 +65,7 @@ static DWORD WINAPI internal_thread_func(LPVOID param) { pa_thread *t = param; assert(t); - pa_once(&thread_tls_once, thread_tls_once_func); + pa_run_once(&thread_tls_once, thread_tls_once_func); pa_tls_set(thread_tls, t); t->thread_func(t->userdata); @@ -122,7 +121,7 @@ int pa_thread_join(pa_thread *t) { } pa_thread* pa_thread_self(void) { - pa_once(&thread_tls_once, thread_tls_once_func); + pa_run_once(&thread_tls_once, thread_tls_once_func); return pa_tls_get(thread_tls); } @@ -130,12 +129,6 @@ void pa_thread_yield(void) { Sleep(0); } -static void monitor_tls_once_func(void) { - monitor_tls = pa_tls_new(NULL); - assert(monitor_tls); - pa_tls_set(monitor_tls, NULL); -} - static DWORD WINAPI monitor_thread_func(LPVOID param) { struct pa_tls_monitor *m = param; assert(m); @@ -191,7 +184,11 @@ void *pa_tls_set(pa_tls *t, void *userdata) { if (t->free_func) { struct pa_tls_monitor *m; - pa_once(&monitor_tls_once, monitor_tls_once_func); + PA_ONCE_BEGIN { + monitor_tls = pa_tls_new(NULL); + assert(monitor_tls); + pa_tls_set(monitor_tls, NULL); + } PA_ONCE_END; m = pa_tls_get(monitor_tls); if (!m) { diff --git a/src/pulsecore/winsock.h b/src/pulsecore/winsock.h index ae868b38..0352bf4d 100644 --- a/src/pulsecore/winsock.h +++ b/src/pulsecore/winsock.h @@ -15,6 +15,8 @@ #define EHOSTUNREACH WSAEHOSTUNREACH #define EWOULDBLOCK WSAEWOULDBLOCK +typedef long suseconds_t; + #endif #ifdef HAVE_WS2TCPIP_H -- cgit From 586ef22ee4a1d5f59fc1756412de9e0b8fb4f362 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 3 Oct 2007 14:48:40 +0000 Subject: Platform dependent semaphore implementation for Windows. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1929 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/semaphore-win32.c | 65 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/pulsecore/semaphore-win32.c diff --git a/src/pulsecore/semaphore-win32.c b/src/pulsecore/semaphore-win32.c new file mode 100644 index 00000000..f6576348 --- /dev/null +++ b/src/pulsecore/semaphore-win32.c @@ -0,0 +1,65 @@ +/* $Id: mutex-win32.c 1426 2007-02-13 15:35:19Z ossman $ */ + +/*** + This file is part of PulseAudio. + + Copyright 2006 Pierre Ossman for Cendio AB + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include + +#include "semaphore.h" + +struct pa_semaphore +{ + HANDLE sema; +}; + +pa_semaphore* pa_semaphore_new(unsigned value) { + pa_semaphore *s; + + s = pa_xnew(pa_semaphore, 1); + + s->sema = CreateSemaphore(NULL, value, 32767, NULL); + pa_assert(s->sema != NULL); + + return s; +} + +void pa_semaphore_free(pa_semaphore *s) { + pa_assert(s); + CloseHandle(s->sema); + pa_xfree(s); +} + +void pa_semaphore_post(pa_semaphore *s) { + pa_assert(s); + ReleaseSemaphore(s->sema, 1, NULL); +} + +void pa_semaphore_wait(pa_semaphore *s) { + pa_assert(s); + WaitForSingleObject(s->sema, INFINITE); +} -- cgit From 60a935b29f69fd25cfb70ced04c366e429499ac4 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 3 Oct 2007 15:00:13 +0000 Subject: module_ladspa used libltdl so make sure it links against it. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1930 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 98e78745..ad7b6520 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1224,7 +1224,7 @@ module_remap_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la module_ladspa_sink_la_SOURCES = modules/module-ladspa-sink.c modules/ladspa.h module_ladspa_sink_la_CFLAGS = -DLADSPA_PATH=\"$(libdir)/ladspa:/usr/local/lib/ladspa:/usr/lib/ladspa\" $(AM_CFLAGS) module_ladspa_sink_la_LDFLAGS = -module -avoid-version -module_ladspa_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la +module_ladspa_sink_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) libpulsecore.la module_match_la_SOURCES = modules/module-match.c module_match_la_LDFLAGS = -module -avoid-version -- cgit From cb400878fe52b1418ac9e12389e5a4fa3231732e Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 3 Oct 2007 15:00:36 +0000 Subject: Don't call pa_rtsig_configure() when we lack the necessary defines. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1931 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/daemon/main.c b/src/daemon/main.c index 0e759d27..c135a6be 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -614,7 +614,9 @@ int main(int argc, char *argv[]) { else pa_log_info("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"); +#ifdef SIGRTMIN pa_rtsig_configure(SIGRTMIN, SIGRTMAX); +#endif pa_assert_se(mainloop = pa_mainloop_new()); -- cgit From 87cc073653f42c4e5237489fdc43fd4cda7e7144 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 4 Oct 2007 22:41:33 +0000 Subject: fix poll.h check, bad boy ossman broke git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1932 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/poll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pulsecore/poll.c b/src/pulsecore/poll.c index 2f8eae89..288f7dfb 100644 --- a/src/pulsecore/poll.c +++ b/src/pulsecore/poll.c @@ -45,7 +45,7 @@ #include "winsock.h" -#ifndef HAVE_SYS_POLL_H +#ifndef HAVE_POLL_H #include -- cgit From d74fa66f35eda1add73313d60c321f63269b3c56 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 7 Oct 2007 13:54:15 +0000 Subject: Fix build; change return value of pa_rtclock_hrtimer() to pa_bool git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1933 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/rtclock.c | 13 ++++++------- src/pulsecore/rtclock.h | 4 +++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/pulsecore/rtclock.c b/src/pulsecore/rtclock.c index 0d983f83..b34e6a41 100644 --- a/src/pulsecore/rtclock.c +++ b/src/pulsecore/rtclock.c @@ -53,12 +53,12 @@ struct timeval *pa_rtclock_get(struct timeval *tv) { #ifdef CLOCK_MONOTONIC if (clock_gettime(CLOCK_MONOTONIC, &ts) >= 0) goto out; -#endif +#endif no_monotonic = 1; } - pa_assert_se(clock_gettime(CLOCK_REALTIME, ts) == 0); + pa_assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0); out: pa_assert(tv); @@ -75,22 +75,21 @@ out: #endif } -int pa_rtclock_hrtimer(void) { +pa_bool_t pa_rtclock_hrtimer(void) { #ifdef HAVE_CLOCK_GETTIME struct timespec ts; - + #ifdef CLOCK_MONOTONIC if (clock_getres(CLOCK_MONOTONIC, &ts) >= 0) return ts.tv_sec == 0 && ts.tv_nsec <= PA_HRTIMER_THRESHOLD_USEC*1000; -#endif +#endif pa_assert_se(clock_getres(CLOCK_REALTIME, &ts) == 0); return ts.tv_sec == 0 && ts.tv_nsec <= PA_HRTIMER_THRESHOLD_USEC*1000; #else /* HAVE_CLOCK_GETTIME */ - return 0; + return FALSE; #endif } - diff --git a/src/pulsecore/rtclock.h b/src/pulsecore/rtclock.h index 0d232a04..72bbd5e9 100644 --- a/src/pulsecore/rtclock.h +++ b/src/pulsecore/rtclock.h @@ -24,13 +24,15 @@ USA. ***/ +#include + struct timeval; /* Something like pulse/timeval.h but based on CLOCK_MONOTONIC */ struct timeval *pa_rtclock_get(struct timeval *ts); pa_usec_t pa_rtclock_age(const struct timeval *tv); -int pa_rtclock_hrtimer(void); +pa_bool_t pa_rtclock_hrtimer(void); /* timer with a resolution better than this are considered high-resolution */ #define PA_HRTIMER_THRESHOLD_USEC 10 -- cgit From efc81a8f20652147aa720d8fd3803105081ad2a6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 7 Oct 2007 13:54:49 +0000 Subject: add new API function pa_timeval_store() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1934 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/timeval.c | 13 +++++++++++-- src/pulse/timeval.h | 3 +++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/pulse/timeval.c b/src/pulse/timeval.c index 44d74c94..dcc0bd75 100644 --- a/src/pulse/timeval.c +++ b/src/pulse/timeval.c @@ -55,7 +55,7 @@ struct timeval *pa_gettimeofday(struct timeval *tv) { #else #define EPOCHFILETIME (116444736000000000LL) #endif - + FILETIME ft; LARGE_INTEGER li; __int64 t; @@ -79,7 +79,7 @@ struct timeval *pa_gettimeofday(struct timeval *tv) { pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) { pa_usec_t r; - + pa_assert(a); pa_assert(b); @@ -147,3 +147,12 @@ struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v) { return tv; } + +struct timeval* pa_timeval_store(struct timeval *tv, pa_usec_t v) { + pa_assert(tv); + + tv->tv_sec = v / PA_USEC_PER_SEC; + tv->tv_usec = v % PA_USEC_PER_SEC; + + return tv; +} diff --git a/src/pulse/timeval.h b/src/pulse/timeval.h index e90df9f8..60b9d085 100644 --- a/src/pulse/timeval.h +++ b/src/pulse/timeval.h @@ -55,6 +55,9 @@ pa_usec_t pa_timeval_age(const struct timeval *tv); /** Add the specified time inmicroseconds to the specified timeval structure */ struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v) PA_GCC_PURE; +/** Store the specified uec value in the timeval struct */ +struct timeval* pa_timeval_store(struct timeval *tv, pa_usec_t v); + PA_C_DECL_END #endif -- cgit From 2198c2ec6e130ba9fbd762026151b57eb6570702 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 7 Oct 2007 13:55:37 +0000 Subject: fix build git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1935 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/rtpoll.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c index c81fcd11..354c4c0e 100644 --- a/src/pulsecore/rtpoll.c +++ b/src/pulsecore/rtpoll.c @@ -385,7 +385,12 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { #ifdef __linux__ if (!p->dont_use_ppoll) #endif - r = ppoll(p->pollfd, p->n_pollfd_used, p->timer_enabled ? &timeout : NULL, p->rtsig < 0 ? NULL : &p->sigset_unblocked); + { + struct timespec ts; + ts.tv_sec = timeout.tv_sec; + ts.tv_nsec = timeout.tv_usec * 1000; + r = ppoll(p->pollfd, p->n_pollfd_used, p->timer_enabled ? &ts : NULL, p->rtsig < 0 ? NULL : &p->sigset_unblocked); + } #ifdef __linux__ else #endif @@ -477,15 +482,20 @@ static void update_timer(pa_rtpoll *p) { memset(&its, 0, sizeof(its)); if (p->timer_enabled) { - its.it_value = p->next_elapse; + its.it_value.tv_sec = p->next_elapse.tv_sec; + its.it_value.tv_nsec = p->next_elapse.tv_usec*1000; /* Make sure that 0,0 is not understood as * "disarming" */ if (its.it_value.tv_sec == 0) its.it_value.tv_nsec = 1; - if (p->period > 0) - pa_timespec_store(&its.it_interval, p->period); + if (p->period > 0) { + struct timeval tv; + pa_timeval_store(&tv, p->period); + its.it_interval.tv_sec = tv.tv_sec; + its.it_interval.tv_nsec = tv.tv_usec*1000; + } } pa_assert_se(timer_settime(p->timer, TIMER_ABSTIME, &its, NULL) == 0); -- cgit From 3736246a364ab7e480924706c2e30f6fcf366f61 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 7 Oct 2007 13:56:07 +0000 Subject: s/timespec/timeval git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1936 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/rtp/module-rtp-recv.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/modules/rtp/module-rtp-recv.c b/src/modules/rtp/module-rtp-recv.c index 62be53ff..6c018931 100644 --- a/src/modules/rtp/module-rtp-recv.c +++ b/src/modules/rtp/module-rtp-recv.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -161,10 +162,10 @@ static void sink_input_kill(pa_sink_input* i) { static int rtpoll_work_cb(pa_rtpoll_item *i) { pa_memchunk chunk; int64_t k, j, delta; - struct timespec now; + struct timeval now; struct session *s; struct pollfd *p; - + pa_assert_se(s = pa_rtpoll_item_get_userdata(i)); p = pa_rtpoll_item_get_pollfd(i, NULL); @@ -173,12 +174,12 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) { pa_log("poll() signalled bad revents."); return -1; } - + if ((p->revents & POLLIN) == 0) return 0; p->revents = 0; - + if (pa_rtp_recv(&s->rtp_context, &chunk, s->userdata->module->core->mempool) < 0) return 0; @@ -234,7 +235,7 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) { static void sink_input_attach(pa_sink_input *i) { struct session *s; struct pollfd *p; - + pa_sink_input_assert_ref(i); pa_assert_se(s = i->userdata); @@ -317,7 +318,7 @@ static struct session *session_new(struct userdata *u, const pa_sdp_info *sdp_in int fd = -1; pa_memblock *silence; pa_sink_input_new_data data; - struct timespec now; + struct timeval now; pa_assert(u); pa_assert(sdp_info); @@ -406,7 +407,7 @@ fail: if (fd >= 0) pa_close(fd); - + return NULL; } @@ -422,7 +423,7 @@ static void session_free(struct session *s) { pa_assert(s->userdata->n_sessions >= 1); s->userdata->n_sessions--; pa_hashmap_remove(s->userdata->by_origin, s->sdp_info.origin); - + pa_memblockq_free(s->memblockq); pa_sdp_info_destroy(&s->sdp_info); pa_rtp_context_destroy(&s->rtp_context); @@ -461,10 +462,10 @@ static void sap_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event pa_sdp_info_destroy(&info); } else { - struct timespec now; + struct timeval now; pa_rtclock_get(&now); pa_atomic_store(&s->timestamp, now.tv_sec); - + pa_sdp_info_destroy(&info); } } @@ -473,7 +474,7 @@ static void sap_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event static void check_death_event_cb(pa_mainloop_api *m, pa_time_event *t, const struct timeval *ptv, void *userdata) { struct session *s, *n; struct userdata *u = userdata; - struct timespec now; + struct timeval now; struct timeval tv; pa_assert(m); @@ -484,7 +485,7 @@ static void check_death_event_cb(pa_mainloop_api *m, pa_time_event *t, const str pa_rtclock_get(&now); pa_log_debug("Checking for dead streams ..."); - + for (s = u->sessions; s; s = n) { int k; n = s->next; @@ -511,7 +512,7 @@ int pa__init(pa_module*m) { const char *sap_address; int fd = -1; struct timeval tv; - + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { @@ -554,7 +555,7 @@ int pa__init(pa_module*m) { pa_gettimeofday(&tv); pa_timeval_add(&tv, DEATH_TIMEOUT * PA_USEC_PER_SEC); u->check_death_event = m->core->mainloop->time_new(m->core->mainloop, &tv, check_death_event_cb, u); - + pa_modargs_free(ma); return 0; @@ -572,7 +573,7 @@ fail: void pa__done(pa_module*m) { struct userdata *u; struct session *s; - + pa_assert(m); if (!(u = m->userdata)) @@ -589,7 +590,7 @@ void pa__done(pa_module*m) { if (u->by_origin) { while ((s = pa_hashmap_get_first(u->by_origin))) session_free(s); - + pa_hashmap_free(u->by_origin, NULL, NULL); } -- cgit From a687c319b7bc394e536b9386d3a3258342f23763 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 7 Oct 2007 13:56:50 +0000 Subject: add missing poll.h inclusion git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1937 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-oss.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index cb975fd7..19dceef2 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include -- cgit From 215cac8be498ab57202c6414a824478da2b8d6e9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 7 Oct 2007 13:57:20 +0000 Subject: add missing poll.h inclusion git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1938 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-pipe-sink.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index edacf04b..41509f4f 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -34,6 +34,7 @@ #include #include #include +#include #include @@ -67,11 +68,11 @@ struct userdata { pa_core *core; pa_module *module; pa_sink *sink; - + pa_thread *thread; pa_thread_mq thread_mq; pa_rtpoll *rtpoll; - + char *filename; int fd; @@ -94,23 +95,23 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse struct userdata *u = PA_SINK(o)->userdata; switch (code) { - + case PA_SINK_MESSAGE_GET_LATENCY: { size_t n = 0; int l; -#ifdef TIOCINQ +#ifdef TIOCINQ if (ioctl(u->fd, TIOCINQ, &l) >= 0 && l > 0) n = (size_t) l; #endif - + n += u->memchunk.length; - + *((pa_usec_t*) data) = pa_bytes_to_usec(n, &u->sink->sample_spec); break; } } - + return pa_sink_process_msg(o, code, data, offset, chunk); } @@ -180,12 +181,12 @@ static void thread_func(void *userdata) { goto finish; pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); - + if (pollfd->revents & ~POLLOUT) { pa_log("FIFO shutdown."); goto fail; } - } + } fail: /* If this was no regular exit from the loop we have to continue @@ -227,7 +228,7 @@ int pa__init(pa_module*m) { pa_thread_mq_init(&u->thread_mq, m->core->mainloop); u->rtpoll = pa_rtpoll_new(); pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); - + u->filename = pa_xstrdup(pa_modargs_get_value(ma, "file", DEFAULT_FILE_NAME)); mkfifo(u->filename, 0666); @@ -257,7 +258,7 @@ int pa__init(pa_module*m) { u->sink->parent.process_msg = sink_process_msg; u->sink->userdata = u; u->sink->flags = PA_SINK_LATENCY; - + pa_sink_set_module(u->sink, m); pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); pa_sink_set_rtpoll(u->sink, u->rtpoll); @@ -291,7 +292,7 @@ fail: void pa__done(pa_module*m) { struct userdata *u; - + pa_assert(m); if (!(u = m->userdata)) @@ -306,7 +307,7 @@ void pa__done(pa_module*m) { } pa_thread_mq_done(&u->thread_mq); - + if (u->sink) pa_sink_unref(u->sink); @@ -315,7 +316,7 @@ void pa__done(pa_module*m) { if (u->rtpoll_item) pa_rtpoll_item_free(u->rtpoll_item); - + if (u->rtpoll) pa_rtpoll_free(u->rtpoll); -- cgit From b0bce200f2484cd0082a081724479627377db5d0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 7 Oct 2007 13:57:35 +0000 Subject: add missing poll.h inclusion git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1939 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/tests/rtpoll-test.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/tests/rtpoll-test.c b/src/tests/rtpoll-test.c index bad8e7d7..3ab992a1 100644 --- a/src/tests/rtpoll-test.c +++ b/src/tests/rtpoll-test.c @@ -24,6 +24,7 @@ #endif #include +#include #include #include @@ -49,7 +50,7 @@ int main(int argc, char *argv[]) { struct pollfd *pollfd; pa_rtsig_configure(SIGRTMIN+10, SIGRTMAX); - + p = pa_rtpoll_new(); i = pa_rtpoll_item_new(p, PA_RTPOLL_EARLY, 1); @@ -62,14 +63,14 @@ int main(int argc, char *argv[]) { w = pa_rtpoll_item_new(p, PA_RTPOLL_NORMAL, 0); pa_rtpoll_item_set_before_callback(w, worker); - + pa_rtpoll_install(p); pa_rtpoll_set_timer_periodic(p, 10000000); /* 10 s */ pa_rtpoll_run(p, 1); - + pa_rtpoll_item_free(i); - + i = pa_rtpoll_item_new(p, PA_RTPOLL_EARLY, 1); pa_rtpoll_item_set_before_callback(i, before); pa_rtpoll_item_set_after_callback(i, after); @@ -77,13 +78,13 @@ int main(int argc, char *argv[]) { pollfd = pa_rtpoll_item_get_pollfd(i, NULL); pollfd->fd = 0; pollfd->events = POLLIN; - + pa_rtpoll_run(p, 1); pa_rtpoll_item_free(i); pa_rtpoll_item_free(w); - + pa_rtpoll_free(p); return 0; -- cgit From 2385efef61043ceef4a9a4d83a71c2d95af2d3e4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 15 Oct 2007 14:38:16 +0000 Subject: fix url git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1940 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index cf9069a1..f9fd12ca 100644 --- a/configure.ac +++ b/configure.ac @@ -34,7 +34,7 @@ AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE([foreign -Wall]) AC_SUBST(PA_MAJORMINOR, "PA_MAJOR.PA_MINOR") -AC_SUBST(PACKAGE_URL, [http://0pointer.de/lennart/projects/pulseaudio/]) +AC_SUBST(PACKAGE_URL, [http://pulseaudio.org/]) AC_SUBST(PA_API_VERSION, 10) AC_SUBST(PA_PROTOCOL_VERSION, 11) -- cgit From 190081782c4f3a45b641d2dcda2337a396677684 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 17 Oct 2007 16:54:46 +0000 Subject: Properly handle if ALSA sends us an POLLERR event, this should allow us to survive a system suspend cycle better git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1941 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/alsa-util.c | 16 ++++++++-------- src/modules/module-alsa-sink.c | 30 +++++++++++++++++++++++++++++- src/modules/module-alsa-source.c | 30 +++++++++++++++++++++++++++++- 3 files changed, 66 insertions(+), 10 deletions(-) diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c index ee2dfdb8..9ea5ad12 100644 --- a/src/modules/alsa-util.c +++ b/src/modules/alsa-util.c @@ -56,7 +56,7 @@ struct pa_alsa_fdlist { }; static void io_cb(pa_mainloop_api*a, pa_io_event* e, PA_GCC_UNUSED int fd, pa_io_event_flags_t events, void *userdata) { - + struct pa_alsa_fdlist *fdl = userdata; int err, i; unsigned short revents; @@ -139,7 +139,7 @@ static void defer_cb(pa_mainloop_api*a, PA_GCC_UNUSED pa_defer_event* e, void *u if (fdl->ios) { for (i = 0; i < fdl->num_fds; i++) a->io_free(fdl->ios[i]); - + if (num_fds != fdl->num_fds) { pa_xfree(fdl->ios); fdl->ios = NULL; @@ -290,7 +290,7 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *p pa_assert(period_size); snd_pcm_hw_params_alloca(&hwparams); - + buffer_size = *periods * *period_size; if ((ret = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0 || @@ -302,11 +302,11 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *p if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) goto finish; - } else if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) + } else if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) goto finish; else if (*use_mmap) *use_mmap = 0; - + if ((ret = set_format(pcm_handle, hwparams, &f)) < 0) goto finish; @@ -363,7 +363,7 @@ finish: int pa_alsa_set_sw_params(snd_pcm_t *pcm) { snd_pcm_sw_params_t *swparams; int err; - + pa_assert(pcm); snd_pcm_sw_params_alloca(&swparams); @@ -382,7 +382,7 @@ int pa_alsa_set_sw_params(snd_pcm_t *pcm) { pa_log_warn("Unable to set start threshold: %s\n", snd_strerror(err)); return err; } - + if ((err = snd_pcm_sw_params(pcm, swparams)) < 0) { pa_log_warn("Unable to set sw params: %s\n", snd_strerror(err)); return err; @@ -418,7 +418,7 @@ int pa_alsa_prepare_mixer(snd_mixer_t *mixer, const char *dev) { snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name, const char *fallback) { snd_mixer_elem_t *elem; snd_mixer_selem_id_t *sid = NULL; - + snd_mixer_selem_id_alloca(&sid); pa_assert(mixer); diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index bb78bca2..a09247fe 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -654,6 +654,7 @@ static void thread_func(void *userdata) { } if (revents & (POLLERR|POLLNVAL|POLLHUP)) { + if (revents & POLLERR) pa_log_warn("Got POLLERR from ALSA"); if (revents & POLLNVAL) @@ -661,7 +662,34 @@ static void thread_func(void *userdata) { if (revents & POLLHUP) pa_log_warn("Got POLLHUP from ALSA"); - goto fail; + /* Try to recover from this error */ + + switch (snd_pcm_state(u->pcm_handle)) { + + case SND_PCM_STATE_XRUN: + if ((err = snd_pcm_recover(u->pcm_handle, -EPIPE, 1)) != 0) { + pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP and XRUN: %s", snd_strerror(err)); + goto fail; + } + break; + + case SND_PCM_STATE_SUSPENDED: + if ((err = snd_pcm_recover(u->pcm_handle, -ESTRPIPE, 1)) != 0) { + pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP and SUSPENDED: %s", snd_strerror(err)); + goto fail; + } + break; + + default: + + snd_pcm_drop(u->pcm_handle); + + if ((err = snd_pcm_prepare(u->pcm_handle)) < 0) { + pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP with snd_pcm_prepare(): %s", snd_strerror(err)); + goto fail; + } + break; + } } } } diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 0f19a4ae..d840cac3 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -636,6 +636,7 @@ static void thread_func(void *userdata) { } if (revents & (POLLERR|POLLNVAL|POLLHUP)) { + if (revents & POLLERR) pa_log_warn("Got POLLERR from ALSA"); if (revents & POLLNVAL) @@ -643,7 +644,34 @@ static void thread_func(void *userdata) { if (revents & POLLHUP) pa_log_warn("Got POLLHUP from ALSA"); - goto fail; + /* Try to recover from this error */ + + switch (snd_pcm_state(u->pcm_handle)) { + + case SND_PCM_STATE_XRUN: + if ((err = snd_pcm_recover(u->pcm_handle, -EPIPE, 1)) != 0) { + pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP and XRUN: %s", snd_strerror(err)); + goto fail; + } + break; + + case SND_PCM_STATE_SUSPENDED: + if ((err = snd_pcm_recover(u->pcm_handle, -ESTRPIPE, 1)) != 0) { + pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP and SUSPENDED: %s", snd_strerror(err)); + goto fail; + } + break; + + default: + + snd_pcm_drop(u->pcm_handle); + + if ((err = snd_pcm_prepare(u->pcm_handle)) < 0) { + pa_log_warn("Could not recover from POLLERR|POLLNVAL|POLLHUP with snd_pcm_prepare(): %s", snd_strerror(err)); + goto fail; + } + break; + } } } } -- cgit From 925eadd9e209da3bfcfef5d06ae324fa4966ecb5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Oct 2007 21:48:16 +0000 Subject: add interleaving/deinterleaving APIs git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1942 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/sample-util.c | 57 +++++++++++++++++++++++++++++++++++++++++++++ src/pulsecore/sample-util.h | 3 +++ 2 files changed, 60 insertions(+) diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c index 56d89c8c..21771302 100644 --- a/src/pulsecore/sample-util.c +++ b/src/pulsecore/sample-util.c @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -485,3 +486,59 @@ int pa_frame_aligned(size_t l, const pa_sample_spec *ss) { return l % fs == 0; } + +void pa_interleave(const void *src[], unsigned channels, void *dst, size_t ss, unsigned n) { + unsigned c; + size_t fs; + + pa_assert(src); + pa_assert(channels > 0); + pa_assert(dst); + pa_assert(ss > 0); + pa_assert(n > 0); + + fs = ss * channels; + + for (c = 0; c < channels; c++) { + unsigned j; + void *d; + const void *s; + + s = src[c]; + d = (uint8_t*) dst + c * ss; + + for (j = 0; j < n; j ++) { + oil_memcpy(d, s, ss); + s = (uint8_t*) s + ss; + d = (uint8_t*) d + fs; + } + } +} + +void pa_deinterleave(const void *src, void *dst[], unsigned channels, size_t ss, unsigned n) { + size_t fs; + unsigned c; + + pa_assert(src); + pa_assert(dst); + pa_assert(channels > 0); + pa_assert(ss > 0); + pa_assert(n > 0); + + fs = ss * channels; + + for (c = 0; c < channels; c++) { + unsigned j; + const void *s; + void *d; + + s = (uint8_t*) src + c * ss; + d = dst[c]; + + for (j = 0; j < n; j ++) { + oil_memcpy(d, s, ss); + s = (uint8_t*) s + fs; + d = (uint8_t*) d + ss; + } + } +} diff --git a/src/pulsecore/sample-util.h b/src/pulsecore/sample-util.h index 92c6e9ff..0a39d5ca 100644 --- a/src/pulsecore/sample-util.h +++ b/src/pulsecore/sample-util.h @@ -60,4 +60,7 @@ size_t pa_frame_align(size_t l, const pa_sample_spec *ss) PA_GCC_PURE; int pa_frame_aligned(size_t l, const pa_sample_spec *ss) PA_GCC_PURE; +void pa_interleave(const void *src[], unsigned channels, void *dst, size_t ss, unsigned n); +void pa_deinterleave(const void *src, void *dst[], unsigned channels, size_t ss, unsigned n); + #endif -- cgit From 402950429bcafdc098309c8cb6e7dd6f5f37f650 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Oct 2007 21:48:34 +0000 Subject: minor fixup git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1943 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-pipe-sink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c index 41509f4f..75748474 100644 --- a/src/modules/module-pipe-sink.c +++ b/src/modules/module-pipe-sink.c @@ -174,7 +174,7 @@ static void thread_func(void *userdata) { /* Hmm, nothing to do. Let's sleep */ pollfd->events = u->sink->thread_info.state == PA_SINK_RUNNING ? POLLOUT : 0; - if ((ret = pa_rtpoll_run(u->rtpoll, 1)) < 0) + if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0) goto fail; if (ret == 0) -- cgit From 468c13e672604fcbc33c24e9e1d0c9d9169ba1a4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Oct 2007 21:48:55 +0000 Subject: Port JACK sink module over from old core git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1944 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-jack-sink.c | 348 +++++++++++++++++++++++------------------ 1 file changed, 196 insertions(+), 152 deletions(-) diff --git a/src/modules/module-jack-sink.c b/src/modules/module-jack-sink.c index 1092aed8..b0cc4b10 100644 --- a/src/modules/module-jack-sink.c +++ b/src/modules/module-jack-sink.c @@ -34,25 +34,39 @@ #include #include #include -#include #include #include #include -#include #include #include #include #include #include -#include +#include +#include +#include +#include #include "module-jack-sink-symdef.h" +/* General overview: + * + * Because JACK has a very unflexible event loop management, which + * doesn't allow us to add our own event sources to the event thread + * we cannot use the JACK real-time thread for dispatching our PA + * work. Instead, we run an additional RT thread which does most of + * the PA handling, and have the JACK RT thread request data from it + * via pa_asyncmsgq. The cost is an additional context switch which + * should hopefully not be that expensive if RT scheduling is + * enabled. A better fix would only be possible with additional event + * source support in JACK. + */ + PA_MODULE_AUTHOR("Lennart Poettering") -PA_MODULE_DESCRIPTION("Jack Sink") +PA_MODULE_DESCRIPTION("JACK Sink") PA_MODULE_VERSION(PACKAGE_VERSION) PA_MODULE_USAGE( "sink_name= " @@ -67,7 +81,6 @@ PA_MODULE_USAGE( struct userdata { pa_core *core; pa_module *module; - pa_sink *sink; unsigned channels; @@ -75,19 +88,18 @@ struct userdata { jack_port_t* port[PA_CHANNELS_MAX]; jack_client_t *client; - pthread_mutex_t mutex; - pthread_cond_t cond; + void *buffer[PA_CHANNELS_MAX]; - void * buffer[PA_CHANNELS_MAX]; - jack_nframes_t frames_requested; - int quit_requested; + pa_thread_mq thread_mq; + pa_asyncmsgq *jack_msgq; + pa_rtpoll *rtpoll; + pa_rtpoll_item *rtpoll_item; - int pipe_fd_type; - int pipe_fds[2]; - pa_io_event *io_event; + pa_thread *thread; jack_nframes_t frames_in_buffer; - jack_nframes_t timestamp; + jack_nframes_t saved_frame_time; + pa_bool_t saved_frame_time_valid; }; static const char* const valid_modargs[] = { @@ -100,146 +112,160 @@ static const char* const valid_modargs[] = { NULL }; -static void stop_sink(struct userdata *u) { - assert (u); - - jack_client_close(u->client); - u->client = NULL; - u->core->mainloop->io_free(u->io_event); - u->io_event = NULL; - pa_sink_disconnect(u->sink); - pa_sink_unref(u->sink); - u->sink = NULL; - pa_module_unload_request(u->module); -} +enum { + SINK_MESSAGE_RENDER = PA_SINK_MESSAGE_MAX, + SINK_MESSAGE_ON_SHUTDOWN +}; -static void io_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event_flags_t flags, void *userdata) { - struct userdata *u = userdata; - char x; +static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *memchunk) { + struct userdata *u = PA_SINK(o)->userdata; - assert(m); - assert(e); - assert(flags == PA_IO_EVENT_INPUT); - assert(u); - assert(u->pipe_fds[0] == fd); + switch (code) { - pa_read(fd, &x, 1, &u->pipe_fd_type); + case SINK_MESSAGE_RENDER: - if (u->quit_requested) { - stop_sink(u); - u->quit_requested = 0; - return; - } + /* Handle the request from the JACK thread */ - pthread_mutex_lock(&u->mutex); + if (u->sink->thread_info.state == PA_SINK_RUNNING) { + pa_memchunk chunk; + size_t nbytes; + void *p; - if (u->frames_requested > 0) { - unsigned fs; - jack_nframes_t frame_idx; - pa_memchunk chunk; - void *p; + pa_assert(offset > 0); + nbytes = offset * pa_frame_size(&u->sink->sample_spec); - fs = pa_frame_size(&u->sink->sample_spec); + pa_sink_render_full(u->sink, nbytes, &chunk); - pa_sink_render_full(u->sink, u->frames_requested * fs, &chunk); - p = pa_memblock_acquire(chunk.memblock); + p = (uint8_t*) pa_memblock_acquire(chunk.memblock) + chunk.index; + pa_deinterleave(p, u->buffer, u->channels, sizeof(float), offset); + pa_memblock_release(chunk.memblock); - for (frame_idx = 0; frame_idx < u->frames_requested; frame_idx ++) { - unsigned c; + pa_memblock_unref(chunk.memblock); + } else { + unsigned c; + pa_sample_spec ss; - for (c = 0; c < u->channels; c++) { - float *s = ((float*) ((uint8_t*) p + chunk.index)) + (frame_idx * u->channels) + c; - float *d = ((float*) u->buffer[c]) + frame_idx; + /* Humm, we're not RUNNING, hence let's write some silence */ - *d = *s; + ss = u->sink->sample_spec; + ss.channels = 1; + + for (c = 0; c < u->channels; c++) + pa_silence_memory(u->buffer[c], offset * pa_sample_size(&ss), &ss); } - } - pa_memblock_release(chunk.memblock); - pa_memblock_unref(chunk.memblock); + u->frames_in_buffer = offset; + u->saved_frame_time = * (jack_nframes_t*) data; + u->saved_frame_time_valid = TRUE; - u->frames_requested = 0; + return 0; - pthread_cond_signal(&u->cond); - } + case SINK_MESSAGE_ON_SHUTDOWN: + pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); + return 0; - pthread_mutex_unlock(&u->mutex); -} + case PA_SINK_MESSAGE_GET_LATENCY: { + jack_nframes_t l, ft, d; + size_t n; -static void request_render(struct userdata *u) { - char c = 'x'; - assert(u); + /* This is the "worst-case" latency */ + l = jack_port_get_total_latency(u->client, u->port[0]) + u->frames_in_buffer; - assert(u->pipe_fds[1] >= 0); - pa_write(u->pipe_fds[1], &c, 1, &u->pipe_fd_type); -} + if (u->saved_frame_time_valid) { + /* Adjust the worst case latency by the time that + * passed since we last handed data to JACK */ -static void jack_shutdown(void *arg) { - struct userdata *u = arg; - assert(u); + ft = jack_frame_time(u->client); + d = ft > u->saved_frame_time ? ft - u->saved_frame_time : 0; + l = l > d ? l - d : 0; + } - u->quit_requested = 1; - request_render(u); + /* Convert it to usec */ + n = l * pa_frame_size(&u->sink->sample_spec); + *((pa_usec_t*) data) = pa_bytes_to_usec(n, &u->sink->sample_spec); + + return 0; + } + } + + return pa_sink_process_msg(o, code, data, offset, memchunk); } static int jack_process(jack_nframes_t nframes, void *arg) { struct userdata *u = arg; - assert(u); + unsigned c; + jack_nframes_t frame_time; + pa_assert(u); - if (jack_transport_query(u->client, NULL) == JackTransportRolling) { - unsigned c; + /* We just forward the request to our other RT thread */ - pthread_mutex_lock(&u->mutex); + for (c = 0; c < u->channels; c++) + pa_assert_se(u->buffer[c] = jack_port_get_buffer(u->port[c], nframes)); - u->frames_requested = nframes; + frame_time = jack_frame_time(u->client); - for (c = 0; c < u->channels; c++) { - u->buffer[c] = jack_port_get_buffer(u->port[c], nframes); - assert(u->buffer[c]); - } + pa_assert_se(pa_asyncmsgq_send(u->jack_msgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_RENDER, &frame_time, nframes, NULL) == 0); + return 0; +} - request_render(u); +static void thread_func(void *userdata) { + struct userdata *u = userdata; - pthread_cond_wait(&u->cond, &u->mutex); + pa_assert(u); - u->frames_in_buffer = nframes; - u->timestamp = jack_get_current_transport_frame(u->client); + pa_log_debug("Thread starting up"); - pthread_mutex_unlock(&u->mutex); - } + if (u->core->high_priority) + pa_make_realtime(); - return 0; -} + pa_thread_mq_install(&u->thread_mq); + pa_rtpoll_install(u->rtpoll); -static pa_usec_t sink_get_latency_cb(pa_sink *s) { - struct userdata *u; - jack_nframes_t n, l, d; + for (;;) { + int ret; - assert(s); - u = s->userdata; + if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0) + goto fail; - if (jack_transport_query(u->client, NULL) != JackTransportRolling) - return 0; + if (ret == 0) + goto finish; + } - n = jack_get_current_transport_frame(u->client); +fail: + /* If this was no regular exit from the loop we have to continue + * processing messages until we received PA_MESSAGE_SHUTDOWN */ + pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); + pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); + +finish: + pa_log_debug("Thread shutting down"); +} - if (n < u->timestamp) - return 0; +static void jack_error_func(const char*t) { + char *s; - d = n - u->timestamp; - l = jack_port_get_total_latency(u->client, u->port[0]) + u->frames_in_buffer; + s = pa_xstrndup(s, strcspn(s, "\n\r")); + pa_log_warn("JACK error >%s<", s); + pa_xfree(s); +} + +static void jack_init(void *arg) { + struct userdata *u = arg; - if (d >= l) - return 0; + pa_log_info("JACK thread starting up."); - return pa_bytes_to_usec((l - d) * pa_frame_size(&s->sample_spec), &s->sample_spec); + if (u->core->high_priority) + pa_make_realtime(); } -static void jack_error_func(const char*t) { - pa_log_warn("JACK error >%s<", t); +static void jack_shutdown(void* arg) { + struct userdata *u = arg; + + pa_log_info("JACK thread shutting down.."); + pa_asyncmsgq_post(u->jack_msgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_ON_SHUTDOWN, NULL, 0, NULL, NULL); } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { struct userdata *u = NULL; pa_sample_spec ss; pa_channel_map map; @@ -252,18 +278,17 @@ int pa__init(pa_core *c, pa_module*m) { const char **ports = NULL, **p; char *t; - assert(c); - assert(m); + pa_assert(m); jack_set_error_function(jack_error_func); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { - pa_log("failed to parse module arguments."); + pa_log("Failed to parse module arguments."); goto fail; } if (pa_modargs_get_value_boolean(ma, "connect", &do_connect) < 0) { - pa_log("failed to parse connect= argument."); + pa_log("Failed to parse connect= argument."); goto fail; } @@ -271,21 +296,23 @@ int pa__init(pa_core *c, pa_module*m) { client_name = pa_modargs_get_value(ma, "client_name", "PulseAudio"); u = pa_xnew0(struct userdata, 1); - m->userdata = u; - u->core = c; + u->core = m->core; u->module = m; - u->pipe_fds[0] = u->pipe_fds[1] = -1; - u->pipe_fd_type = 0; + m->userdata = u; + u->saved_frame_time_valid = FALSE; + pa_thread_mq_init(&u->thread_mq, m->core->mainloop); + u->rtpoll = pa_rtpoll_new(); + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); - pthread_mutex_init(&u->mutex, NULL); - pthread_cond_init(&u->cond, NULL); + /* The queue linking the JACK thread and our RT thread */ + u->jack_msgq = pa_asyncmsgq_new(0); - if (pipe(u->pipe_fds) < 0) { - pa_log("pipe() failed: %s", pa_cstrerror(errno)); - goto fail; - } - - pa_make_nonblock_fd(u->pipe_fds[1]); + /* The msgq from the JACK RT thread should have an even higher + * priority than the normal message queues, to match the guarantee + * all other drivers make: supplying the audio device with data is + * the top priority -- and as long as that is possible we don't do + * anything else */ + u->rtpoll_item = pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY-1, u->jack_msgq); if (!(u->client = jack_client_open(client_name, server_name ? JackServerName : JackNullOption, &status, server_name))) { pa_log("jack_client_open() failed."); @@ -299,16 +326,16 @@ int pa__init(pa_core *c, pa_module*m) { channels++; if (!channels) - channels = c->default_sample_spec.channels; + channels = m->core->default_sample_spec.channels; if (pa_modargs_get_value_u32(ma, "channels", &channels) < 0 || channels <= 0 || channels >= PA_CHANNELS_MAX) { - pa_log("failed to parse channels= argument."); + pa_log("Failed to parse channels= argument."); goto fail; } pa_channel_map_init_auto(&map, channels, PA_CHANNEL_MAP_ALSA); - if (pa_modargs_get_channel_map(ma, &map) < 0 || map.channels != channels) { - pa_log("failed to parse channel_map= argument."); + if (pa_modargs_get_channel_map(ma, NULL, &map) < 0 || map.channels != channels) { + pa_log("Failed to parse channel_map= argument."); goto fail; } @@ -318,7 +345,7 @@ int pa__init(pa_core *c, pa_module*m) { ss.rate = jack_get_sample_rate(u->client); ss.format = PA_SAMPLE_FLOAT32NE; - assert(pa_sample_spec_valid(&ss)); + pa_assert(pa_sample_spec_valid(&ss)); for (i = 0; i < ss.channels; i++) { if (!(u->port[i] = jack_port_register(u->client, pa_channel_position_to_string(map.map[i]), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput|JackPortIsTerminal, 0))) { @@ -327,19 +354,29 @@ int pa__init(pa_core *c, pa_module*m) { } } - if (!(u->sink = pa_sink_new(c, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map))) { + if (!(u->sink = pa_sink_new(m->core, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map))) { pa_log("failed to create sink."); goto fail; } + u->sink->parent.process_msg = sink_process_msg; u->sink->userdata = u; - pa_sink_set_owner(u->sink, m); + u->sink->flags = PA_SINK_LATENCY; + + pa_sink_set_module(u->sink, m); + pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); + pa_sink_set_rtpoll(u->sink, u->rtpoll); pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Jack sink (%s)", jack_get_client_name(u->client))); pa_xfree(t); - u->sink->get_latency = sink_get_latency_cb; jack_set_process_callback(u->client, jack_process, u); jack_on_shutdown(u->client, jack_shutdown, u); + jack_set_thread_init_callback(u->client, jack_init, u); + + if (!(u->thread = pa_thread_new(thread_func, u))) { + pa_log("Failed to create thread."); + goto fail; + } if (jack_activate(u->client)) { pa_log("jack_activate() failed"); @@ -350,21 +387,20 @@ int pa__init(pa_core *c, pa_module*m) { for (i = 0, p = ports; i < ss.channels; i++, p++) { if (!*p) { - pa_log("not enough physical output ports, leaving unconnected."); + pa_log("Not enough physical output ports, leaving unconnected."); break; } - pa_log_info("connecting %s to %s", jack_port_name(u->port[i]), *p); + pa_log_info("Connecting %s to %s", jack_port_name(u->port[i]), *p); if (jack_connect(u->client, jack_port_name(u->port[i]), *p)) { - pa_log("failed to connect %s to %s, leaving unconnected.", jack_port_name(u->port[i]), *p); + pa_log("Failed to connect %s to %s, leaving unconnected.", jack_port_name(u->port[i]), *p); break; } } - } - u->io_event = c->mainloop->io_new(c->mainloop, u->pipe_fds[0], PA_IO_EVENT_INPUT, io_event_cb, u); + pa_sink_put(u->sink); free(ports); pa_modargs_free(ma); @@ -377,14 +413,15 @@ fail: free(ports); - pa__done(c, m); + pa__done(m); return -1; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - assert(c && m); + + pa_assert(m); if (!(u = m->userdata)) return; @@ -392,20 +429,27 @@ void pa__done(pa_core *c, pa_module*m) { if (u->client) jack_client_close(u->client); - if (u->io_event) - c->mainloop->io_free(u->io_event); + if (u->sink) + pa_sink_unlink(u->sink); - if (u->sink) { - pa_sink_disconnect(u->sink); - pa_sink_unref(u->sink); + if (u->thread) { + pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); + pa_thread_free(u->thread); } - if (u->pipe_fds[0] >= 0) - close(u->pipe_fds[0]); - if (u->pipe_fds[1] >= 0) - close(u->pipe_fds[1]); + pa_thread_mq_done(&u->thread_mq); + + if (u->sink) + pa_sink_unref(u->sink); + + if (u->rtpoll_item) + pa_rtpoll_item_free(u->rtpoll_item); + + if (u->jack_msgq) + pa_asyncmsgq_unref(u->jack_msgq); + + if (u->rtpoll) + pa_rtpoll_free(u->rtpoll); - pthread_mutex_destroy(&u->mutex); - pthread_cond_destroy(&u->cond); pa_xfree(u); } -- cgit From 02adb5f32ef2fc29c1e123a82dbbe0816926b095 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Oct 2007 21:49:14 +0000 Subject: enable jack sink in Makefile git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1945 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index ad7b6520..c7bc66ee 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1025,11 +1025,11 @@ modlibexec_LTLIBRARIES += \ module-mmkbd-evdev.la endif -#if HAVE_JACK -#modlibexec_LTLIBRARIES += \ -# module-jack-sink.la \ +if HAVE_JACK +modlibexec_LTLIBRARIES += \ + module-jack-sink.la # module-jack-source.la -#endif +endif if HAVE_GCONF modlibexec_LTLIBRARIES += \ @@ -1360,15 +1360,15 @@ module_rtp_recv_la_CFLAGS = $(AM_CFLAGS) # JACK -#module_jack_sink_la_SOURCES = modules/module-jack-sink.c -#module_jack_sink_la_LDFLAGS = -module -avoid-version -#module_jack_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la $(JACK_LIBS) -#module_jack_sink_la_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS) +module_jack_sink_la_SOURCES = modules/module-jack-sink.c +module_jack_sink_la_LDFLAGS = -module -avoid-version +module_jack_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la $(JACK_LIBS) +module_jack_sink_la_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS) -#module_jack_source_la_SOURCES = modules/module-jack-source.c -#module_jack_source_la_LDFLAGS = -module -avoid-version -#module_jack_source_la_LIBADD = $(AM_LIBADD) libpulsecore.la $(JACK_LIBS) -#module_jack_source_la_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS) +module_jack_source_la_SOURCES = modules/module-jack-source.c +module_jack_source_la_LDFLAGS = -module -avoid-version +module_jack_source_la_LIBADD = $(AM_LIBADD) libpulsecore.la $(JACK_LIBS) +module_jack_source_la_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS) # HAL libdbus_util_la_SOURCES = modules/dbus-util.c modules/dbus-util.h -- cgit From 498a156a8d73b23aaab21d9639c2238dedfbd3eb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 22 Oct 2007 22:39:51 +0000 Subject: also port over JACK source to new core git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1946 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 4 +- src/modules/module-jack-sink.c | 2 +- src/modules/module-jack-source.c | 312 ++++++++++++++++++++------------------- 3 files changed, 166 insertions(+), 152 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index c7bc66ee..fcfee4f9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1027,8 +1027,8 @@ endif if HAVE_JACK modlibexec_LTLIBRARIES += \ - module-jack-sink.la -# module-jack-source.la + module-jack-sink.la \ + module-jack-source.la endif if HAVE_GCONF diff --git a/src/modules/module-jack-sink.c b/src/modules/module-jack-sink.c index b0cc4b10..49943fa4 100644 --- a/src/modules/module-jack-sink.c +++ b/src/modules/module-jack-sink.c @@ -293,7 +293,7 @@ int pa__init(pa_module*m) { } server_name = pa_modargs_get_value(ma, "server_name", NULL); - client_name = pa_modargs_get_value(ma, "client_name", "PulseAudio"); + client_name = pa_modargs_get_value(ma, "client_name", "PulseAudio JACK Sink"); u = pa_xnew0(struct userdata, 1); u->core = m->core; diff --git a/src/modules/module-jack-source.c b/src/modules/module-jack-source.c index e19b2181..d0124cff 100644 --- a/src/modules/module-jack-source.c +++ b/src/modules/module-jack-source.c @@ -34,25 +34,29 @@ #include #include #include -#include #include #include #include -#include #include #include #include #include #include -#include +#include +#include +#include +#include #include "module-jack-source-symdef.h" +/* See module-jack-sink for a few comments how this module basically + * works */ + PA_MODULE_AUTHOR("Lennart Poettering") -PA_MODULE_DESCRIPTION("Jack Source") +PA_MODULE_DESCRIPTION("JACK Source") PA_MODULE_VERSION(PACKAGE_VERSION) PA_MODULE_USAGE( "source_name= " @@ -67,7 +71,6 @@ PA_MODULE_USAGE( struct userdata { pa_core *core; pa_module *module; - pa_source *source; unsigned channels; @@ -75,19 +78,15 @@ struct userdata { jack_port_t* port[PA_CHANNELS_MAX]; jack_client_t *client; - pthread_mutex_t mutex; - pthread_cond_t cond; + pa_thread_mq thread_mq; + pa_asyncmsgq *jack_msgq; + pa_rtpoll *rtpoll; + pa_rtpoll_item *rtpoll_item; - void * buffer[PA_CHANNELS_MAX]; - jack_nframes_t frames_posted; - int quit_requested; + pa_thread *thread; - int pipe_fds[2]; - int pipe_fd_type; - pa_io_event *io_event; - - jack_nframes_t frames_in_buffer; - jack_nframes_t timestamp; + jack_nframes_t saved_frame_time; + pa_bool_t saved_frame_time_valid; }; static const char* const valid_modargs[] = { @@ -100,146 +99,150 @@ static const char* const valid_modargs[] = { NULL }; -static void stop_source(struct userdata *u) { - assert (u); - - jack_client_close(u->client); - u->client = NULL; - u->core->mainloop->io_free(u->io_event); - u->io_event = NULL; - pa_source_disconnect(u->source); - pa_source_unref(u->source); - u->source = NULL; - pa_module_unload_request(u->module); -} +enum { + SOURCE_MESSAGE_POST = PA_SOURCE_MESSAGE_MAX, + SOURCE_MESSAGE_ON_SHUTDOWN +}; -static void io_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event_flags_t flags, void *userdata) { - struct userdata *u = userdata; - char x; +static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { + struct userdata *u = PA_SOURCE(o)->userdata; - assert(m); - assert(flags == PA_IO_EVENT_INPUT); - assert(u); - assert(u->pipe_fds[0] == fd); + switch (code) { - pa_read(fd, &x, 1, &u->pipe_fd_type); + case SOURCE_MESSAGE_POST: - if (u->quit_requested) { - stop_source(u); - u->quit_requested = 0; - return; - } + /* Handle the new block from the JACK thread */ + pa_assert(chunk); + pa_assert(chunk->length > 0); - pthread_mutex_lock(&u->mutex); + if (u->source->thread_info.state == PA_SOURCE_RUNNING) + pa_source_post(u->source, chunk); - if (u->frames_posted > 0) { - unsigned fs; - jack_nframes_t frame_idx; - pa_memchunk chunk; - void *p; + u->saved_frame_time = offset; + u->saved_frame_time_valid = TRUE; - fs = pa_frame_size(&u->source->sample_spec); + return 0; - chunk.memblock = pa_memblock_new(u->core->mempool, chunk.length = u->frames_posted * fs); - chunk.index = 0; + case SOURCE_MESSAGE_ON_SHUTDOWN: + pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); + return 0; - p = pa_memblock_acquire(chunk.memblock); + case PA_SOURCE_MESSAGE_GET_LATENCY: { + jack_nframes_t l, ft, d; + size_t n; - for (frame_idx = 0; frame_idx < u->frames_posted; frame_idx ++) { - unsigned c; + /* This is the "worst-case" latency */ + l = jack_port_get_total_latency(u->client, u->port[0]); - for (c = 0; c < u->channels; c++) { - float *s = ((float*) u->buffer[c]) + frame_idx; - float *d = ((float*) ((uint8_t*) p + chunk.index)) + (frame_idx * u->channels) + c; + if (u->saved_frame_time_valid) { + /* Adjust the worst case latency by the time that + * passed since we last handed data to JACK */ - *d = *s; + ft = jack_frame_time(u->client); + d = ft > u->saved_frame_time ? ft - u->saved_frame_time : 0; + l += d; } + + /* Convert it to usec */ + n = l * pa_frame_size(&u->source->sample_spec); + *((pa_usec_t*) data) = pa_bytes_to_usec(n, &u->source->sample_spec); + + return 0; } + } + + return pa_source_process_msg(o, code, data, offset, chunk); +} - pa_memblock_release(chunk.memblock); +static int jack_process(jack_nframes_t nframes, void *arg) { + unsigned c; + struct userdata *u = arg; + const void *buffer[PA_CHANNELS_MAX]; + void *p; + jack_nframes_t frame_time; + pa_memchunk chunk; - pa_source_post(u->source, &chunk); - pa_memblock_unref(chunk.memblock); + pa_assert(u); - u->frames_posted = 0; + for (c = 0; c < u->channels; c++) + pa_assert(buffer[c] = jack_port_get_buffer(u->port[c], nframes)); - pthread_cond_signal(&u->cond); - } + /* We interleave the data and pass it on to the other RT thread */ - pthread_mutex_unlock(&u->mutex); -} + pa_memchunk_reset(&chunk); + chunk.length = nframes * pa_frame_size(&u->source->sample_spec); + chunk.memblock = pa_memblock_new(u->core->mempool, chunk.length); + p = pa_memblock_acquire(chunk.memblock); + pa_interleave(buffer, u->channels, p, sizeof(float), nframes); + pa_memblock_release(chunk.memblock); -static void request_post(struct userdata *u) { - char c = 'x'; - assert(u); + frame_time = jack_frame_time(u->client); - assert(u->pipe_fds[1] >= 0); - pa_write(u->pipe_fds[1], &c, 1, &u->pipe_fd_type); -} + pa_asyncmsgq_post(u->jack_msgq, PA_MSGOBJECT(u->source), SOURCE_MESSAGE_POST, NULL, frame_time, &chunk, NULL); -static void jack_shutdown(void *arg) { - struct userdata *u = arg; - assert(u); + pa_memblock_unref(chunk.memblock); - u->quit_requested = 1; - request_post(u); + return 0; } -static int jack_process(jack_nframes_t nframes, void *arg) { - struct userdata *u = arg; - assert(u); +static void thread_func(void *userdata) { + struct userdata *u = userdata; - if (jack_transport_query(u->client, NULL) == JackTransportRolling) { - unsigned c; + pa_assert(u); - pthread_mutex_lock(&u->mutex); + pa_log_debug("Thread starting up"); - u->frames_posted = nframes; + if (u->core->high_priority) + pa_make_realtime(); - for (c = 0; c < u->channels; c++) { - u->buffer[c] = jack_port_get_buffer(u->port[c], nframes); - assert(u->buffer[c]); - } + pa_thread_mq_install(&u->thread_mq); + pa_rtpoll_install(u->rtpoll); - request_post(u); + for (;;) { + int ret; - pthread_cond_wait(&u->cond, &u->mutex); - - u->frames_in_buffer = nframes; - u->timestamp = jack_get_current_transport_frame(u->client); + if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0) + goto fail; - pthread_mutex_unlock(&u->mutex); + if (ret == 0) + goto finish; } - return 0; -} - -static pa_usec_t source_get_latency_cb(pa_source *s) { - struct userdata *u; - jack_nframes_t n, l, d; +fail: + /* If this was no regular exit from the loop we have to continue + * processing messages until we received PA_MESSAGE_SHUTDOWN */ + pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); + pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); - assert(s); - u = s->userdata; +finish: + pa_log_debug("Thread shutting down"); +} - if (jack_transport_query(u->client, NULL) != JackTransportRolling) - return 0; +static void jack_error_func(const char*t) { + char *s; - n = jack_get_current_transport_frame(u->client); + s = pa_xstrndup(s, strcspn(s, "\n\r")); + pa_log_warn("JACK error >%s<", s); + pa_xfree(s); +} - if (n < u->timestamp) - return 0; +static void jack_init(void *arg) { + struct userdata *u = arg; - d = n - u->timestamp; - l = jack_port_get_total_latency(u->client, u->port[0]); + pa_log_info("JACK thread starting up."); - return pa_bytes_to_usec((l + d) * pa_frame_size(&s->sample_spec), &s->sample_spec); + if (u->core->high_priority) + pa_make_realtime(); } -static void jack_error_func(const char*t) { - pa_log_warn("JACK error >%s<", t); +static void jack_shutdown(void* arg) { + struct userdata *u = arg; + + pa_log_info("JACK thread shutting down.."); + pa_asyncmsgq_post(u->jack_msgq, PA_MSGOBJECT(u->source), SOURCE_MESSAGE_ON_SHUTDOWN, NULL, 0, NULL, NULL); } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { struct userdata *u = NULL; pa_sample_spec ss; pa_channel_map map; @@ -252,40 +255,34 @@ int pa__init(pa_core *c, pa_module*m) { const char **ports = NULL, **p; char *t; - assert(c); assert(m); jack_set_error_function(jack_error_func); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { - pa_log("failed to parse module arguments."); + pa_log("Failed to parse module arguments."); goto fail; } if (pa_modargs_get_value_boolean(ma, "connect", &do_connect) < 0) { - pa_log("failed to parse connect= argument."); + pa_log("Failed to parse connect= argument."); goto fail; } server_name = pa_modargs_get_value(ma, "server_name", NULL); - client_name = pa_modargs_get_value(ma, "client_name", "PulseAudio"); + client_name = pa_modargs_get_value(ma, "client_name", "PulseAudio JACK Source"); u = pa_xnew0(struct userdata, 1); - m->userdata = u; - u->core = c; + u->core = m->core; u->module = m; - u->pipe_fds[0] = u->pipe_fds[1] = -1; - u->pipe_fd_type = 0; - - pthread_mutex_init(&u->mutex, NULL); - pthread_cond_init(&u->cond, NULL); - - if (pipe(u->pipe_fds) < 0) { - pa_log("pipe() failed: %s", pa_cstrerror(errno)); - goto fail; - } + m->userdata = u; + u->saved_frame_time_valid = FALSE; + pa_thread_mq_init(&u->thread_mq, m->core->mainloop); + u->rtpoll = pa_rtpoll_new(); + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); - pa_make_nonblock_fd(u->pipe_fds[1]); + u->jack_msgq = pa_asyncmsgq_new(0); + u->rtpoll_item = pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY-1, u->jack_msgq); if (!(u->client = jack_client_open(client_name, server_name ? JackServerName : JackNullOption, &status, server_name))) { pa_log("jack_client_open() failed."); @@ -299,7 +296,7 @@ int pa__init(pa_core *c, pa_module*m) { channels++; if (!channels) - channels = c->default_sample_spec.channels; + channels = m->core->default_sample_spec.channels; if (pa_modargs_get_value_u32(ma, "channels", &channels) < 0 || channels <= 0 || channels >= PA_CHANNELS_MAX) { pa_log("failed to parse channels= argument."); @@ -307,7 +304,7 @@ int pa__init(pa_core *c, pa_module*m) { } pa_channel_map_init_auto(&map, channels, PA_CHANNEL_MAP_ALSA); - if (pa_modargs_get_channel_map(ma, &map) < 0 || map.channels != channels) { + if (pa_modargs_get_channel_map(ma, NULL, &map) < 0 || map.channels != channels) { pa_log("failed to parse channel_map= argument."); goto fail; } @@ -327,19 +324,29 @@ int pa__init(pa_core *c, pa_module*m) { } } - if (!(u->source = pa_source_new(c, __FILE__, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME), 0, &ss, &map))) { + if (!(u->source = pa_source_new(m->core, __FILE__, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME), 0, &ss, &map))) { pa_log("failed to create source."); goto fail; } + u->source->parent.process_msg = source_process_msg; u->source->userdata = u; - pa_source_set_owner(u->source, m); + u->source->flags = PA_SOURCE_LATENCY; + + pa_source_set_module(u->source, m); + pa_source_set_asyncmsgq(u->source, u->thread_mq.inq); + pa_source_set_rtpoll(u->source, u->rtpoll); pa_source_set_description(u->source, t = pa_sprintf_malloc("Jack source (%s)", jack_get_client_name(u->client))); pa_xfree(t); - u->source->get_latency = source_get_latency_cb; jack_set_process_callback(u->client, jack_process, u); jack_on_shutdown(u->client, jack_shutdown, u); + jack_set_thread_init_callback(u->client, jack_init, u); + + if (!(u->thread = pa_thread_new(thread_func, u))) { + pa_log("Failed to create thread."); + goto fail; + } if (jack_activate(u->client)) { pa_log("jack_activate() failed"); @@ -364,7 +371,7 @@ int pa__init(pa_core *c, pa_module*m) { } - u->io_event = c->mainloop->io_new(c->mainloop, u->pipe_fds[0], PA_IO_EVENT_INPUT, io_event_cb, u); + pa_source_put(u->source); free(ports); pa_modargs_free(ma); @@ -377,14 +384,14 @@ fail: free(ports); - pa__done(c, m); + pa__done(m); return -1; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - assert(c && m); + assert(m); if (!(u = m->userdata)) return; @@ -392,20 +399,27 @@ void pa__done(pa_core *c, pa_module*m) { if (u->client) jack_client_close(u->client); - if (u->io_event) - c->mainloop->io_free(u->io_event); + if (u->source) + pa_source_unlink(u->source); - if (u->source) { - pa_source_disconnect(u->source); - pa_source_unref(u->source); + if (u->thread) { + pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); + pa_thread_free(u->thread); } - if (u->pipe_fds[0] >= 0) - close(u->pipe_fds[0]); - if (u->pipe_fds[1] >= 0) - close(u->pipe_fds[1]); + pa_thread_mq_done(&u->thread_mq); + + if (u->source) + pa_source_unref(u->source); + + if (u->rtpoll_item) + pa_rtpoll_item_free(u->rtpoll_item); + + if (u->jack_msgq) + pa_asyncmsgq_unref(u->jack_msgq); + + if (u->rtpoll) + pa_rtpoll_free(u->rtpoll); - pthread_mutex_destroy(&u->mutex); - pthread_cond_destroy(&u->cond); pa_xfree(u); } -- cgit From 65b570cdaef65b978796e93062c307684a7a0af8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 23 Oct 2007 00:07:52 +0000 Subject: properly copy error string git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1947 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-jack-sink.c | 2 +- src/modules/module-jack-source.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/modules/module-jack-sink.c b/src/modules/module-jack-sink.c index 49943fa4..5019d656 100644 --- a/src/modules/module-jack-sink.c +++ b/src/modules/module-jack-sink.c @@ -244,7 +244,7 @@ finish: static void jack_error_func(const char*t) { char *s; - s = pa_xstrndup(s, strcspn(s, "\n\r")); + s = pa_xstrndup(t, strcspn(t, "\n\r")); pa_log_warn("JACK error >%s<", s); pa_xfree(s); } diff --git a/src/modules/module-jack-source.c b/src/modules/module-jack-source.c index d0124cff..b62ebe7a 100644 --- a/src/modules/module-jack-source.c +++ b/src/modules/module-jack-source.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -221,7 +220,7 @@ finish: static void jack_error_func(const char*t) { char *s; - s = pa_xstrndup(s, strcspn(s, "\n\r")); + s = pa_xstrndup(t, strcspn(t, "\n\r")); pa_log_warn("JACK error >%s<", s); pa_xfree(s); } @@ -255,7 +254,7 @@ int pa__init(pa_module*m) { const char **ports = NULL, **p; char *t; - assert(m); + pa_assert(m); jack_set_error_function(jack_error_func); @@ -277,6 +276,7 @@ int pa__init(pa_module*m) { u->module = m; m->userdata = u; u->saved_frame_time_valid = FALSE; + pa_thread_mq_init(&u->thread_mq, m->core->mainloop); u->rtpoll = pa_rtpoll_new(); pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); @@ -315,7 +315,7 @@ int pa__init(pa_module*m) { ss.rate = jack_get_sample_rate(u->client); ss.format = PA_SAMPLE_FLOAT32NE; - assert(pa_sample_spec_valid(&ss)); + pa_assert(pa_sample_spec_valid(&ss)); for (i = 0; i < ss.channels; i++) { if (!(u->port[i] = jack_port_register(u->client, pa_channel_position_to_string(map.map[i]), JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput|JackPortIsTerminal, 0))) { @@ -391,7 +391,7 @@ fail: void pa__done(pa_module*m) { struct userdata *u; - assert(m); + pa_assert(m); if (!(u = m->userdata)) return; -- cgit From 9464b9b45f4675bb668960734c335e4404d4d49e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 23 Oct 2007 22:50:39 +0000 Subject: add definition of PA_USEC_PER_MSEC git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1948 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/timeval.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pulse/timeval.h b/src/pulse/timeval.h index 60b9d085..a7d3ba33 100644 --- a/src/pulse/timeval.h +++ b/src/pulse/timeval.h @@ -36,6 +36,7 @@ PA_C_DECL_BEGIN #define PA_MSEC_PER_SEC 1000 #define PA_USEC_PER_SEC 1000000 #define PA_NSEC_PER_SEC 1000000000 +#define PA_USEC_PER_MSEC 1000 struct timeval; -- cgit From dc987e9df842732336c529201694f10054d401cb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 23 Oct 2007 22:55:56 +0000 Subject: add better time interpolator: use linear regression to determine gradient from measurements, predict a short distance ahead, and smoothen estimation function with 3rd degree spline interpolation. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1949 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 19 ++- src/pulsecore/time-smoother.c | 317 ++++++++++++++++++++++++++++++++++++++++++ src/pulsecore/time-smoother.h | 37 +++++ src/tests/smoother-test.c | 72 ++++++++++ 4 files changed, 439 insertions(+), 6 deletions(-) create mode 100644 src/pulsecore/time-smoother.c create mode 100644 src/pulsecore/time-smoother.h create mode 100644 src/tests/smoother-test.c diff --git a/src/Makefile.am b/src/Makefile.am index fcfee4f9..be55994c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -237,7 +237,8 @@ noinst_PROGRAMS = \ queue-test \ rtpoll-test \ sig2str-test \ - resampler-test + resampler-test \ + smoother-test if HAVE_SIGXCPU noinst_PROGRAMS += \ @@ -387,6 +388,11 @@ resampler_test_LDADD = $(AM_LDADD) libpulsecore.la resampler_test_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS) resampler_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS) +smoother_test_SOURCES = tests/smoother-test.c +smoother_test_LDADD = $(AM_LDADD) libpulsecore.la +smoother_test_CFLAGS = $(AM_CFLAGS) +smoother_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) + ################################### # Client library # ################################### @@ -716,6 +722,7 @@ libpulsecore_la_SOURCES += \ pulsecore/rtclock.c pulsecore/rtclock.h \ pulsecore/macro.h \ pulsecore/once.c pulsecore/once.h \ + pulsecore/time-smoother.c pulsecore/time-smoother.h \ $(PA_THREAD_OBJS) if OS_IS_WIN32 @@ -948,9 +955,9 @@ modlibexec_LTLIBRARIES += \ module-combine.la \ module-remap-sink.la \ module-ladspa-sink.la -# module-tunnel-sink.la \ -# module-tunnel-source.la \ # module-esound-sink.la +# module-tunnel-sink.la +# module-tunnel-source.la # See comment at librtp.la above if !OS_IS_WIN32 @@ -1187,9 +1194,9 @@ module_esound_compat_spawnpid_la_SOURCES = modules/module-esound-compat-spawnpid module_esound_compat_spawnpid_la_LDFLAGS = -module -avoid-version module_esound_compat_spawnpid_la_LIBADD = $(AM_LIBADD) libpulsecore.la -#module_esound_sink_la_SOURCES = modules/module-esound-sink.c -#module_esound_sink_la_LDFLAGS = -module -avoid-version -#module_esound_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la libiochannel.la libsocket-client.la libauthkey.la +# module_esound_sink_la_SOURCES = modules/module-esound-sink.c +# module_esound_sink_la_LDFLAGS = -module -avoid-version +# module_esound_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la libiochannel.la libsocket-client.la libauthkey.la # Pipes diff --git a/src/pulsecore/time-smoother.c b/src/pulsecore/time-smoother.c new file mode 100644 index 00000000..0b3594a3 --- /dev/null +++ b/src/pulsecore/time-smoother.c @@ -0,0 +1,317 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2007 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include + +#include + +#include "time-smoother.h" + +#define HISTORY_MAX 100 + +/* + * Implementation of a time smoothing algorithm to synchronize remote + * clocks to a local one. Evens out noise, adjusts to clock skew and + * allows cheap estimations of the remote time while clock updates may + * be seldom and recieved in non-equidistant intervals. + * + * Basically, we estimate the gradient of received clock samples in a + * certain history window (of size 'history_time') with linear + * regression. With that info we estimate the remote time in + * 'adjust_time' ahead and smoothen our current estimation function + * towards that point with a 3rd order polynomial interpolation with + * fitting derivatives. (more or less a b-spline) + * + * The larger 'history_time' is chosen the better we will surpress + * noise -- but we'll adjust to clock skew slower.. + * + * The larger 'adjust_time' is chosen the smoother our estimation + * function will be -- but we'll adjust to clock skew slower, too. + * + * If 'monotonic' is TRUE the resulting estimation function is + * guaranteed to be monotonic. + */ + +struct pa_smoother { + pa_usec_t adjust_time, history_time; + pa_bool_t monotonic; + + pa_usec_t px, py; /* Point p, where we want to reach stability */ + double dp; /* Gradient we want at point p */ + + pa_usec_t ex, ey; /* Point e, which we estimated before and need to smooth to */ + double de; /* Gradient we estimated for point e */ + + /* History of last measurements */ + pa_usec_t history_x[HISTORY_MAX], history_y[HISTORY_MAX]; + unsigned history_idx, n_history; + + /* To even out for monotonicity */ + pa_usec_t last_y; + + /* Cached parameters for our interpolation polynomial y=ax^3+b^2+cx */ + double a, b, c; + pa_bool_t abc_valid; +}; + +pa_smoother* pa_smoother_new(pa_usec_t adjust_time, pa_usec_t history_time, pa_bool_t monotonic) { + pa_smoother *s; + + pa_assert(adjust_time > 0); + pa_assert(history_time > 0); + + s = pa_xnew(pa_smoother, 1); + s->adjust_time = adjust_time; + s->history_time = history_time; + s->monotonic = monotonic; + + s->px = s->py = 0; + s->dp = 1; + + s->ex = s->ey = 0; + s->de = 1; + + s->history_idx = 0; + s->n_history = 0; + + s->last_y = 0; + + s->abc_valid = FALSE; + + return s; +} + +static void drop_old(pa_smoother *s, pa_usec_t x) { + unsigned j; + + /* First drop items from history which are too old, but make sure + * to always keep two entries in the history */ + + for (j = s->n_history; j > 2; j--) { + + if (s->history_x[s->history_idx] + s->history_time >= x) { + /* This item is still valid, and thus all following ones + * are too, so let's quit this loop */ + break; + } + + /* Item is too old, let's drop it */ + s->history_idx ++; + while (s->history_idx >= HISTORY_MAX) + s->history_idx -= HISTORY_MAX; + + s->n_history --; + } +} + +static void add_to_history(pa_smoother *s, pa_usec_t x, pa_usec_t y) { + unsigned j; + pa_assert(s); + + drop_old(s, x); + + /* Calculate position for new entry */ + j = s->history_idx + s->n_history; + while (j >= HISTORY_MAX) + j -= HISTORY_MAX; + + /* Fill in entry */ + s->history_x[j] = x; + s->history_y[j] = y; + + /* Adjust counter */ + s->n_history ++; + + /* And make sure we don't store more entries than fit in */ + if (s->n_history >= HISTORY_MAX) { + s->history_idx += s->n_history - HISTORY_MAX; + s->n_history = HISTORY_MAX; + } +} + +static double avg_gradient(pa_smoother *s, pa_usec_t x) { + unsigned i, j, c = 0; + int64_t ax = 0, ay = 0, k, t; + double r; + + drop_old(s, x); + + /* First, calculate average of all measurements */ + i = s->history_idx; + for (j = s->n_history; j > 0; j--) { + + ax += s->history_x[i]; + ay += s->history_y[i]; + c++; + + i++; + while (i >= HISTORY_MAX) + i -= HISTORY_MAX; + } + + /* Too few measurements, assume gradient of 1 */ + if (c < 2) + return 1; + + ax /= c; + ay /= c; + + /* Now, do linear regression */ + k = t = 0; + + i = s->history_idx; + for (j = s->n_history; j > 0; j--) { + int64_t dx, dy; + + dx = (int64_t) s->history_x[i] - ax; + dy = (int64_t) s->history_y[i] - ay; + + k += dx*dy; + t += dx*dx; + + i++; + while (i >= HISTORY_MAX) + i -= HISTORY_MAX; + } + + r = (double) k / t; + + return s->monotonic && r < 0 ? 0 : r; +} + +static void estimate(pa_smoother *s, pa_usec_t x, pa_usec_t *y, double *deriv) { + pa_assert(s); + pa_assert(y); + + if (x >= s->px) { + int64_t t; + + /* The requested point is right of the point where we wanted + * to be on track again, thus just linearly estimate */ + + t = (int64_t) s->py + (int64_t) (s->dp * (x - s->px)); + + if (t < 0) + t = 0; + + *y = (pa_usec_t) t; + + if (deriv) + *deriv = s->dp; + + } else { + + if (!s->abc_valid) { + pa_usec_t ex, ey, px, py; + int64_t kx, ky; + double de, dp; + + /* Ok, we're not yet on track, thus let's interpolate, and + * make sure that the first derivative is smooth */ + + /* We have two points: (ex|ey) and (px|py) with two gradients + * at these points de and dp. We do a polynomial interpolation + * of degree 3 with these 6 values */ + + ex = s->ex; ey = s->ey; + px = s->px; py = s->py; + de = s->de; dp = s->dp; + + pa_assert(ex < px); + + /* To increase the dynamic range and symplify calculation, we + * move these values to the origin */ + kx = (int64_t) px - (int64_t) ex; + ky = (int64_t) py - (int64_t) ey; + + /* Calculate a, b, c for y=ax^3+b^2+cx */ + s->c = de; + s->b = (((double) (3*ky)/kx - dp - 2*de)) / kx; + s->a = (dp/kx - 2*s->b - de/kx) / (3*kx); + + s->abc_valid = TRUE; + } + + /* Move to origin */ + x -= s->ex; + + /* Horner scheme */ + *y = (pa_usec_t) ((double) x * (s->c + (double) x * (s->b + (double) x * s->a))); + + /* Move back from origin */ + *y += s->ey; + + /* Horner scheme */ + if (deriv) + *deriv = s->c + ((double) x * (s->b*2 + (double) x * s->a*3)); + } + + /* Guarantee monotonicity */ + if (s->monotonic) { + + if (*y < s->last_y) + *y = s->last_y; + else + s->last_y = *y; + + if (deriv && *deriv < 0) + *deriv = 0; + } +} + +void pa_smoother_put(pa_smoother *s, pa_usec_t x, pa_usec_t y) { + pa_assert(s); + + /* First, we calculate the position we'd estimate for x, so that + * we can adjust our position smoothly from this one */ + estimate(s, x, &s->ey, &s->de); + s->ex = x; + + /* Then, we add the new measurement to our history */ + add_to_history(s, x, y); + + /* And determine the average gradient of the history */ + s->dp = avg_gradient(s, x); + + /* And calculate when we want to be on track again */ + s->px = x + s->adjust_time; + s->py = y + s->dp *s->adjust_time; + + s->abc_valid = FALSE; +} + +pa_usec_t pa_smoother_get(pa_smoother *s, pa_usec_t x) { + pa_usec_t y; + + pa_assert(s); + + estimate(s, x, &y, NULL); + return y; +} diff --git a/src/pulsecore/time-smoother.h b/src/pulsecore/time-smoother.h new file mode 100644 index 00000000..038b7ae4 --- /dev/null +++ b/src/pulsecore/time-smoother.h @@ -0,0 +1,37 @@ +#ifndef foopulsetimesmootherhfoo +#define foopulsetimesmootherhfoo + +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + Copyright 2007 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include +#include + +typedef struct pa_smoother pa_smoother; + +pa_smoother* pa_smoother_new(pa_usec_t adjust_x, pa_usec_t history_x, pa_bool_t monotonic); + +void pa_smoother_put(pa_smoother *s, pa_usec_t x, pa_usec_t y); +pa_usec_t pa_smoother_get(pa_smoother *s, pa_usec_t x); + +#endif diff --git a/src/tests/smoother-test.c b/src/tests/smoother-test.c new file mode 100644 index 00000000..ed4327e9 --- /dev/null +++ b/src/tests/smoother-test.c @@ -0,0 +1,72 @@ +/* $Id$ */ + +/*** + This file is part of PulseAudio. + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include + +int main(int argc, char*argv[]) { + pa_usec_t x; + unsigned u = 0; + pa_smoother *s; + int m; + +/* unsigned msec[] = { */ +/* 200, 200, */ +/* 300, 320, */ +/* 400, 400, */ +/* 500, 480, */ +/* 0, 0 */ +/* }; */ + + int msec[200]; + + for (m = 0, u = 0; u < PA_ELEMENTSOF(msec)-2; u+= 2) { + + msec[u] = m+1; + msec[u+1] = m + rand() % 2000 - 1000; + + m += rand() % 100; + } + + msec[PA_ELEMENTSOF(msec)-2] = 0; + msec[PA_ELEMENTSOF(msec)-1] = 0; + + s = pa_smoother_new(1000*PA_USEC_PER_MSEC, 2000*PA_USEC_PER_MSEC, TRUE); + + for (x = 0, u = 0; x < PA_USEC_PER_SEC * 10; x += PA_USEC_PER_MSEC) { + + while (msec[u] > 0 && msec[u]*PA_USEC_PER_MSEC < x) { + pa_smoother_put(s, msec[u]*PA_USEC_PER_MSEC, msec[u+1]*PA_USEC_PER_MSEC); + printf("%i\t\t%i\n", msec[u], msec[u+1]); + u += 2; + } + + printf("%llu\t%llu\n", x/PA_USEC_PER_MSEC, pa_smoother_get(s, x)/PA_USEC_PER_MSEC); + } + +} -- cgit From 0d84e4ccb97b6dfa1c8022a93c9f3af129359140 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 24 Oct 2007 13:30:47 +0000 Subject: fix alsa mmap initialization bogosity, discovered by Jyri Sarha git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1950 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/alsa-util.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c index 9ea5ad12..906de58d 100644 --- a/src/modules/alsa-util.c +++ b/src/modules/alsa-util.c @@ -298,14 +298,19 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *p goto finish; if (use_mmap && *use_mmap) { - if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0) + if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0) { + + /* mmap() didn't work, fall back to interleaved */ + if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) goto finish; + if (use_mmap) + *use_mmap = 0; + } + } else if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) goto finish; - else if (*use_mmap) - *use_mmap = 0; if ((ret = set_format(pcm_handle, hwparams, &f)) < 0) goto finish; -- cgit From 81ed6e6c6f10796f7111318a7029d80bce3028dd Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Thu, 25 Oct 2007 05:36:02 +0000 Subject: A couple of comment typo fixes. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1951 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/asyncmsgq.c | 2 +- src/pulsecore/asyncmsgq.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/asyncmsgq.c b/src/pulsecore/asyncmsgq.c index 9910f651..96b43a71 100644 --- a/src/pulsecore/asyncmsgq.c +++ b/src/pulsecore/asyncmsgq.c @@ -134,7 +134,7 @@ void pa_asyncmsgq_post(pa_asyncmsgq *a, pa_msgobject *object, int code, const vo pa_memchunk_reset(&i->memchunk); i->semaphore = NULL; - /* Thus mutex makes the queue multiple-writer safe. This lock is only used on the writing side */ + /* This mutex makes the queue multiple-writer safe. This lock is only used on the writing side */ pa_mutex_lock(a->mutex); pa_assert_se(pa_asyncq_push(a->asyncq, i, 1) == 0); pa_mutex_unlock(a->mutex); diff --git a/src/pulsecore/asyncmsgq.h b/src/pulsecore/asyncmsgq.h index 393bb0b1..5d3867ba 100644 --- a/src/pulsecore/asyncmsgq.h +++ b/src/pulsecore/asyncmsgq.h @@ -45,7 +45,7 @@ * A memchunk (may be NULL) * * There are two functions for submitting messages: _post and - * _send. The fromer just enqueues the message asynchronously, the + * _send. The former just enqueues the message asynchronously, the * latter waits for completion, synchronously. */ enum { -- cgit From 7ccf40ee3bb2d91e6fad6e40acaa7ac9e2e1b4fb Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Thu, 25 Oct 2007 05:49:11 +0000 Subject: Add "support" for plugins that have control output ports, i.e. don't crash on them anymore (the plugins correctly assume that every port is connected to a buffer, so we connect them to a dummy buffer that isn't used anywhere). git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1952 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/modules/module-ladspa-sink.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/modules/module-ladspa-sink.c b/src/modules/module-ladspa-sink.c index 29ca89f0..0265d971 100644 --- a/src/modules/module-ladspa-sink.c +++ b/src/modules/module-ladspa-sink.c @@ -21,6 +21,9 @@ USA. ***/ +/* TODO: Some plugins cause latency, and some even report it by using a control + out port. We don't currently use the latency information. */ + #ifdef HAVE_CONFIG_H #include #endif @@ -71,6 +74,10 @@ struct userdata { unsigned long input_port, output_port; LADSPA_Data *control; + /* This is a dummy buffer. Every port must be connected, but we don't care + about control out ports. We connect them all to this single buffer. */ + LADSPA_Data control_out; + pa_memchunk memchunk; }; @@ -386,8 +393,10 @@ int pa__init(pa_module*m) { } else if (LADSPA_IS_PORT_INPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p])) n_control++; - else - pa_log("Cannot handle type of port %s", d->PortNames[p]); + else { + pa_assert(LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p]) && LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p])); + pa_log_info("Ignored port \"%s\", because we ignore all control out ports.", d->PortNames[p]); + } } if ((input_port == (unsigned long) -1) || (output_port == (unsigned long) -1)) { @@ -466,9 +475,15 @@ int pa__init(pa_module*m) { for (p = 0; p < d->PortCount; p++) { LADSPA_PortRangeHintDescriptor hint = d->PortRangeHints[p].HintDescriptor; - if (!LADSPA_IS_PORT_INPUT(d->PortDescriptors[p]) || !LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p])) + if (!LADSPA_IS_PORT_CONTROL(d->PortDescriptors[p])) continue; + if (LADSPA_IS_PORT_OUTPUT(d->PortDescriptors[p])) { + for (c = 0; c < ss.channels; c++) + d->connect_port(u->handle[c], p, &u->control_out); + continue; + } + pa_assert(h < n_control); if (use_default[h]) { -- cgit -- cgit From ca744a4ac55e5ef5d1894a0ddfd404ec237a43b6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 27 Oct 2007 12:57:57 +0000 Subject: add pa_timeval_load() API git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1954 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulse/timeval.c | 8 ++++++++ src/pulse/timeval.h | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/pulse/timeval.c b/src/pulse/timeval.c index dcc0bd75..70ceb71e 100644 --- a/src/pulse/timeval.c +++ b/src/pulse/timeval.c @@ -156,3 +156,11 @@ struct timeval* pa_timeval_store(struct timeval *tv, pa_usec_t v) { return tv; } + +pa_usec_t pa_timeval_load(const struct timeval *tv) { + pa_assert(tv); + + return + (pa_usec_t) tv->tv_sec * PA_USEC_PER_SEC + + (pa_usec_t) tv->tv_usec; +} diff --git a/src/pulse/timeval.h b/src/pulse/timeval.h index a7d3ba33..65a0e513 100644 --- a/src/pulse/timeval.h +++ b/src/pulse/timeval.h @@ -56,9 +56,12 @@ pa_usec_t pa_timeval_age(const struct timeval *tv); /** Add the specified time inmicroseconds to the specified timeval structure */ struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v) PA_GCC_PURE; -/** Store the specified uec value in the timeval struct */ +/** Store the specified uec value in the timeval struct. \since 0.9.7 */ struct timeval* pa_timeval_store(struct timeval *tv, pa_usec_t v); +/** Load the specified tv value and return it in usec. \since 0.9.7 */ +pa_usec_t pa_timeval_load(const struct timeval *tv); + PA_C_DECL_END #endif -- cgit From b4bb747ba70caf2675c61c7d93e700adae28e209 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 27 Oct 2007 12:58:24 +0000 Subject: add pa_rtclock_usec() API git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1955 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/rtclock.c | 6 ++++++ src/pulsecore/rtclock.h | 3 +++ 2 files changed, 9 insertions(+) diff --git a/src/pulsecore/rtclock.c b/src/pulsecore/rtclock.c index b34e6a41..cec7124f 100644 --- a/src/pulsecore/rtclock.c +++ b/src/pulsecore/rtclock.c @@ -93,3 +93,9 @@ pa_bool_t pa_rtclock_hrtimer(void) { #endif } + +pa_usec_t pa_rtclock_usec(void) { + struct timeval tv; + + return pa_timeval_load(pa_rtclock_get(&tv)); +} diff --git a/src/pulsecore/rtclock.h b/src/pulsecore/rtclock.h index 72bbd5e9..f0360af3 100644 --- a/src/pulsecore/rtclock.h +++ b/src/pulsecore/rtclock.h @@ -31,6 +31,9 @@ struct timeval; /* Something like pulse/timeval.h but based on CLOCK_MONOTONIC */ struct timeval *pa_rtclock_get(struct timeval *ts); + +pa_usec_t pa_rtclock_usec(void); + pa_usec_t pa_rtclock_age(const struct timeval *tv); pa_bool_t pa_rtclock_hrtimer(void); -- cgit From c4d9a2bf858e1603649352fce0551cbdcbfaad0c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 27 Oct 2007 12:58:54 +0000 Subject: add missing pa_smoother destructor git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1956 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/time-smoother.c | 6 ++++++ src/pulsecore/time-smoother.h | 1 + src/tests/smoother-test.c | 3 +++ 3 files changed, 10 insertions(+) diff --git a/src/pulsecore/time-smoother.c b/src/pulsecore/time-smoother.c index 0b3594a3..f8d2f912 100644 --- a/src/pulsecore/time-smoother.c +++ b/src/pulsecore/time-smoother.c @@ -108,6 +108,12 @@ pa_smoother* pa_smoother_new(pa_usec_t adjust_time, pa_usec_t history_time, pa_b return s; } +void pa_smoother_free(pa_smoother* s) { + pa_assert(s); + + pa_xfree(s); +} + static void drop_old(pa_smoother *s, pa_usec_t x) { unsigned j; diff --git a/src/pulsecore/time-smoother.h b/src/pulsecore/time-smoother.h index 038b7ae4..81647184 100644 --- a/src/pulsecore/time-smoother.h +++ b/src/pulsecore/time-smoother.h @@ -30,6 +30,7 @@ typedef struct pa_smoother pa_smoother; pa_smoother* pa_smoother_new(pa_usec_t adjust_x, pa_usec_t history_x, pa_bool_t monotonic); +void pa_smoother_free(pa_smoother* s); void pa_smoother_put(pa_smoother *s, pa_usec_t x, pa_usec_t y); pa_usec_t pa_smoother_get(pa_smoother *s, pa_usec_t x); diff --git a/src/tests/smoother-test.c b/src/tests/smoother-test.c index ed4327e9..96acdd40 100644 --- a/src/tests/smoother-test.c +++ b/src/tests/smoother-test.c @@ -69,4 +69,7 @@ int main(int argc, char*argv[]) { printf("%llu\t%llu\n", x/PA_USEC_PER_MSEC, pa_smoother_get(s, x)/PA_USEC_PER_MSEC); } + pa_smoother_free(s); + + return 0; } -- cgit From 55e4a3e221ef2adbc53a7c00a2e2fade2390036e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 27 Oct 2007 12:59:59 +0000 Subject: modernize pa_iochannel a bit, add pa_iochannel_get_send_fd() git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1957 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/iochannel.c | 66 +++++++++++++++++++++++++---------------------- src/pulsecore/iochannel.h | 14 +++++----- src/pulsecore/pstream.c | 18 ++++++------- 3 files changed, 52 insertions(+), 46 deletions(-) diff --git a/src/pulsecore/iochannel.c b/src/pulsecore/iochannel.c index 90136fe6..01f17ab3 100644 --- a/src/pulsecore/iochannel.c +++ b/src/pulsecore/iochannel.c @@ -58,11 +58,11 @@ struct pa_iochannel { pa_iochannel_cb_t callback; void*userdata; - int readable; - int writable; - int hungup; + pa_bool_t readable; + pa_bool_t writable; + pa_bool_t hungup; - int no_close; + pa_bool_t no_close; pa_io_event* input_event, *output_event; }; @@ -90,7 +90,7 @@ static void enable_mainloop_sources(pa_iochannel *io) { static void callback(pa_mainloop_api* m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) { pa_iochannel *io = userdata; - int changed = 0; + pa_bool_t changed = FALSE; pa_assert(m); pa_assert(e); @@ -98,19 +98,19 @@ static void callback(pa_mainloop_api* m, pa_io_event *e, int fd, pa_io_event_fla pa_assert(userdata); if ((f & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) && !io->hungup) { - io->hungup = 1; - changed = 1; + io->hungup = TRUE; + changed = TRUE; } if ((f & PA_IO_EVENT_INPUT) && !io->readable) { - io->readable = 1; - changed = 1; + io->readable = TRUE; + changed = TRUE; pa_assert(e == io->input_event); } if ((f & PA_IO_EVENT_OUTPUT) && !io->writable) { - io->writable = 1; - changed = 1; + io->writable = TRUE; + changed = TRUE; pa_assert(e == io->output_event); } @@ -136,10 +136,10 @@ pa_iochannel* pa_iochannel_new(pa_mainloop_api*m, int ifd, int ofd) { io->userdata = NULL; io->callback = NULL; - io->readable = 0; - io->writable = 0; - io->hungup = 0; - io->no_close = 0; + io->readable = FALSE; + io->writable = FALSE; + io->hungup = FALSE; + io->no_close = FALSE; io->input_event = io->output_event = NULL; @@ -182,19 +182,19 @@ void pa_iochannel_free(pa_iochannel*io) { pa_xfree(io); } -int pa_iochannel_is_readable(pa_iochannel*io) { +pa_bool_t pa_iochannel_is_readable(pa_iochannel*io) { pa_assert(io); return io->readable || io->hungup; } -int pa_iochannel_is_writable(pa_iochannel*io) { +pa_bool_t pa_iochannel_is_writable(pa_iochannel*io) { pa_assert(io); return io->writable && !io->hungup; } -int pa_iochannel_is_hungup(pa_iochannel*io) { +pa_bool_t pa_iochannel_is_hungup(pa_iochannel*io) { pa_assert(io); return io->hungup; @@ -208,9 +208,8 @@ ssize_t pa_iochannel_write(pa_iochannel*io, const void*data, size_t l) { pa_assert(l); pa_assert(io->ofd >= 0); - r = pa_write(io->ofd, data, l, &io->ofd_type); - if (r >= 0) { - io->writable = 0; + if ((r = pa_write(io->ofd, data, l, &io->ofd_type)) >= 0) { + io->writable = FALSE; enable_mainloop_sources(io); } @@ -224,9 +223,8 @@ ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l) { pa_assert(data); pa_assert(io->ifd >= 0); - r = pa_read(io->ifd, data, l, &io->ifd_type); - if (r >= 0) { - io->readable = 0; + if ((r = pa_read(io->ifd, data, l, &io->ifd_type)) >= 0) { + io->readable = FALSE; enable_mainloop_sources(io); } @@ -235,7 +233,7 @@ ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l) { #ifdef HAVE_CREDS -int pa_iochannel_creds_supported(pa_iochannel *io) { +pa_bool_t pa_iochannel_creds_supported(pa_iochannel *io) { struct sockaddr_un sa; socklen_t l; @@ -309,14 +307,14 @@ ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l mh.msg_flags = 0; if ((r = sendmsg(io->ofd, &mh, MSG_NOSIGNAL)) >= 0) { - io->writable = 0; + io->writable = FALSE; enable_mainloop_sources(io); } return r; } -ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, pa_creds *creds, int *creds_valid) { +ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, pa_creds *creds, pa_bool_t *creds_valid) { ssize_t r; struct msghdr mh; struct iovec iov; @@ -358,12 +356,12 @@ ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, pa_cr creds->gid = u.gid; creds->uid = u.uid; - *creds_valid = 1; + *creds_valid = TRUE; break; } } - io->readable = 0; + io->readable = FALSE; enable_mainloop_sources(io); } @@ -379,10 +377,10 @@ void pa_iochannel_set_callback(pa_iochannel*io, pa_iochannel_cb_t _callback, voi io->userdata = userdata; } -void pa_iochannel_set_noclose(pa_iochannel*io, int b) { +void pa_iochannel_set_noclose(pa_iochannel*io, pa_bool_t b) { pa_assert(io); - io->no_close = b; + io->no_close = !!b; } void pa_iochannel_socket_peer_to_string(pa_iochannel*io, char*s, size_t l) { @@ -416,3 +414,9 @@ int pa_iochannel_get_recv_fd(pa_iochannel *io) { return io->ifd; } + +int pa_iochannel_get_send_fd(pa_iochannel *io) { + pa_assert(io); + + return io->ofd; +} diff --git a/src/pulsecore/iochannel.h b/src/pulsecore/iochannel.h index 90eb963c..c9794d99 100644 --- a/src/pulsecore/iochannel.h +++ b/src/pulsecore/iochannel.h @@ -33,6 +33,7 @@ #include #include +#include /* A wrapper around UNIX file descriptors for attaching them to the a main event loop. Everytime new data may be read or be written to @@ -58,20 +59,20 @@ ssize_t pa_iochannel_write(pa_iochannel*io, const void*data, size_t l); ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l); #ifdef HAVE_CREDS -int pa_iochannel_creds_supported(pa_iochannel *io); +pa_bool_t pa_iochannel_creds_supported(pa_iochannel *io); int pa_iochannel_creds_enable(pa_iochannel *io); ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l, const pa_creds *ucred); -ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, pa_creds *ucred, int *creds_valid); +ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, pa_creds *ucred, pa_bool_t *creds_valid); #endif -int pa_iochannel_is_readable(pa_iochannel*io); -int pa_iochannel_is_writable(pa_iochannel*io); -int pa_iochannel_is_hungup(pa_iochannel*io); +pa_bool_t pa_iochannel_is_readable(pa_iochannel*io); +pa_bool_t pa_iochannel_is_writable(pa_iochannel*io); +pa_bool_t pa_iochannel_is_hungup(pa_iochannel*io); /* Don't close the file descirptors when the io channel is freed. By * default the file descriptors are closed. */ -void pa_iochannel_set_noclose(pa_iochannel*io, int b); +void pa_iochannel_set_noclose(pa_iochannel*io, pa_bool_t b); /* Set the callback function that is called whenever data becomes available for read or write */ typedef void (*pa_iochannel_cb_t)(pa_iochannel*io, void *userdata); @@ -87,5 +88,6 @@ int pa_iochannel_socket_set_sndbuf(pa_iochannel*io, size_t l); pa_mainloop_api* pa_iochannel_get_mainloop_api(pa_iochannel *io); int pa_iochannel_get_recv_fd(pa_iochannel *io); +int pa_iochannel_get_send_fd(pa_iochannel *io); #endif diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c index 333012c0..9d32a363 100644 --- a/src/pulsecore/pstream.c +++ b/src/pulsecore/pstream.c @@ -217,12 +217,12 @@ static void io_callback(pa_iochannel*io, void *userdata) { static void defer_callback(pa_mainloop_api *m, pa_defer_event *e, void*userdata) { pa_pstream *p = userdata; - + pa_assert(p); pa_assert(PA_REFCNT_VALUE(p) > 0); pa_assert(p->defer_event == e); pa_assert(p->mainloop == m); - + do_something(p); } @@ -244,7 +244,7 @@ pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_mempool *poo p->mainloop = m; p->defer_event = m->defer_new(m, defer_callback, p); m->defer_enable(p->defer_event, 0); - + p->send_queue = pa_queue_new(); p->write.current = NULL; @@ -266,7 +266,7 @@ pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_mempool *poo p->revoke_callback_userdata = NULL; p->release_callback = NULL; p->release_callback_userdata = NULL; - + p->mempool = pool; p->use_shm = 0; @@ -335,7 +335,7 @@ void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const pa_creds *cre if (!(i = pa_flist_pop(PA_STATIC_FLIST_GET(items)))) i = pa_xnew(struct item_info, 1); - + i->type = PA_PSTREAM_ITEM_PACKET; i->packet = pa_packet_ref(packet); @@ -365,7 +365,7 @@ void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa length = chunk->length; bsm = pa_mempool_block_size_max(p->mempool); - + while (length > 0) { struct item_info *i; size_t n; @@ -662,7 +662,7 @@ static int do_read(pa_pstream *p) { #ifdef HAVE_CREDS { - int b = 0; + pa_bool_t b = 0; if ((r = pa_iochannel_read_with_creds(p->io, d, l, &p->read_creds, &b)) <= 0) goto fail; @@ -970,7 +970,7 @@ void pa_pstream_unlink(pa_pstream *p) { if (p->dead) return; - + p->dead = 1; if (p->import) { @@ -991,7 +991,7 @@ void pa_pstream_unlink(pa_pstream *p) { if (p->defer_event) { p->mainloop->defer_free(p->defer_event); p->defer_event = NULL; - } + } p->die_callback = NULL; p->drain_callback = NULL; -- cgit From 581e7f18023682c05cb172ad06ced0c25d5e0c0f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 27 Oct 2007 15:48:01 +0000 Subject: add ability to "pause" the input time temporarily. don't accidently overwrite variables we still need. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1958 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/time-smoother.c | 61 ++++++++++++++++++++++++++++++++++++++++--- src/pulsecore/time-smoother.h | 7 ++++- 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/src/pulsecore/time-smoother.c b/src/pulsecore/time-smoother.c index f8d2f912..6bda3df0 100644 --- a/src/pulsecore/time-smoother.c +++ b/src/pulsecore/time-smoother.c @@ -34,7 +34,7 @@ #include "time-smoother.h" -#define HISTORY_MAX 100 +#define HISTORY_MAX 50 /* * Implementation of a time smoothing algorithm to synchronize remote @@ -63,6 +63,8 @@ struct pa_smoother { pa_usec_t adjust_time, history_time; pa_bool_t monotonic; + pa_usec_t time_offset; + pa_usec_t px, py; /* Point p, where we want to reach stability */ double dp; /* Gradient we want at point p */ @@ -79,6 +81,9 @@ struct pa_smoother { /* Cached parameters for our interpolation polynomial y=ax^3+b^2+cx */ double a, b, c; pa_bool_t abc_valid; + + pa_bool_t paused; + pa_usec_t pause_time; }; pa_smoother* pa_smoother_new(pa_usec_t adjust_time, pa_usec_t history_time, pa_bool_t monotonic) { @@ -90,6 +95,7 @@ pa_smoother* pa_smoother_new(pa_usec_t adjust_time, pa_usec_t history_time, pa_b s = pa_xnew(pa_smoother, 1); s->adjust_time = adjust_time; s->history_time = history_time; + s->time_offset = 0; s->monotonic = monotonic; s->px = s->py = 0; @@ -105,6 +111,8 @@ pa_smoother* pa_smoother_new(pa_usec_t adjust_time, pa_usec_t history_time, pa_b s->abc_valid = FALSE; + s->paused = FALSE; + return s; } @@ -293,12 +301,24 @@ static void estimate(pa_smoother *s, pa_usec_t x, pa_usec_t *y, double *deriv) { } void pa_smoother_put(pa_smoother *s, pa_usec_t x, pa_usec_t y) { + pa_usec_t ney; + double nde; + pa_assert(s); + pa_assert(x >= s->time_offset); + + /* Fix up x value */ + if (s->paused) + x = s->pause_time; + else + x -= s->time_offset; + + pa_assert(x >= s->ex); /* First, we calculate the position we'd estimate for x, so that * we can adjust our position smoothly from this one */ - estimate(s, x, &s->ey, &s->de); - s->ex = x; + estimate(s, x, &ney, &nde); + s->ex = x; s->ey = ney; s->de = nde; /* Then, we add the new measurement to our history */ add_to_history(s, x, y); @@ -317,7 +337,42 @@ pa_usec_t pa_smoother_get(pa_smoother *s, pa_usec_t x) { pa_usec_t y; pa_assert(s); + pa_assert(x >= s->time_offset); + + /* Fix up x value */ + if (s->paused) + x = s->pause_time; + else + x -= s->time_offset; + + pa_assert(x >= s->ex); estimate(s, x, &y, NULL); return y; } + +void pa_smoother_set_time_offset(pa_smoother *s, pa_usec_t offset) { + pa_assert(s); + + s->time_offset = offset; +} + +void pa_smoother_pause(pa_smoother *s, pa_usec_t x) { + pa_assert(s); + + if (s->paused) + return; + + s->paused = TRUE; + s->pause_time = x; +} + +void pa_smoother_resume(pa_smoother *s, pa_usec_t x) { + pa_assert(s); + + if (!s->paused) + return; + + s->paused = FALSE; + s->time_offset += x - s->pause_time; +} diff --git a/src/pulsecore/time-smoother.h b/src/pulsecore/time-smoother.h index 81647184..8b8512e2 100644 --- a/src/pulsecore/time-smoother.h +++ b/src/pulsecore/time-smoother.h @@ -29,10 +29,15 @@ typedef struct pa_smoother pa_smoother; -pa_smoother* pa_smoother_new(pa_usec_t adjust_x, pa_usec_t history_x, pa_bool_t monotonic); +pa_smoother* pa_smoother_new(pa_usec_t adjust_time, pa_usec_t history_time, pa_bool_t monotonic); void pa_smoother_free(pa_smoother* s); void pa_smoother_put(pa_smoother *s, pa_usec_t x, pa_usec_t y); pa_usec_t pa_smoother_get(pa_smoother *s, pa_usec_t x); +void pa_smoother_set_time_offset(pa_smoother *s, pa_usec_t offset); + +void pa_smoother_pause(pa_smoother *s, pa_usec_t x); +void pa_smoother_resume(pa_smoother *s, pa_usec_t x); + #endif -- cgit From 56804de3d384d6d2b345a53e69a488b2d4587aef Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 27 Oct 2007 15:48:23 +0000 Subject: minor fixups, to make the test more deterministic git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1959 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/tests/smoother-test.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tests/smoother-test.c b/src/tests/smoother-test.c index 96acdd40..c0501ecc 100644 --- a/src/tests/smoother-test.c +++ b/src/tests/smoother-test.c @@ -45,12 +45,17 @@ int main(int argc, char*argv[]) { int msec[200]; + srand(0); + for (m = 0, u = 0; u < PA_ELEMENTSOF(msec)-2; u+= 2) { msec[u] = m+1; msec[u+1] = m + rand() % 2000 - 1000; m += rand() % 100; + + if (msec[u+1] < 0) + msec[u+1] = 0; } msec[PA_ELEMENTSOF(msec)-2] = 0; -- cgit From 87faa546c2e32e49f810e77b5e1ea1d3b990d39b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 27 Oct 2007 16:16:01 +0000 Subject: minor fix to make gcc shut up git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1960 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/tests/smoother-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/smoother-test.c b/src/tests/smoother-test.c index c0501ecc..caa7df70 100644 --- a/src/tests/smoother-test.c +++ b/src/tests/smoother-test.c @@ -65,7 +65,7 @@ int main(int argc, char*argv[]) { for (x = 0, u = 0; x < PA_USEC_PER_SEC * 10; x += PA_USEC_PER_MSEC) { - while (msec[u] > 0 && msec[u]*PA_USEC_PER_MSEC < x) { + while (msec[u] > 0 && (pa_usec_t) msec[u]*PA_USEC_PER_MSEC < x) { pa_smoother_put(s, msec[u]*PA_USEC_PER_MSEC, msec[u+1]*PA_USEC_PER_MSEC); printf("%i\t\t%i\n", msec[u], msec[u+1]); u += 2; -- cgit From 98d363c8ef6de57f6dae0c77a86291144a1f426a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 27 Oct 2007 22:05:20 +0000 Subject: minor cleanup git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1961 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/rtclock.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/pulsecore/rtclock.c b/src/pulsecore/rtclock.c index cec7124f..07d776e4 100644 --- a/src/pulsecore/rtclock.c +++ b/src/pulsecore/rtclock.c @@ -44,23 +44,20 @@ pa_usec_t pa_rtclock_age(const struct timeval *tv) { struct timeval *pa_rtclock_get(struct timeval *tv) { #ifdef HAVE_CLOCK_GETTIME - static int no_monotonic = 0; struct timespec ts; - /* No locking or atomic ops for no_monotonic here */ - - if (!no_monotonic) { #ifdef CLOCK_MONOTONIC - if (clock_gettime(CLOCK_MONOTONIC, &ts) >= 0) - goto out; -#endif + /* No locking or atomic ops for no_monotonic here */ + static pa_bool_t no_monotonic = FALSE; - no_monotonic = 1; - } + if (!no_monotonic) + if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) + no_monotonic = TRUE; - pa_assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0); + if (no_monotonic) +#endif + pa_assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0); -out: pa_assert(tv); tv->tv_sec = ts.tv_sec; -- cgit From 66dc0b44c5571d09699c62b36fe8fecacb6acca6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 27 Oct 2007 22:06:20 +0000 Subject: don't use SIGRTMAX, for compatibility with valgrind which apparently uses this signal git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1962 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/daemon/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/daemon/main.c b/src/daemon/main.c index c135a6be..6c9f6627 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -615,7 +615,8 @@ int main(int argc, char *argv[]) { pa_log_info("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"); #ifdef SIGRTMIN - pa_rtsig_configure(SIGRTMIN, SIGRTMAX); + /* Valgrind uses SIGRTMAX. To easy debugging we don't use it here */ + pa_rtsig_configure(SIGRTMIN, SIGRTMAX-1); #endif pa_assert_se(mainloop = pa_mainloop_new()); -- cgit From 94cf167f40e9a4aae8e158cdd655b5b546d546fe Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 27 Oct 2007 22:07:21 +0000 Subject: port module-esound-sink to new core git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1963 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 2 +- src/Makefile.am | 10 +- src/modules/module-esound-sink.c | 480 ++++++++++++++++++++++++++++----------- 3 files changed, 354 insertions(+), 138 deletions(-) diff --git a/configure.ac b/configure.ac index f9fd12ca..27806cea 100644 --- a/configure.ac +++ b/configure.ac @@ -187,7 +187,7 @@ AC_HEADER_STDC AC_CHECK_HEADERS([arpa/inet.h glob.h grp.h netdb.h netinet/in.h \ netinet/in_systm.h netinet/tcp.h poll.h pwd.h sched.h \ sys/mman.h sys/resource.h sys/select.h sys/socket.h sys/wait.h \ - syslog.h sys/dl.h dlfcn.h]) + syslog.h sys/dl.h dlfcn.h linux/sockios.h]) AC_CHECK_HEADERS([netinet/ip.h], [], [], [#include #if HAVE_NETINET_IN_H diff --git a/src/Makefile.am b/src/Makefile.am index be55994c..eee47191 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -954,8 +954,8 @@ modlibexec_LTLIBRARIES += \ module-esound-protocol-tcp.la \ module-combine.la \ module-remap-sink.la \ - module-ladspa-sink.la -# module-esound-sink.la + module-ladspa-sink.la \ + module-esound-sink.la # module-tunnel-sink.la # module-tunnel-source.la @@ -1194,9 +1194,9 @@ module_esound_compat_spawnpid_la_SOURCES = modules/module-esound-compat-spawnpid module_esound_compat_spawnpid_la_LDFLAGS = -module -avoid-version module_esound_compat_spawnpid_la_LIBADD = $(AM_LIBADD) libpulsecore.la -# module_esound_sink_la_SOURCES = modules/module-esound-sink.c -# module_esound_sink_la_LDFLAGS = -module -avoid-version -# module_esound_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la libiochannel.la libsocket-client.la libauthkey.la +module_esound_sink_la_SOURCES = modules/module-esound-sink.c +module_esound_sink_la_LDFLAGS = -module -avoid-version +module_esound_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la libiochannel.la libsocket-client.la libauthkey.la # Pipes diff --git a/src/modules/module-esound-sink.c b/src/modules/module-esound-sink.c index faa77a54..8b46637e 100644 --- a/src/modules/module-esound-sink.c +++ b/src/modules/module-esound-sink.c @@ -28,14 +28,23 @@ #include #include #include -#include #include #include #include #include #include +#include +#include +#include +#include +#include + +#ifdef HAVE_LINUX_SOCKIOS_H +#include +#endif #include +#include #include #include @@ -47,27 +56,37 @@ #include #include #include +#include +#include +#include +#include +#include #include "module-esound-sink-symdef.h" PA_MODULE_AUTHOR("Lennart Poettering") PA_MODULE_DESCRIPTION("ESOUND Sink") PA_MODULE_VERSION(PACKAGE_VERSION) -PA_MODULE_USAGE("sink_name= server=
cookie= format= channels= rate=") +PA_MODULE_USAGE( + "sink_name= " + "server=
cookie= " + "format= " + "channels= " + "rate=") -#define DEFAULT_SINK_NAME "esound_output" +#define DEFAULT_SINK_NAME "esound_out" struct userdata { pa_core *core; - + pa_module *module; pa_sink *sink; - pa_iochannel *io; - pa_socket_client *client; - pa_defer_event *defer_event; + pa_thread_mq thread_mq; + pa_rtpoll *rtpoll; + pa_rtpoll_item *rtpoll_item; + pa_thread *thread; pa_memchunk memchunk; - pa_module *module; void *write_data; size_t write_length, write_index; @@ -75,12 +94,28 @@ struct userdata { void *read_data; size_t read_length, read_index; - enum { STATE_AUTH, STATE_LATENCY, STATE_RUNNING, STATE_DEAD } state; + enum { + STATE_AUTH, + STATE_LATENCY, + STATE_PREPARE, + STATE_RUNNING, + STATE_DEAD + } state; pa_usec_t latency; esd_format_t format; int32_t rate; + + pa_smoother *smoother; + int fd; + + int64_t offset; + + pa_iochannel *io; + pa_socket_client *client; + + size_t block_size; }; static const char* const valid_modargs[] = { @@ -93,42 +128,211 @@ static const char* const valid_modargs[] = { NULL }; -static void cancel(struct userdata *u) { - assert(u); +enum { + SINK_MESSAGE_PASS_SOCKET = PA_SINK_MESSAGE_MAX +}; - u->state = STATE_DEAD; +static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { + struct userdata *u = PA_SINK(o)->userdata; - if (u->io) { - pa_iochannel_free(u->io); - u->io = NULL; - } + switch (code) { - if (u->defer_event) { - u->core->mainloop->defer_free(u->defer_event); - u->defer_event = NULL; - } + case PA_SINK_MESSAGE_SET_STATE: - if (u->sink) { - pa_sink_disconnect(u->sink); - pa_sink_unref(u->sink); - u->sink = NULL; + switch ((pa_sink_state_t) PA_PTR_TO_UINT(data)) { + + case PA_SINK_SUSPENDED: + pa_assert(PA_SINK_OPENED(u->sink->thread_info.state)); + + pa_smoother_pause(u->smoother, pa_rtclock_usec()); + break; + + case PA_SINK_IDLE: + case PA_SINK_RUNNING: + + if (u->sink->thread_info.state == PA_SINK_SUSPENDED) + pa_smoother_resume(u->smoother, pa_rtclock_usec()); + + break; + + case PA_SINK_UNLINKED: + case PA_SINK_INIT: + ; + } + + break; + + case PA_SINK_MESSAGE_GET_LATENCY: { + pa_usec_t w, r; + + r = pa_smoother_get(u->smoother, pa_rtclock_usec()); + w = pa_bytes_to_usec(u->offset + u->memchunk.length, &u->sink->sample_spec); + + *((pa_usec_t*) data) = w > r ? w - r : 0; + break; + } + + case SINK_MESSAGE_PASS_SOCKET: { + struct pollfd *pollfd; + + pa_assert(!u->rtpoll_item); + + u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1); + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + pollfd->fd = u->fd; + pollfd->events = pollfd->revents = 0; + + return 0; + } } - if (u->module) { - pa_module_unload_request(u->module); - u->module = NULL; + return pa_sink_process_msg(o, code, data, offset, chunk); +} + +static void thread_func(void *userdata) { + struct userdata *u = userdata; + int write_type = 0; + + pa_assert(u); + + pa_log_debug("Thread starting up"); + + pa_thread_mq_install(&u->thread_mq); + pa_rtpoll_install(u->rtpoll); + + pa_smoother_set_time_offset(u->smoother, pa_rtclock_usec()); + + for (;;) { + int ret; + + if (u->rtpoll_item) { + struct pollfd *pollfd; + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + + /* Render some data and write it to the fifo */ + if (PA_SINK_OPENED(u->sink->thread_info.state) && pollfd->revents) { + pa_usec_t usec; + int64_t n; + + for (;;) { + ssize_t l; + void *p; + + if (u->memchunk.length <= 0) + pa_sink_render(u->sink, u->block_size, &u->memchunk); + + pa_assert(u->memchunk.length > 0); + + p = pa_memblock_acquire(u->memchunk.memblock); + l = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length, &write_type); + pa_memblock_release(u->memchunk.memblock); + + pa_assert(l != 0); + + if (l < 0) { + + if (errno == EINTR) + continue; + else if (errno == EAGAIN) { + + /* OK, we filled all socket buffers up + * now. */ + goto filled_up; + + } else { + pa_log("Failed to write data to FIFO: %s", pa_cstrerror(errno)); + goto fail; + } + + } else { + u->offset += l; + + u->memchunk.index += l; + u->memchunk.length -= l; + + if (u->memchunk.length <= 0) { + pa_memblock_unref(u->memchunk.memblock); + pa_memchunk_reset(&u->memchunk); + } + + pollfd->revents = 0; + + if (u->memchunk.length > 0) + + /* OK, we wrote less that we asked for, + * hence we can assume that the socket + * buffers are full now */ + goto filled_up; + } + } + + filled_up: + + /* At this spot we know that the socket buffers are + * fully filled up. This is the best time to estimate + * the playback position of the server */ + + n = u->offset; + +#ifdef SIOCOUTQ + { + int l; + if (ioctl(u->fd, SIOCOUTQ, &l) >= 0 && l > 0) + n -= l; + } +#endif + + usec = pa_bytes_to_usec(n, &u->sink->sample_spec); + + if (usec > u->latency) + usec -= u->latency; + else + usec = 0; + + pa_smoother_put(u->smoother, pa_rtclock_usec(), usec); + } + + /* Hmm, nothing to do. Let's sleep */ + pollfd->events = PA_SINK_OPENED(u->sink->thread_info.state) ? POLLOUT : 0; + } + + if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0) + goto fail; + + if (ret == 0) + goto finish; + + if (u->rtpoll_item) { + struct pollfd* pollfd; + + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + + if (pollfd->revents & ~POLLOUT) { + pa_log("FIFO shutdown."); + goto fail; + } + } } + +fail: + /* If this was no regular exit from the loop we have to continue + * processing messages until we received PA_MESSAGE_SHUTDOWN */ + pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); + pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); + +finish: + pa_log_debug("Thread shutting down"); } static int do_write(struct userdata *u) { ssize_t r; - assert(u); + pa_assert(u); if (!pa_iochannel_is_writable(u->io)) return 0; if (u->write_data) { - assert(u->write_index < u->write_length); + pa_assert(u->write_index < u->write_length); if ((r = pa_iochannel_write(u->io, (uint8_t*) u->write_data + u->write_index, u->write_length - u->write_index)) <= 0) { pa_log("write() failed: %s", pa_cstrerror(errno)); @@ -136,52 +340,44 @@ static int do_write(struct userdata *u) { } u->write_index += r; - assert(u->write_index <= u->write_length); + pa_assert(u->write_index <= u->write_length); if (u->write_index == u->write_length) { - free(u->write_data); + pa_xfree(u->write_data); u->write_data = NULL; u->write_index = u->write_length = 0; } - } else if (u->state == STATE_RUNNING) { - void *p; - - pa_module_set_used(u->module, pa_sink_used_by(u->sink)); + } - if (!u->memchunk.length) - if (pa_sink_render(u->sink, 8192, &u->memchunk) < 0) - return 0; + if (!u->write_data && u->state == STATE_PREPARE) { + /* OK, we're done with sending all control data we need to, so + * let's hand the socket over to the IO thread now */ - assert(u->memchunk.memblock); - assert(u->memchunk.length); + pa_assert(u->fd < 0); + u->fd = pa_iochannel_get_send_fd(u->io); - p = pa_memblock_acquire(u->memchunk.memblock); + pa_iochannel_set_noclose(u->io, TRUE); + pa_iochannel_free(u->io); + u->io = NULL; - if ((r = pa_iochannel_write(u->io, (uint8_t*) p + u->memchunk.index, u->memchunk.length)) < 0) { - pa_memblock_release(u->memchunk.memblock); - pa_log("write() failed: %s", pa_cstrerror(errno)); - return -1; - } - pa_memblock_release(u->memchunk.memblock); + pa_make_tcp_socket_low_delay(u->fd); - u->memchunk.index += r; - u->memchunk.length -= r; + pa_log_info("Connection authenticated, handing fd to IO thread..."); - if (u->memchunk.length <= 0) { - pa_memblock_unref(u->memchunk.memblock); - u->memchunk.memblock = NULL; - } + pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_PASS_SOCKET, NULL, 0, NULL, NULL); + u->state = STATE_RUNNING; } return 0; } static int handle_response(struct userdata *u) { - assert(u); + pa_assert(u); switch (u->state) { + case STATE_AUTH: - assert(u->read_length == sizeof(int32_t)); + pa_assert(u->read_length == sizeof(int32_t)); /* Process auth data */ if (!*(int32_t*) u->read_data) { @@ -190,14 +386,14 @@ static int handle_response(struct userdata *u) { } /* Request latency data */ - assert(!u->write_data); + pa_assert(!u->write_data); *(int32_t*) (u->write_data = pa_xmalloc(u->write_length = sizeof(int32_t))) = ESD_PROTO_LATENCY; u->write_index = 0; u->state = STATE_LATENCY; /* Space for next response */ - assert(u->read_length >= sizeof(int32_t)); + pa_assert(u->read_length >= sizeof(int32_t)); u->read_index = 0; u->read_length = sizeof(int32_t); @@ -205,7 +401,7 @@ static int handle_response(struct userdata *u) { case STATE_LATENCY: { int32_t *p; - assert(u->read_length == sizeof(int32_t)); + pa_assert(u->read_length == sizeof(int32_t)); /* Process latency info */ u->latency = (pa_usec_t) ((double) (*(int32_t*) u->read_data) * 1000000 / 44100); @@ -215,7 +411,7 @@ static int handle_response(struct userdata *u) { } /* Create stream */ - assert(!u->write_data); + pa_assert(!u->write_data); p = u->write_data = pa_xmalloc0(u->write_length = sizeof(int32_t)*3+ESD_NAME_MAX); *(p++) = ESD_PROTO_STREAM_PLAY; *(p++) = u->format; @@ -223,7 +419,7 @@ static int handle_response(struct userdata *u) { pa_strlcpy((char*) p, "PulseAudio Tunnel", ESD_NAME_MAX); u->write_index = 0; - u->state = STATE_RUNNING; + u->state = STATE_PREPARE; /* Don't read any further */ pa_xfree(u->read_data); @@ -234,14 +430,14 @@ static int handle_response(struct userdata *u) { } default: - abort(); + pa_assert_not_reached(); } return 0; } static int do_read(struct userdata *u) { - assert(u); + pa_assert(u); if (!pa_iochannel_is_readable(u->io)) return 0; @@ -252,16 +448,15 @@ static int do_read(struct userdata *u) { if (!u->read_data) return 0; - assert(u->read_index < u->read_length); + pa_assert(u->read_index < u->read_length); if ((r = pa_iochannel_read(u->io, (uint8_t*) u->read_data + u->read_index, u->read_length - u->read_index)) <= 0) { pa_log("read() failed: %s", r < 0 ? pa_cstrerror(errno) : "EOF"); - cancel(u); return -1; } u->read_index += r; - assert(u->read_index <= u->read_length); + pa_assert(u->read_index <= u->read_length); if (u->read_index == u->read_length) return handle_response(u); @@ -270,42 +465,19 @@ static int do_read(struct userdata *u) { return 0; } -static void do_work(struct userdata *u) { - assert(u); - - u->core->mainloop->defer_enable(u->defer_event, 0); - - if (do_read(u) < 0 || do_write(u) < 0) - cancel(u); -} - -static void notify_cb(pa_sink*s) { - struct userdata *u = s->userdata; - assert(s && u); - - if (pa_iochannel_is_writable(u->io)) - u->core->mainloop->defer_enable(u->defer_event, 1); -} - -static pa_usec_t get_latency_cb(pa_sink *s) { - struct userdata *u = s->userdata; - assert(s && u); +static void io_callback(PA_GCC_UNUSED pa_iochannel *io, void*userdata) { + struct userdata *u = userdata; + pa_assert(u); - return - u->latency + - (u->memchunk.memblock ? pa_bytes_to_usec(u->memchunk.length, &s->sample_spec) : 0); -} + if (do_read(u) < 0 || do_write(u) < 0) { -static void defer_callback(PA_GCC_UNUSED pa_mainloop_api *m, PA_GCC_UNUSED pa_defer_event*e, void *userdata) { - struct userdata *u = userdata; - assert(u); - do_work(u); -} + if (u->io) { + pa_iochannel_free(u->io); + u->io = NULL; + } -static void io_callback(PA_GCC_UNUSED pa_iochannel *io, void*userdata) { - struct userdata *u = userdata; - assert(u); - do_work(u); + pa_module_unload_request(u->module); + } } static void on_connection(PA_GCC_UNUSED pa_socket_client *c, pa_iochannel*io, void *userdata) { @@ -315,30 +487,34 @@ static void on_connection(PA_GCC_UNUSED pa_socket_client *c, pa_iochannel*io, vo u->client = NULL; if (!io) { - pa_log("connection failed: %s", pa_cstrerror(errno)); - cancel(u); + pa_log("Connection failed: %s", pa_cstrerror(errno)); + pa_module_unload_request(u->module); return; } + pa_assert(!u->io); u->io = io; pa_iochannel_set_callback(u->io, io_callback, u); + + pa_log_info("Connection established, authenticating ..."); } -int pa__init(pa_core *c, pa_module*m) { +int pa__init(pa_module*m) { struct userdata *u = NULL; const char *p; pa_sample_spec ss; pa_modargs *ma = NULL; char *t; + const char *espeaker; - assert(c && m); + pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("failed to parse module arguments"); goto fail; } - ss = c->default_sample_spec; + ss = m->core->default_sample_spec; if (pa_modargs_get_sample_spec(ma, &ss) < 0) { pa_log("invalid sample format specification"); goto fail; @@ -350,37 +526,62 @@ int pa__init(pa_core *c, pa_module*m) { goto fail; } - u = pa_xmalloc0(sizeof(struct userdata)); - u->core = c; + u = pa_xnew0(struct userdata, 1); + u->core = m->core; u->module = m; m->userdata = u; + u->fd = -1; + u->smoother = pa_smoother_new(PA_USEC_PER_SEC, PA_USEC_PER_SEC*2, TRUE); + pa_memchunk_reset(&u->memchunk); + u->offset = 0; + + pa_thread_mq_init(&u->thread_mq, m->core->mainloop); + u->rtpoll = pa_rtpoll_new(); + pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); + u->rtpoll_item = NULL; + u->format = (ss.format == PA_SAMPLE_U8 ? ESD_BITS8 : ESD_BITS16) | (ss.channels == 2 ? ESD_STEREO : ESD_MONO); u->rate = ss.rate; - u->sink = NULL; - u->client = NULL; - u->io = NULL; + u->block_size = pa_usec_to_bytes(PA_USEC_PER_SEC/20, &ss); + u->read_data = u->write_data = NULL; u->read_index = u->write_index = u->read_length = u->write_length = 0; + u->state = STATE_AUTH; u->latency = 0; - if (!(u->sink = pa_sink_new(c, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, NULL))) { + if (!(u->sink = pa_sink_new(m->core, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, NULL))) { pa_log("failed to create sink."); goto fail; } - if (!(u->client = pa_socket_client_new_string(u->core->mainloop, p = pa_modargs_get_value(ma, "server", ESD_UNIX_SOCKET_NAME), ESD_DEFAULT_PORT))) { - pa_log("failed to connect to server."); + u->sink->parent.process_msg = sink_process_msg; + u->sink->userdata = u; + u->sink->flags = PA_SINK_LATENCY; + + pa_sink_set_module(u->sink, m); + pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); + pa_sink_set_rtpoll(u->sink, u->rtpoll); + + if (!(espeaker = getenv("ESPEAKER"))) + espeaker = ESD_UNIX_SOCKET_NAME; + + if (!(u->client = pa_socket_client_new_string(u->core->mainloop, p = pa_modargs_get_value(ma, "server", espeaker), ESD_DEFAULT_PORT))) { + pa_log("Failed to connect to server."); goto fail; } + + pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Esound sink '%s'", p)); + pa_xfree(t); + pa_socket_client_set_callback(u->client, on_connection, u); /* Prepare the initial request */ u->write_data = pa_xmalloc(u->write_length = ESD_KEY_LEN + sizeof(int32_t)); if (pa_authkey_load_auto(pa_modargs_get_value(ma, "cookie", ".esd_auth"), u->write_data, ESD_KEY_LEN) < 0) { - pa_log("failed to load cookie"); + pa_log("Failed to load cookie"); goto fail; } *(int32_t*) ((uint8_t*) u->write_data + ESD_KEY_LEN) = ESD_ENDIAN_KEY; @@ -388,19 +589,12 @@ int pa__init(pa_core *c, pa_module*m) { /* Reserve space for the response */ u->read_data = pa_xmalloc(u->read_length = sizeof(int32_t)); - u->sink->notify = notify_cb; - u->sink->get_latency = get_latency_cb; - u->sink->userdata = u; - pa_sink_set_owner(u->sink, m); - pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Esound sink '%s'", p)); - pa_xfree(t); - - u->memchunk.memblock = NULL; - u->memchunk.length = 0; - - u->defer_event = c->mainloop->defer_new(c->mainloop, defer_callback, u); - c->mainloop->defer_enable(u->defer_event, 0); + if (!(u->thread = pa_thread_new(thread_func, u))) { + pa_log("Failed to create thread."); + goto fail; + } + pa_sink_put(u->sink); pa_modargs_free(ma); @@ -410,20 +604,39 @@ fail: if (ma) pa_modargs_free(ma); - pa__done(c, m); + pa__done(m); return -1; } -void pa__done(pa_core *c, pa_module*m) { +void pa__done(pa_module*m) { struct userdata *u; - assert(c && m); + pa_assert(m); if (!(u = m->userdata)) return; - u->module = NULL; - cancel(u); + if (u->sink) + pa_sink_unlink(u->sink); + + if (u->thread) { + pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); + pa_thread_free(u->thread); + } + + pa_thread_mq_done(&u->thread_mq); + + if (u->sink) + pa_sink_unref(u->sink); + + if (u->io) + pa_iochannel_free(u->io); + + if (u->rtpoll_item) + pa_rtpoll_item_free(u->rtpoll_item); + + if (u->rtpoll) + pa_rtpoll_free(u->rtpoll); if (u->memchunk.memblock) pa_memblock_unref(u->memchunk.memblock); @@ -434,8 +647,11 @@ void pa__done(pa_core *c, pa_module*m) { pa_xfree(u->read_data); pa_xfree(u->write_data); - pa_xfree(u); -} - + if (u->smoother) + pa_smoother_free(u->smoother); + if (u->fd >= 0) + pa_close(u->fd); + pa_xfree(u); +} -- cgit From daa2863daf54bd34ee895d8d514bf58ab64a6af9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 28 Oct 2007 16:13:25 +0000 Subject: don't use errno on EOF git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1964 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-esound.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c index adefaf98..76ba9dd0 100644 --- a/src/pulsecore/protocol-esound.c +++ b/src/pulsecore/protocol-esound.c @@ -82,11 +82,11 @@ typedef struct connection { pa_msgobject parent; uint32_t index; - int dead; + pa_bool_t dead; pa_protocol_esound *protocol; pa_iochannel *io; pa_client *client; - int authorized, swap_byte_order; + pa_bool_t authorized, swap_byte_order; void *write_data; size_t write_data_alloc, write_data_index, write_data_length; void *read_data; @@ -302,7 +302,7 @@ static void connection_write(connection *c, const void *data, size_t length) { memcpy((uint8_t*) c->write_data + i, data, length); } -static void format_esd2native(int format, int swap_bytes, pa_sample_spec *ss) { +static void format_esd2native(int format, pa_bool_t swap_bytes, pa_sample_spec *ss) { pa_assert(ss); ss->channels = ((format & ESD_MASK_CHAN) == ESD_STEREO) ? 2 : 1; @@ -344,7 +344,7 @@ static int esd_proto_connect(connection *c, PA_GCC_UNUSED esd_proto_t request, c return -1; } - c->authorized = 1; + c->authorized = TRUE; if (c->auth_timeout_event) { c->protocol->core->mainloop->time_free(c->auth_timeout_event); c->auth_timeout_event = NULL; @@ -355,9 +355,9 @@ static int esd_proto_connect(connection *c, PA_GCC_UNUSED esd_proto_t request, c memcpy(&ekey, data, sizeof(uint32_t)); if (ekey == ESD_ENDIAN_KEY) - c->swap_byte_order = 0; + c->swap_byte_order = FALSE; else if (ekey == ESD_SWAP_ENDIAN_KEY) - c->swap_byte_order = 1; + c->swap_byte_order = TRUE; else { pa_log_warn("Client sent invalid endian key"); return -1; @@ -893,7 +893,7 @@ static void client_kill_cb(pa_client *c) { static int do_read(connection *c) { connection_assert_ref(c); -/* pa_log("READ"); */ +/* pa_log("READ"); */ if (c->state == ESD_NEXT_REQUEST) { ssize_t r; @@ -948,7 +948,7 @@ static int do_read(connection *c) { pa_assert(c->read_data && c->read_data_length < handler->data_length); if ((r = pa_iochannel_read(c->io, (uint8_t*) c->read_data + c->read_data_length, handler->data_length - c->read_data_length)) <= 0) { - if (errno == EINTR || errno == EAGAIN) + if (r < 0 && (errno == EINTR || errno == EAGAIN)) return 0; pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); @@ -978,7 +978,7 @@ static int do_read(connection *c) { pa_memblock_release(c->scache.memchunk.memblock); if (r <= 0) { - if (errno == EINTR || errno == EAGAIN) + if (r < 0 && (errno == EINTR || errno == EAGAIN)) return 0; pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); @@ -1041,7 +1041,7 @@ static int do_read(connection *c) { if (r <= 0) { - if (errno == EINTR || errno == EAGAIN) + if (r < 0 && (errno == EINTR || errno == EAGAIN)) return 0; pa_log_debug("read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); @@ -1072,7 +1072,7 @@ static int do_write(connection *c) { pa_assert(c->write_data_index < c->write_data_length); if ((r = pa_iochannel_write(c->io, (uint8_t*) c->write_data+c->write_data_index, c->write_data_length-c->write_data_index)) < 0) { - if (errno == EINTR || errno == EAGAIN) + if (r < 0 && (errno == EINTR || errno == EAGAIN)) return 0; pa_log("write(): %s", pa_cstrerror(errno)); @@ -1101,7 +1101,7 @@ static int do_write(connection *c) { if (r < 0) { - if (errno == EINTR || errno == EAGAIN) + if (r < 0 && (errno == EINTR || errno == EAGAIN)) return 0; pa_log("write(): %s", pa_cstrerror(errno)); @@ -1142,7 +1142,7 @@ static void do_work(connection *c) { fail: if (c->state == ESD_STREAMING_DATA && c->sink_input) { - c->dead = 1; + c->dead = TRUE; pa_iochannel_free(c->io); c->io = NULL; @@ -1354,8 +1354,8 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) c->client->userdata = c; c->authorized = !!p->public; - c->swap_byte_order = 0; - c->dead = 0; + c->swap_byte_order = FALSE; + c->dead = FALSE; c->read_data_length = 0; c->read_data = pa_xmalloc(c->read_data_alloc = proto_map[ESD_PROTO_CONNECT].data_length); @@ -1385,7 +1385,7 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) if (!c->authorized && p->auth_ip_acl && pa_ip_acl_check(p->auth_ip_acl, pa_iochannel_get_recv_fd(io)) > 0) { pa_log_info("Client authenticated by IP ACL."); - c->authorized = 1; + c->authorized = TRUE; } if (!c->authorized) { -- cgit From b718d18a2391726758e60862bfb6b6ee1b848daf Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 28 Oct 2007 16:35:09 +0000 Subject: fix error handling git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1965 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-simple.c | 15 +++++++-------- src/pulsecore/socket-client.c | 30 +++++++++++++++--------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index da5f24e7..64e2a81c 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -69,7 +69,7 @@ typedef struct connection { PA_DECLARE_CLASS(connection); #define CONNECTION(o) (connection_cast(o)) static PA_DEFINE_CHECK_TYPE(connection, pa_msgobject); - + struct pa_protocol_simple { pa_module *module; pa_core *core; @@ -108,7 +108,7 @@ static void connection_unlink(connection *c) { if (!c->protocol) return; - + if (c->sink_input) { pa_sink_input_unlink(c->sink_input); pa_sink_input_unref(c->sink_input); @@ -130,7 +130,7 @@ static void connection_unlink(connection *c) { pa_iochannel_free(c->io); c->io = NULL; } - + pa_assert_se(pa_idxset_remove_by_data(c->protocol->connections, c, NULL) == c); c->protocol = NULL; connection_unref(c); @@ -141,7 +141,7 @@ static void connection_free(pa_object *o) { pa_assert(c); connection_unref(c); - + if (c->playback.current_memblock) pa_memblock_unref(c->playback.current_memblock); @@ -185,7 +185,7 @@ static int do_read(connection *c) { if (r <= 0) { - if (errno == EINTR || errno == EAGAIN) + if (r < 0 && (errno == EINTR || errno == EAGAIN)) return 0; pa_log_debug("read(): %s", r == 0 ? "EOF" : pa_cstrerror(errno)); @@ -284,7 +284,7 @@ static int connection_process_msg(pa_msgobject *o, int code, void*userdata, int6 case CONNECTION_MESSAGE_REQUEST_DATA: do_work(c); break; - + case CONNECTION_MESSAGE_POST_DATA: /* pa_log("got data %u", chunk->length); */ pa_memblockq_push_align(c->output_memblockq, chunk); @@ -319,7 +319,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int pa_memblockq_push_align(c->input_memblockq, chunk); /* pa_log("got data, %u", pa_memblockq_get_length(c->input_memblockq)); */ - + return 0; } @@ -634,4 +634,3 @@ void pa_protocol_simple_free(pa_protocol_simple *p) { pa_xfree(p); } - diff --git a/src/pulsecore/socket-client.c b/src/pulsecore/socket-client.c index 6748c285..5b5bc5ca 100644 --- a/src/pulsecore/socket-client.c +++ b/src/pulsecore/socket-client.c @@ -134,7 +134,7 @@ static void do_call(pa_socket_client *c) { pa_iochannel *io = NULL; int error; socklen_t lerror; - + pa_assert(c); pa_assert(PA_REFCNT_VALUE(c) >= 1); pa_assert(c->callback); @@ -156,7 +156,7 @@ static void do_call(pa_socket_client *c) { } if (error != 0) { - pa_log_debug("connect(): %s", pa_cstrerror(errno)); + pa_log_debug("connect(): %s", pa_cstrerror(error)); errno = error; goto finish; } @@ -179,7 +179,7 @@ finish: static void connect_fixed_cb(pa_mainloop_api *m, pa_defer_event *e, void *userdata) { pa_socket_client *c = userdata; - + pa_assert(m); pa_assert(c); pa_assert(PA_REFCNT_VALUE(c) >= 1); @@ -196,13 +196,13 @@ static void connect_io_cb(pa_mainloop_api*m, pa_io_event *e, int fd, PA_GCC_UNUS pa_assert(PA_REFCNT_VALUE(c) >= 1); pa_assert(c->io_event == e); pa_assert(fd >= 0); - + do_call(c); } static int do_connect(pa_socket_client *c, const struct sockaddr *sa, socklen_t len) { int r; - + pa_assert(c); pa_assert(PA_REFCNT_VALUE(c) >= 1); pa_assert(sa); @@ -230,15 +230,15 @@ static int do_connect(pa_socket_client *c, const struct sockaddr *sa, socklen_t pa_socket_client* pa_socket_client_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port) { struct sockaddr_in sa; - + pa_assert(m); pa_assert(port > 0); - + memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = htons(port); sa.sin_addr.s_addr = htonl(address); - + return pa_socket_client_new_sockaddr(m, (struct sockaddr*) &sa, sizeof(sa)); } @@ -246,7 +246,7 @@ pa_socket_client* pa_socket_client_new_ipv4(pa_mainloop_api *m, uint32_t address pa_socket_client* pa_socket_client_new_unix(pa_mainloop_api *m, const char *filename) { struct sockaddr_un sa; - + pa_assert(m); pa_assert(filename); @@ -307,11 +307,11 @@ static int sockaddr_prepare(pa_socket_client *c, const struct sockaddr *sa, size pa_socket_client* pa_socket_client_new_sockaddr(pa_mainloop_api *m, const struct sockaddr *sa, size_t salen) { pa_socket_client *c; - + pa_assert(m); pa_assert(sa); pa_assert(salen > 0); - + pa_assert_se(c = pa_socket_client_new(m)); if (sockaddr_prepare(c, sa, salen) < 0) @@ -375,7 +375,7 @@ pa_socket_client* pa_socket_client_new_ipv6(pa_mainloop_api *m, uint8_t address[ pa_assert(m); pa_assert(address); pa_assert(port > 0); - + memset(&sa, 0, sizeof(sa)); sa.sin6_family = AF_INET6; sa.sin6_port = htons(port); @@ -390,7 +390,7 @@ static void asyncns_cb(pa_mainloop_api*m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_socket_client *c = userdata; struct addrinfo *res = NULL; int ret; - + pa_assert(m); pa_assert(c); pa_assert(PA_REFCNT_VALUE(c) >= 1); @@ -432,7 +432,7 @@ fail: static void timeout_cb(pa_mainloop_api *m, pa_time_event *e, const struct timeval *tv, void *userdata) { pa_socket_client *c = userdata; - + pa_assert(m); pa_assert(e); pa_assert(tv); @@ -460,7 +460,7 @@ static void start_timeout(pa_socket_client *c) { pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, const char*name, uint16_t default_port) { pa_socket_client *c = NULL; pa_parsed_address a; - + pa_assert(m); pa_assert(name); -- cgit From d8976a21aadf7e998e995c5e5416a8ed3703557e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 28 Oct 2007 16:45:59 +0000 Subject: Merge r1473 from trunk (mixer ioctls on /dev/dsp) git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1966 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/utils/padsp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/padsp.c b/src/utils/padsp.c index 299033e4..b48af93c 100644 --- a/src/utils/padsp.c +++ b/src/utils/padsp.c @@ -2292,7 +2292,8 @@ static int dsp_ioctl(fd_info *i, unsigned long request, void*argp, int *_errno) break; default: - debug(DEBUG_LEVEL_NORMAL, __FILE__": unknown ioctl 0x%08lx\n", request); + /* Mixer ioctls are valid on /dev/dsp aswell */ + return mixer_ioctl(i, request, argp, _errno); inval: *_errno = EINVAL; -- cgit From 9eb840cdee99ce4ecf835c00e32c62889ad4a561 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 28 Oct 2007 16:49:25 +0000 Subject: Merge r1503 from trunk: Make -no-undefined actually work (and fix up error found by it). git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1967 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index eee47191..28ed8699 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -64,7 +64,7 @@ AM_LIBADD = $(PTHREAD_LIBS) AM_LDADD = $(PTHREAD_LIBS) # Only required on some platforms but defined for all to avoid errors -AM_LDFLAGS = -no-undefined +AM_LDFLAGS = -Wl,-no-undefined if STATIC_BINS BINLDFLAGS = -static @@ -1271,7 +1271,7 @@ liboss_util_la_LIBADD = libpulsecore.la module_oss_la_SOURCES = modules/module-oss.c module_oss_la_LDFLAGS = -module -avoid-version -module_oss_la_LIBADD = $(AM_LIBADD) libiochannel.la liboss-util.la +module_oss_la_LIBADD = $(AM_LIBADD) libiochannel.la liboss-util.la libpulsecore.la # ALSA -- cgit From c6071b05a54ed8a5d3b06af3f586fa262279bc13 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 28 Oct 2007 16:50:25 +0000 Subject: Merge r1505 from trunk: Make sure we link to the core to get all symbols. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1968 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 28ed8699..e17e5ece 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1294,7 +1294,7 @@ module_alsa_source_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) module_solaris_la_SOURCES = modules/module-solaris.c module_solaris_la_LDFLAGS = -module -avoid-version -module_solaris_la_LIBADD = $(AM_LIBADD) libiochannel.la +module_solaris_la_LIBADD = $(AM_LIBADD) libiochannel.la libpulsecore.la # Avahi -- cgit From f096ca40aa2a607f18683ff1bdef5468c9be23f0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 28 Oct 2007 16:53:47 +0000 Subject: Merge r1504 from trunk: Solaris hides inet_ntop in nsl git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1969 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 27806cea..1a817c55 100644 --- a/configure.ac +++ b/configure.ac @@ -253,6 +253,7 @@ AC_SEARCH_LIBS([pow], [m]) AC_SEARCH_LIBS([sched_setscheduler], [rt]) AC_SEARCH_LIBS([dlopen], [dl]) AC_SEARCH_LIBS([shm_open], [rt]) +AC_SEARCH_LIBS([inet_ntop], [nsl]) # BSD AC_SEARCH_LIBS([connect], [socket]) -- cgit From 575541d20c4c21383d0c7ba40dd3c45c2949e18a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 28 Oct 2007 16:55:15 +0000 Subject: Merge r1502 from trunk: Move pthreads detection as it gets confused by things in LIBS. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1970 fefdeb5f-60dc-0310-8127-8f9354f1896f --- configure.ac | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 1a817c55..3a075e6c 100644 --- a/configure.ac +++ b/configure.ac @@ -244,6 +244,10 @@ AC_CHECK_DEFINE([INADDR_NONE], [netinet/in.h], [], [AC_CHECK_DEFINE([INADDR_NONE], [winsock2.h], [], [AC_DEFINE([INADDR_NONE], [0xffffffff], [Define INADDR_NONE if not found in ])])]) +#### POSIX threads #### + +ACX_PTHREAD + #### Check for libs #### # ISO @@ -297,10 +301,6 @@ AC_CHECK_FUNCS([lstat]) AC_CHECK_FUNCS([setresuid setresgid setreuid setregid seteuid setegid ppoll strsignal sig2str strtof_l]) -#### POSIX threads #### - -ACX_PTHREAD - AC_MSG_CHECKING([for PTHREAD_PRIO_INHERIT]) AC_LANG_CONFTEST([AC_LANG_SOURCE([[ #include -- cgit