1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "c/thread.h"
17 #include "cpp/thread.h"
18 #include "internal_inc/osal.h"
19 #include "dfx/log/ffrt_log_api.h"
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 struct ThreadRes {
25     bool is_joinable;
26     void* result;
27 };
28 API_ATTRIBUTE((visibility("default")))
29 int ffrt_thread_create(ffrt_thread_t* thr, const ffrt_thread_attr_t* attr, void* (*func)(void*), void* arg)
30 {
31     if (!thr || !func) {
32         FFRT_LOGE("thr and func should not be empty");
33         return ffrt_error_inval;
34     }
35     if (attr) {
36         FFRT_LOGE("attr should be empty");
37         return ffrt_error;
38     }
39 
40     auto p = reinterpret_cast<ThreadRes*>(malloc(sizeof(ThreadRes)));
41     if (p == nullptr) {
42         FFRT_LOGE("p is empty");
43         return ffrt_error_nomem;
44     }
45     p->is_joinable = true;
46     p->result = nullptr;
__anon42dd67380102() 47     ffrt::submit([p, func, arg]() {
48         p->result = func(arg);
49     }, {}, {p});
50 
51     *thr = p;
52     return ffrt_success;
53 }
54 
55 API_ATTRIBUTE((visibility("default")))
56 int ffrt_thread_join(ffrt_thread_t thr, void** res)
57 {
58     if (!thr || !res) {
59         FFRT_LOGE("thr or res should not be empty");
60         return ffrt_error_inval;
61     }
62 
63     auto p = reinterpret_cast<ThreadRes*>(thr);
64     if (p == nullptr || !p->is_joinable) {
65         return ffrt_error_inval;
66     }
67     ffrt::wait({p});
68     *res = p->result;
69     p->is_joinable = false;
70     free(p);
71     return ffrt_success;
72 }
73 
74 API_ATTRIBUTE((visibility("default")))
75 int ffrt_thread_detach(ffrt_thread_t thr)
76 {
77     if (!thr) {
78         FFRT_LOGE("thr should not be empty");
79         return ffrt_error_inval;
80     }
81     auto p = reinterpret_cast<ThreadRes*>(thr);
82     if (p == nullptr || !p->is_joinable) {
83         return ffrt_error_inval;
84     }
85     p->is_joinable = false;
__anon42dd67380502() 86     ffrt::submit([thr]() { free(thr); }, {thr});
87     return ffrt_success;
88 }
89 #ifdef __cplusplus
90 }
91 #endif
92