Closing fd should be performed on the thread.
This patch modified what was handled on the main thread.
Changes:
* Remove FdErrorHandler()
* Add to Disconnect() at socket destructor.
* Add some logs for debugging.
Change-Id: I436a6e987e5691970e0e76892b995e131d22e034
Signed-off-by: Changgyu Choi <changyu.choi@samsung.com>
socket_ = std::make_unique<pkgmgr_common::socket::ClientSocket>(SOCK_PATH);
}
-PkgInfoClient::~PkgInfoClient() {
- if (socket_ != nullptr)
- socket_->Disconnect();
-}
-
bool PkgInfoClient::SendRequest() {
if (socket_ == nullptr) {
LOGE("Socket is not ready");
}
if (!socket_->Connect()) {
LOGE("Failed to connect client socket, try to direct access");
- socket_->Disconnect();
is_offline_ = true;
return RequestHandlerDirectAccess();
}
if (socket_->SendData(&req_type_, sizeof(req_type_)) != 0) {
LOGE("fail to send data");
- socket_->Disconnect();
return false;
}
if (socket_->SendData(&len, sizeof(len)) != 0) {
LOGE("fail to send data");
- socket_->Disconnect();
return false;
}
if (socket_->SendData(&raw[0], len) != 0) {
LOGE("Fail to send data");
- socket_->Disconnect();
return false;
}
int len = 0;
if (socket_->ReceiveData(&len, sizeof(len)) != 0 || len <= 0) {
LOGE("Fail to receive data");
- socket_->Disconnect();
return nullptr;
}
unsigned char* raw = new (std::nothrow) unsigned char[len];
if (raw == nullptr) {
LOGE("Out of memory");
- socket_->Disconnect();
return nullptr;
}
if (socket_->ReceiveData(raw, len) != 0) {
LOGE("Fail to receive data");
- socket_->Disconnect();
delete[] raw;
return nullptr;
}
- socket_->Disconnect();
auto res = pkgmgr_common::parcel::ParcelableFactory::GetInst().CreateParcel(
raw, len);
PkgInfoClient(
std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcel,
uid_t uid, pkgmgr_common::ReqType req_type);
- ~PkgInfoClient();
+ ~PkgInfoClient() = default;
bool SendRequest();
std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> GetResultParcel();
AbstractSocket::AbstractSocket(int fd) : fd_(fd), addr_{} {}
-AbstractSocket::~AbstractSocket() {}
+AbstractSocket::~AbstractSocket() {
+ Disconnect();
+}
int AbstractSocket::SendData(const void* buf, unsigned int size) {
auto buffer = static_cast<const unsigned char*>(buf);
ClientSocket::ClientSocket(std::string path) : AbstractSocket(std::move(path)) {
}
-ClientSocket::~ClientSocket() {}
-
void ClientSocket::SetTimeout(int timeout_msec) {
if (timeout_msec == -1) timeout_msec = 5000;
class EXPORT_API ClientSocket: public AbstractSocket {
public:
ClientSocket(std::string path);
- ~ClientSocket();
bool Connect();
private:
DataSocket::DataSocket(int fd) : AbstractSocket(fd) {}
-DataSocket::~DataSocket() {}
-
} // namespace socket
} // namespace pkgmgr_common
class EXPORT_API DataSocket: public AbstractSocket {
public:
DataSocket(int fd);
- ~DataSocket();
};
} // namespace socket
LOGD("Server socket is created(%s)", path_.c_str());
}
-ServerSocket::~ServerSocket() {}
-
int ServerSocket::Bind() {
return bind(fd_, reinterpret_cast<struct sockaddr*>(&addr_), sizeof(addr_));
}
class EXPORT_API ServerSocket: public AbstractSocket {
public:
ServerSocket(std::string path);
- ~ServerSocket();
-
int Accept();
private:
if (socket_->SendData(&size, sizeof(size)) < 0)
return false;
- return (socket_->SendData(data, size) < 0);
+ return (socket_->SendData(data, size) == 0);
}
} // namespace pkgmgr_server
*/
#include <glib-unix.h>
+#include <stdlib.h>
#include <vconf.h>
#include <algorithm>
static const std::string SOCK_PATH = "/run/pkgmgr-info-server";
-Runner::Runner(unsigned int thread_num) : sid_(-1) {
+Runner::Runner(unsigned int thread_num) {
/* thread_num_ <= hardware_concurrency */
thread_num_ = std::min(thread_num, std::thread::hardware_concurrency());
server_ = std::make_unique<pkgmgr_common::socket::ServerSocket>(SOCK_PATH);
thread_pool_ = std::make_unique<WorkerThread>(thread_num_);
- sid_ = g_unix_fd_add(server_->GetFd(), G_IO_IN, OnReceiveRequest, this);
+ auto condition = static_cast<GIOCondition>(
+ G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL);
+ sid_ = g_unix_fd_add(server_->GetFd(), condition, OnReceiveRequest, this);
vconf_notify_key_changed(VCONFKEY_LANGSET, OnLanguageChange, this);
std::unique_ptr<char, decltype(std::free)*> locale(
_get_system_locale(), std::free);
vconf_ignore_key_changed(VCONFKEY_LANGSET, OnLanguageChange);
}
-int Runner::FdErrorHandler(int fd, GIOCondition cond, void* user_data) {
- auto runner = static_cast<Runner*>(user_data);
- if (static_cast<int>(cond) & (G_IO_ERR | G_IO_HUP)) {
- auto it = runner->sid_map_.find(fd);
- if (it != runner->sid_map_.end()) {
- g_source_remove(it->second);
- runner->sid_map_.erase(it);
- }
- close(fd);
+int Runner::OnReceiveRequest(int fd, GIOCondition cond, void* user_data) {
+ if (static_cast<int>(cond) & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
+ LOGE("Invalid condition fd(%d) condition(%d)", fd, static_cast<int>(cond));
+ abort();
+ return G_SOURCE_REMOVE;
}
- return G_SOURCE_CONTINUE;
-}
-
-int Runner::OnReceiveRequest(int fd, GIOCondition cond, void* user_data) {
auto runner = static_cast<Runner*>(user_data);
int client_fd = runner->server_->Accept();
if (client_fd < 0) {
- LOGE("Failed to Accept. (%d)", client_fd);
+ LOGE("Failed to Accept. errno(%d)", errno);
return G_SOURCE_CONTINUE;
}
- auto condition = static_cast<GIOCondition>(G_IO_ERR | G_IO_HUP);
- int sid = g_unix_fd_add(client_fd, condition, FdErrorHandler, runner);
- runner->sid_map_[client_fd] = sid;
runner->QueueRequest(client_fd);
return G_SOURCE_CONTINUE;
}
static int OnReceiveRequest(int fd, GIOCondition cond, void* user_data);
static void OnLanguageChange(keynode_t* key, void* user_data);
bool QueueRequest(int client_fd);
- static int FdErrorHandler(int fd, GIOCondition cond, void* user_data);
private:
int sid_;
unsigned int thread_num_;
- std::unordered_map<int, int> sid_map_;
std::unique_ptr<pkgmgr_common::socket::ServerSocket> server_;
std::unique_ptr<WorkerThread> thread_pool_;
};
continue;
}
pkgmgr_common::ReqType type = req->GetRequestType();
- LOGD("Request type(%s), pid(%d)",
+ LOGW("Request type(%s), pid(%d)",
pkgmgr_common::ReqTypeToString(type), req->GetSenderPID());
if (type <= pkgmgr_common::ReqType::REQ_TYPE_NONE
|| type >= pkgmgr_common::ReqType::MAX) {
- LOGE("Request type is invalid (%d)", static_cast<int>(type));
+ LOGE("Request type is invalid (%d) pid(%d)", static_cast<int>(type),
+ req->GetSenderPID());
pkgmgr_common::parcel::AbstractParcelable parcelable(
0, pkgmgr_common::parcel::ParcelableType::Unknown, PMINFO_R_ERROR);
locale_.GetObject()))
LOGE("Failed to handle request");
} catch (const std::exception& err) {
- LOGE("Exception occurred (%s)", err.what());
+ LOGE("Exception occurred (%s) pid(%d)", err.what(), req->GetSenderPID());
pkgmgr_common::parcel::AbstractParcelable parcelable(
0, pkgmgr_common::parcel::ParcelableType::Unknown, PMINFO_R_ERROR);
tizen_base::Parcel p;
req->SendData(&raw[0], raw.size());
continue;
} catch (...) {
- LOGE("Exception occurred");
+ LOGE("Exception occurred pid(%d)", req->GetSenderPID());
pkgmgr_common::parcel::AbstractParcelable parcelable(
0, pkgmgr_common::parcel::ParcelableType::Unknown, PMINFO_R_ERROR);
tizen_base::Parcel p;
}
std::vector<uint8_t> result_data = handler[type]->ExtractResult();
- req->SendData(result_data.data(), result_data.size());
+ if (req->SendData(result_data.data(), result_data.size()) == false) {
+ LOGE("Failed to send response pid(%d)", req->GetSenderPID());
+ continue;
+ }
+ LOGW("Success response pid(%d)", req->GetSenderPID());
}
}