1 /*
2 * Copyright (C) 2024 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 "listener_list.h"
17
18 namespace OHOS::Request {
19
AddListenerInner(napi_value cb)20 napi_status ListenerList::AddListenerInner(napi_value cb)
21 {
22 std::lock_guard<std::recursive_mutex> lock(allCbMutex_);
23 if (this->IsListenerAdded(cb)) {
24 return napi_ok;
25 }
26
27 napi_ref ref;
28 napi_status status = napi_create_reference(env_, cb, 1, &ref);
29 if (status != napi_ok) {
30 return status;
31 }
32
33 this->allCb_.push_back(std::make_pair(true, ref));
34 ++this->validCbNum;
35
36 return napi_ok;
37 }
38
RemoveListenerInner(napi_value cb)39 napi_status ListenerList::RemoveListenerInner(napi_value cb)
40 {
41 std::lock_guard<std::recursive_mutex> lock(allCbMutex_);
42 if (this->validCbNum == 0) {
43 return napi_ok;
44 }
45
46 if (cb == nullptr) {
47 for (auto it = this->allCb_.begin(); it != this->allCb_.end(); it++) {
48 it->first = false;
49 }
50 this->validCbNum = 0;
51 return napi_ok;
52 }
53
54 for (auto it = this->allCb_.begin(); it != this->allCb_.end(); it++) {
55 napi_value copyValue = nullptr;
56 napi_get_reference_value(this->env_, it->second, ©Value);
57
58 bool isEquals = false;
59 napi_strict_equals(this->env_, cb, copyValue, &isEquals);
60 if (isEquals) {
61 if (it->first == true) {
62 it->first = false;
63 --this->validCbNum;
64 }
65 break;
66 }
67 }
68 return napi_ok;
69 }
70
OnMessageReceive(napi_value * value,uint32_t paramNumber)71 void ListenerList::OnMessageReceive(napi_value *value, uint32_t paramNumber)
72 {
73 std::lock_guard<std::recursive_mutex> lock(allCbMutex_);
74 for (auto it = this->allCb_.begin(); it != this->allCb_.end();) {
75 if (it->first == false) {
76 napi_delete_reference(this->env_, it->second);
77 it = this->allCb_.erase(it);
78 continue;
79 }
80 napi_value callbackFunc = nullptr;
81 napi_get_reference_value(this->env_, it->second, &callbackFunc);
82 napi_value callbackResult = nullptr;
83 napi_call_function(this->env_, nullptr, callbackFunc, paramNumber, value, &callbackResult);
84 it++;
85 }
86 }
87
IsListenerAdded(napi_value cb)88 bool ListenerList::IsListenerAdded(napi_value cb)
89 {
90 if (cb == nullptr) {
91 return true;
92 }
93 for (auto it = this->allCb_.begin(); it != this->allCb_.end(); it++) {
94 napi_value copyValue = nullptr;
95 napi_get_reference_value(this->env_, it->second, ©Value);
96
97 bool isEquals = false;
98 napi_strict_equals(this->env_, cb, copyValue, &isEquals);
99 if (isEquals) {
100 return it->first;
101 }
102 }
103
104 return false;
105 }
106
HasListener()107 bool ListenerList::HasListener()
108 {
109 return this->validCbNum != 0;
110 }
111
DeleteAllListenerRef()112 void ListenerList::DeleteAllListenerRef()
113 {
114 std::lock_guard<std::recursive_mutex> lock(allCbMutex_);
115 for (auto it = this->allCb_.begin(); it != this->allCb_.end();) {
116 it->first = false;
117 napi_delete_reference(this->env_, it->second);
118 it = this->allCb_.erase(it);
119 }
120 this->validCbNum = 0;
121 return;
122 }
123
124 } // namespace OHOS::Request