summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeungbae Shin <seungbae.shin@samsung.com>2022-11-18 20:15:09 +0900
committerSeungbae Shin <seungbae.shin@samsung.com>2022-12-06 14:24:42 +0900
commit72d7bd5fca1262d23e39c9b797226638694d30cf (patch)
tree0ac9d6f998683df732cb94a94a99f486797bf354
parent9999a714150fcc0e27923ba03d81aba33a0570d7 (diff)
downloadlibmm-sound-72d7bd5fca1262d23e39c9b797226638694d30cf.tar.gz
libmm-sound-72d7bd5fca1262d23e39c9b797226638694d30cf.tar.bz2
libmm-sound-72d7bd5fca1262d23e39c9b797226638694d30cf.zip
focus_socket: wait for socket listen readyaccepted/tizen/unified/20221207.171506
In addition, client retry added for abnormal socket condition [Version] 0.13.23 [Issue Type] Update Change-Id: I3e18abaffa0ffae8472d58f2e593e5ab76a610ad
-rw-r--r--focus_server/include/mm_sound_mgr_focus_socket.h28
-rw-r--r--focus_server/mm_sound_focus_server.c11
-rw-r--r--focus_server/mm_sound_mgr_focus_socket.c177
-rw-r--r--mm_sound_focus_socket.c26
-rw-r--r--packaging/libmm-sound.spec2
5 files changed, 184 insertions, 60 deletions
diff --git a/focus_server/include/mm_sound_mgr_focus_socket.h b/focus_server/include/mm_sound_mgr_focus_socket.h
index 9768c48..2a0e67d 100644
--- a/focus_server/include/mm_sound_mgr_focus_socket.h
+++ b/focus_server/include/mm_sound_mgr_focus_socket.h
@@ -1,9 +1,29 @@
+/*
+ * libmm-sound
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Sangchul Lee <sc11.lee@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
#ifndef __MM_SOUND_MGR_FOCUS_SOCKET_H__
#define __MM_SOUND_MGR_FOCUS_SOCKET_H__
-int MMSoundMgrFocusSocketInit(int *fd);
-void MMSoundMgrFocusSocketFini(int fd);
-int MMSoundMgrFocusSocketReadyToWork(int fd);
-
+int MMSoundMgrFocusSocketInit(int *sockfd);
+void MMSoundMgrFocusSocketFini(int *sockfd);
+int MMSoundMgrFocusSocketReadyToWork(const int *sockfd);
#endif /* __MM_SOUND_MGR_FOCUS_SOCKET_H__ */
diff --git a/focus_server/mm_sound_focus_server.c b/focus_server/mm_sound_focus_server.c
index f6adf8f..3d7a581 100644
--- a/focus_server/mm_sound_focus_server.c
+++ b/focus_server/mm_sound_focus_server.c
@@ -141,7 +141,7 @@ static void _signal_handler(int signo)
MMSoundMgrFocusDbusFini();
MMSoundMgrFocusFini();
- MMSoundMgrFocusSocketFini(g_socket_fd);
+ MMSoundMgrFocusSocketFini(&g_socket_fd);
#ifdef USE_GCOV
mm_sound_gcov_flush();
@@ -219,8 +219,6 @@ int main(int argc, char **argv)
#if !defined(USE_SYSTEM_SERVER_PROCESS_MONITORING)
int pid;
#endif
- int socket_fd = -1;
-
if (_get_option(argc, argv, &serveropt))
return 1;
@@ -263,17 +261,16 @@ int main(int argc, char **argv)
/* Change the file mode mask */
umask(0);
- if (MMSoundMgrFocusSocketInit(&socket_fd)) {
+ if (MMSoundMgrFocusSocketInit(&g_socket_fd)) {
debug_error("focus_server [%d] terminating, due to the error of socket init.", getpid());
return 0;
}
- if (MMSoundMgrFocusSocketReadyToWork(socket_fd)) {
+ if (MMSoundMgrFocusSocketReadyToWork(&g_socket_fd)) {
debug_error("focus_server [%d] terminating, due to the error of thread init.", getpid());
return 0;
}
MMSoundMgrFocusDbusInit();
MMSoundMgrFocusInit();
- g_socket_fd = socket_fd;
}
debug_warning("focus_server [%d] initialization complete...now, start running!!", getpid());
@@ -301,7 +298,7 @@ int main(int argc, char **argv)
if (serveropt.startserver) {
MMSoundMgrFocusDbusFini();
MMSoundMgrFocusFini();
- MMSoundMgrFocusSocketFini(socket_fd);
+ MMSoundMgrFocusSocketFini(&g_socket_fd);
}
_signal_finalize();
diff --git a/focus_server/mm_sound_mgr_focus_socket.c b/focus_server/mm_sound_mgr_focus_socket.c
index a06800d..162c552 100644
--- a/focus_server/mm_sound_mgr_focus_socket.c
+++ b/focus_server/mm_sound_mgr_focus_socket.c
@@ -62,6 +62,15 @@ enum {
FOCUS_FUNCTION_MAX,
};
+#define DEFAULT_FOCUS_THREAD_READY_TIMEOUT 5
+
+typedef struct mm_sound_focus_thread_data {
+ const int *sockfd;
+ GMutex wait_mutex;
+ GCond wait_cond;
+ gboolean listen_ready;
+} focus_thread_data_t;
+
typedef struct mm_sound_focus_function_intf {
const char *name;
focus_function_handler handler;
@@ -266,7 +275,7 @@ static int focus_functions_handler(int fd, _mm_sound_focus_socket_param_t *param
if (param == NULL)
return MM_ERROR_INVALID_ARGUMENT;
- debug_log("fd[%d], param[%p], function_name[%s]", fd, param, param->func_name);
+ debug_msg("fd[%d], param[%p], function_name[%s]", fd, param, param->func_name);
for (i = 0; i < FOCUS_FUNCTION_MAX; i++) {
if (!strncmp(param->func_name, functions[i].name, MAX_ERROR_LEN))
@@ -286,7 +295,68 @@ static bool need_to_exit(const char *func_name)
return false;
}
-static void* work_thread_func(void *data)
+
+static focus_thread_data_t *__focus_thread_data_create(const int *sockfd)
+{
+ focus_thread_data_t *thread_data = NULL;
+ thread_data = g_new0(focus_thread_data_t, 1);
+
+ thread_data->sockfd = sockfd;
+ g_mutex_init(&thread_data->wait_mutex);
+ g_cond_init(&thread_data->wait_cond);
+ thread_data->listen_ready = FALSE;
+
+ return thread_data;
+}
+
+static void __focus_thread_ready_signal(focus_thread_data_t *thread_data)
+{
+ g_assert(thread_data);
+
+ g_mutex_lock(&thread_data->wait_mutex);
+
+ debug_msg("signaling focus thread ready!");
+ thread_data->listen_ready = TRUE;
+ g_cond_signal(&thread_data->wait_cond);
+
+ g_mutex_unlock(&thread_data->wait_mutex);
+}
+
+static gboolean __focus_thread_ready_wait(focus_thread_data_t *thread_data, int timeout_sec)
+{
+ gint64 end_time;
+ g_autoptr(GMutexLocker) locker = NULL;
+
+ g_assert(thread_data);
+
+ locker = g_mutex_locker_new(&thread_data->wait_mutex);
+
+ end_time = g_get_monotonic_time() + timeout_sec * G_TIME_SPAN_SECOND;
+
+ while (!thread_data->listen_ready) {
+ if (!g_cond_wait_until(&thread_data->wait_cond,
+ &thread_data->wait_mutex,
+ end_time)) {
+ debug_error("timeout!!!");
+ break;
+ }
+ debug_msg("wait done! ready:%d", thread_data->listen_ready);
+ }
+
+ return thread_data->listen_ready;
+}
+
+static void __focus_thread_data_destroy(focus_thread_data_t *thread_data)
+{
+ g_assert(thread_data);
+
+ g_mutex_clear(&thread_data->wait_mutex);
+ g_cond_clear(&thread_data->wait_cond);
+
+ g_free(thread_data);
+}
+
+static void *work_thread_func(void *data)
{
int accepted_fd = -1;
char str_error[MAX_ERROR_LEN] = {'\0',};
@@ -294,16 +364,16 @@ static void* work_thread_func(void *data)
_mm_sound_focus_socket_result_t result;
int rval = 0;
- if (data == NULL) {
+ debug_fenter();
+
+ if (!data) {
debug_error("invalid data");
pthread_exit(NULL);
}
- debug_fenter();
-
accepted_fd = (int)(uintptr_t)(data);
- do {
+ while (1) {
memset(&read_data, 0x00, sizeof(_mm_sound_focus_socket_param_t));
if ((rval = read(accepted_fd, &read_data, sizeof(_mm_sound_focus_socket_param_t))) < 0) {
strerror_r(errno, str_error, sizeof(str_error));
@@ -327,33 +397,36 @@ static void* work_thread_func(void *data)
}
if (need_to_exit(read_data.func_name))
- goto LEAVE;
+ break;
} else {
debug_error("failed to read(), read size mismatched, rval(%d), expect size(%zu)",
rval, sizeof(_mm_sound_focus_socket_param_t));
- goto LEAVE;
+ break;
}
- } while (1);
+ }
-LEAVE:
- debug_fleave();
- debug_log("now close fd[%d]", accepted_fd);
/* clean-up FD and focus node */
mm_sound_mgr_focus_emergent_exit_by_id(accepted_fd);
+
+ debug_msg("now close fd[%d]", accepted_fd);
close(accepted_fd);
+
+ debug_fleave();
+
pthread_exit(NULL);
}
-static void* ready_thread_func(void *data)
+static void *ready_thread_func(void *data)
{
- int fd = -1;
int accepted_fd = -1;
char str_error[MAX_ERROR_LEN] = {'\0',};
int ret = 0;
pthread_t focus_work_thread_id;
pthread_attr_t attr;
- if (data == NULL) {
+ focus_thread_data_t *thread_data = (focus_thread_data_t *)data;
+
+ if (!thread_data) {
debug_error("invalid data");
pthread_exit(NULL);
}
@@ -372,47 +445,48 @@ static void* ready_thread_func(void *data)
goto LEAVE;
}
- fd = (int)(uintptr_t)data;
-
- if (listen(fd, 5)) {
+ if (listen(*thread_data->sockfd, 5)) {
strerror_r(errno, str_error, sizeof(str_error));
debug_error("failed to listen(), err: %s", str_error);
goto LEAVE;
}
- debug_log("listen for fd [%d] success", fd);
+ debug_msg("listen for fd [%d] success", *thread_data->sockfd);
+
+ __focus_thread_ready_signal(thread_data);
- do {
- accepted_fd = accept(fd, NULL, NULL);
+ while (*thread_data->sockfd != -1) {
+ accepted_fd = accept(*thread_data->sockfd, NULL, NULL);
if (accepted_fd == -1) {
strerror_r(errno, str_error, sizeof(str_error));
debug_error("failed to accept(), err: %s", str_error);
- goto LEAVE;
+ break;
}
debug_log("accepted fd [%d]", accepted_fd);
if (pthread_create(&focus_work_thread_id, &attr, (void *)work_thread_func, (void *)(uintptr_t)accepted_fd)) {
debug_error("failed to create work thread, accepted_fd(%d)", accepted_fd);
- goto LEAVE;
+ break;
}
+ }
- } while (1);
+ __focus_thread_data_destroy(thread_data);
LEAVE:
- debug_fleave();
pthread_attr_destroy(&attr);
- if (fd != -1)
- close(fd);
+
+ debug_fleave();
+
pthread_exit(NULL);
}
-int MMSoundMgrFocusSocketInit(int *fd)
+int MMSoundMgrFocusSocketInit(int *sockfd)
{
int socket_fd;
struct sockaddr_un addr_un;
char str_error[128] = {'\0',};
- if (fd == NULL) {
+ if (!sockfd) {
debug_error("input param fd is null");
return MM_ERROR_INVALID_ARGUMENT;
}
@@ -424,7 +498,7 @@ int MMSoundMgrFocusSocketInit(int *fd)
goto LEAVE;
}
- debug_log("focus server socket fd [%d]", socket_fd);
+ debug_msg("focus server socket fd [%d]", socket_fd);
memset(&addr_un, 0, sizeof(addr_un));
addr_un.sun_family = AF_UNIX;
@@ -447,9 +521,9 @@ int MMSoundMgrFocusSocketInit(int *fd)
}
}
- debug_log("focus server socket binding success");
+ debug_msg("focus server socket binding success");
- *fd = socket_fd;
+ *sockfd = socket_fd;
debug_leave();
@@ -462,38 +536,57 @@ LEAVE:
return MM_ERROR_SOUND_INTERNAL;
}
-void MMSoundMgrFocusSocketFini(int fd)
+void MMSoundMgrFocusSocketFini(int *sockfd)
{
debug_enter();
if (g_focus_ready_thread_id) {
unlink(FOCUS_SERVER_SOCK);
- shutdown(fd, SHUT_RDWR);
- close(fd);
+
+ if (*sockfd != -1) {
+ shutdown(*sockfd, SHUT_RDWR);
+ close(*sockfd);
+ *sockfd = -1;
+ }
+
+ debug_msg("try pthread join for thread id:%lu", g_focus_ready_thread_id);
pthread_join(g_focus_ready_thread_id, NULL);
- debug_msg("pthread join well");
+ debug_msg("pthread joined well");
g_focus_ready_thread_id = 0;
}
debug_leave();
}
-int MMSoundMgrFocusSocketReadyToWork(int fd)
+int MMSoundMgrFocusSocketReadyToWork(const int *sockfd)
{
debug_enter();
+ focus_thread_data_t *thread_data = NULL;
- if (fd < 0) {
- debug_error("input param fd [%d] is not valid", fd);
+ if (*sockfd < 0) {
+ debug_error("input param sockfd [%d] is not valid", *sockfd);
return MM_ERROR_INVALID_ARGUMENT;
}
- debug_log("fd [%d]", fd);
- if (pthread_create(&g_focus_ready_thread_id, NULL, (void *)ready_thread_func, (void *)(uintptr_t)fd)) {
+ debug_msg("sockfd [%d]", *sockfd);
+
+ thread_data = __focus_thread_data_create(sockfd);
+
+ if (pthread_create(&g_focus_ready_thread_id, NULL, (void *)ready_thread_func, thread_data)) {
debug_error("failed to create ready thread");
- return MM_ERROR_SOUND_INTERNAL;
+ goto ERROR_INTERNAL;
+ }
+
+ if (!__focus_thread_ready_wait(thread_data, DEFAULT_FOCUS_THREAD_READY_TIMEOUT)) {
+ debug_error("focus thread is not ready for %u sec!!!", DEFAULT_FOCUS_THREAD_READY_TIMEOUT);
+ goto ERROR_INTERNAL;
}
debug_leave();
return MM_ERROR_NONE;
+
+ERROR_INTERNAL:
+ __focus_thread_data_destroy(thread_data);
+ return MM_ERROR_SOUND_INTERNAL;
}
diff --git a/mm_sound_focus_socket.c b/mm_sound_focus_socket.c
index 4d8c96f..fa5083c 100644
--- a/mm_sound_focus_socket.c
+++ b/mm_sound_focus_socket.c
@@ -28,6 +28,9 @@
#include "include/mm_sound_common.h"
#include "include/mm_sound_focus_socket.h"
+#define MAX_CONNECT_RETRY 10
+#define RETRY_CONNECT_INTERVAL_US 300000
+
#define _FILL_SOCKET_PARAM(x_param, x_func_name, x_pid) \
do { \
MMSOUND_STRNCPY(x_param.func_name, x_func_name, MM_SOUND_NAME_NUM); \
@@ -116,6 +119,8 @@ static int _get_client_socket_fd(int *fd)
static int _connect_socket_fd(int fd)
{
+ int retry_remaining = MAX_CONNECT_RETRY;
+ int ret = 0;
struct sockaddr_un addr_un;
char str_error[128] = {'\0',};
@@ -128,15 +133,24 @@ static int _connect_socket_fd(int fd)
addr_un.sun_family = AF_UNIX;
strncpy(addr_un.sun_path, FOCUS_SERVER_SOCK, sizeof(addr_un.sun_path));
- if (connect(fd, (struct sockaddr *)&addr_un, sizeof(addr_un)) < 0) {
+ do {
+ ret = connect(fd, (struct sockaddr *)&addr_un, sizeof(addr_un));
+ if (ret == 0) {
+ debug_log("connected successfully, fd[%d]", fd);
+ return MM_ERROR_NONE;
+ }
+
strerror_r(errno, str_error, sizeof(str_error));
- debug_error("failed to connect() to %s, err: %s", addr_un.sun_path, str_error);
- return MM_ERROR_SOUND_INTERNAL;
- }
+ debug_error("[%2d] failed to connect() to %s, err: %s",
+ retry_remaining, addr_un.sun_path, str_error);
- debug_log("connected successfully, fd[%d]", fd);
+ usleep(RETRY_CONNECT_INTERVAL_US);
+ } while (--retry_remaining > 0);
- return MM_ERROR_NONE;
+ debug_error("Timed-out(%u us) for connection",
+ MAX_CONNECT_RETRY * RETRY_CONNECT_INTERVAL_US);
+
+ return MM_ERROR_SOUND_INTERNAL;
}
static int _send_data_to_server(int fd, _mm_sound_focus_socket_param_t *data, _mm_sound_focus_socket_result_t *result)
diff --git a/packaging/libmm-sound.spec b/packaging/libmm-sound.spec
index 0420af2..45bc369 100644
--- a/packaging/libmm-sound.spec
+++ b/packaging/libmm-sound.spec
@@ -1,6 +1,6 @@
Name: libmm-sound
Summary: MMSound Package contains client lib and focus server binary
-Version: 0.13.22
+Version: 0.13.23
Release: 0
Group: System/Libraries
License: Apache-2.0