• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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