• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "common-interop.h"
17 #include "callback-resource.h"
18 #include <deque>
19 #include <unordered_map>
20 #include <algorithm>
21 #include <stdexcept>
22 
23 // NOLINTBEGIN
24 
25 static bool needReleaseFront = false;
26 static std::deque<CallbackEventKind> callbackEventsQueue;
27 static std::deque<CallbackBuffer> callbackCallSubqueue;
28 static std::deque<InteropInt32> callbackResourceSubqueue;
29 
EnqueueCallback(const CallbackBuffer * event)30 void EnqueueCallback(const CallbackBuffer *event)
31 {
32     callbackEventsQueue.push_back(EVENT_CALL_CALLBACK);
33     callbackCallSubqueue.push_back(*event);
34 }
35 
HoldManagedCallbackResource(InteropInt32 resourceId)36 void HoldManagedCallbackResource(InteropInt32 resourceId)
37 {
38     callbackEventsQueue.push_back(EVENT_HOLD_MANAGED_RESOURCE);
39     callbackResourceSubqueue.push_back(resourceId);
40 }
41 
ReleaseManagedCallbackResource(InteropInt32 resourceId)42 void ReleaseManagedCallbackResource(InteropInt32 resourceId)
43 {
44     callbackEventsQueue.push_back(EVENT_RELEASE_MANAGED_RESOURCE);
45     callbackResourceSubqueue.push_back(resourceId);
46 }
47 
impl_CheckCallbackEvent(KByte * result,KInt size)48 KInt impl_CheckCallbackEvent(KByte *result, [[maybe_unused]] KInt size)
49 {
50     if (needReleaseFront) {
51         switch (callbackEventsQueue.front()) {
52             case EVENT_CALL_CALLBACK:
53                 callbackCallSubqueue.front().resourceHolder.release();
54                 callbackCallSubqueue.pop_front();
55                 break;
56             case EVENT_HOLD_MANAGED_RESOURCE:
57             case EVENT_RELEASE_MANAGED_RESOURCE:
58                 callbackResourceSubqueue.pop_front();
59                 break;
60             default:
61                 throw std::runtime_error("Unknown event kind");
62         }
63         callbackEventsQueue.pop_front();
64         needReleaseFront = false;
65     }
66     if (callbackEventsQueue.empty()) {
67         return 0;
68     }
69     const CallbackEventKind frontEventKind = callbackEventsQueue.front();
70     std::copy_n(&frontEventKind, 4U, result);
71     switch (frontEventKind) {
72         case EVENT_CALL_CALLBACK:
73             std::copy_n(callbackCallSubqueue.front().buffer, sizeof(CallbackBuffer::buffer), result + 4U);
74             break;
75         case EVENT_HOLD_MANAGED_RESOURCE:
76         case EVENT_RELEASE_MANAGED_RESOURCE: {
77             const InteropInt32 resourceId = callbackResourceSubqueue.front();
78             std::copy_n(&resourceId, 4U, result + 4U);
79             break;
80         }
81         default:
82             throw std::runtime_error("Unknown event kind");
83     }
84     needReleaseFront = true;
85     return 1;
86 }
TS_INTEROP_2(CheckCallbackEvent,KInt,KByte *,KInt)87 TS_INTEROP_2(CheckCallbackEvent, KInt, KByte *, KInt)
88 
89 void impl_ReleaseCallbackResource(InteropInt32 resourceId)
90 {
91     ReleaseManagedCallbackResource(resourceId);
92 }
TS_INTEROP_V1(ReleaseCallbackResource,KInt)93 TS_INTEROP_V1(ReleaseCallbackResource, KInt)
94 
95 void impl_HoldCallbackResource(InteropInt32 resourceId)
96 {
97     HoldManagedCallbackResource(resourceId);
98 }
99 TS_INTEROP_V1(HoldCallbackResource, KInt)
100 
101 // NOLINTEND
102