ipc: fix return without mutex unlock
[dpdk.git] / lib / librte_eal / common / eal_common_proc.c
index c888c84..ad02c00 100644 (file)
@@ -129,7 +129,7 @@ create_socket_path(const char *name, char *buf, int len)
        if (strlen(name) > 0)
                snprintf(buf, len, "%s_%s", prefix, name);
        else
-               snprintf(buf, len, "%s", prefix);
+               strlcpy(buf, prefix, len);
 }
 
 int
@@ -200,7 +200,7 @@ rte_mp_action_register(const char *name, rte_mp_t action)
                rte_errno = ENOMEM;
                return -1;
        }
-       strcpy(entry->action_name, name);
+       strlcpy(entry->action_name, name, sizeof(entry->action_name));
        entry->action = action;
 
        pthread_mutex_lock(&mp_mutex_action);
@@ -323,6 +323,7 @@ process_msg(struct mp_msg_internal *m, struct sockaddr_un *s)
                         */
                        struct rte_mp_msg dummy;
                        memset(&dummy, 0, sizeof(dummy));
+                       strlcpy(dummy.name, msg->name, sizeof(dummy.name));
                        mp_send(&dummy, s->sun_path, MP_IGN);
                } else {
                        RTE_LOG(ERR, EAL, "Cannot find action: %s\n",
@@ -524,6 +525,7 @@ async_reply_handle(void *arg __rte_unused)
                wait_for_async_messages();
 
                if (gettimeofday(&now, NULL) < 0) {
+                       pthread_mutex_unlock(&pending_requests.lock);
                        RTE_LOG(ERR, EAL, "Cannot get current time\n");
                        break;
                }
@@ -619,11 +621,11 @@ rte_mp_channel_init(void)
 
        /* create filter path */
        create_socket_path("*", path, sizeof(path));
-       snprintf(mp_filter, sizeof(mp_filter), "%s", basename(path));
+       strlcpy(mp_filter, basename(path), sizeof(mp_filter));
 
        /* path may have been modified, so recreate it */
        create_socket_path("*", path, sizeof(path));
-       snprintf(mp_dir_path, sizeof(mp_dir_path), "%s", dirname(path));
+       strlcpy(mp_dir_path, dirname(path), sizeof(mp_dir_path));
 
        /* lock the directory */
        dir_fd = open(mp_dir_path, O_RDONLY);
@@ -671,11 +673,11 @@ rte_mp_channel_init(void)
        }
 
        /* try best to set thread name */
-       snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "rte_mp_handle");
+       strlcpy(thread_name, "rte_mp_handle", RTE_MAX_THREAD_NAME_LEN);
        rte_thread_setname(mp_handle_tid, thread_name);
 
        /* try best to set thread name */
-       snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "rte_mp_async_handle");
+       strlcpy(thread_name, "rte_mp_async_handle", RTE_MAX_THREAD_NAME_LEN);
        rte_thread_setname(async_reply_handle_tid, thread_name);
 
        /* unlock the directory */
@@ -708,7 +710,7 @@ send_msg(const char *dst_path, struct rte_mp_msg *msg, int type)
 
        memset(&dst, 0, sizeof(dst));
        dst.sun_family = AF_UNIX;
-       snprintf(dst.sun_path, sizeof(dst.sun_path), "%s", dst_path);
+       strlcpy(dst.sun_path, dst_path, sizeof(dst.sun_path));
 
        memset(&msgh, 0, sizeof(msgh));
        memset(control, 0, sizeof(control));
@@ -868,7 +870,7 @@ mp_request_async(const char *dst, struct rte_mp_msg *req,
        memset(reply_msg, 0, sizeof(*reply_msg));
 
        sync_req->type = REQUEST_TYPE_ASYNC;
-       strcpy(sync_req->dst, dst);
+       strlcpy(sync_req->dst, dst, sizeof(sync_req->dst));
        sync_req->request = req;
        sync_req->reply = reply_msg;
        sync_req->async.param = param;
@@ -876,9 +878,7 @@ mp_request_async(const char *dst, struct rte_mp_msg *req,
        /* queue already locked by caller */
 
        exist = find_sync_request(dst, req->name);
-       if (!exist) {
-               TAILQ_INSERT_TAIL(&pending_requests.requests, sync_req, next);
-       } else {
+       if (exist) {
                RTE_LOG(ERR, EAL, "A pending request %s:%s\n", dst, req->name);
                rte_errno = EEXIST;
                ret = -1;
@@ -895,6 +895,7 @@ mp_request_async(const char *dst, struct rte_mp_msg *req,
                ret = 0;
                goto fail;
        }
+       TAILQ_INSERT_TAIL(&pending_requests.requests, sync_req, next);
 
        param->user_reply.nb_sent++;
 
@@ -915,19 +916,15 @@ mp_request_sync(const char *dst, struct rte_mp_msg *req,
 
        sync_req.type = REQUEST_TYPE_SYNC;
        sync_req.reply_received = 0;
-       strcpy(sync_req.dst, dst);
+       strlcpy(sync_req.dst, dst, sizeof(sync_req.dst));
        sync_req.request = req;
        sync_req.reply = &msg;
        pthread_cond_init(&sync_req.sync.cond, NULL);
 
-       pthread_mutex_lock(&pending_requests.lock);
        exist = find_sync_request(dst, req->name);
-       if (!exist)
-               TAILQ_INSERT_TAIL(&pending_requests.requests, &sync_req, next);
        if (exist) {
                RTE_LOG(ERR, EAL, "A pending request %s:%s\n", dst, req->name);
                rte_errno = EEXIST;
-               pthread_mutex_unlock(&pending_requests.lock);
                return -1;
        }
 
@@ -939,6 +936,8 @@ mp_request_sync(const char *dst, struct rte_mp_msg *req,
        } else if (ret == 0)
                return 0;
 
+       TAILQ_INSERT_TAIL(&pending_requests.requests, &sync_req, next);
+
        reply->nb_sent++;
 
        do {
@@ -946,9 +945,7 @@ mp_request_sync(const char *dst, struct rte_mp_msg *req,
                                &pending_requests.lock, ts);
        } while (ret != 0 && ret != ETIMEDOUT);
 
-       /* We got the lock now */
        TAILQ_REMOVE(&pending_requests.requests, &sync_req, next);
-       pthread_mutex_unlock(&pending_requests.lock);
 
        if (sync_req.reply_received == 0) {
                RTE_LOG(ERR, EAL, "Fail to recv reply for request %s:%s\n",
@@ -1007,8 +1004,12 @@ rte_mp_request_sync(struct rte_mp_msg *req, struct rte_mp_reply *reply,
        reply->msgs = NULL;
 
        /* for secondary process, send request to the primary process only */
-       if (rte_eal_process_type() == RTE_PROC_SECONDARY)
-               return mp_request_sync(eal_mp_socket_path(), req, reply, &end);
+       if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+               pthread_mutex_lock(&pending_requests.lock);
+               ret = mp_request_sync(eal_mp_socket_path(), req, reply, &end);
+               pthread_mutex_unlock(&pending_requests.lock);
+               return ret;
+       }
 
        /* for primary process, broadcast request, and collect reply 1 by 1 */
        mp_dir = opendir(mp_dir_path);
@@ -1028,6 +1029,7 @@ rte_mp_request_sync(struct rte_mp_msg *req, struct rte_mp_reply *reply,
                return -1;
        }
 
+       pthread_mutex_lock(&pending_requests.lock);
        while ((ent = readdir(mp_dir))) {
                char path[PATH_MAX];
 
@@ -1037,9 +1039,13 @@ rte_mp_request_sync(struct rte_mp_msg *req, struct rte_mp_reply *reply,
                snprintf(path, sizeof(path), "%s/%s", mp_dir_path,
                         ent->d_name);
 
+               /* unlocks the mutex while waiting for response,
+                * locks on receive
+                */
                if (mp_request_sync(path, req, reply, &end))
                        ret = -1;
        }
+       pthread_mutex_unlock(&pending_requests.lock);
        /* unlock the directory */
        flock(dir_fd, LOCK_UN);