1 /*
2 * Copyright (c) 2021 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 "ishared_result_set_stub.h"
17 #include <future>
18 #include "logger.h"
19 #include "rdb_errno.h"
20
21 namespace OHOS::NativeRdb {
22 std::function<sptr<ISharedResultSet>(std::shared_ptr<AbsSharedResultSet>,
23 MessageParcel &)> ISharedResultSet::providerCreator_ = ISharedResultSetStub::CreateStub;
24 constexpr ISharedResultSetStub::Handler ISharedResultSetStub::handlers[ISharedResultSet::FUNC_BUTT];
25
CreateStub(std::shared_ptr<AbsSharedResultSet> result,OHOS::MessageParcel & parcel)26 sptr<ISharedResultSet> ISharedResultSetStub::CreateStub(std::shared_ptr<AbsSharedResultSet> result,
27 OHOS::MessageParcel &parcel)
28 {
29 sptr<ISharedResultSet> stub = new ISharedResultSetStub(result);
30 if (result == nullptr) {
31 LOG_ERROR("result is nullptr");
32 return nullptr;
33 }
34 parcel.WriteRemoteObject(stub->AsObject());
35 result->Marshalling(parcel);
36 return stub;
37 }
38
ISharedResultSetStub(std::shared_ptr<AbsSharedResultSet> resultSet)39 ISharedResultSetStub::ISharedResultSetStub(std::shared_ptr<AbsSharedResultSet> resultSet)
40 : resultSet_(std::move(resultSet)),
41 runnables_(MAX_RUNNABLE),
42 thread_(&ISharedResultSetStub::Run, this)
43 {
44 thread_.detach();
45 LOG_ERROR("ISharedResultSetStub start thread(%{public}" PRIx64 ")", uint64_t(thread_.native_handle()));
46 }
~ISharedResultSetStub()47 ISharedResultSetStub::~ISharedResultSetStub()
48 {
49 auto handle = thread_.native_handle();
50 isRunning_ = false;
51 // do not delete this code, this code is waiting the thread exit.
52 isRunning_ = Submit([this]() -> bool { return isRunning_;}).get();
53 LOG_ERROR("~ISharedResultSetStub thread(%{public}" PRIx64 ")", uint64_t(handle));
54 }
55
OnRemoteRequest(uint32_t code,OHOS::MessageParcel & data,OHOS::MessageParcel & reply,OHOS::MessageOption & option)56 int ISharedResultSetStub::OnRemoteRequest(uint32_t code, OHOS::MessageParcel &data,
57 OHOS::MessageParcel &reply, OHOS::MessageOption &option)
58 {
59 if (GetDescriptor() != data.ReadInterfaceToken()) {
60 LOG_ERROR("IPC descriptor is not equal");
61 return INVALID_FD;
62 }
63
64 if (code >= FUNC_BUTT) {
65 LOG_ERROR("OnRemoteRequest method code(%{public}d) out of range", code);
66 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
67 }
68 Handler handler = handlers[code];
69 if (handler == nullptr) {
70 LOG_ERROR("OnRemoteRequest method code(%{public}d) is not support", code);
71 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
72 }
73
74 auto future = Submit([this, &data, &reply, handler]() -> int {
75 return (this->*handler)(data, reply);
76 });
77 return future.get();
78 }
79
HandleGetRowCountRequest(MessageParcel & data,MessageParcel & reply)80 int ISharedResultSetStub::HandleGetRowCountRequest(MessageParcel &data, MessageParcel &reply)
81 {
82 int count = -1;
83 int errCode = resultSet_->GetRowCount(count);
84 reply.WriteInt32(errCode);
85 if (errCode == E_OK) {
86 reply.WriteInt32(count);
87 }
88 LOG_DEBUG("HandleGetRowCountRequest call %{public}d", errCode);
89 return NO_ERROR;
90 }
91
HandleGetAllColumnNamesRequest(MessageParcel & data,MessageParcel & reply)92 int ISharedResultSetStub::HandleGetAllColumnNamesRequest(MessageParcel &data, MessageParcel &reply)
93 {
94 std::vector<std::string> names;
95 int errCode = resultSet_->GetAllColumnNames(names);
96 reply.WriteInt32(errCode);
97 if (errCode == E_OK) {
98 reply.WriteStringVector(names);
99 }
100 LOG_DEBUG("HandleGetAllColumnNamesRequest call %{public}d", errCode);
101 return NO_ERROR;
102 }
103
HandleOnGoRequest(MessageParcel & data,MessageParcel & reply)104 int ISharedResultSetStub::HandleOnGoRequest(MessageParcel &data, MessageParcel &reply)
105 {
106 int oldRow = data.ReadInt32();
107 int newRow = data.ReadInt32();
108 int errCode = resultSet_->OnGo(oldRow, newRow);
109 reply.WriteInt32(errCode);
110 LOG_DEBUG("HandleOnGoRequest call %{public}d", errCode);
111 return NO_ERROR;
112 }
113
HandleCloseRequest(MessageParcel & data,MessageParcel & reply)114 int ISharedResultSetStub::HandleCloseRequest(MessageParcel &data, MessageParcel &reply)
115 {
116 int errCode = resultSet_->Close();
117 reply.WriteInt32(errCode);
118 LOG_DEBUG("HandleCloseRequest call %{public}d", errCode);
119 return NO_ERROR;
120 }
121
Run()122 void ISharedResultSetStub::Run()
123 {
124 auto handle = thread_.native_handle();
125 bool isRunning = true;
126 while (isRunning) {
127 auto runnable = runnables_.Pop();
128 if (runnable == nullptr) {
129 continue;
130 }
131 isRunning = runnable();
132 }
133 LOG_ERROR("ISharedResultSetStub thread(%{public}" PRIx64 ") is exited", uint64_t(handle));
134 }
135 } // namespace OHOS::NativeRdb