audio_server: shared memory leak fix binder [1/1]

PD#SWPL-136663

Problem:
Shared memory was not being unmapped for binder server
close stream operations.

Solution:
Unmap shared memory for binder server close stream operations.

Verify:
yocto

Change-Id: I8a334012375e81e70d6fe59d24bd8eaa71d2b00c
Signed-off-by: jesse.huang <jesse.huang@amlogic.com>
diff --git a/src/binder/audio_client_binder.cpp b/src/binder/audio_client_binder.cpp
index 8e68246..cd137eb 100644
--- a/src/binder/audio_client_binder.cpp
+++ b/src/binder/audio_client_binder.cpp
@@ -37,6 +37,7 @@
     do { \
         if ((tr) != 0) { \
             if ((tr) == BINDER_EXCEPTION) { std::cout << PROCESS_NAME_LOG << " Service exception." << std::endl; on_service_exception(); } \
+            std::cout << PROCESS_NAME_LOG << " Error with transact " << (l) << ". transactRet = " << (tr) << "." << std::endl; \
             return (r); \
         } \
     } while (0)
@@ -207,6 +208,8 @@
     stream_out_client = new audio_stream_out_client_t;
     if (!stream_out_client) return -ENOMEM;
 
+    stream_out_client->shm = nullptr;
+
     send.writeStrongBinder(::android::sp<AudioClientBinder>(this));
 
     int seq = new_stream_name(stream_out_client->name, sizeof(stream_out_client->name));
@@ -252,10 +255,14 @@
         if (streamoutClients.empty()) return;
     }
 
-    struct audio_stream_out_client* stream_out_client = audio_stream_out_to_client(stream_out);
+    audio_stream_out_client_t* stream_out_client = audio_stream_out_to_client(stream_out);
 
     const char* name = stream_out_client->name;
-    posixCloseFile(PROCESS_NAME_LOG, OUTPUT_STREAM_LABEL, name, stream_out_client->fd);
+    {
+        std::lock_guard<std::mutex> lock(stream_out_client->stream_mutex);
+        posixCloseFile(PROCESS_NAME_LOG, OUTPUT_STREAM_LABEL, name, stream_out_client->fd);
+        stream_out_client->shm = nullptr;
+    }
 
     {
         std::lock_guard<std::mutex> lock(stream_out_clients_mutex_);
@@ -284,6 +291,8 @@
     stream_in_client = new audio_stream_in_client_t;
     if (!stream_in_client) return -ENOMEM;
 
+    stream_in_client->shm = nullptr;
+
     send.writeStrongBinder(::android::sp<AudioClientBinder>(this));
 
     int seq = new_stream_name(stream_in_client->name, sizeof(stream_in_client->name));
@@ -331,10 +340,14 @@
         if (streaminClients.empty()) return;
     }
 
-    struct audio_stream_in_client* stream_in_client = audio_stream_in_to_client(stream_in);
+    audio_stream_in_client* stream_in_client = audio_stream_in_to_client(stream_in);
 
     const char* name = stream_in_client->name;
-    posixCloseFile(PROCESS_NAME_LOG, INPUT_STREAM_LABEL, name, stream_in_client->fd);
+    {
+        std::lock_guard<std::mutex> lock(stream_in_client->stream_mutex);
+        posixCloseFile(PROCESS_NAME_LOG, INPUT_STREAM_LABEL, name, stream_in_client->fd);
+        stream_in_client->shm = nullptr;
+    }
 
     {
         std::lock_guard<std::mutex> lock(stream_in_clients_mutex_);
@@ -415,13 +428,14 @@
 audio_channel_mask_t AudioClientBinder::Stream_get_channels(const struct audio_stream* stream) {
     ::android::Parcel send, reply;
 
-    struct audio_stream_client* stream_client = audio_stream_to_client(stream);
-
-    void* stream_hw = stream_client->stream_hw;
+    void* stream_hw = (audio_stream_to_client(stream))->stream_hw;
     send.write(&stream_hw, sizeof(stream_hw));
 
     int transactRet = mAudioServiceBinder->transact(CMD_AS_SGC, send, &reply);
-    if (transactRet == BINDER_EXCEPTION) { std::cout << PROCESS_NAME_LOG << " Service exception." << std::endl; on_service_exception(); }
+    if (transactRet != 0) {
+        if (transactRet == BINDER_EXCEPTION) { std::cout << PROCESS_NAME_LOG << " Service exception." << std::endl; on_service_exception(); }
+        std::cout << PROCESS_NAME_LOG << " Error with transact data for stream get channels. transactRet = " << transactRet << "." << std::endl;
+    }
 
     return (audio_channel_mask_t) reply.readUint32();
 }
@@ -433,7 +447,10 @@
     send.write(&stream_hw, sizeof(stream_hw));
 
     int transactRet = mAudioServiceBinder->transact(CMD_AS_SGF, send, &reply);
-    if (transactRet == BINDER_EXCEPTION) { std::cout << PROCESS_NAME_LOG << " Service exception." << std::endl; on_service_exception(); }
+    if (transactRet != 0) {
+        if (transactRet == BINDER_EXCEPTION) { std::cout << PROCESS_NAME_LOG << " Service exception." << std::endl; on_service_exception(); }
+        std::cout << PROCESS_NAME_LOG << " Error with transact data for stream get format. transactRet = " << transactRet << "." << std::endl;
+    }
 
     return (audio_format_t) reply.readUint32();
 }
@@ -516,15 +533,19 @@
 
     ::android::Parcel send, reply;
 
-    struct audio_stream_out_client* stream_out_client = audio_stream_out_to_client(stream);
+    audio_stream_out_client_t* stream_out_client = audio_stream_out_to_client(stream);
 
-    if (!stream_out_client->shm) {
-        std::cout << PROCESS_NAME_LOG << " Shared memory to " << OUTPUT_STREAM_LABEL << " " << stream_out_client->name << " was not previously allocated on client. Allocating." << std::endl;
-        if (setShmAndFdForStreamOutClient(stream_out_client) == -1) return -1;
+    {
+        std::lock_guard<std::mutex> lock(stream_out_client->stream_mutex);
+
+        if (stream_out_client->shm == nullptr) {
+            std::cout << PROCESS_NAME_LOG << " Shared memory to " << OUTPUT_STREAM_LABEL << " " << stream_out_client->name << " was not previously allocated on client. Allocating." << std::endl;
+            if (setShmAndFdForStreamOutClient(stream_out_client) == -1) return -1;
+        }
+
+        memcpy(stream_out_client->shm, buffer, std::min(bytes, (size_t) KSHAREDBUFFERSIZE));
     }
 
-    memcpy(stream_out_client->shm, buffer, std::min(bytes, (size_t) KSHAREDBUFFERSIZE));
-
     send.write(&stream_out_client->stream_out_info, sizeof(stream_out_client->stream_out_info));
     send.write(&bytes, sizeof(bytes));
 
@@ -600,7 +621,7 @@
 
     ::android::Parcel send, reply;
 
-    struct audio_stream_in_client* stream_in_client = audio_stream_in_to_client(stream);
+    audio_stream_in_client_t* stream_in_client = audio_stream_in_to_client(stream);
 
     void* stream_in_info = stream_in_client->stream_in_info;
     send.write(&stream_in_info, sizeof(stream_in_info));
@@ -612,7 +633,9 @@
 
     ssize_t ret = reply.readInt32();
     if (ret > 0) {
-        if (!stream_in_client->shm) {
+        std::lock_guard<std::mutex> lock(stream_in_client->stream_mutex);
+
+        if (stream_in_client->shm == nullptr) {
             std::cout << PROCESS_NAME_LOG << " Shared memory to " << INPUT_STREAM_LABEL << " " << stream_in_client->name << " was not previously allocated on client. Allocating." << std::endl;
             setShmAndFdForStreamInClient(stream_in_client);
         }
@@ -887,7 +910,10 @@
 
         audio_stream_out_client_t* stream_out_client = it->second;
         if (stream_out_client != nullptr) {
-            posixCloseFile(PROCESS_NAME_LOG, OUTPUT_STREAM_LABEL, name, stream_out_client->fd);
+            {
+                std::lock_guard<std::mutex> lock(stream_out_client->stream_mutex);
+                posixCloseFile(PROCESS_NAME_LOG, OUTPUT_STREAM_LABEL, name, stream_out_client->fd);
+            }
             delete stream_out_client;
             stream_out_client = nullptr;
         }
@@ -904,7 +930,10 @@
 
         audio_stream_in_client_t* stream_in_client = it->second;
         if (stream_in_client != nullptr) {
-            posixCloseFile(PROCESS_NAME_LOG, INPUT_STREAM_LABEL, name, stream_in_client->fd);
+            {
+                std::lock_guard<std::mutex> lock(stream_in_client->stream_mutex);
+                posixCloseFile(PROCESS_NAME_LOG, INPUT_STREAM_LABEL, name, stream_in_client->fd);
+            }
             delete stream_in_client;
             stream_in_client = nullptr;
         }
@@ -920,7 +949,10 @@
     reply.read(&(stream_out_client->stream_hw), sizeof(stream_out_client->stream_hw));
     reply.read(&(stream_out_client->stream_out_info), sizeof(stream_out_client->stream_out_info));
 
-    return setShmAndFdForStreamOutClient(stream_out_client);
+    {
+        std::lock_guard<std::mutex> lock(stream_out_client->stream_mutex);
+        return setShmAndFdForStreamOutClient(stream_out_client);
+    }
 }
 
 int AudioClientBinder::updateStreamInClient(const ::android::Parcel& reply, audio_stream_in_client_t* stream_in_client) {
@@ -930,11 +962,15 @@
     reply.read(&(stream_in_client->stream_hw), sizeof(stream_in_client->stream_hw));
     reply.read(&(stream_in_client->stream_in_info), sizeof(stream_in_client->stream_in_info));
 
-    return setShmAndFdForStreamInClient(stream_in_client);
+    {
+        std::lock_guard<std::mutex> lock(stream_in_client->stream_mutex);
+        return setShmAndFdForStreamInClient(stream_in_client);
+    }
 }
 
 int AudioClientBinder::setShmAndFdForStreamOutClient(audio_stream_out_client_t* stream_out_client) {
-    int fd; void* streamoutShm;
+    int fd; void* streamoutShm = nullptr;
+
     fd = posixOpenFileAndMapData(PROCESS_NAME_LOG, OUTPUT_STREAM_LABEL, stream_out_client->name, O_RDWR, S_IRUSR | S_IWUSR, streamoutShm, KSHAREDBUFFERSIZE, PROT_READ | PROT_WRITE, MAP_SHARED);
     if (fd == -1) {
         return -1;
@@ -945,7 +981,7 @@
 }
 
 int AudioClientBinder::setShmAndFdForStreamInClient(audio_stream_in_client_t* stream_in_client) {
-    int fd; void* streaminShm;
+    int fd; void* streaminShm = nullptr;
     fd = posixOpenFileAndMapData(PROCESS_NAME_LOG, INPUT_STREAM_LABEL, stream_in_client->name, O_RDWR, S_IRUSR | S_IWUSR, streaminShm, KSHAREDBUFFERSIZE, PROT_READ | PROT_WRITE, MAP_SHARED);
     if (fd == -1) {
         return -1;
diff --git a/src/binder/audio_client_binder.h b/src/binder/audio_client_binder.h
index f21dde0..ae07e33 100644
--- a/src/binder/audio_client_binder.h
+++ b/src/binder/audio_client_binder.h
@@ -35,6 +35,7 @@
     void* stream_hw;
     struct audio_stream_out stream_out;
     void* stream_out_info;
+    std::mutex stream_mutex;
     int fd;
     void* shm;
 } audio_stream_out_client_t;
@@ -44,6 +45,7 @@
     void* stream_hw;
     struct audio_stream_in stream_in;
     void* stream_in_info;
+    std::mutex stream_mutex;
     int fd;
     void* shm;
 } audio_stream_in_client_t;
diff --git a/src/binder/audio_service_binder.cpp b/src/binder/audio_service_binder.cpp
index 927ad5d..e07ecc4 100644
--- a/src/binder/audio_service_binder.cpp
+++ b/src/binder/audio_service_binder.cpp
@@ -144,13 +144,15 @@
                                             struct audio_config& config,
                                             const char* address,
                                             int& clientId,
-                                            audio_stream*& stream_hw,
+                                            struct audio_stream*& stream_hw,
                                             audio_stream_out_info_t*& stream_out_info) {
     CHKP_AND_RET(dev_, -1);
 
     stream_out_info = new audio_stream_out_info_t;
     if (!stream_out_info) return -ENOMEM;
 
+    stream_out_info->shm = nullptr;
+
     int client_id = ::android::IPCThreadState::self()->getCallingPid();
     if (client_id < 0) {
         clientId = -1;
@@ -184,11 +186,15 @@
     const char* name = stream_out_info->name;
     const std::string nameStr(name);
 
-    posixUnlinkNameAndCloseFile(PROCESS_NAME_LOG, OUTPUT_STREAM_LABEL, name, stream_out_info->fd);
+    {
+        std::lock_guard<std::mutex> lock(stream_out_info->stream_mutex);
+        posixUnmapDataCloseFileAndUnlinkName(PROCESS_NAME_LOG, OUTPUT_STREAM_LABEL, name, stream_out_info->shm, KSHAREDBUFFERSIZE, stream_out_info->fd);
+    }
 
-    if (dev_) {
+    struct audio_stream_out* stream_out_hw = stream_out_info->stream_out_hw;
+    if (dev_ && stream_out_hw) {
         std::cout << PROCESS_NAME_LOG << " close " << OUTPUT_STREAM_LABEL << " " << name << std::endl;
-        dev_->close_output_stream(dev_, stream_out_info->stream_out_hw);
+        dev_->close_output_stream(dev_, stream_out_hw);
     }
 
     int client_id = ::android::IPCThreadState::self()->getCallingPid();
@@ -215,6 +221,8 @@
     stream_in_info = new audio_stream_in_info_t;
     if (!stream_in_info) return -ENOMEM;
 
+    stream_in_info->shm = nullptr;
+
     int client_id = ::android::IPCThreadState::self()->getCallingPid();
     if (client_id < 0) {
         clientId = -1;
@@ -247,11 +255,15 @@
     const char* name = stream_in_info->name;
     const std::string nameStr(name);
 
-    posixUnlinkNameAndCloseFile(PROCESS_NAME_LOG, INPUT_STREAM_LABEL, name, stream_in_info->fd);
+    {
+        std::lock_guard<std::mutex> lock(stream_in_info->stream_mutex);
+        posixUnmapDataCloseFileAndUnlinkName(PROCESS_NAME_LOG, INPUT_STREAM_LABEL, name, stream_in_info->shm, KSHAREDBUFFERSIZE, stream_in_info->fd);
+    }
 
-    if (dev_) {
+    struct audio_stream_in* stream_in_hw = stream_in_info->stream_in_hw;
+    if (dev_ && stream_in_hw) {
         std::cout << PROCESS_NAME_LOG << " close " << INPUT_STREAM_LABEL << " " << name << std::endl;
-        dev_->close_input_stream(dev_, stream_in_info->stream_in_hw);
+        dev_->close_input_stream(dev_, stream_in_hw);
     }
 
     int client_id = ::android::IPCThreadState::self()->getCallingPid();
@@ -335,7 +347,7 @@
     return (uint32_t) stream_hw->get_channels(stream_hw);
 }
 
-int AudioServiceBinder::Stream_get_format(struct audio_stream* stream_hw) {
+uint32_t AudioServiceBinder::Stream_get_format(struct audio_stream* stream_hw) {;
     return (uint32_t) stream_hw->get_format(stream_hw);
 }
 
@@ -377,22 +389,35 @@
 
 ssize_t AudioServiceBinder::StreamOut_write(audio_stream_out_info_t* stream_out_info, size_t bytes) {
     CHKP_AND_RET(dev_, -1);
+    CHKP_AND_RET(stream_out_info, -1);
 
-    if (stream_out_info->shm == nullptr) {
-        const char* name = stream_out_info->name;
-        std::cout << PROCESS_NAME_LOG << " Shared memory to " << OUTPUT_STREAM_LABEL << " " << name << " was not previously allocated on service. Allocating." << std::endl;
-        if (setShmAndFdForStreamOutInfo(name, stream_out_info) == -1) return -1;
+    {
+        std::lock_guard<std::mutex> lock(stream_out_info->stream_mutex);
+
+        if (stream_out_info->shm == nullptr) {
+            const char* name = stream_out_info->name;
+            std::cout << PROCESS_NAME_LOG << " Shared memory to " << OUTPUT_STREAM_LABEL << " " << name << " was not previously allocated on service. Allocating." << std::endl;
+            if (setShmAndFdForStreamOutInfo(name, stream_out_info) == -1) {
+                return -1;
+            }
+        }
     }
 
     struct audio_stream_out* stream_out_hw = stream_out_info->stream_out_hw;
     CHKP_AND_RET(stream_out_hw, -1);
 
-    return stream_out_hw->write(stream_out_hw, stream_out_info->shm, bytes);
+    {
+        std::lock_guard<std::mutex> lock(stream_out_info->stream_mutex);
+        CHKP_AND_RET(stream_out_info->shm, -1);
+        return stream_out_hw->write(stream_out_hw, stream_out_info->shm, bytes);
+    }
 }
 
 int AudioServiceBinder::StreamOut_get_render_position(struct audio_stream_out* stream_out_hw, uint32_t& dsp_frames) {
     CHKP_AND_RET(dev_, -1);
     CHKP_AND_RET(stream_out_hw, -1);
+
+    dsp_frames = 0;
     return stream_out_hw->get_render_position(stream_out_hw, &dsp_frames);
 }
 
@@ -440,17 +465,28 @@
 
 int AudioServiceBinder::StreamIn_read(audio_stream_in_info_t* stream_in_info, size_t bytes) {
     CHKP_AND_RET(dev_, -1);
+    CHKP_AND_RET(stream_in_info, -1);
 
-    if (stream_in_info->shm == nullptr) {
-        const char* name = stream_in_info->name;
-        std::cout << PROCESS_NAME_LOG << " Shared memory to " << INPUT_STREAM_LABEL << " " << name << " was not previously allocated on service. Allocating." << std::endl;
-        if (setShmAndFdForStreamInInfo(name, stream_in_info) == -1) return -1;
+    {
+        std::lock_guard<std::mutex> lock(stream_in_info->stream_mutex);
+
+        if (stream_in_info->shm == nullptr) {
+            const char* name = stream_in_info->name;
+            std::cout << PROCESS_NAME_LOG << " Shared memory to " << INPUT_STREAM_LABEL << " " << name << " was not previously allocated on service. Allocating." << std::endl;
+            if (setShmAndFdForStreamInInfo(name, stream_in_info) == -1) {
+                return -1;
+            }
+        }
     }
 
     struct audio_stream_in* stream_in_hw = stream_in_info->stream_in_hw;
     CHKP_AND_RET(stream_in_hw, -1);
 
-    return stream_in_hw->read(stream_in_hw, stream_in_info->shm, std::min(bytes, (size_t) KSHAREDBUFFERSIZE));
+    {
+        std::lock_guard<std::mutex> lock(stream_in_info->stream_mutex);
+        CHKP_AND_RET(stream_in_info->shm, -1);
+        return stream_in_hw->read(stream_in_hw, stream_in_info->shm, std::min(bytes, (size_t) KSHAREDBUFFERSIZE));
+    }
 }
 
 uint32_t AudioServiceBinder::StreamIn_get_input_frames_lost(struct audio_stream_in* stream_in_hw) {
@@ -461,7 +497,6 @@
 
 int AudioServiceBinder::StreamIn_get_capture_position(struct audio_stream_in* stream_in_hw, int64_t& frames, int64_t& time) {
     CHKP_AND_RET(dev_, -1);
-
     CHKP_AND_RET(stream_in_hw, -1);
 
     frames = time = 0;
@@ -506,14 +541,14 @@
         if (streamDirection == AUDIO_STREAM_OUT) {
             audio_stream_out_info_t* stream_out_info = static_cast<audio_stream_out_info_t*>(streamInfo);
             if (stream_out_info != nullptr) {
-                streamout_gc_(streamNameCStr, stream_out_info->fd, stream_out_info->stream_out_hw);
+                streamout_gc_(stream_out_info->stream_mutex, streamNameCStr, stream_out_info->shm, stream_out_info->fd, stream_out_info->stream_out_hw);
                 delete stream_out_info;
                 stream_out_info = nullptr;
             }
         } else {
             audio_stream_in_info_t* stream_in_info = static_cast<audio_stream_in_info_t*>(streamInfo);
             if (stream_in_info != nullptr) {
-                streamin_gc_(streamNameCStr, stream_in_info->fd, stream_in_info->stream_in_hw);
+                streamin_gc_(stream_in_info->stream_mutex, streamNameCStr, stream_in_info->shm, stream_in_info->fd, stream_in_info->stream_in_hw);
                 delete stream_in_info;
                 stream_in_info = nullptr;
             }
@@ -521,17 +556,25 @@
     }
 }
 
-void AudioServiceBinder::streamout_gc_(const char* name, int fd, audio_stream_out* stream_out_hw) {
-    posixUnlinkNameAndCloseFile(PROCESS_NAME_LOG, OUTPUT_STREAM_LABEL, name, fd);
-    if (dev_) {
+void AudioServiceBinder::streamout_gc_(std::mutex& stream_mutex, const char* name, void* shm, int fd, audio_stream_out* stream_out_hw) {
+    {
+        std::lock_guard<std::mutex> lock(stream_mutex);
+        posixUnmapDataCloseFileAndUnlinkName(PROCESS_NAME_LOG, OUTPUT_STREAM_LABEL, name, shm, KSHAREDBUFFERSIZE, fd);
+    }
+
+    if (dev_ && stream_out_hw) {
         std::cout << PROCESS_NAME_LOG << " close " << OUTPUT_STREAM_LABEL << " " << name << std::endl;
         dev_->close_output_stream(dev_, stream_out_hw);
     }
 }
 
-void AudioServiceBinder::streamin_gc_(const char* name, int fd, audio_stream_in* stream_in_hw) {
-    posixUnlinkNameAndCloseFile(PROCESS_NAME_LOG, INPUT_STREAM_LABEL, name, fd);
-    if (dev_) {
+void AudioServiceBinder::streamin_gc_(std::mutex& stream_mutex, const char* name, void* shm, int fd, audio_stream_in* stream_in_hw) {
+    {
+        std::lock_guard<std::mutex> lock(stream_mutex);
+        posixUnmapDataCloseFileAndUnlinkName(PROCESS_NAME_LOG, INPUT_STREAM_LABEL, name, shm, KSHAREDBUFFERSIZE, fd);
+    }
+
+    if (dev_ && stream_in_hw) {
         std::cout << PROCESS_NAME_LOG << " close " << INPUT_STREAM_LABEL << " " << name << std::endl;
         dev_->close_input_stream(dev_, stream_in_hw);
     }
@@ -540,13 +583,19 @@
 int AudioServiceBinder::updateStreamOutInfo(const char* name, struct audio_stream_out* stream, audio_stream_out_info_t* stream_out_info) {
     strcpy(stream_out_info->name, name);
     stream_out_info->stream_out_hw = stream;
-    return setShmAndFdForStreamOutInfo(name, stream_out_info);
+    {
+        std::lock_guard<std::mutex> lock(stream_out_info->stream_mutex);
+        return setShmAndFdForStreamOutInfo(name, stream_out_info);
+    }
 }
 
 int AudioServiceBinder::updateStreamInInfo(const char* name, struct audio_stream_in* stream, audio_stream_in_info_t* stream_in_info) {
     strcpy(stream_in_info->name, name);
     stream_in_info->stream_in_hw = stream;
-    return setShmAndFdForStreamInInfo(name, stream_in_info);
+    {
+        std::lock_guard<std::mutex> lock(stream_in_info->stream_mutex);
+        return setShmAndFdForStreamInInfo(name, stream_in_info);
+    }
 }
 
 int AudioServiceBinder::setShmAndFdForStreamOutInfo(const char* name, audio_stream_out_info_t* stream_out_info) {
@@ -898,13 +947,13 @@
             break;
         }
         case CMD_AS_SO_GL: {
-            struct audio_stream_out_info* stream_out_info; data.read(&stream_out_info, sizeof(stream_out_info));
+            audio_stream_out_info_t* stream_out_info; data.read(&stream_out_info, sizeof(stream_out_info));
             uint32_t ret = StreamOut_get_latency(stream_out_info->stream_out_hw);
             reply->writeUint32(ret);
             break;
         }
         case CMD_AS_SO_SV: {
-            struct audio_stream_out_info* stream_out_info; data.read(&stream_out_info, sizeof(stream_out_info));
+            audio_stream_out_info_t* stream_out_info; data.read(&stream_out_info, sizeof(stream_out_info));
             float left = data.readFloat();
             float right = data.readFloat();
             int ret = StreamOut_set_volume(stream_out_info->stream_out_hw, left, right);
@@ -912,14 +961,14 @@
             break;
         }
         case CMD_AS_SO_W: {
-            struct audio_stream_out_info* stream_out_info; data.read(&stream_out_info, sizeof(stream_out_info));
+            audio_stream_out_info_t* stream_out_info; data.read(&stream_out_info, sizeof(stream_out_info));
             size_t bytes; data.read(&bytes, sizeof(bytes));
             int ret = StreamOut_write(stream_out_info, bytes);
             reply->writeInt32(ret);
             break;
         }
         case CMD_AS_SO_GRP: {
-            struct audio_stream_out_info* stream_out_info; data.read(&stream_out_info, sizeof(stream_out_info));
+            audio_stream_out_info_t* stream_out_info; data.read(&stream_out_info, sizeof(stream_out_info));
             uint32_t dsp_frames;
             int ret = StreamOut_get_render_position(stream_out_info->stream_out_hw, dsp_frames);
             reply->writeInt32(ret);
@@ -927,7 +976,7 @@
             break;
         }
         case CMD_AS_SO_GNWT: {
-            struct audio_stream_out_info* stream_out_info; data.read(&stream_out_info, sizeof(stream_out_info));
+            audio_stream_out_info_t* stream_out_info; data.read(&stream_out_info, sizeof(stream_out_info));
             int64_t timestamp;
             int ret = StreamOut_get_next_write_timestamp(stream_out_info->stream_out_hw, timestamp);
             reply->writeInt32(ret);
@@ -935,25 +984,25 @@
             break;
         }
         case CMD_AS_SO_P: {
-            struct audio_stream_out_info* stream_out_info; data.read(&stream_out_info, sizeof(stream_out_info));
+            audio_stream_out_info_t* stream_out_info; data.read(&stream_out_info, sizeof(stream_out_info));
             int ret = StreamOut_pause(stream_out_info->stream_out_hw);
             reply->writeInt32(ret);
             break;
         }
         case CMD_AS_SO_R: {
-            struct audio_stream_out_info* stream_out_info; data.read(&stream_out_info, sizeof(stream_out_info));
+            audio_stream_out_info_t* stream_out_info; data.read(&stream_out_info, sizeof(stream_out_info));
             int ret = StreamOut_resume(stream_out_info->stream_out_hw);
             reply->writeInt32(ret);
             break;
         }
         case CMD_AS_SO_F: {
-            struct audio_stream_out_info* stream_out_info; data.read(&stream_out_info, sizeof(stream_out_info));
+            audio_stream_out_info_t* stream_out_info; data.read(&stream_out_info, sizeof(stream_out_info));
             int ret = StreamOut_flush(stream_out_info->stream_out_hw);
             reply->writeInt32(ret);
             break;
         }
         case CMD_AS_SO_GPP: {
-            struct audio_stream_out_info* stream_out_info; data.read(&stream_out_info, sizeof(stream_out_info));
+            audio_stream_out_info_t* stream_out_info; data.read(&stream_out_info, sizeof(stream_out_info));
             uint64_t frames; struct timespec timestamp;
             int ret = StreamOut_get_presentation_position(stream_out_info->stream_out_hw, frames, timestamp);
             reply->writeInt32(ret);
@@ -963,21 +1012,21 @@
             break;
         }
         case CMD_AS_SI_SG: {
-            struct audio_stream_in_info* stream_in_info; data.read(&stream_in_info, sizeof(stream_in_info));
+            audio_stream_in_info_t* stream_in_info; data.read(&stream_in_info, sizeof(stream_in_info));
             float gain = data.readFloat();
             int ret = StreamIn_set_gain(stream_in_info->stream_in_hw, gain);
             reply->writeInt32(ret);
             break;
         }
         case CMD_AS_SI_R: {
-            struct audio_stream_in_info* stream_in_info; data.read(&stream_in_info, sizeof(stream_in_info));
+            audio_stream_in_info_t* stream_in_info; data.read(&stream_in_info, sizeof(stream_in_info));
             size_t bytes; data.read(&bytes, sizeof(bytes));
             int ret = StreamIn_read(stream_in_info, bytes);
             reply->writeInt32(ret);
             break;
         }
         case CMD_AS_SI_GIFL: {
-            struct audio_stream_in_info* stream_in_info; data.read(&stream_in_info, sizeof(stream_in_info));
+            audio_stream_in_info_t* stream_in_info; data.read(&stream_in_info, sizeof(stream_in_info));
             uint32_t ret = StreamIn_get_input_frames_lost(stream_in_info->stream_in_hw);
             reply->writeUint32(ret);
             break;
diff --git a/src/binder/audio_service_binder.h b/src/binder/audio_service_binder.h
index c911e2e..d381a34 100644
--- a/src/binder/audio_service_binder.h
+++ b/src/binder/audio_service_binder.h
@@ -27,6 +27,7 @@
 typedef struct audio_stream_out_info {
     char name[32];
     struct audio_stream_out* stream_out_hw;
+    std::mutex stream_mutex;
     int fd;
     void* shm;
 } audio_stream_out_info_t;
@@ -34,6 +35,7 @@
 typedef struct audio_stream_in_info {
     char name[32];
     struct audio_stream_in* stream_in_hw;
+    std::mutex stream_mutex;
     int fd;
     void* shm;
 } audio_stream_in_info_t;
@@ -177,7 +179,7 @@
         uint32_t Stream_get_channels(struct audio_stream* stream_hw);
 
         // Return the audio format - e.g. AUDIO_FORMAT_PCM_16_BIT
-        int Stream_get_format(struct audio_stream* stream_hw);
+        uint32_t Stream_get_format(struct audio_stream* stream_hw);
 
         // Put the audio hardware input/output into standby mode.
         // Driver should exit from standby mode at the next I/O operation.
@@ -338,8 +340,8 @@
 
         // garbage collection
         void stream_gc_(const std::unordered_map<std::string, stream_data_t>& streamsInfo);
-        void streamout_gc_(const char* name, int fd, audio_stream_out* stream_out_hw);
-        void streamin_gc_(const char* name, int fd, audio_stream_in* stream_in_hw);
+        void streamout_gc_(std::mutex& stream_mutex, const char* name, void* shm, int fd, audio_stream_out* stream_out_hw);
+        void streamin_gc_(std::mutex& stream_mutex, const char* name, void* shm, int fd, audio_stream_in* stream_in_hw);
 
         /* helper methods */
         int updateStreamOutInfo(const char* name, struct audio_stream_out* stream, audio_stream_out_info_t* stream_out_info);
diff --git a/src/binder/common.cpp b/src/binder/common.cpp
index 856f43f..d97dfbe 100644
--- a/src/binder/common.cpp
+++ b/src/binder/common.cpp
@@ -81,20 +81,24 @@
     return 0;
 }
 
-int posixUnmapDataAndCloseFile(const std::string& processNameLog, const char* identifierLabel, const char* identifier, void* data, size_t length, int fd) {
-    if (munmap(data, length) == -1) {
-        perror(std::string(processNameLog + " " + DEBUG_INFO + ", could not unmap from " + identifierLabel + " " + identifier + " data").c_str());
+int posixUnmapDataCloseFileAndUnlinkName(const std::string& processNameLog, const char* identifierLabel, const char* identifier, void*& data, size_t length, int fd) {
+    if (data == nullptr) {
+        std::cout << processNameLog << " " << DEBUG_INFO << ", unmap completed or " << identifierLabel << " " << identifier << " data pointer set to null elsewhere." << std::endl;
+    } else {
+        if (munmap(data, length) == -1) {
+            perror(std::string(processNameLog + " " + DEBUG_INFO + ", could not unmap from " + identifierLabel + " " + identifier + " data").c_str());
+            return -1;
+        }
+    }
+    data = nullptr;
+    if (posixCloseFile(processNameLog, identifierLabel, identifier, fd) == -1) {
         return -1;
     }
-    return posixCloseFile(processNameLog, identifierLabel, identifier, fd);
-}
-
-int posixUnlinkNameAndCloseFile(const std::string& processNameLog, const char* identifierLabel, const char* identifier, int fd) {
     if (shm_unlink(identifier) == -1) {
         perror(std::string(processNameLog + " " + DEBUG_INFO + ", could not unlink name from " + identifierLabel + " " + identifier + " data").c_str());
         return -1;
     }
-    return posixCloseFile(processNameLog, identifierLabel, identifier, fd);
+    return 0;
 }
 
 void SetAudioPermissions(const std::string& processNameLog, const char* file_path) {
diff --git a/src/binder/common.h b/src/binder/common.h
index 9e1f6f5..3dabd39 100644
--- a/src/binder/common.h
+++ b/src/binder/common.h
@@ -142,9 +142,7 @@
 
 extern int posixCloseFile(const std::string& processNameLog, const char* identifierLabel, const char* identifier, int fd);
 
-extern int posixUnmapDataAndCloseFile(const std::string& processNameLog, const char* identifierLabel, const char* identifier, void* data, size_t length, int fd);
-
-extern int posixUnlinkNameAndCloseFile(const std::string& processNameLog, const char* identifierLabel, const char* identifier, int fd);
+extern int posixUnmapDataCloseFileAndUnlinkName(const std::string& processNameLog, const char* identifierLabel, const char* identifier, void*& data, size_t length, int fd);
 
 extern void SetAudioPermissions(const std::string& processNameLog, const char* file_path);