[pulseaudio-commits] r1404 - in /trunk/src: ./ modules/ modules/rtp/ pulse/ pulsecore/ tests/

svnmailer-noreply at 0pointer.de svnmailer-noreply at 0pointer.de
Tue Sep 26 16:50:56 PDT 2006


Author: lennart
Date: Wed Sep 27 01:50:56 2006
New Revision: 1404

URL: http://0pointer.de/cgi-bin/viewcvs.cgi?rev=3D1404&root=3Dpulseaudio&vi=
ew=3Drev
Log:
rework memory block management to be thread-safe and mostly lock-free.

pa_memblock is now an opaque structure. Access to its fields is now done
through various accessor functions in a thread-safe manner.

pa_memblock_acquire() and pa_memblock_release() are now used to access the
attached audio data. Why? To allow safe manipulation of the memory pointer
maintained by the memory block. Internally _acquire() and _release() mainta=
in a
reference counter. Please do not confuse this reference counter whith the o=
ne
maintained by pa_memblock_ref()/_unref()!

As a side effect this patch removes all direct usages of AO_t and replaces =
it
with pa_atomic_xxx based code.

This stuff needs some serious testing love. Especially if threads are activ=
ely
used.


Modified:
    trunk/src/Makefile.am
    trunk/src/modules/module-alsa-sink.c
    trunk/src/modules/module-alsa-source.c
    trunk/src/modules/module-esound-sink.c
    trunk/src/modules/module-jack-sink.c
    trunk/src/modules/module-jack-source.c
    trunk/src/modules/module-oss-mmap.c
    trunk/src/modules/module-oss.c
    trunk/src/modules/module-pipe-sink.c
    trunk/src/modules/module-pipe-source.c
    trunk/src/modules/module-sine.c
    trunk/src/modules/rtp/rtp.c
    trunk/src/pulse/internal.h
    trunk/src/pulse/stream.c
    trunk/src/pulsecore/cli-command.c
    trunk/src/pulsecore/mcalign.c
    trunk/src/pulsecore/memblock.c
    trunk/src/pulsecore/memblock.h
    trunk/src/pulsecore/memblockq.c
    trunk/src/pulsecore/memchunk.c
    trunk/src/pulsecore/play-memchunk.c
    trunk/src/pulsecore/protocol-esound.c
    trunk/src/pulsecore/protocol-native.c
    trunk/src/pulsecore/protocol-simple.c
    trunk/src/pulsecore/pstream.c
    trunk/src/pulsecore/resampler.c
    trunk/src/pulsecore/sample-util.c
    trunk/src/pulsecore/sample-util.h
    trunk/src/pulsecore/sink-input.c
    trunk/src/pulsecore/sink.c
    trunk/src/pulsecore/sound-file-stream.c
    trunk/src/pulsecore/sound-file.c
    trunk/src/tests/flist-test.c
    trunk/src/tests/mcalign-test.c
    trunk/src/tests/memblock-test.c
    trunk/src/tests/memblockq-test.c

Modified: trunk/src/Makefile.am
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/Makefile.am?rev=3D140=
4&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Wed Sep 27 01:50:56 2006
@@ -268,8 +268,7 @@
 thread_test_LDADD =3D $(AM_LDADD) libpulsecore.la
 thread_test_LDFLAGS =3D $(AM_LDFLAGS) $(BINLDFLAGS) =

 =

-flist_test_SOURCES =3D tests/flist-test.c \
-		pulsecore/flist.c pulsecore/flist.h
+flist_test_SOURCES =3D tests/flist-test.c
 flist_test_CFLAGS =3D $(AM_CFLAGS)
 flist_test_LDADD =3D $(AM_LDADD) libpulsecore.la
 flist_test_LDFLAGS =3D $(AM_LDFLAGS) $(BINLDFLAGS) =

@@ -448,6 +447,8 @@
 		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/anotify.c pulsecore/anotify.h \
 		$(PA_THREAD_OBJS)
 =

 if OS_IS_WIN32
@@ -628,6 +629,8 @@
 		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

Modified: trunk/src/modules/module-alsa-sink.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/modules/module-alsa-s=
ink.c?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/modules/module-alsa-sink.c (original)
+++ trunk/src/modules/module-alsa-sink.c Wed Sep 27 01:50:56 2006
@@ -144,6 +144,7 @@
     update_usage(u);
     =

     for (;;) {
+        void *p;
         pa_memchunk *memchunk =3D NULL;
         snd_pcm_sframes_t frames;
         =

@@ -156,9 +157,15 @@
                 memchunk =3D &u->memchunk;
         }
             =

-        assert(memchunk->memblock && memchunk->memblock->data && memchunk-=
>length && memchunk->memblock->length && (memchunk->length % u->frame_size)=
 =3D=3D 0);
-
-        if ((frames =3D snd_pcm_writei(u->pcm_handle, (uint8_t*) memchunk-=
>memblock->data + memchunk->index, memchunk->length / u->frame_size)) < 0) {
+        assert(memchunk->memblock);
+        assert(memchunk->length);
+        assert((memchunk->length % u->frame_size) =3D=3D 0);
+
+        p =3D pa_memblock_acquire(memchunk->memblock);
+        =

+        if ((frames =3D snd_pcm_writei(u->pcm_handle, (uint8_t*) p + memch=
unk->index, memchunk->length / u->frame_size)) < 0) {
+            pa_memblock_release(memchunk->memblock);
+            =

             if (frames =3D=3D -EAGAIN)
                 return;
 =

@@ -175,6 +182,9 @@
             pa_module_unload_request(u->module);
             return;
         }
+
+        pa_memblock_release(memchunk->memblock);
+        =

 =

         if (memchunk =3D=3D &u->memchunk) {
             size_t l =3D frames * u->frame_size;

Modified: trunk/src/modules/module-alsa-source.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/modules/module-alsa-s=
ource.c?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/modules/module-alsa-source.c (original)
+++ trunk/src/modules/module-alsa-source.c Wed Sep 27 01:50:56 2006
@@ -149,6 +149,7 @@
         pa_memchunk post_memchunk;
         snd_pcm_sframes_t frames;
         size_t l;
+        void *p;
         =

         if (!u->memchunk.memblock) {
             u->memchunk.memblock =3D pa_memblock_new(u->source->core->memp=
ool, u->memchunk.length =3D u->fragment_size);
@@ -157,11 +158,13 @@
             =

         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 =3D=3D 0);
 =

-        if ((frames =3D snd_pcm_readi(u->pcm_handle, (uint8_t*) u->memchun=
k.memblock->data + u->memchunk.index, u->memchunk.length / u->frame_size)) =
< 0) {
+        p =3D pa_memblock_acquire(u->memchunk.memblock);
+        =

+        if ((frames =3D snd_pcm_readi(u->pcm_handle, (uint8_t*) p + u->mem=
chunk.index, u->memchunk.length / u->frame_size)) < 0) {
+            pa_memblock_release(u->memchunk.memblock);
+            =

             if (frames =3D=3D -EAGAIN)
                 return;
             =

@@ -178,6 +181,7 @@
             pa_module_unload_request(u->module);
             return;
         }
+        pa_memblock_release(u->memchunk.memblock);
 =

         l =3D frames * u->frame_size;
         =


Modified: trunk/src/modules/module-esound-sink.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/modules/module-esound=
-sink.c?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/modules/module-esound-sink.c (original)
+++ trunk/src/modules/module-esound-sink.c Wed Sep 27 01:50:56 2006
@@ -142,18 +142,25 @@
             u->write_index =3D u->write_length =3D 0;
         }
     } else if (u->state =3D=3D 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);
-        =

-        if ((r =3D pa_iochannel_write(u->io, (uint8_t*) u->memchunk.memblo=
ck->data + u->memchunk.index, u->memchunk.length)) < 0) {
+        assert(u->memchunk.memblock);
+        assert(u->memchunk.length);
+
+        p =3D pa_memblock_acquire(u->memchunk.memblock);
+        =

+        if ((r =3D pa_iochannel_write(u->io, (uint8_t*) p + u->memchunk.in=
dex, 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 +=3D r;
         u->memchunk.length -=3D r;

Modified: trunk/src/modules/module-jack-sink.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/modules/module-jack-s=
ink.c?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/modules/module-jack-sink.c (original)
+++ trunk/src/modules/module-jack-sink.c Wed Sep 27 01:50:56 2006
@@ -135,22 +135,25 @@
         unsigned fs;
         jack_nframes_t frame_idx;
         pa_memchunk chunk;
+        void *p;
         =

         fs =3D pa_frame_size(&u->sink->sample_spec);
 =

         pa_sink_render_full(u->sink, u->frames_requested * fs, &chunk);
+        p =3D pa_memblock_acquire(chunk.memblock);
 =

         for (frame_idx =3D 0; frame_idx < u->frames_requested; frame_idx +=
+) {
             unsigned c;
                 =

             for (c =3D 0; c < u->channels; c++) {
-                float *s =3D ((float*) ((uint8_t*) chunk.memblock->data + =
chunk.index)) + (frame_idx * u->channels) + c;
+                float *s =3D ((float*) ((uint8_t*) p + chunk.index)) + (fr=
ame_idx * u->channels) + c;
                 float *d =3D ((float*) u->buffer[c]) + frame_idx;
                 =

                 *d =3D *s;
             }
         }
         =

+        pa_memblock_release(chunk.memblock);
         pa_memblock_unref(chunk.memblock);
 =

         u->frames_requested =3D 0;

Modified: trunk/src/modules/module-jack-source.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/modules/module-jack-s=
ource.c?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/modules/module-jack-source.c (original)
+++ trunk/src/modules/module-jack-source.c Wed Sep 27 01:50:56 2006
@@ -134,23 +134,28 @@
         unsigned fs;
         jack_nframes_t frame_idx;
         pa_memchunk chunk;
+        void *p;
         =

         fs =3D pa_frame_size(&u->source->sample_spec);
 =

         chunk.memblock =3D pa_memblock_new(u->core->mempool, chunk.length =
=3D u->frames_posted * fs);
         chunk.index =3D 0;
+
+        p =3D pa_memblock_acquire(chunk.memblock);
         =

         for (frame_idx =3D 0; frame_idx < u->frames_posted; frame_idx ++) {
             unsigned c;
                 =

             for (c =3D 0; c < u->channels; c++) {
                 float *s =3D ((float*) u->buffer[c]) + frame_idx;
-                float *d =3D ((float*) ((uint8_t*) chunk.memblock->data + =
chunk.index)) + (frame_idx * u->channels) + c;
+                float *d =3D ((float*) ((uint8_t*) p + chunk.index)) + (fr=
ame_idx * u->channels) + c;
                 =

                 *d =3D *s;
             }
         }
 =

+        pa_memblock_release(chunk.memblock);
+        =

         pa_source_post(u->source, &chunk);
         pa_memblock_unref(chunk.memblock);
 =


Modified: trunk/src/modules/module-oss-mmap.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/modules/module-oss-mm=
ap.c?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/modules/module-oss-mmap.c (original)
+++ trunk/src/modules/module-oss-mmap.c Wed Sep 27 01:50:56 2006
@@ -170,7 +170,7 @@
                     u->out_fragment_size,
                     1);
         assert(chunk.memblock);
-        chunk.length =3D chunk.memblock->length;
+        chunk.length =3D pa_memblock_get_length(chunk.memblock);
         chunk.index =3D 0;
         =

         pa_sink_render_into_full(u->sink, &chunk);
@@ -214,7 +214,7 @@
         =

         if (!u->in_memblocks[u->in_current]) {
             chunk.memblock =3D u->in_memblocks[u->in_current] =3D pa_membl=
ock_new_fixed(u->core->mempool, (uint8_t*) u->in_mmap+u->in_fragment_size*u=
->in_current, u->in_fragment_size, 1);
-            chunk.length =3D chunk.memblock->length;
+            chunk.length =3D pa_memblock_get_length(chunk.memblock);
             chunk.index =3D 0;
             =

             pa_source_post(u->source, &chunk);

Modified: trunk/src/modules/module-oss.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/modules/module-oss.c?=
rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/modules/module-oss.c (original)
+++ trunk/src/modules/module-oss.c Wed Sep 27 01:50:56 2006
@@ -155,6 +155,7 @@
     }
 =

     do {
+        void *p;
         memchunk =3D &u->memchunk;
         =

         if (!memchunk->length)
@@ -162,16 +163,18 @@
                 memchunk =3D &u->silence;
         =

         assert(memchunk->memblock);
-        assert(memchunk->memblock->data);
         assert(memchunk->length);
-        =

-        if ((r =3D pa_iochannel_write(u->io, (uint8_t*) memchunk->memblock=
->data + memchunk->index, memchunk->length)) < 0) {
+
+        p =3D pa_memblock_acquire(memchunk->memblock);
+        if ((r =3D pa_iochannel_write(u->io, (uint8_t*) p + memchunk->inde=
x, memchunk->length)) < 0) {
+            pa_memblock_release(memchunk->memblock);
             pa_log("write() failed: %s", pa_cstrerror(errno));
 =

             clear_up(u);
             pa_module_unload_request(u->module);
             break;
         }
+        pa_memblock_release(memchunk->memblock);
         =

         if (memchunk =3D=3D &u->silence)
             assert(r % u->sample_size =3D=3D 0);
@@ -217,9 +220,13 @@
     }
     =

     do {
+        void *p;
         memchunk.memblock =3D pa_memblock_new(u->core->mempool, l);
-        assert(memchunk.memblock);
-        if ((r =3D pa_iochannel_read(u->io, memchunk.memblock->data, memch=
unk.memblock->length)) < 0) {
+
+        p =3D pa_memblock_acquire(memchunk.memblock);
+        =

+        if ((r =3D pa_iochannel_read(u->io, p, pa_memblock_get_length(memc=
hunk.memblock))) < 0) {
+            pa_memblock_release(memchunk.memblock);
             pa_memblock_unref(memchunk.memblock);
             if (errno !=3D EAGAIN) {
                 pa_log("read() failed: %s", pa_cstrerror(errno));
@@ -228,9 +235,10 @@
             }
             break;
         }
-        =

-        assert(r <=3D (ssize_t) memchunk.memblock->length);
-        memchunk.length =3D memchunk.memblock->length =3D r;
+        pa_memblock_release(memchunk.memblock);
+        =

+        assert(r <=3D (ssize_t) pa_memblock_get_length(memchunk.memblock));
+        memchunk.length =3D r;
         memchunk.index =3D 0;
         =

         pa_source_post(u->source, &memchunk);

Modified: trunk/src/modules/module-pipe-sink.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/modules/module-pipe-s=
ink.c?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/modules/module-pipe-sink.c (original)
+++ trunk/src/modules/module-pipe-sink.c Wed Sep 27 01:50:56 2006
@@ -84,6 +84,8 @@
 =

 static void do_write(struct userdata *u) {
     ssize_t r;
+    void *p;
+    =

     assert(u);
 =

     u->core->mainloop->defer_enable(u->defer_event, 0);
@@ -97,12 +99,17 @@
         if (pa_sink_render(u->sink, PIPE_BUF, &u->memchunk) < 0)
             return;
 =

-    assert(u->memchunk.memblock && u->memchunk.length);
-    =

-    if ((r =3D pa_iochannel_write(u->io, (uint8_t*) u->memchunk.memblock->=
data + u->memchunk.index, u->memchunk.length)) < 0) {
+    assert(u->memchunk.memblock);
+    assert(u->memchunk.length);
+
+    p =3D pa_memblock_acquire(u->memchunk.memblock);
+    =

+    if ((r =3D pa_iochannel_write(u->io, (uint8_t*) p + u->memchunk.index,=
 u->memchunk.length)) < 0) {
+        pa_memblock_release(u->memchunk.memblock);
         pa_log("write(): %s", pa_cstrerror(errno));
         return;
     }
+    pa_memblock_release(u->memchunk.memblock);
 =

     u->memchunk.index +=3D r;
     u->memchunk.length -=3D r;

Modified: trunk/src/modules/module-pipe-source.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/modules/module-pipe-s=
ource.c?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/modules/module-pipe-source.c (original)
+++ trunk/src/modules/module-pipe-source.c Wed Sep 27 01:50:56 2006
@@ -82,7 +82,9 @@
 =

 static void do_read(struct userdata *u) {
     ssize_t r;
+    void *p;
     pa_memchunk chunk;
+    =

     assert(u);
 =

     if (!pa_iochannel_is_readable(u->io))
@@ -95,17 +97,22 @@
         u->chunk.index =3D chunk.length =3D 0;
     }
 =

-    assert(u->chunk.memblock && u->chunk.memblock->length > u->chunk.index=
);
-    if ((r =3D pa_iochannel_read(u->io, (uint8_t*) u->chunk.memblock->data=
 + u->chunk.index, u->chunk.memblock->length - u->chunk.index)) <=3D 0) {
+    assert(u->chunk.memblock);
+    assert(pa_memblock_get_length(u->chunk.memblock) > u->chunk.index);
+
+    p =3D pa_memblock_acquire(u->chunk.memblock);
+    if ((r =3D pa_iochannel_read(u->io, (uint8_t*) p + u->chunk.index, pa_=
memblock_get_length(u->chunk.memblock) - u->chunk.index)) <=3D 0) {
+        pa_memblock_release(u->chunk.memblock);
         pa_log("read(): %s", pa_cstrerror(errno));
         return;
     }
+    pa_memblock_release(u->chunk.memblock);
 =

     u->chunk.length =3D r;
     pa_source_post(u->source, &u->chunk);
     u->chunk.index +=3D r;
 =

-    if (u->chunk.index >=3D u->chunk.memblock->length) {
+    if (u->chunk.index >=3D pa_memblock_get_length(u->chunk.memblock)) {
         u->chunk.index =3D u->chunk.length =3D 0;
         pa_memblock_unref(u->chunk.memblock);
         u->chunk.memblock =3D NULL;

Modified: trunk/src/modules/module-sine.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/modules/module-sine.c=
?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/modules/module-sine.c (original)
+++ trunk/src/modules/module-sine.c Wed Sep 27 01:50:56 2006
@@ -63,7 +63,7 @@
 =

     chunk->memblock =3D pa_memblock_ref(u->memblock);
     chunk->index =3D u->peek_index;
-    chunk->length =3D u->memblock->length - u->peek_index;
+    chunk->length =3D pa_memblock_get_length(u->memblock) - u->peek_index;
     return 0;
 }
 =

@@ -72,11 +72,12 @@
     assert(i && chunk && length && i->userdata);
     u =3D i->userdata;
 =

-    assert(chunk->memblock =3D=3D u->memblock && length <=3D u->memblock->=
length-u->peek_index);
+    assert(chunk->memblock =3D=3D u->memblock);
+    assert(length <=3D pa_memblock_get_length(u->memblock)-u->peek_index);
 =

     u->peek_index +=3D length;
 =

-    if (u->peek_index >=3D u->memblock->length)
+    if (u->peek_index >=3D pa_memblock_get_length(u->memblock))
         u->peek_index =3D 0;
 }
 =

@@ -109,6 +110,7 @@
     pa_sample_spec ss;
     uint32_t frequency;
     char t[256];
+    void *p;
     pa_sink_input_new_data data;
 =

     if (!(ma =3D pa_modargs_new(m->argument, valid_modargs))) {
@@ -140,8 +142,10 @@
     }
     =

     u->memblock =3D pa_memblock_new(c->mempool, pa_bytes_per_second(&ss));
-    calc_sine(u->memblock->data, u->memblock->length, frequency);
-
+    p =3D 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);
 =

     pa_sink_input_new_data_init(&data);

Modified: trunk/src/modules/rtp/rtp.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/modules/rtp/rtp.c?rev=
=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/modules/rtp/rtp.c (original)
+++ trunk/src/modules/rtp/rtp.c Wed Sep 27 01:50:56 2006
@@ -79,7 +79,7 @@
             size_t k =3D n + chunk.length > size ? size - n : chunk.length;
 =

             if (chunk.memblock) {
-                iov[iov_idx].iov_base =3D (void*)((uint8_t*) chunk.membloc=
k->data + chunk.index);
+                iov[iov_idx].iov_base =3D (void*)((uint8_t*) pa_memblock_a=
cquire(chunk.memblock) + chunk.index);
                 iov[iov_idx].iov_len =3D k;
                 mb[iov_idx] =3D chunk.memblock;
                 iov_idx ++;
@@ -114,8 +114,10 @@
                 =

                 k =3D sendmsg(c->fd, &m, MSG_DONTWAIT);
 =

-                for (i =3D 1; i < iov_idx; i++)
+                for (i =3D 1; i < iov_idx; i++) {
+                    pa_memblock_release(mb[i]);
                     pa_memblock_unref(mb[i]);
+                }
 =

                 c->sequence++;
             } else
@@ -172,7 +174,7 @@
 =

     chunk->memblock =3D pa_memblock_new(pool, size);
 =

-    iov.iov_base =3D chunk->memblock->data;
+    iov.iov_base =3D pa_memblock_acquire(chunk->memblock);
     iov.iov_len =3D size;
 =

     m.msg_name =3D NULL;
@@ -193,9 +195,9 @@
         goto fail;
     }
 =

-    memcpy(&header, chunk->memblock->data, sizeof(uint32_t));
-    memcpy(&c->timestamp, (uint8_t*) chunk->memblock->data + 4, sizeof(uin=
t32_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 =3D ntohl(header);
     c->timestamp =3D ntohl(c->timestamp);
@@ -236,8 +238,10 @@
     return 0;
 =

 fail:
-    if (chunk->memblock)
+    if (chunk->memblock) {
+        pa_memblock_release(chunk->memblock);
         pa_memblock_unref(chunk->memblock);
+    }
 =

     return -1;
 }

Modified: trunk/src/pulse/internal.h
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulse/internal.h?rev=
=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulse/internal.h (original)
+++ trunk/src/pulse/internal.h Wed Sep 27 01:50:56 2006
@@ -113,6 +113,7 @@
     uint32_t requested_bytes;
 =

     pa_memchunk peek_memchunk;
+    void *peek_data;
     pa_memblockq *record_memblockq;
 =

     int corked;

Modified: trunk/src/pulse/stream.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulse/stream.c?rev=3D=
1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulse/stream.c (original)
+++ trunk/src/pulse/stream.c Wed Sep 27 01:50:56 2006
@@ -88,6 +88,7 @@
     s->peek_memchunk.index =3D 0;
     s->peek_memchunk.length =3D 0;
     s->peek_memchunk.memblock =3D NULL;
+    s->peek_data =3D NULL;
 =

     s->record_memblockq =3D NULL;
 =

@@ -122,8 +123,11 @@
         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);
@@ -605,8 +609,11 @@
     if (free_cb) =

         chunk.memblock =3D pa_memblock_new_user(s->context->mempool, (void=
*) data, length, free_cb, 1);
     else {
+        void *tdata;
         chunk.memblock =3D pa_memblock_new(s->context->mempool, length);
-        memcpy(chunk.memblock->data, data, length);
+        tdata =3D pa_memblock_acquire(chunk.memblock);
+        memcpy(tdata, data, length);
+        pa_memblock_release(chunk.memblock);
     }
         =

     chunk.index =3D 0;
@@ -672,9 +679,12 @@
             *length =3D 0;
             return 0;
         }
-    }
-
-    *data =3D (const char*) s->peek_memchunk.memblock->data + s->peek_memc=
hunk.index;
+
+        s->peek_data =3D pa_memblock_acquire(s->peek_memchunk.memblock);
+    }
+
+    assert(s->peek_data);
+    *data =3D (uint8_t*) s->peek_data + s->peek_memchunk.index;
     *length =3D s->peek_memchunk.length;
     return 0;
 }
@@ -692,7 +702,9 @@
     /* Fix the simulated local read index */
     if (s->timing_info_valid && !s->timing_info.read_index_corrupt)
         s->timing_info.read_index +=3D 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 =3D 0;
     s->peek_memchunk.index =3D 0;

Modified: trunk/src/pulsecore/cli-command.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/cli-command=
.c?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulsecore/cli-command.c (original)
+++ trunk/src/pulsecore/cli-command.c Wed Sep 27 01:50:56 2006
@@ -259,20 +259,20 @@
     stat =3D pa_mempool_get_stat(c->mempool);
     =

     pa_strbuf_printf(buf, "Memory blocks currently allocated: %u, size: %s=
.\n",
-                     (unsigned) AO_load_acquire_read((AO_t*) &stat->n_allo=
cated),
-                     pa_bytes_snprint(s, sizeof(s), (size_t) AO_load_acqui=
re_read((AO_t*) &stat->allocated_size)));
+                     (unsigned) pa_atomic_load(&stat->n_allocated),
+                     pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_loa=
d(&stat->allocated_size)));
 =

     pa_strbuf_printf(buf, "Memory blocks allocated during the whole lifeti=
me: %u, size: %s.\n",
-                     (unsigned) AO_load_acquire_read((AO_t*) &stat->n_accu=
mulated),
-                     pa_bytes_snprint(s, sizeof(s), (size_t) AO_load_acqui=
re_read((AO_t*) &stat->accumulated_size)));
+                     (unsigned) pa_atomic_load(&stat->n_accumulated),
+                     pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_loa=
d(&stat->accumulated_size)));
 =

     pa_strbuf_printf(buf, "Memory blocks imported from other processes: %u=
, size: %s.\n",
-                     (unsigned) AO_load_acquire_read((AO_t*) &stat->n_impo=
rted),
-                     pa_bytes_snprint(s, sizeof(s), (size_t) AO_load_acqui=
re_read((AO_t*) &stat->imported_size)));
+                     (unsigned) pa_atomic_load(&stat->n_imported),
+                     pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_loa=
d(&stat->imported_size)));
 =

     pa_strbuf_printf(buf, "Memory blocks exported to other processes: %u, =
size: %s.\n",
-                     (unsigned) AO_load_acquire_read((AO_t*) &stat->n_expo=
rted),
-                     pa_bytes_snprint(s, sizeof(s), (size_t) AO_load_acqui=
re_read((AO_t*) &stat->exported_size)));
+                     (unsigned) pa_atomic_load(&stat->n_exported),
+                     pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_loa=
d(&stat->exported_size)));
 =

     pa_strbuf_printf(buf, "Total sample cache size: %s.\n",
                      pa_bytes_snprint(s, sizeof(s), pa_scache_total_size(c=
)));
@@ -289,8 +289,8 @@
         pa_strbuf_printf(buf,
                          "Memory blocks of type %s: %u allocated/%u accumu=
lated.\n",
                          type_table[k],
-                         (unsigned) AO_load_acquire_read(&stat->n_allocate=
d_by_type[k]),
-                         (unsigned) AO_load_acquire_read(&stat->n_accumula=
ted_by_type[k]));
+                         (unsigned) pa_atomic_load(&stat->n_allocated_by_t=
ype[k]),
+                         (unsigned) pa_atomic_load(&stat->n_accumulated_by=
_type[k]));
     =

     return 0;
 }

Modified: trunk/src/pulsecore/mcalign.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/mcalign.c?r=
ev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulsecore/mcalign.c (original)
+++ trunk/src/pulsecore/mcalign.c Wed Sep 27 01:50:56 2006
@@ -89,6 +89,7 @@
 =

         } else {
             size_t l;
+            void *lo_data, *m_data;
 =

             /* We have to copy */
             assert(m->leftover.length < m->base);
@@ -100,10 +101,15 @@
             /* Can we use the current block? */
             pa_memchunk_make_writable(&m->leftover, m->base);
 =

-            memcpy((uint8_t*) m->leftover.memblock->data + m->leftover.ind=
ex + m->leftover.length, (uint8_t*) c->memblock->data + c->index, l);
+            lo_data =3D pa_memblock_acquire(m->leftover.memblock);
+            m_data =3D pa_memblock_acquire(c->memblock);
+            memcpy((uint8_t*) lo_data + m->leftover.index + m->leftover.le=
ngth, (uint8_t*) m_data + c->index, l);
+            pa_memblock_release(m->leftover.memblock);
+            pa_memblock_release(c->memblock);
             m->leftover.length +=3D l;
 =

-            assert(m->leftover.length <=3D m->base && m->leftover.length <=
=3D m->leftover.memblock->length);
+            assert(m->leftover.length <=3D m->base);
+            assert(m->leftover.length <=3D pa_memblock_get_length(m->lefto=
ver.memblock));
 =

             if (c->length > l) {
                 /* Save the remainder of the memory block */

Modified: trunk/src/pulsecore/memblock.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/memblock.c?=
rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulsecore/memblock.c (original)
+++ trunk/src/pulsecore/memblock.c Wed Sep 27 01:50:56 2006
@@ -30,10 +30,13 @@
 #include <unistd.h>
 =

 #include <pulse/xmalloc.h>
+#include <pulse/def.h>
 =

 #include <pulsecore/shm.h>
 #include <pulsecore/log.h>
 #include <pulsecore/hashmap.h>
+#include <pulsecore/mutex.h>
+#include <pulsecore/flist.h>
 =

 #include "memblock.h"
 =

@@ -44,6 +47,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_int_t n_acquired;
+    pa_atomic_int_t please_signal;
+
+    union {
+        struct {
+            /* If type =3D=3D PA_MEMBLOCK_USER this points to a function f=
or 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;
@@ -52,6 +81,8 @@
 };
 =

 struct pa_memimport {
+    pa_mutex *mutex;
+    =

     pa_mempool *pool;
     pa_hashmap *segments;
     pa_hashmap *blocks;
@@ -70,9 +101,11 @@
 };
 =

 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;
@@ -92,63 +125,71 @@
 };
 =

 struct pa_mempool {
+    pa_mutex *mutex;
+    pa_cond *cond;
+    =

     pa_shm memory;
     size_t block_size;
-    unsigned n_blocks, n_init;
+    unsigned n_blocks;
+
+    pa_atomic_int_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);
 =

-    AO_fetch_and_add1_release_write(&b->pool->stat.n_allocated);
-    AO_fetch_and_add_release_write(&b->pool->stat.allocated_size, (AO_t) b=
->length);
-
-    AO_fetch_and_add1_release_write(&b->pool->stat.n_accumulated);
-    AO_fetch_and_add_release_write(&b->pool->stat.accumulated_size, (AO_t)=
 b->length);
+    pa_atomic_inc(&b->pool->stat.n_allocated);
+    pa_atomic_add(&b->pool->stat.allocated_size, (int) b->length);
+
+    pa_atomic_inc(&b->pool->stat.n_accumulated);
+    pa_atomic_add(&b->pool->stat.accumulated_size, (int) b->length);
 =

     if (b->type =3D=3D PA_MEMBLOCK_IMPORTED) {
-        AO_fetch_and_add1_release_write(&b->pool->stat.n_imported);
-        AO_fetch_and_add_release_write(&b->pool->stat.imported_size, (AO_t=
) b->length);
-    }
-
-    AO_fetch_and_add1_release_write(&b->pool->stat.n_allocated_by_type[b->=
type]);
-    AO_fetch_and_add1_release_write(&b->pool->stat.n_accumulated_by_type[b=
->type]);
-}
-
+        pa_atomic_inc(&b->pool->stat.n_imported);
+        pa_atomic_add(&b->pool->stat.imported_size, (int) b->length);
+    }
+
+    pa_atomic_inc(&b->pool->stat.n_allocated_by_type[b->type]);
+    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);
 =

-    assert(AO_load_acquire_read(&b->pool->stat.n_allocated) > 0);
-    assert(AO_load_acquire_read(&b->pool->stat.allocated_size) >=3D (AO_t)=
 b->length);
+    assert(pa_atomic_load(&b->pool->stat.n_allocated) > 0);
+    assert(pa_atomic_load(&b->pool->stat.allocated_size) >=3D (int) b->len=
gth);
            =

-    AO_fetch_and_sub1_release_write(&b->pool->stat.n_allocated);
-    AO_fetch_and_add_release_write(&b->pool->stat.allocated_size,  (AO_t) =
(-b->length));
+    pa_atomic_dec(&b->pool->stat.n_allocated);
+    pa_atomic_add(&b->pool->stat.allocated_size, - (int) b->length);
 =

     if (b->type =3D=3D PA_MEMBLOCK_IMPORTED) {
-        assert(AO_load_acquire_read(&b->pool->stat.n_imported) > 0);
-        assert(AO_load_acquire_read(&b->pool->stat.imported_size) >=3D (AO=
_t) b->length);
+        assert(pa_atomic_load(&b->pool->stat.n_imported) > 0);
+        assert(pa_atomic_load(&b->pool->stat.imported_size) >=3D (int) b->=
length);
         =

-        AO_fetch_and_sub1_release_write(&b->pool->stat.n_imported);
-        AO_fetch_and_add_release_write(&b->pool->stat.imported_size, (AO_t=
)  (-b->length));
-    }
-
-    AO_fetch_and_sub1_release_write(&b->pool->stat.n_allocated_by_type[b->=
type]);
+        pa_atomic_dec(&b->pool->stat.n_imported);
+        pa_atomic_add(&b->pool->stat.imported_size, - (int) b->length);
+    }
+
+    pa_atomic_dec(&b->pool->stat.n_allocated_by_type[b->type]);
 }
 =

 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;
     =

@@ -161,6 +202,7 @@
     return b;
 }
 =

+/* No lock necessary */
 static pa_memblock *memblock_new_appended(pa_mempool *p, size_t length) {
     pa_memblock *b;
 =

@@ -168,49 +210,61 @@
     assert(length > 0);
 =

     b =3D pa_xmalloc(sizeof(pa_memblock) + length);
+    PA_REFCNT_INIT(b);
+    b->pool =3D p;
     b->type =3D PA_MEMBLOCK_APPENDED;
     b->read_only =3D 0;
-    PA_REFCNT_INIT(b);
+    pa_atomic_ptr_store(&b->data, (uint8_t*)b + sizeof(pa_memblock));
     b->length =3D length;
-    b->data =3D (uint8_t*) b + sizeof(pa_memblock);
-    b->pool =3D 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 =3D p->free_slots;
-        PA_LLIST_REMOVE(struct mempool_slot, p->free_slots, slot);
-    } else if (p->n_init < p->n_blocks)
-        slot =3D (struct mempool_slot*) ((uint8_t*) p->memory.ptr + (p->bl=
ock_size * p->n_init++));
-    else {
-        pa_log_debug("Pool full");
-        AO_fetch_and_add1_release_write(&p->stat.n_pool_full);
-        return NULL;
+    if (!(slot =3D pa_flist_pop(p->free_slots))) {
+        int idx;
+        =

+        /* The free list was empty, we have to allocate a new entry */
+
+        if ((unsigned) (idx =3D pa_atomic_inc(&p->n_init)) >=3D p->n_block=
s)
+            pa_atomic_dec(&p->n_init);
+        else
+            slot =3D (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 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 >=3D (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;
 =

@@ -220,6 +274,7 @@
     return (struct mempool_slot*) ((uint8_t*) p->memory.ptr + (idx * p->bl=
ock_size));
 }
 =

+/* No lock necessary */
 pa_memblock *pa_memblock_new_pool(pa_mempool *p, size_t length) {
     pa_memblock *b =3D NULL;
     struct mempool_slot *slot;
@@ -234,7 +289,7 @@
         =

         b =3D mempool_slot_data(slot);
         b->type =3D PA_MEMBLOCK_POOL;
-        b->data =3D (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) >=3D length) {
 =

@@ -243,22 +298,26 @@
         =

         b =3D pa_xnew(pa_memblock, 1);
         b->type =3D PA_MEMBLOCK_POOL_EXTERNAL;
-        b->data =3D 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));
-        AO_fetch_and_add1_release_write(&p->stat.n_too_large_for_pool);
+        pa_atomic_inc(&p->stat.n_too_large_for_pool);
         return NULL;
     }
 =

-    b->length =3D length;
-    b->read_only =3D 0;
     PA_REFCNT_INIT(b);
     b->pool =3D p;
+    b->read_only =3D 0;
+    b->length =3D 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;
 =

@@ -267,17 +326,20 @@
     assert(length > 0);
 =

     b =3D pa_xnew(pa_memblock, 1);
+    PA_REFCNT_INIT(b);
+    b->pool =3D p;
     b->type =3D PA_MEMBLOCK_FIXED;
     b->read_only =3D read_only;
-    PA_REFCNT_INIT(b);
+    pa_atomic_ptr_store(&b->data, d);
     b->length =3D length;
-    b->data =3D d;
-    b->pool =3D 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, v=
oid (*free_cb)(void *p), int read_only) {
     pa_memblock *b;
 =

@@ -287,18 +349,72 @@
     assert(free_cb);
     =

     b =3D pa_xnew(pa_memblock, 1);
+    PA_REFCNT_INIT(b);
+    b->pool =3D p;
     b->type =3D PA_MEMBLOCK_USER;
     b->read_only =3D read_only;
-    PA_REFCNT_INIT(b);
+    pa_atomic_ptr_store(&b->data, d);
     b->length =3D length;
-    b->data =3D d;
+    pa_atomic_store(&b->n_acquired, 0);
+    pa_atomic_store(&b->please_signal, 0);
+            =

     b->per_type.user.free_cb =3D free_cb;
-    b->pool =3D 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) =3D=3D 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 =3D pa_atomic_dec(&b->n_acquired);
+    assert(r >=3D 1);
+
+    if (r =3D=3D 1 && pa_atomic_load(&b->please_signal)) {
+        pa_mempool *p =3D b->pool;
+        /* Signal a waiting thread that this memblock is no longer used */
+        pa_mutex_lock(p->mutex);
+        pa_cond_signal(p->cond, 1);
+        pa_mutex_unlock(p->mutex);
+    }
+}
+
+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);
@@ -307,19 +423,17 @@
     return b;
 }
 =

-void pa_memblock_unref(pa_memblock*b) {
-    assert(b);
-    assert(PA_REFCNT_VALUE(b) > 0);
-
-    if (PA_REFCNT_DEC(b) > 0)
-        return;
-    =

+static void memblock_free(pa_memblock *b) {
+    assert(b);
+    =

+    assert(pa_atomic_load(&b->n_acquired) =3D=3D 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 */
 =

@@ -330,17 +444,23 @@
 =

         case PA_MEMBLOCK_IMPORTED : {
             pa_memimport_segment *segment;
-
+            pa_memimport *import;
+            =

+            /* FIXME! This should be implemented lock-free */
+            =

             segment =3D b->per_type.imported.segment;
             assert(segment);
-            assert(segment->import);
+            import =3D segment->import;
+            assert(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.impor=
ted.id, segment->import->userdata);
-
+            pa_mutex_lock(import->mutex);
+            pa_hashmap_remove(import->blocks, PA_UINT32_TO_PTR(b->per_type=
.imported.id));
             if (-- segment->n_blocks <=3D 0)
                 segment_detach(segment);
-            =

+            pa_mutex_unlock(import->mutex);
+
+            import->release_cb(import, b->per_type.imported.id, import->us=
erdata);
+
             pa_xfree(b);
             break;
         }
@@ -348,13 +468,20 @@
         case PA_MEMBLOCK_POOL_EXTERNAL:
         case PA_MEMBLOCK_POOL: {
             struct mempool_slot *slot;
-
-            slot =3D mempool_slot_by_ptr(b->pool, b->data);
+            int call_free;
+
+            slot =3D mempool_slot_by_ptr(b->pool, pa_atomic_ptr_load(&b->d=
ata));
             assert(slot);
+
+            call_free =3D b->type =3D=3D 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)
+                ;
             =

-            PA_LLIST_PREPEND(struct mempool_slot, b->pool->free_slots, slo=
t);
-            =

-            if (b->type =3D=3D PA_MEMBLOCK_POOL_EXTERNAL)
+            if (call_free)
                 pa_xfree(b);
 =

             break;
@@ -366,10 +493,42 @@
     }
 }
 =

+/* 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);
+
+        pa_mutex_lock(b->pool->mutex);
+        while (pa_atomic_load(&b->n_acquired) > 0)
+            pa_cond_wait(b->pool->cond, b->pool->mutex);
+        pa_mutex_unlock(b->pool->mutex);
+
+        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);
 =

-    AO_fetch_and_sub1_release_write(&b->pool->stat.n_allocated_by_type[b->=
type]);
+    pa_atomic_dec(&b->pool->stat.n_allocated_by_type[b->type]);
 =

     if (b->length <=3D b->pool->block_size - sizeof(struct mempool_slot)) {
         struct mempool_slot *slot;
@@ -378,53 +537,61 @@
             void *new_data;
             /* We can move it into a local pool, perfect! */
             =

+            new_data =3D 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 =3D PA_MEMBLOCK_POOL_EXTERNAL;
             b->read_only =3D 0;
 =

-            new_data =3D mempool_slot_data(slot);
-            memcpy(new_data, b->data, b->length);
-            b->data =3D new_data;
             goto finish;
         }
     }
 =

     /* Humm, not enough space in the pool, so lets allocate the memory wit=
h malloc() */
+    b->per_type.user.free_cb =3D pa_xfree;
+    pa_atomic_ptr_store(&b->data, pa_xmemdup(pa_atomic_ptr_load(&b->data),=
 b->length));
+
     b->type =3D PA_MEMBLOCK_USER;
-    b->per_type.user.free_cb =3D pa_xfree;
     b->read_only =3D 0;
-    b->data =3D pa_xmemdup(b->data, b->length);
 =

 finish:
-    AO_fetch_and_add1_release_write(&b->pool->stat.n_allocated_by_type[b->=
type]);
-    AO_fetch_and_add1_release_write(&b->pool->stat.n_accumulated_by_type[b=
->type]);
-}
-
+    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 =3D=3D 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;
     =

     assert(b);
     assert(b->type =3D=3D PA_MEMBLOCK_IMPORTED);
 =

-    assert(AO_load_acquire_read(&b->pool->stat.n_imported) > 0);
-    assert(AO_load_acquire_read(&b->pool->stat.imported_size) >=3D (AO_t) =
b->length);
-    AO_fetch_and_sub1_release_write(&b->pool->stat.n_imported);
-    AO_fetch_and_add_release_write(&b->pool->stat.imported_size, (AO_t) - =
b->length);
+    assert(pa_atomic_load(&b->pool->stat.n_imported) > 0);
+    assert(pa_atomic_load(&b->pool->stat.imported_size) >=3D (int) b->leng=
th);
+    pa_atomic_dec(&b->pool->stat.n_imported);
+    pa_atomic_add(&b->pool->stat.imported_size, (int) - b->length);
 =

     seg =3D b->per_type.imported.segment;
     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));
@@ -433,6 +600,8 @@
 =

     if (-- seg->n_blocks <=3D 0)
         segment_detach(seg);
+
+    pa_mutex_unlock(seg->import->mutex);
 }
 =

 pa_mempool* pa_mempool_new(int shared) {
@@ -441,12 +610,15 @@
 =

     p =3D pa_xnew(pa_mempool, 1);
 =

+    p->mutex =3D pa_mutex_new(1);
+    p->cond =3D pa_cond_new();
+
 #ifdef HAVE_SYSCONF
     ps =3D (size_t) sysconf(_SC_PAGESIZE);
 #elif defined(PAGE_SIZE)
-	ps =3D (size_t) PAGE_SIZE;
+    ps =3D (size_t) PAGE_SIZE;
 #else
-	ps =3D 4096; /* Let's hope it's like x86. */
+    ps =3D 4096; /* Let's hope it's like x86. */
 #endif
 =

     p->block_size =3D (PA_MEMPOOL_SLOT_SIZE/ps)*ps;
@@ -463,19 +635,21 @@
         return NULL;
     }
 =

-    p->n_init =3D 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 =3D pa_flist_new(p->n_blocks*2);
 =

     return p;
 }
 =

 void pa_mempool_free(pa_mempool *p) {
     assert(p);
+
+    pa_mutex_lock(p->mutex);
 =

     while (p->imports)
         pa_memimport_free(p->imports);
@@ -483,28 +657,54 @@
     while (p->exports)
         pa_memexport_free(p->exports);
 =

-    if (AO_load_acquire_read(&p->stat.n_allocated) > 0)
+    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 blo=
cks freed!");
+
+    pa_flist_free(p->free_slots, NULL);
     =

     pa_shm_free(&p->memory);
+
+    pa_mutex_free(p->mutex);
+    pa_cond_free(p->cond);
+    =

     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;
-    =

-    assert(p);
-
-    for (slot =3D p->free_slots; slot; slot =3D slot->next)
-        pa_shm_punch(&p->memory, (uint8_t*) slot + sizeof(struct mempool_s=
lot) - (uint8_t*) p->memory.ptr, p->block_size - sizeof(struct mempool_slot=
));
-}
-
+    pa_flist *list;
+    =

+    assert(p);
+
+    list =3D pa_flist_new(p->n_blocks*2);
+
+    while ((slot =3D pa_flist_pop(p->free_slots)))
+        while (pa_flist_push(list, slot) < 0)
+            ;
+
+    while ((slot =3D pa_flist_pop(list))) {
+        pa_shm_punch(&p->memory,
+                     (uint8_t*) slot - (uint8_t*) p->memory.ptr + sizeof(s=
truct 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);
 =

@@ -516,6 +716,7 @@
     return 0;
 }
 =

+/* No lock necessary */
 int pa_mempool_is_shared(pa_mempool *p) {
     assert(p);
 =

@@ -530,18 +731,23 @@
     assert(cb);
     =

     i =3D pa_xnew(pa_memimport, 1);
+    i->mutex =3D pa_mutex_new(0);
     i->pool =3D p;
     i->segments =3D pa_hashmap_new(NULL, NULL);
     i->blocks =3D pa_hashmap_new(NULL, NULL);
     i->release_cb =3D cb;
     i->userdata =3D 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;
 =

@@ -562,6 +768,7 @@
     return seg;
 }
 =

+/* Should be called locked */
 static void segment_detach(pa_memimport_segment *seg) {
     assert(seg);
 =

@@ -570,51 +777,68 @@
     pa_xfree(seg);
 }
 =

+/* Self-locked. Not multiple-caller safe */
 void pa_memimport_free(pa_memimport *i) {
     pa_memexport *e;
     pa_memblock *b;
     =

     assert(i);
 =

+    pa_mutex_lock(i->mutex);
+
+    while ((b =3D pa_hashmap_get_first(i->blocks)))
+        memblock_replace_import(b);
+
+    assert(pa_hashmap_size(i->segments) =3D=3D 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 =3D i->pool->exports; e; e =3D e->next)
         memexport_revoke_blocks(e, i);
 =

-    while ((b =3D pa_hashmap_get_first(i->blocks)))
-        memblock_replace_import(b);
-
-    assert(pa_hashmap_size(i->segments) =3D=3D 0);
-
+    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 =3D NULL;
     pa_memimport_segment *seg;
     =

     assert(i);
 =

+    pa_mutex_lock(i->mutex);
+    =

     if (pa_hashmap_size(i->blocks) >=3D PA_MEMIMPORT_SLOTS_MAX)
-        return NULL;
+        goto finish;
 =

     if (!(seg =3D pa_hashmap_get(i->segments, PA_UINT32_TO_PTR(shm_id)))) =

         if (!(seg =3D segment_attach(i, shm_id)))
-            return NULL;
+            goto finish;
 =

     if (offset+size > seg->memory.size)
-        return NULL;
-    =

+        goto finish;
+
     b =3D pa_xnew(pa_memblock, 1);
+    PA_REFCNT_INIT(b);
+    b->pool =3D i->pool;
     b->type =3D PA_MEMBLOCK_IMPORTED;
     b->read_only =3D 1;
-    PA_REFCNT_INIT(b);
+    pa_atomic_ptr_store(&b->data, (uint8_t*) seg->memory.ptr + offset);
     b->length =3D size;
-    b->data =3D (uint8_t*) seg->memory.ptr + offset;
-    b->pool =3D i->pool;
+    pa_atomic_store(&b->n_acquired, 0);
+    pa_atomic_store(&b->please_signal, 0);
     b->per_type.imported.id =3D block_id;
     b->per_type.imported.segment =3D seg;
 =

@@ -622,7 +846,11 @@
 =

     seg->n_blocks++;
     =

-    stat_add(b);
+finish:
+    pa_mutex_unlock(i->mutex);
+
+    if (b)
+        stat_add(b);
     =

     return b;
 }
@@ -631,10 +859,15 @@
     pa_memblock *b;
     assert(i);
 =

+    pa_mutex_lock(i->mutex);
+
     if (!(b =3D pa_hashmap_get(i->blocks, PA_UINT32_TO_PTR(id))))
         return -1;
     =

     memblock_replace_import(b);
+
+    pa_mutex_unlock(i->mutex);
+
     return 0;
 }
 =

@@ -649,57 +882,83 @@
         return NULL;
     =

     e =3D pa_xnew(pa_memexport, 1);
+    e->mutex =3D pa_mutex_new(1);
     e->pool =3D p;
     PA_LLIST_HEAD_INIT(struct memexport_slot, e->free_slots);
     PA_LLIST_HEAD_INIT(struct memexport_slot, e->used_slots);
     e->n_init =3D 0;
     e->revoke_cb =3D cb;
     e->userdata =3D 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 >=3D e->n_init)
-        return -1;
+        goto fail;
 =

     if (!e->slots[id].block)
-        return -1;
-
-/*     pa_log("Processing release for %u", id); */
-
-    assert(AO_load_acquire_read(&e->pool->stat.n_exported) > 0);
-    assert(AO_load_acquire_read(&e->pool->stat.exported_size) >=3D (AO_t) =
e->slots[id].block->length);
-    =

-    AO_fetch_and_sub1_release_write(&e->pool->stat.n_exported);
-    AO_fetch_and_add_release_write(&e->pool->stat.exported_size, (AO_t) -e=
->slots[id].block->length);
-    =

-    pa_memblock_unref(e->slots[id].block);
+        goto fail;
+
+    b =3D e->slots[id].block;
     e->slots[id].block =3D 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) >=3D (int) b->leng=
th);
+    =

+    pa_atomic_dec(&e->pool->stat.n_exported);
+    pa_atomic_add(&e->pool->stat.exported_size, (int) -b->length);
+    =

+    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 =3D e->used_slots; slot; slot =3D next) {
         uint32_t idx;
@@ -713,8 +972,11 @@
         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;
 =

@@ -731,13 +993,16 @@
     if (!(n =3D 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);
@@ -750,12 +1015,15 @@
     if (!(b =3D memblock_shared_copy(e->pool, b)))
         return -1;
 =

+    pa_mutex_lock(e->mutex);
+    =

     if (e->free_slots) {
         slot =3D 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 =3D &e->slots[e->n_init++];
-    } else {
+    else {
+        pa_mutex_unlock(e->mutex);
         pa_memblock_unref(b);
         return -1;
     }
@@ -764,7 +1032,10 @@
     slot->block =3D b;
     *block_id =3D slot - e->slots;
 =

+    pa_mutex_unlock(e->mutex);
 /*     pa_log("Got block id %u", *block_id); */
+
+    data =3D pa_memblock_acquire(b);
 =

     if (b->type =3D=3D PA_MEMBLOCK_IMPORTED) {
         assert(b->per_type.imported.segment);
@@ -775,15 +1046,17 @@
         memory =3D &b->pool->memory;
     }
         =

-    assert(b->data >=3D memory->ptr);
-    assert((uint8_t*) b->data + b->length <=3D (uint8_t*) memory->ptr + me=
mory->size);
+    assert(data >=3D memory->ptr);
+    assert((uint8_t*) data + length <=3D (uint8_t*) memory->ptr + memory->=
size);
     =

     *shm_id =3D memory->id;
-    *offset =3D (uint8_t*) b->data - (uint8_t*) memory->ptr;
-    *size =3D b->length;
-
-    AO_fetch_and_add1_release_write(&e->pool->stat.n_exported);
-    AO_fetch_and_add_release_write(&e->pool->stat.exported_size, (AO_t) b-=
>length);
+    *offset =3D (uint8_t*) data - (uint8_t*) memory->ptr;
+    *size =3D length;
+
+    pa_memblock_release(b);
+    =

+    pa_atomic_inc(&e->pool->stat.n_exported);
+    pa_atomic_add(&e->pool->stat.exported_size, (int) length);
 =

     return 0;
 }

Modified: trunk/src/pulsecore/memblock.h
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/memblock.h?=
rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulsecore/memblock.h (original)
+++ trunk/src/pulsecore/memblock.h Wed Sep 27 01:50:56 2006
@@ -25,6 +25,7 @@
 #include <sys/types.h>
 #include <inttypes.h>
 =

+#include <pulse/def.h>
 #include <pulsecore/llist.h>
 #include <pulsecore/refcnt.h>
 =

@@ -54,45 +55,25 @@
 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_i=
d, 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 =3D=3D 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 {
-    AO_t n_allocated;
-    AO_t n_accumulated;
-    AO_t n_imported;
-    AO_t n_exported;
-    AO_t allocated_size;
-    AO_t accumulated_size;
-    AO_t imported_size;
-    AO_t exported_size;
+    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;
 =

-    AO_t n_too_large_for_pool;
-    AO_t n_pool_full;
+    pa_atomic_int_t n_too_large_for_pool;
+    pa_atomic_int_t n_pool_full;
 =

-    AO_t n_allocated_by_type[PA_MEMBLOCK_TYPE_MAX];
-    AO_t n_accumulated_by_type[PA_MEMBLOCK_TYPE_MAX];
+    pa_atomic_int_t n_allocated_by_type[PA_MEMBLOCK_TYPE_MAX];
+    pa_atomic_int_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 */
@@ -116,8 +97,16 @@
 /* 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);

Modified: trunk/src/pulsecore/memblockq.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/memblockq.c=
?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulsecore/memblockq.c (original)
+++ trunk/src/pulsecore/memblockq.c Wed Sep 27 01:50:56 2006
@@ -176,7 +176,7 @@
     assert(uchunk);
     assert(uchunk->memblock);
     assert(uchunk->length > 0);
-    assert(uchunk->index + uchunk->length <=3D uchunk->memblock->length);
+    assert(uchunk->index + uchunk->length <=3D pa_memblock_get_length(uchu=
nk->memblock));
 =

     if (uchunk->length % bq->base)
         return -1;
@@ -360,8 +360,8 @@
         if (bq->silence) {
             chunk->memblock =3D pa_memblock_ref(bq->silence);
 =

-            if (!length || length > chunk->memblock->length)
-                length =3D chunk->memblock->length;
+            if (!length || length > pa_memblock_get_length(chunk->memblock=
))
+                length =3D pa_memblock_get_length(chunk->memblock);
                 =

             chunk->length =3D length;
         } else {
@@ -413,8 +413,8 @@
 =

             if (bq->silence) {
 =

-                if (!l || l > bq->silence->length)
-                    l =3D bq->silence->length;
+                if (!l || l > pa_memblock_get_length(bq->silence))
+                    l =3D pa_memblock_get_length(bq->silence);
 =

             }
 =


Modified: trunk/src/pulsecore/memchunk.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/memchunk.c?=
rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulsecore/memchunk.c (original)
+++ trunk/src/pulsecore/memchunk.c Wed Sep 27 01:50:56 2006
@@ -35,22 +35,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) =3D=3D 1 &&
-        !c->memblock->read_only &&
-        c->memblock->length >=3D c->index+min)
+    if (pa_memblock_is_read_only(c->memblock) &&
+        pa_memblock_get_length(c->memblock) >=3D c->index+min)
         return;
 =

     l =3D c->length;
     if (l < min)
         l =3D min;
     =

-    n =3D pa_memblock_new(c->memblock->pool, l);
-    memcpy(n->data, (uint8_t*) c->memblock->data + c->index, c->length);
+    n =3D pa_memblock_new(pa_memblock_get_pool(c->memblock), l);
+    tdata =3D pa_memblock_acquire(n);
+    sdata =3D 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 =3D n;
     c->index =3D 0;

Modified: trunk/src/pulsecore/play-memchunk.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/play-memchu=
nk.c?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulsecore/play-memchunk.c (original)
+++ trunk/src/pulsecore/play-memchunk.c Wed Sep 27 01:50:56 2006
@@ -55,7 +55,7 @@
     if (c->length <=3D 0)
         return -1;
     =

-    assert(c->memblock && c->memblock->length);
+    assert(c->memblock);
     *chunk =3D *c;
     pa_memblock_ref(c->memblock);
 =


Modified: trunk/src/pulsecore/protocol-esound.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/protocol-es=
ound.c?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulsecore/protocol-esound.c (original)
+++ trunk/src/pulsecore/protocol-esound.c Wed Sep 27 01:50:56 2006
@@ -891,14 +891,22 @@
         }
     } else if (c->state =3D=3D ESD_CACHING_SAMPLE) {
         ssize_t r;
-
-        assert(c->scache.memchunk.memblock && c->scache.name && c->scache.=
memchunk.index < c->scache.memchunk.length);
-        =

-        if ((r =3D pa_iochannel_read(c->io, (uint8_t*) c->scache.memchunk.=
memblock->data+c->scache.memchunk.index, c->scache.memchunk.length-c->scach=
e.memchunk.index)) <=3D 0) {
+        void *p;
+
+        assert(c->scache.memchunk.memblock);
+        assert(c->scache.name);
+        assert(c->scache.memchunk.index < c->scache.memchunk.length);
+
+        p =3D pa_memblock_acquire(c->scache.memchunk.memblock);
+        =

+        if ((r =3D pa_iochannel_read(c->io, (uint8_t*) p+c->scache.memchun=
k.index, c->scache.memchunk.length-c->scache.memchunk.index)) <=3D 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 +=3D r;
         assert(c->scache.memchunk.index <=3D c->scache.memchunk.length);
         =

@@ -925,6 +933,7 @@
         pa_memchunk chunk;
         ssize_t r;
         size_t l;
+        void *p;
 =

         assert(c->input_memblockq);
 =

@@ -937,7 +946,7 @@
             l =3D c->playback.fragment_size;
 =

         if (c->playback.current_memblock) =

-            if (c->playback.current_memblock->length - c->playback.membloc=
k_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 =3D NULL;
                 c->playback.memblock_index =3D 0;
@@ -945,15 +954,21 @@
         =

         if (!c->playback.current_memblock) {
             c->playback.current_memblock =3D pa_memblock_new(c->protocol->=
core->mempool, c->playback.fragment_size*2);
-            assert(c->playback.current_memblock && c->playback.current_mem=
block->length >=3D l);
+            assert(c->playback.current_memblock);
+            assert(pa_memblock_get_length(c->playback.current_memblock) >=
=3D l);
             c->playback.memblock_index =3D 0;
         }
 =

-        if ((r =3D pa_iochannel_read(c->io, (uint8_t*) c->playback.current=
_memblock->data+c->playback.memblock_index, l)) <=3D 0) {
+        p =3D pa_memblock_acquire(c->playback.current_memblock);
+        =

+        if ((r =3D pa_iochannel_read(c->io, (uint8_t*) p+c->playback.membl=
ock_index, l)) <=3D 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 =3D c->playback.current_memblock;
         chunk.index =3D c->playback.memblock_index;
         chunk.length =3D r;
@@ -990,18 +1005,25 @@
     } else if (c->state =3D=3D 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);
-        =

-        if ((r =3D pa_iochannel_write(c->io, (uint8_t*) chunk.memblock->da=
ta+chunk.index, chunk.length)) < 0) {
+        assert(chunk.memblock);
+        assert(chunk.length);
+
+        p =3D pa_memblock_acquire(chunk.memblock);
+        =

+        if ((r =3D pa_iochannel_write(c->io, (uint8_t*) p+chunk.index, chu=
nk.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);

Modified: trunk/src/pulsecore/protocol-native.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/protocol-na=
tive.c?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulsecore/protocol-native.c (original)
+++ trunk/src/pulsecore/protocol-native.c Wed Sep 27 01:50:56 2006
@@ -2274,6 +2274,7 @@
     } else {
         struct upload_stream *u =3D (struct upload_stream*) stream;
         size_t l;
+        =

         assert(u->type =3D=3D UPLOAD_STREAM);
 =

         if (!u->memchunk.memblock) {
@@ -2293,9 +2294,18 @@
         if (l > chunk->length)
             l =3D chunk->length;
 =

+        =

         if (l > 0) {
-            memcpy((uint8_t*) u->memchunk.memblock->data + u->memchunk.ind=
ex + u->memchunk.length,
-                   (uint8_t*) chunk->memblock->data+chunk->index, l);
+            void *src, *dst;
+            dst =3D pa_memblock_acquire(u->memchunk.memblock);
+            src =3D 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 +=3D l;
             u->length -=3D l;
         }

Modified: trunk/src/pulsecore/protocol-simple.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/protocol-si=
mple.c?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulsecore/protocol-simple.c (original)
+++ trunk/src/pulsecore/protocol-simple.c Wed Sep 27 01:50:56 2006
@@ -113,6 +113,7 @@
     pa_memchunk chunk;
     ssize_t r;
     size_t l;
+    void *p;
 =

     if (!c->sink_input || !(l =3D pa_memblockq_missing(c->input_memblockq)=
))
         return 0;
@@ -121,7 +122,7 @@
         l =3D c->playback.fragment_size;
 =

     if (c->playback.current_memblock) =

-        if (c->playback.current_memblock->length - c->playback.memblock_in=
dex < l) {
+        if (pa_memblock_get_length(c->playback.current_memblock) - c->play=
back.memblock_index < l) {
             pa_memblock_unref(c->playback.current_memblock);
             c->playback.current_memblock =3D NULL;
             c->playback.memblock_index =3D 0;
@@ -129,15 +130,20 @@
 =

     if (!c->playback.current_memblock) {
         c->playback.current_memblock =3D pa_memblock_new(c->protocol->core=
->mempool, c->playback.fragment_size*2);
-        assert(c->playback.current_memblock && c->playback.current_membloc=
k->length >=3D l);
+        assert(c->playback.current_memblock);
+        assert(pa_memblock_get_length(c->playback.current_memblock) >=3D l=
);
         c->playback.memblock_index =3D 0;
     }
-    =

-    if ((r =3D pa_iochannel_read(c->io, (uint8_t*) c->playback.current_mem=
block->data+c->playback.memblock_index, l)) <=3D 0) {
+
+    p =3D pa_memblock_acquire(c->playback.current_memblock);
+    =

+    if ((r =3D pa_iochannel_read(c->io, (uint8_t*) p + c->playback.membloc=
k_index, l)) <=3D 0) {
+        pa_memblock_release(c->playback.current_memblock);
         pa_log_debug("read(): %s", r =3D=3D 0 ? "EOF" : pa_cstrerror(errno=
));
         return -1;
     }
 =

+    pa_memblock_release(c->playback.current_memblock);
     chunk.memblock =3D c->playback.current_memblock;
     chunk.index =3D c->playback.memblock_index;
     chunk.length =3D r;
@@ -156,7 +162,8 @@
 static int do_write(struct connection *c) {
     pa_memchunk chunk;
     ssize_t r;
-
+    void *p;
+    =

     if (!c->source_output)
         return 0;    =

 =

@@ -165,12 +172,17 @@
         return 0;
     =

     assert(chunk.memblock && chunk.length);
-    =

-    if ((r =3D pa_iochannel_write(c->io, (uint8_t*) chunk.memblock->data+c=
hunk.index, chunk.length)) < 0) {
+
+    p =3D pa_memblock_acquire(chunk.memblock);
+    =

+    if ((r =3D pa_iochannel_write(c->io, (uint8_t*) p+chunk.index, chunk.l=
ength)) < 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);

Modified: trunk/src/pulsecore/pstream.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/pstream.c?r=
ev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulsecore/pstream.c (original)
+++ trunk/src/pulsecore/pstream.c Wed Sep 27 01:50:56 2006
@@ -48,6 +48,7 @@
 #include <pulsecore/creds.h>
 #include <pulsecore/mutex.h>
 #include <pulsecore/refcnt.h>
+#include <pulsecore/anotify.h>
 =

 #include "pstream.h"
 =

@@ -113,10 +114,11 @@
     PA_REFCNT_DECLARE;
     =

     pa_mainloop_api *mainloop;
-    pa_defer_event *defer_event;
     pa_iochannel *io;
+
     pa_queue *send_queue;
-    pa_mutex *mutex;
+    pa_mutex *mutex;  /* only for access to the queue */
+    pa_anotify *anotify;
 =

     int dead;
 =

@@ -126,6 +128,7 @@
         uint32_t shm_info[PA_PSTREAM_SHM_MAX];
         void *data;
         size_t index;
+        pa_memchunk memchunk;
     } write;
 =

     struct {
@@ -170,10 +173,6 @@
 =

     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)) {
         if (do_read(p) < 0)
             goto fail;
@@ -185,8 +184,6 @@
             goto fail;
     }
 =

-    pa_mutex_unlock(p->mutex);
-
     pa_pstream_unref(p);
     return;
 =

@@ -197,8 +194,6 @@
     if (p->die_callback)
         p->die_callback(p, p->die_callback_userdata);
     =

-    pa_mutex_unlock(p->mutex);
-    =

     pa_pstream_unref(p);
 }
 =

@@ -211,13 +206,10 @@
     do_something(p);
 }
 =

-static void defer_callback(pa_mainloop_api *m, pa_defer_event *e, void*use=
rdata) {
+static void anotify_callback(uint8_t event, void *userdata) {
     pa_pstream *p =3D userdata;
 =

     assert(p);
-    assert(p->defer_event =3D=3D e);
-    assert(p->mainloop =3D=3D m);
-    =

     do_something(p);
 }
 =

@@ -237,16 +229,16 @@
     p->dead =3D 0;
 =

     p->mutex =3D pa_mutex_new(1);
+    p->anotify =3D pa_anotify_new(m, anotify_callback, p);
 =

     p->mainloop =3D m;
-    p->defer_event =3D m->defer_new(m, defer_callback, p);
-    m->defer_enable(p->defer_event, 0);
     =

     p->send_queue =3D pa_queue_new();
     assert(p->send_queue);
 =

     p->write.current =3D NULL;
     p->write.index =3D 0;
+    pa_memchunk_reset(&p->write.memchunk);
     p->read.memblock =3D NULL;
     p->read.packet =3D NULL;
     p->read.index =3D 0;
@@ -309,9 +301,15 @@
     if (p->read.packet)
         pa_packet_unref(p->read.packet);
 =

+    if (p->write.memchunk.memblock)
+        pa_memblock_unref(p->write.memchunk.memblock);
+
     if (p->mutex)
         pa_mutex_free(p->mutex);
 =

+    if (p->anotify)
+        pa_anotify_free(p->anotify);
+
     pa_xfree(p);
 }
 =

@@ -322,11 +320,6 @@
     assert(PA_REFCNT_VALUE(p) > 0);
     assert(packet);
 =

-    pa_mutex_lock(p->mutex);
-    =

-    if (p->dead)
-        goto finish;
-    =

     i =3D pa_xnew(struct item_info, 1);
     i->type =3D PA_PSTREAM_ITEM_PACKET;
     i->packet =3D pa_packet_ref(packet);
@@ -336,12 +329,11 @@
         i->creds =3D *creds;
 #endif
 =

+    pa_mutex_lock(p->mutex);
     pa_queue_push(p->send_queue, i);
-    p->mainloop->defer_enable(p->defer_event, 1);
-
-finish:
-
     pa_mutex_unlock(p->mutex);
+    =

+    pa_anotify_signal(p->anotify, 0);
 }
 =

 void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offs=
et, pa_seek_mode_t seek_mode, const pa_memchunk *chunk) {
@@ -352,12 +344,6 @@
     assert(channel !=3D (uint32_t) -1);
     assert(chunk);
 =

-    pa_mutex_lock(p->mutex);
-    =

-    if (p->dead)
-        goto finish;
-
-    length =3D chunk->length;
     idx =3D 0;
 =

     while (length > 0) {
@@ -379,17 +365,15 @@
         i->with_creds =3D 0;
 #endif
         =

+        pa_mutex_lock(p->mutex);
         pa_queue_push(p->send_queue, i);
+        pa_mutex_unlock(p->mutex);
 =

         idx +=3D n;
         length -=3D n;
     }
-        =

-    p->mainloop->defer_enable(p->defer_event, 1);
-
-finish:
-    =

-    pa_mutex_unlock(p->mutex);
+
+    pa_anotify_signal(p->anotify, 0);
 }
 =

 static void memimport_release_cb(pa_memimport *i, uint32_t block_id, void =
*userdata) {
@@ -399,11 +383,6 @@
     assert(p);
     assert(PA_REFCNT_VALUE(p) > 0);
 =

-    pa_mutex_lock(p->mutex);
-    =

-    if (p->dead)
-        goto finish;
-
 /*     pa_log("Releasing block %u", block_id); */
 =

     item =3D pa_xnew(struct item_info, 1);
@@ -413,12 +392,11 @@
     item->with_creds =3D 0;
 #endif
 =

+    pa_mutex_lock(p->mutex);
     pa_queue_push(p->send_queue, item);
-    p->mainloop->defer_enable(p->defer_event, 1);
-
-finish:
-
     pa_mutex_unlock(p->mutex);
+
+    pa_anotify_signal(p->anotify, 0);
 }
 =

 static void memexport_revoke_cb(pa_memexport *e, uint32_t block_id, void *=
userdata) {
@@ -428,11 +406,6 @@
     assert(p);
     assert(PA_REFCNT_VALUE(p) > 0);
 =

-    pa_mutex_lock(p->mutex);
-    =

-    if (p->dead)
-        goto finish;
-
 /*     pa_log("Revoking block %u", block_id); */
     =

     item =3D pa_xnew(struct item_info, 1);
@@ -442,23 +415,27 @@
     item->with_creds =3D 0;
 #endif
 =

+    pa_mutex_lock(p->mutex);
     pa_queue_push(p->send_queue, item);
-    p->mainloop->defer_enable(p->defer_event, 1);
-
-finish:
-
     pa_mutex_unlock(p->mutex);
+
+    pa_anotify_signal(p->anotify, 0);
 }
 =

 static void prepare_next_write_item(pa_pstream *p) {
     assert(p);
     assert(PA_REFCNT_VALUE(p) > 0);
 =

-    if (!(p->write.current =3D pa_queue_pop(p->send_queue)))
+    pa_mutex_lock(p->mutex);
+    p->write.current =3D pa_queue_pop(p->send_queue);
+    pa_mutex_unlock(p->mutex);
+
+    if (!p->write.current)
         return;
     =

     p->write.index =3D 0;
     p->write.data =3D NULL;
+    pa_memchunk_reset(&p->write.memchunk);
 =

     p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] =3D 0;
     p->write.descriptor[PA_PSTREAM_DESCRIPTOR_CHANNEL] =3D htonl((uint32_t=
) -1);
@@ -525,7 +502,9 @@
 =

         if (send_payload) {
             p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] =3D htonl(p-=
>write.current->chunk.length);
-            p->write.data =3D (uint8_t*) p->write.current->chunk.memblock-=
>data + p->write.current->chunk.index;
+            p->write.memchunk =3D p->write.current->chunk;
+            pa_memblock_ref(p->write.memchunk.memblock);
+            p->write.data =3D NULL;
         }
         =

         p->write.descriptor[PA_PSTREAM_DESCRIPTOR_FLAGS] =3D htonl(flags);
@@ -541,6 +520,7 @@
     void *d;
     size_t l;
     ssize_t r;
+    pa_memblock *release_memblock =3D NULL;
     =

     assert(p);
     assert(PA_REFCNT_VALUE(p) > 0);
@@ -555,9 +535,16 @@
         d =3D (uint8_t*) p->write.descriptor + p->write.index;
         l =3D PA_PSTREAM_DESCRIPTOR_SIZE - p->write.index;
     } else {
-        assert(p->write.data);
-    =

-        d =3D (uint8_t*) p->write.data + p->write.index - PA_PSTREAM_DESCR=
IPTOR_SIZE;
+        assert(p->write.data || p->write.memchunk.memblock);
+
+        if (p->write.data)
+            d =3D p->write.data;
+        else {
+            d =3D (uint8_t*) pa_memblock_acquire(p->write.memchunk.membloc=
k) + p->write.memchunk.index;
+            release_memblock =3D p->write.memchunk.memblock;
+        }
+    =

+        d =3D (uint8_t*) d + p->write.index - PA_PSTREAM_DESCRIPTOR_SIZE;
         l =3D ntohl(p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]) - (=
p->write.index - PA_PSTREAM_DESCRIPTOR_SIZE);
     }
 =

@@ -567,14 +554,17 @@
     if (p->send_creds_now) {
 =

         if ((r =3D pa_iochannel_write_with_creds(p->io, d, l, &p->write_cr=
eds)) < 0)
-            return -1;
+            goto fail;
 =

         p->send_creds_now =3D 0;
     } else
 #endif
 =

     if ((r =3D pa_iochannel_write(p->io, d, l)) < 0)
-        return -1;
+        goto fail;
+
+    if (release_memblock)
+        pa_memblock_release(release_memblock);
 =

     p->write.index +=3D r;
 =

@@ -588,12 +578,20 @@
     }
 =

     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 =3D NULL;
     =

     assert(p);
     assert(PA_REFCNT_VALUE(p) > 0);
@@ -602,8 +600,16 @@
         d =3D (uint8_t*) p->read.descriptor + p->read.index;
         l =3D PA_PSTREAM_DESCRIPTOR_SIZE - p->read.index;
     } else {
-        assert(p->read.data);
-        d =3D (uint8_t*) p->read.data + p->read.index - PA_PSTREAM_DESCRIP=
TOR_SIZE;
+        assert(p->read.data || p->read.memblock);
+
+        if (p->read.data)
+            d =3D p->read.data;
+        else {
+            d =3D pa_memblock_acquire(p->read.memblock);
+            release_memblock =3D p->read.memblock;
+        }
+        =

+        d =3D (uint8_t*) d + p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE;
         l =3D ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]) - (p=
->read.index - PA_PSTREAM_DESCRIPTOR_SIZE);
     }
 =

@@ -612,14 +618,17 @@
         int b =3D 0;
         =

         if ((r =3D pa_iochannel_read_with_creds(p->io, d, l, &p->read_cred=
s, &b)) <=3D 0)
-            return -1;
+            goto fail;
 =

         p->read_creds_valid =3D p->read_creds_valid || b;
     }
 #else
     if ((r =3D pa_iochannel_read(p->io, d, l)) <=3D 0)
-        return -1;
-#endif
+        goto fail;
+#endif
+
+    if (release_memblock)
+        pa_memblock_release(release_memblock);
     =

     p->read.index +=3D r;
 =

@@ -701,7 +710,7 @@
                 /* Frame is a memblock frame */
                 =

                 p->read.memblock =3D pa_memblock_new(p->mempool, length);
-                p->read.data =3D p->read.memblock->data;
+                p->read.data =3D NULL;
             } else {
                 =

                 pa_log_warn("Recieved memblock frame with invalid flags va=
lue.");
@@ -788,7 +797,7 @@
                     =

                     chunk.memblock =3D b;
                     chunk.index =3D 0;
-                    chunk.length =3D b->length;
+                    chunk.length =3D pa_memblock_get_length(b);
 =

                     offset =3D (int64_t) (
                             (((uint64_t) ntohl(p->read.descriptor[PA_PSTRE=
AM_DESCRIPTOR_OFFSET_HI])) << 32) |
@@ -816,52 +825,51 @@
     p->read.memblock =3D NULL;
     p->read.packet =3D NULL;
     p->read.index =3D 0;
+    p->read.data =3D NULL;
 =

 #ifdef HAVE_CREDS
     p->read_creds_valid =3D 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 =3D cb;
     p->die_callback_userdata =3D userdata;
-    pa_mutex_unlock(p->mutex);
 }
 =

 void pa_pstream_set_drain_callback(pa_pstream *p, pa_pstream_notify_cb_t c=
b, void *userdata) {
     assert(p);
     assert(PA_REFCNT_VALUE(p) > 0);
 =

-    pa_mutex_lock(p->mutex);
     p->drain_callback =3D cb;
     p->drain_callback_userdata =3D userdata;
-    pa_mutex_unlock(p->mutex);
 }
 =

 void pa_pstream_set_recieve_packet_callback(pa_pstream *p, pa_pstream_pack=
et_cb_t cb, void *userdata) {
     assert(p);
     assert(PA_REFCNT_VALUE(p) > 0);
 =

-    pa_mutex_lock(p->mutex);
     p->recieve_packet_callback =3D cb;
     p->recieve_packet_callback_userdata =3D userdata;
-    pa_mutex_unlock(p->mutex);
 }
 =

 void pa_pstream_set_recieve_memblock_callback(pa_pstream *p, pa_pstream_me=
mblock_cb_t cb, void *userdata) {
     assert(p);
     assert(PA_REFCNT_VALUE(p) > 0);
 =

-    pa_mutex_lock(p->mutex);
     p->recieve_memblock_callback =3D cb;
     p->recieve_memblock_callback_userdata =3D userdata;
-    pa_mutex_unlock(p->mutex);
 }
 =

 int pa_pstream_is_pending(pa_pstream *p) {
@@ -901,8 +909,6 @@
 void pa_pstream_close(pa_pstream *p) {
     assert(p);
 =

-    pa_mutex_lock(p->mutex);
-    =

     p->dead =3D 1;
 =

     if (p->import) {
@@ -918,26 +924,17 @@
     if (p->io) {
         pa_iochannel_free(p->io);
         p->io =3D NULL;
-    }
-
-    if (p->defer_event) {
-        p->mainloop->defer_free(p->defer_event);
-        p->defer_event =3D NULL;
     }
 =

     p->die_callback =3D NULL;
     p->drain_callback =3D NULL;
     p->recieve_packet_callback =3D NULL;
     p->recieve_memblock_callback =3D 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 =3D enable;
 =

@@ -953,6 +950,4 @@
             p->export =3D NULL;
         }
     }
-
-    pa_mutex_unlock(p->mutex);
-}
+}

Modified: trunk/src/pulsecore/resampler.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/resampler.c=
?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulsecore/resampler.c (original)
+++ trunk/src/pulsecore/resampler.c Wed Sep 27 01:50:56 2006
@@ -51,8 +51,7 @@
 };
 =

 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;
@@ -224,14 +223,14 @@
     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);
 }
 =

@@ -270,64 +269,80 @@
     }
 }
 =

-static float * convert_to_float(pa_resampler *r, void *input, unsigned n_f=
rames) {
+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 =3D 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 =3D n_frames * r->i_ss.channels;
-
-    if (u->buf1_samples < n_samples) {
-        if (u->buf1_block)
-            pa_memblock_unref(u->buf1_block);
+    n_samples =3D (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);
 =

         u->buf1_samples =3D n_samples;
-        u->buf1_block =3D pa_memblock_new(r->mempool, sizeof(float) * n_sa=
mples);
-        u->buf1 =3D u->buf1_block->data;
-    }
-    =

-    u->to_float32ne_func(n_samples, input, u->buf1);
-
-    return u->buf1;
-}
-
-static float *remap_channels(pa_resampler *r, float *input, unsigned n_fra=
mes) {
-    struct impl_libsamplerate *u;
-    unsigned n_samples;
+        u->buf1.memblock =3D pa_memblock_new(r->mempool, u->buf1.length =
=3D sizeof(float) * n_samples);
+        u->buf1.index =3D 0;
+    }
+
+    src =3D (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
+    dst =3D (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 =3D sizeof(float) * n_samples;
+
+    return &u->buf1;
+}
+
+static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
+    struct impl_libsamplerate *u;
+    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 =3D 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 =3D n_frames * r->o_ss.channels;
-
-    if (u->buf2_samples < n_samples) {
-        if (u->buf2_block)
-            pa_memblock_unref(u->buf2_block);
+    n_samples =3D input->length / sizeof(float);
+    n_frames =3D n_samples / r->o_ss.channels;
+
+    if (!u->buf2.memblock || u->buf2_samples < n_samples) {
+        if (u->buf2.memblock)
+            pa_memblock_unref(u->buf2.memblock);
 =

         u->buf2_samples =3D n_samples;
-        u->buf2_block =3D pa_memblock_new(r->mempool, sizeof(float) * n_sa=
mples);
-        u->buf2 =3D u->buf2_block->data;
-    }
-
-    memset(u->buf2, 0, n_samples * sizeof(float));
+        u->buf2.memblock =3D pa_memblock_new(r->mempool, u->buf2.length =
=3D sizeof(float) * n_samples);
+        u->buf2.index =3D 0;
+    }
+
+    src =3D (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + in=
put->index);
+    dst =3D (float*) pa_memblock_acquire(u->buf2.memblock);
+    =

+    memset(dst, 0, n_samples * sizeof(float));
 =

     o_skip =3D sizeof(float) * r->o_ss.channels;
     i_skip =3D sizeof(float) * r->i_ss.channels;
@@ -338,49 +353,57 @@
 =

         for (i =3D 0; i < PA_CHANNELS_MAX && u->map_table[oc][i] >=3D 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;
-}
-
-static float *resample(pa_resampler *r, float *input, unsigned *n_frames) {
+    pa_memblock_release(input->memblock);
+    pa_memblock_release(u->buf2.memblock);
+
+    u->buf2.length =3D n_frames * sizeof(float) * r->o_ss.channels;
+
+    return &u->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;
 =

     assert(r);
     assert(input);
-    assert(n_frames);
     assert(r->impl_data);
     u =3D 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 =3D (*n_frames*r->o_ss.rate/r->i_ss.rate)+1024;
+    in_n_samples =3D input->length / sizeof(float);
+    in_n_frames =3D in_n_samples * r->o_ss.channels;
+
+    out_n_frames =3D (in_n_frames*r->o_ss.rate/r->i_ss.rate)+1024;
     out_n_samples =3D 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 =3D out_n_samples;
-        u->buf3_block =3D pa_memblock_new(r->mempool, sizeof(float) * out_=
n_samples);
-        u->buf3 =3D u->buf3_block->data;
-    }
-    =

-    data.data_in =3D input;
-    data.input_frames =3D *n_frames;
-
-    data.data_out =3D u->buf3;
+        u->buf3.memblock =3D pa_memblock_new(r->mempool, u->buf3.length =
=3D sizeof(float) * out_n_samples);
+        u->buf3.index =3D 0;
+    }
+    =

+    data.data_in =3D (float*) ((uint8_t*) pa_memblock_acquire(input->membl=
ock) + input->index);
+    data.input_frames =3D in_n_frames;
+
+    data.data_out =3D (float*) pa_memblock_acquire(u->buf3.memblock);
     data.output_frames =3D out_n_frames;
         =

     data.src_ratio =3D (double) r->o_ss.rate / r->i_ss.rate;
@@ -388,16 +411,20 @@
         =

     ret =3D src_process(u->src_state, &data);
     assert(ret =3D=3D 0);
-    assert((unsigned) data.input_frames_used =3D=3D *n_frames);
-
-    *n_frames =3D data.output_frames_gen;
-
-    return u->buf3;
-}
-
-static void *convert_from_float(pa_resampler *r, float *input, unsigned n_=
frames) {
-    struct impl_libsamplerate *u;
-    unsigned n_samples;
+    assert((unsigned) data.input_frames_used =3D=3D in_n_frames);
+
+    pa_memblock_release(input->memblock);
+    pa_memblock_release(u->buf3.memblock);
+    =

+    u->buf3.length =3D data.output_frames_gen * sizeof(float) * r->o_ss.ch=
annels;
+
+    return &u->buf3;
+}
+
+static pa_memchunk *convert_from_float(pa_resampler *r, pa_memchunk *input=
) {
+    struct impl_libsamplerate *u;
+    unsigned n_samples, n_frames;
+    void *src, *dst;
     =

     assert(r);
     assert(input);
@@ -406,30 +433,35 @@
     =

     /* 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 =3D input->length / sizeof(float) / r->o_ss.channels;
     n_samples =3D 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 =3D n_samples;
-        u->buf4_block =3D pa_memblock_new(r->mempool, sizeof(float) * n_sa=
mples);
-        u->buf4 =3D u->buf4_block->data;
-    }
-        =

-    u->from_float32ne_func(n_samples, input, u->buf4);
-
-    return u->buf4;
+        u->buf4.memblock =3D pa_memblock_new(r->mempool, u->buf4.length =
=3D r->o_fz * n_frames);
+        u->buf4.index =3D 0;
+    }
+
+    src =3D (uint8_t*) pa_memblock_acquire(input->memblock) + input->lengt=
h;
+    dst =3D 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);
+
+    u->buf4.length =3D r->o_fz * n_frames;
+    =

+    return &u->buf4;
 }
 =

 static void libsamplerate_run(pa_resampler *r, const pa_memchunk *in, pa_m=
emchunk *out) {
     struct impl_libsamplerate *u;
-    float *buf;
-    void *input, *output;
-    unsigned n_frames;
+    pa_memchunk *buf;
 =

     assert(r);
     assert(in);
@@ -441,55 +473,23 @@
     =

     u =3D r->impl_data;
 =

-    input =3D ((uint8_t*) in->memblock->data + in->index);
-    n_frames =3D in->length / r->i_fz;
-    assert(n_frames > 0);
-    =

-    buf =3D convert_to_float(r, input, n_frames);
-    buf =3D remap_channels(r, buf, n_frames);
-    buf =3D resample(r, buf, &n_frames);
-
-    if (n_frames) {
-        output =3D convert_from_float(r, buf, n_frames);
-
-        if (output =3D=3D input) {
-            /* Mm, no adjustment has been necessary, so let's return the o=
riginal block */
-            out->memblock =3D pa_memblock_ref(in->memblock);
-            out->index =3D in->index;
-            out->length =3D in->length;
-        } else {
-            out->length =3D n_frames * r->o_fz;
-            out->index =3D 0;
-            out->memblock =3D NULL;
-            =

-            if (output =3D=3D u->buf1) {
-                u->buf1 =3D NULL;
-                u->buf1_samples =3D 0;
-                out->memblock =3D u->buf1_block;
-                u->buf1_block =3D NULL;
-            } else if (output =3D=3D u->buf2) {
-                u->buf2 =3D NULL;
-                u->buf2_samples =3D 0;
-                out->memblock =3D u->buf2_block;
-                u->buf2_block =3D NULL;
-            } else if (output =3D=3D u->buf3) {
-                u->buf3 =3D NULL;
-                u->buf3_samples =3D 0;
-                out->memblock =3D u->buf3_block;
-                u->buf3_block =3D NULL;
-            } else if (output =3D=3D u->buf4) {
-                u->buf4 =3D NULL;
-                u->buf4_samples =3D 0;
-                out->memblock =3D u->buf4_block;
-                u->buf4_block =3D NULL;
-            }
-
-            assert(out->memblock);
-        }
-    } else {
-        out->memblock =3D NULL;
-        out->index =3D out->length =3D 0;
-    }
+    buf =3D convert_to_float(r, (pa_memchunk*) in);
+    buf =3D remap_channels(r, buf);
+    buf =3D resample(r, buf);
+
+    if (buf->length) {
+        buf =3D convert_from_float(r, buf);
+        *out =3D *buf;
+
+        if (buf =3D=3D 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=
) {
@@ -516,8 +516,10 @@
 =

     r->impl_data =3D u =3D pa_xnew(struct impl_libsamplerate, 1);
 =

-    u->buf1 =3D u->buf2 =3D u->buf3 =3D u->buf4 =3D NULL;
-    u->buf1_block =3D u->buf2_block =3D u->buf3_block =3D u->buf4_block =
=3D NULL;
+    pa_memchunk_reset(&u->buf1);
+    pa_memchunk_reset(&u->buf2);
+    pa_memchunk_reset(&u->buf3);
+    pa_memchunk_reset(&u->buf4);
     u->buf1_samples =3D u->buf2_samples =3D u->buf3_samples =3D u->buf4_sa=
mples =3D 0;
 =

     if (r->i_ss.format =3D=3D PA_SAMPLE_FLOAT32NE)
@@ -578,12 +580,16 @@
         /* Do real resampling */
         size_t l;
         unsigned o_index;
+        void *src, *dst;
         =

         /* The length of the new memory block rounded up */
         l =3D ((((n_frames+1) * r->o_ss.rate) / r->i_ss.rate) + 1) * fz;
         =

         out->index =3D 0;
         out->memblock =3D pa_memblock_new(r->mempool, l);
+
+        src =3D (uint8_t*) pa_memblock_acquire(in->memblock) + in->index;
+        dst =3D pa_memblock_acquire(out->memblock);
         =

         for (o_index =3D 0;; o_index++, u->o_counter++) {
             unsigned j;
@@ -594,13 +600,16 @@
             if (j >=3D 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 =3D o_index*fz;
     }
 =


Modified: trunk/src/pulsecore/sample-util.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/sample-util=
.c?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulsecore/sample-util.c (original)
+++ trunk/src/pulsecore/sample-util.c Wed Sep 27 01:50:56 2006
@@ -46,15 +46,27 @@
 }
 =

 pa_memblock *pa_silence_memblock(pa_memblock* b, const pa_sample_spec *spe=
c) {
-    assert(b && b->data && spec);
-    pa_silence_memory(b->data, b->length, spec);
+    void *data;
+
+    assert(b);
+    assert(spec);
+    =

+    data =3D 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);
-
-    pa_silence_memory((uint8_t*) c->memblock->data+c->index, c->length, sp=
ec);
+    void *data;
+    =

+    assert(c);
+    assert(c->memblock);
+    assert(spec);
+
+    data =3D 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)=
 {
@@ -82,26 +94,38 @@
 }
 =

 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) {
-    =

-    assert(streams && data && length && spec);
-
+        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 =3D 0;
+    unsigned k;
+    =

+    assert(streams);
+    assert(data);
+    assert(length);
+    assert(spec);
+
+    if (!volume)
+        volume =3D pa_cvolume_reset(&full_volume, spec->channels);
+
+    for (k =3D 0; k < nstreams; k++)
+        streams[k].internal =3D pa_memblock_acquire(streams[k].chunk.membl=
ock);
+    =

     switch (spec->format) {
         case PA_SAMPLE_S16NE:{
-            size_t d;
             unsigned channel =3D 0;
             =

             for (d =3D 0;; d +=3D sizeof(int16_t)) {
                 int32_t sum =3D 0;
                 =

                 if (d >=3D length)
-                    return d;
+                    goto finish;
 =

                 if (!mute && volume->values[channel] !=3D PA_VOLUME_MUTED)=
 {
                     unsigned i;
@@ -111,12 +135,12 @@
                         pa_volume_t cvolume =3D streams[i].volume.values[c=
hannel];
                         =

                         if (d >=3D streams[i].chunk.length)
-                            return d;
+                            goto finish;
                         =

                         if (cvolume =3D=3D PA_VOLUME_MUTED)
                             v =3D 0;
                         else {
-                            v =3D *((int16_t*) ((uint8_t*) streams[i].chun=
k.memblock->data + streams[i].chunk.index + d));
+                            v =3D *((int16_t*) ((uint8_t*) streams[i].inte=
rnal + streams[i].chunk.index + d));
                             =

                             if (cvolume !=3D PA_VOLUME_NORM)
                                 v =3D (int32_t) (v * pa_sw_volume_to_linea=
r(cvolume));
@@ -139,17 +163,18 @@
                 if (++channel >=3D spec->channels)
                     channel =3D 0;
             }
+            =

+            break;
         }
 =

         case PA_SAMPLE_S16RE:{
-            size_t d;
             unsigned channel =3D 0;
             =

             for (d =3D 0;; d +=3D sizeof(int16_t)) {
                 int32_t sum =3D 0;
                 =

                 if (d >=3D length)
-                    return d;
+                    goto finish;
 =

                 if (!mute && volume->values[channel] !=3D PA_VOLUME_MUTED)=
 {
                     unsigned i;
@@ -159,12 +184,12 @@
                         pa_volume_t cvolume =3D streams[i].volume.values[c=
hannel];
                         =

                         if (d >=3D streams[i].chunk.length)
-                            return d;
+                            goto finish;
                         =

                         if (cvolume =3D=3D PA_VOLUME_MUTED)
                             v =3D 0;
                         else {
-                            v =3D INT16_SWAP(*((int16_t*) ((uint8_t*) stre=
ams[i].chunk.memblock->data + streams[i].chunk.index + d)));
+                            v =3D INT16_SWAP(*((int16_t*) ((uint8_t*) stre=
ams[i].internal + streams[i].chunk.index + d)));
                             =

                             if (cvolume !=3D PA_VOLUME_NORM)
                                 v =3D (int32_t) (v * pa_sw_volume_to_linea=
r(cvolume));
@@ -187,17 +212,18 @@
                 if (++channel >=3D spec->channels)
                     channel =3D 0;
             }
+
+            break;
         }
             =

         case PA_SAMPLE_U8: {
-            size_t d;
             unsigned channel =3D 0;
             =

             for (d =3D 0;; d ++) {
                 int32_t sum =3D 0;
                 =

                 if (d >=3D length)
-                    return d;
+                    goto finish;
 =

                 if (!mute && volume->values[channel] !=3D PA_VOLUME_MUTED)=
 {
                     unsigned i;
@@ -207,12 +233,12 @@
                         pa_volume_t cvolume =3D streams[i].volume.values[c=
hannel];
                         =

                         if (d >=3D streams[i].chunk.length)
-                            return d;
+                            goto finish;
                         =

                         if (cvolume =3D=3D PA_VOLUME_MUTED)
                             v =3D 0;
                         else {
-                            v =3D (int32_t) *((uint8_t*) streams[i].chunk.=
memblock->data + streams[i].chunk.index + d) - 0x80;
+                            v =3D (int32_t) *((uint8_t*) streams[i].intern=
al + streams[i].chunk.index + d) - 0x80;
                             =

                             if (cvolume !=3D PA_VOLUME_NORM)
                                 v =3D (int32_t) (v * pa_sw_volume_to_linea=
r(cvolume));
@@ -235,17 +261,18 @@
                 if (++channel >=3D spec->channels)
                     channel =3D 0;
             }
+            =

+            break;
         }
             =

         case PA_SAMPLE_FLOAT32NE: {
-            size_t d;
             unsigned channel =3D 0;
             =

             for (d =3D 0;; d +=3D sizeof(float)) {
                 float sum =3D 0;
                 =

                 if (d >=3D length)
-                    return d;
+                    goto finish;
                 =

                 if (!mute && volume->values[channel] !=3D PA_VOLUME_MUTED)=
 {
                     unsigned i;
@@ -255,12 +282,12 @@
                         pa_volume_t cvolume =3D streams[i].volume.values[c=
hannel];
                         =

                         if (d >=3D streams[i].chunk.length)
-                            return d;
+                            goto finish;
                         =

                         if (cvolume =3D=3D PA_VOLUME_MUTED)
                             v =3D 0;
                         else {
-                            v =3D *((float*) ((uint8_t*) streams[i].chunk.=
memblock->data + streams[i].chunk.index + d));
+                            v =3D *((float*) ((uint8_t*) streams[i].intern=
al + streams[i].chunk.index + d));
                             =

                             if (cvolume !=3D PA_VOLUME_NORM)
                                 v *=3D pa_sw_volume_to_linear(cvolume);
@@ -279,17 +306,34 @@
                 if (++channel >=3D spec->channels)
                     channel =3D 0;
             }
+
+            break;
         }
             =

         default:
             pa_log_error("ERROR: Unable to mix audio data of format %s.", =
pa_sample_format_to_string(spec->format));
             abort();
     }
-}
-
-
-void pa_volume_memchunk(pa_memchunk*c, const pa_sample_spec *spec, const p=
a_cvolume *volume) {
-    assert(c && spec && (c->length % pa_frame_size(spec) =3D=3D 0));
+
+finish:
+
+    for (k =3D 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) {
+
+    void *ptr;
+    =

+    assert(c);
+    assert(spec);
+    assert(c->length % pa_frame_size(spec) =3D=3D 0);
     assert(volume);
 =

     if (pa_cvolume_channels_equal_to(volume, PA_VOLUME_NORM))
@@ -299,6 +343,8 @@
         pa_silence_memchunk(c, spec);
         return;
     }
+
+    ptr =3D pa_memblock_acquire(c->memblock);
 =

     switch (spec->format) {
         case PA_SAMPLE_S16NE: {
@@ -310,7 +356,7 @@
             for (channel =3D 0; channel < spec->channels; channel++)
                 linear[channel] =3D pa_sw_volume_to_linear(volume->values[=
channel]);
             =

-            for (channel =3D 0, d =3D (int16_t*) ((uint8_t*) c->memblock->=
data+c->index), n =3D c->length/sizeof(int16_t); n > 0; d++, n--) {
+            for (channel =3D 0, d =3D (int16_t*) ((uint8_t*) ptr + c->inde=
x), n =3D c->length/sizeof(int16_t); n > 0; d++, n--) {
                 int32_t t =3D (int32_t)(*d);
                 =

                 t =3D (int32_t) (t * linear[channel]);
@@ -335,7 +381,7 @@
             for (channel =3D 0; channel < spec->channels; channel++)
                 linear[channel] =3D pa_sw_volume_to_linear(volume->values[=
channel]);
             =

-            for (channel =3D 0, d =3D (int16_t*) ((uint8_t*) c->memblock->=
data+c->index), n =3D c->length/sizeof(int16_t); n > 0; d++, n--) {
+            for (channel =3D 0, d =3D (int16_t*) ((uint8_t*) ptr + c->inde=
x), n =3D c->length/sizeof(int16_t); n > 0; d++, n--) {
                 int32_t t =3D (int32_t)(INT16_SWAP(*d));
                 =

                 t =3D (int32_t) (t * linear[channel]);
@@ -357,7 +403,7 @@
             size_t n;
             unsigned channel =3D 0;
             =

-            for (d =3D (uint8_t*) c->memblock->data + c->index, n =3D c->l=
ength; n > 0; d++, n--) {
+            for (d =3D (uint8_t*) ptr + c->index, n =3D c->length; n > 0; =
d++, n--) {
                 int32_t t =3D (int32_t) *d - 0x80;
                 =

                 t =3D (int32_t) (t * pa_sw_volume_to_linear(volume->values=
[channel]));
@@ -379,7 +425,7 @@
             unsigned n;
             unsigned channel;
         =

-            d =3D (float*) ((uint8_t*) c->memblock->data + c->index);
+            d =3D (float*) ((uint8_t*) ptr + c->index);
             skip =3D spec->channels * sizeof(float);
             n =3D c->length/sizeof(float)/spec->channels;
             =

@@ -402,5 +448,7 @@
                 pa_sample_format_to_string(spec->format));
             abort();
     }
-}
-
+
+    pa_memblock_release(c->memblock);
+}
+

Modified: trunk/src/pulsecore/sample-util.h
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/sample-util=
.h?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulsecore/sample-util.h (original)
+++ trunk/src/pulsecore/sample-util.h Wed Sep 27 01:50:56 2006
@@ -36,10 +36,11 @@
     pa_memchunk chunk;
     pa_cvolume volume;
     void *userdata;
+    void *internal; /* Used internally by pa_mix(), should not be initiali=
sed 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,

Modified: trunk/src/pulsecore/sink-input.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/sink-input.=
c?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulsecore/sink-input.c (original)
+++ trunk/src/pulsecore/sink-input.c Wed Sep 27 01:50:56 2006
@@ -294,6 +294,7 @@
     assert(i->state =3D=3D PA_SINK_INPUT_RUNNING || i->state =3D=3D PA_SIN=
K_INPUT_DRAINED);
 =

     if (i->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 */
@@ -303,7 +304,8 @@
 =

         chunk->memblock =3D pa_memblock_ref(i->silence_memblock);
         chunk->index =3D 0;
-        chunk->length =3D i->move_silence < chunk->memblock->length ? i->m=
ove_silence : chunk->memblock->length;
+        l =3D pa_memblock_get_length(chunk->memblock);
+        chunk->length =3D i->move_silence < l ? i->move_silence : l;
 =

         ret =3D 0;
         do_volume_adj_here =3D 1;
@@ -389,10 +391,13 @@
     if (i->move_silence > 0) {
 =

         if (chunk) {
-
+            size_t l;
+
+            l =3D pa_memblock_get_length(i->silence_memblock);
+            =

             if (chunk->memblock !=3D i->silence_memblock ||
                 chunk->index !=3D 0 ||
-                (chunk->memblock && (chunk->length !=3D (i->silence_memblo=
ck->length < i->move_silence ? i->silence_memblock->length : i->move_silenc=
e)))) =

+                (chunk->memblock && (chunk->length !=3D (l < i->move_silen=
ce ? l : i->move_silence)))) =

                 return;
             =

         }

Modified: trunk/src/pulsecore/sink.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/sink.c?rev=
=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulsecore/sink.c (original)
+++ trunk/src/pulsecore/sink.c Wed Sep 27 01:50:56 2006
@@ -237,7 +237,6 @@
         info->userdata =3D i;
         =

         assert(info->chunk.memblock);
-        assert(info->chunk.memblock->data);
         assert(info->chunk.length);
         =

         info++;
@@ -305,13 +304,16 @@
                 pa_volume_memchunk(result, &s->sample_spec, &volume);
         }
     } else {
+        void *ptr;
         result->memblock =3D pa_memblock_new(s->core->mempool, length);
         assert(result->memblock);
 =

 /*          pa_log("mixing %i", n);  */
 =

-        result->length =3D pa_mix(info, n, result->memblock->data, length,
-            &s->sample_spec, &s->sw_volume, s->sw_muted);
+        ptr =3D pa_memblock_acquire(result->memblock);
+        result->length =3D pa_mix(info, n, ptr, length, &s->sample_spec, &=
s->sw_volume, s->sw_muted);
+        pa_memblock_release(result->memblock);
+        =

         result->index =3D 0;
     }
 =

@@ -332,13 +334,13 @@
     pa_mix_info info[MAX_MIX_CHANNELS];
     unsigned n;
     int r =3D -1;
+    void *ptr;
     =

     assert(s);
     assert(s->ref >=3D 1);
     assert(target);
     assert(target->memblock);
     assert(target->length);
-    assert(target->memblock->data);
 =

     pa_sink_ref(s);
     =

@@ -347,15 +349,22 @@
     if (n <=3D 0)
         goto finish;
 =

+    ptr =3D pa_memblock_acquire(target->memblock);
+    =

     if (n =3D=3D 1) {
+        void *src;
         pa_cvolume volume;
 =

         if (target->length > info[0].chunk.length)
             target->length =3D info[0].chunk.length;
-        =

-        memcpy((uint8_t*) target->memblock->data + target->index,
-               (uint8_t*) info[0].chunk.memblock->data + info[0].chunk.ind=
ex,
+
+        src =3D 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(info[0].chunk.memblock);
 =

         pa_sw_cvolume_multiply(&volume, &s->sw_volume, &info[0].volume);
 =

@@ -365,11 +374,13 @@
             pa_volume_memchunk(target, &s->sample_spec, &volume);
     } else
         target->length =3D 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);
+
+    pa_memblock_release(target->memblock);
     =

     inputs_drop(s, info, n, target->length);
 =

@@ -393,7 +404,6 @@
     assert(target);
     assert(target->memblock);
     assert(target->length);
-    assert(target->memblock->data);
 =

     pa_sink_ref(s);
     =


Modified: trunk/src/pulsecore/sound-file-stream.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/sound-file-=
stream.c?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulsecore/sound-file-stream.c (original)
+++ trunk/src/pulsecore/sound-file-stream.c Wed Sep 27 01:50:56 2006
@@ -74,21 +74,26 @@
     if (!u->memchunk.memblock) {
         uint32_t fs =3D pa_frame_size(&i->sample_spec);
         sf_count_t n;
+        void *p;
 =

         u->memchunk.memblock =3D pa_memblock_new(i->sink->core->mempool, B=
UF_SIZE);
         u->memchunk.index =3D 0;
 =

+        p =3D pa_memblock_acquire(u->memchunk.memblock);
+        =

         if (u->readf_function) {
-            if ((n =3D u->readf_function(u->sndfile, u->memchunk.memblock-=
>data, BUF_SIZE/fs)) <=3D 0)
+            if ((n =3D u->readf_function(u->sndfile, p, BUF_SIZE/fs)) <=3D=
 0)
                 n =3D 0;
 =

             u->memchunk.length =3D n * fs;
         } else {
-            if ((n =3D sf_read_raw(u->sndfile, u->memchunk.memblock->data,=
 BUF_SIZE)) <=3D 0)
+            if ((n =3D sf_read_raw(u->sndfile, p, BUF_SIZE)) <=3D 0)
                 n =3D 0;
             =

             u->memchunk.length =3D n;
         }
+
+        pa_memblock_release(u->memchunk.memblock);
         =

         if (!u->memchunk.length) {
             free_userdata(u);

Modified: trunk/src/pulsecore/sound-file.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/sound-file.=
c?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/pulsecore/sound-file.c (original)
+++ trunk/src/pulsecore/sound-file.c Wed Sep 27 01:50:56 2006
@@ -40,7 +40,11 @@
     int ret =3D -1;
     size_t l;
     sf_count_t (*readf_function)(SNDFILE *sndfile, void *ptr, sf_count_t f=
rames) =3D NULL;
-    assert(fname && ss && chunk);
+    void *ptr =3D NULL;
+    =

+    assert(fname);
+    assert(ss);
+    assert(chunk);
 =

     chunk->memblock =3D NULL;
     chunk->index =3D chunk->length =3D 0;
@@ -97,8 +101,10 @@
     chunk->index =3D 0;
     chunk->length =3D l;
 =

-    if ((readf_function && readf_function(sf, chunk->memblock->data, sfinf=
o.frames) !=3D sfinfo.frames) ||
-        (!readf_function && sf_read_raw(sf, chunk->memblock->data, l) !=3D=
 l)) {
+    ptr =3D pa_memblock_acquire(chunk->memblock);
+    =

+    if ((readf_function && readf_function(sf, ptr, sfinfo.frames) !=3D sfi=
nfo.frames) ||
+        (!readf_function && sf_read_raw(sf, ptr, l) !=3D l)) {
         pa_log("Premature file end");
         goto finish;
     }
@@ -110,6 +116,9 @@
     if (sf)
         sf_close(sf);
 =

+    if (ptr)
+        pa_memblock_release(chunk->memblock);
+    =

     if (ret !=3D 0 && chunk->memblock)
         pa_memblock_unref(chunk->memblock);
     =


Modified: trunk/src/tests/flist-test.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/tests/flist-test.c?re=
v=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/tests/flist-test.c (original)
+++ trunk/src/tests/flist-test.c Wed Sep 27 01:50:56 2006
@@ -54,7 +54,7 @@
     int b =3D 1;
 =

     while (!quit) {
-        char *text, *t;
+        char *text;
 =

         /* Allocate some memory, if possible take it from the flist */
         if (b && (text =3D pa_flist_pop(flist)))

Modified: trunk/src/tests/mcalign-test.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/tests/mcalign-test.c?=
rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/tests/mcalign-test.c (original)
+++ trunk/src/tests/mcalign-test.c Wed Sep 27 01:50:56 2006
@@ -59,24 +59,27 @@
             c.index =3D c.length =3D 0;
         }
 =

-        assert(c.index < c.memblock->length);
+        assert(c.index < pa_memblock_get_length(c.memblock));
 =

-        l =3D c.memblock->length - c.index;
+        l =3D pa_memblock_get_length(c.memblock) - c.index;
 =

         l =3D l <=3D 1 ? l : rand() % (l-1) +1 ;
-        =

-        if ((r =3D read(STDIN_FILENO, (uint8_t*) c.memblock->data + c.inde=
x, l)) <=3D 0) {
+
+        p =3D pa_memblock_acquire(c.memblock);
+        if ((r =3D read(STDIN_FILENO, (uint8_t*) p + c.index, l)) <=3D 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 =3D r;
         pa_mcalign_push(a, &c);
         fprintf(stderr, "Read %ld bytes\n", (long)r);
 =

         c.index +=3D r;
 =

-        if (c.index >=3D c.memblock->length) {
+        if (c.index >=3D pa_memblock_get_length(c.memblock)) {
             pa_memblock_unref(c.memblock);
             pa_memchunk_reset(&c);
         }
@@ -87,7 +90,9 @@
             if (pa_mcalign_pop(a, &t) < 0)
                 break;
 =

-            pa_loop_write(STDOUT_FILENO, (uint8_t*) t.memblock->data + t.i=
ndex, t.length, NULL);
+            p =3D 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);

Modified: trunk/src/tests/memblock-test.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/tests/memblock-test.c=
?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/tests/memblock-test.c (original)
+++ trunk/src/tests/memblock-test.c Wed Sep 27 01:50:56 2006
@@ -76,6 +76,7 @@
     pa_memblock* blocks[5];
     uint32_t id, shm_id;
     size_t offset, size;
+    char *x;
 =

     const char txt[] =3D "This is a test!";
     =

@@ -90,10 +91,17 @@
     assert(pool_a && pool_b && pool_c);
     =

     blocks[0] =3D pa_memblock_new_fixed(pool_a, (void*) txt, sizeof(txt), =
1);
+
     blocks[1] =3D pa_memblock_new(pool_a, sizeof(txt));
-    snprintf(blocks[1]->data, blocks[1]->length, "%s", txt);
+    x =3D pa_memblock_acquire(blocks[1]);
+    snprintf(x, pa_memblock_get_length(blocks[1]), "%s", txt);
+    pa_memblock_release(blocks[1]);
+    =

     blocks[2] =3D pa_memblock_new_pool(pool_a, sizeof(txt));
-    snprintf(blocks[2]->data, blocks[2]->length, "%s", txt);
+    x =3D pa_memblock_acquire(blocks[2]);
+    snprintf(x, pa_memblock_get_length(blocks[2]), "%s", txt);
+    pa_memblock_release(blocks[1]);
+
     blocks[3] =3D pa_memblock_new_malloced(pool_a, pa_xstrdup(txt), sizeof=
(txt));
     blocks[4] =3D NULL;
 =

@@ -130,14 +138,18 @@
         =

         mb_c =3D pa_memimport_get(import_c, id, shm_id, offset, size);
         assert(mb_c);
-        printf("1 data=3D%s\n", (char*) mb_c->data);
+        x =3D pa_memblock_acquire(mb_c);
+        printf("1 data=3D%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=3D%s\n", (char*) mb_c->data);
+        x =3D pa_memblock_acquire(mb_c);
+        printf("2 data=3D%s\n", x);
+        pa_memblock_release(mb_c);
         pa_memblock_unref(mb_c);
         =

         pa_memimport_free(import_b);

Modified: trunk/src/tests/memblockq-test.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/tests/memblockq-test.=
c?rev=3D1404&root=3Dpulseaudio&r1=3D1403&r2=3D1404&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/src/tests/memblockq-test.c (original)
+++ trunk/src/tests/memblockq-test.c Wed Sep 27 01:50:56 2006
@@ -131,8 +131,10 @@
         if (pa_memblockq_peek(bq, &out) < 0)
             break;
 =

-        for (e =3D (char*) out.memblock->data + out.index, n =3D 0; n < ou=
t.length; n++)
+        p =3D pa_memblock_acquire(out.memblock);
+        for (e =3D (char*) p + out.index, n =3D 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);




More information about the pulseaudio-commits mailing list