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 #define KOALA_INTEROP_MODULE InteropNativeModule
17 #include "common-interop.h"
18 #include "interop-types.h"
19 #include "callback-resource.h"
20 #include <deque>
21 #include <unordered_map>
22
23
24 static bool needReleaseFront = false;
25 static std::deque<CallbackEventKind> callbackEventsQueue;
26 static std::deque<CallbackBuffer> callbackCallSubqueue;
27 static std::deque<InteropInt32> callbackResourceSubqueue;
28
enqueueCallback(const CallbackBuffer * event)29 void enqueueCallback(const CallbackBuffer* event) {
30 callbackEventsQueue.push_back(Event_CallCallback);
31 callbackCallSubqueue.push_back(*event);
32 }
33
holdManagedCallbackResource(InteropInt32 resourceId)34 void holdManagedCallbackResource(InteropInt32 resourceId) {
35 callbackEventsQueue.push_back(Event_HoldManagedResource);
36 callbackResourceSubqueue.push_back(resourceId);
37 }
38
releaseManagedCallbackResource(InteropInt32 resourceId)39 void releaseManagedCallbackResource(InteropInt32 resourceId) {
40 callbackEventsQueue.push_back(Event_ReleaseManagedResource);
41 callbackResourceSubqueue.push_back(resourceId);
42 }
43
impl_CheckCallbackEvent(KSerializerBuffer buffer,KInt size)44 KInt impl_CheckCallbackEvent(KSerializerBuffer buffer, KInt size) {
45 KByte* result = (KByte*)buffer;
46 if (needReleaseFront)
47 {
48 switch (callbackEventsQueue.front())
49 {
50 case Event_CallCallback:
51 callbackCallSubqueue.front().resourceHolder.release();
52 callbackCallSubqueue.pop_front();
53 break;
54 case Event_HoldManagedResource:
55 case Event_ReleaseManagedResource:
56 callbackResourceSubqueue.pop_front();
57 break;
58 default:
59 INTEROP_FATAL("Unknown event kind");
60 }
61 callbackEventsQueue.pop_front();
62 needReleaseFront = false;
63 }
64 if (callbackEventsQueue.empty()) {
65 return 0;
66 }
67 const CallbackEventKind frontEventKind = callbackEventsQueue.front();
68 memcpy(result, &frontEventKind, 4);
69 switch (frontEventKind)
70 {
71 case Event_CallCallback:
72 memcpy(result + 4, callbackCallSubqueue.front().buffer, sizeof(CallbackBuffer::buffer));
73 break;
74 case Event_HoldManagedResource:
75 case Event_ReleaseManagedResource: {
76 const InteropInt32 resourceId = callbackResourceSubqueue.front();
77 memcpy(result + 4, &resourceId, 4);
78 break;
79 }
80 default:
81 INTEROP_FATAL("Unknown event kind");
82 }
83 needReleaseFront = true;
84 return 1;
85 }
KOALA_INTEROP_DIRECT_2(CheckCallbackEvent,KInt,KSerializerBuffer,KInt)86 KOALA_INTEROP_DIRECT_2(CheckCallbackEvent, KInt, KSerializerBuffer, KInt)
87
88 void impl_ReleaseCallbackResource(InteropInt32 resourceId) {
89 releaseManagedCallbackResource(resourceId);
90 }
KOALA_INTEROP_V1(ReleaseCallbackResource,KInt)91 KOALA_INTEROP_V1(ReleaseCallbackResource, KInt)
92
93 void impl_HoldCallbackResource(InteropInt32 resourceId) {
94 holdManagedCallbackResource(resourceId);
95 }
96 KOALA_INTEROP_V1(HoldCallbackResource, KInt)
97