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