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