This patch uses MSG_DONTWAIT flag instead of socket existence check.
If calling the send() function returns an error with the errno value
that is EAGAIN or EWOULDBLOCK, the method will call the sleep() and try
to send the data again.
The interval is 2ms. The maximum retry count is 10.
If the retry count exceeds 10 times, AMD will close the file descriptor
to disconnect the connection. When handling the disconnected event,
AMD doesn't invoke the disconnected event callback function if the
client socket is closed. It means the connection is closed by AMD forcedly.
Change-Id: I8217d889506d82418c271d79491817634b33e32d
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
if (found == channels_.end())
return;
+ auto& client_channel = found->second;
+ bool is_closed = client_channel->IsClosed();
channels_.erase(found);
- if (disconn_cb_)
+ if (!is_closed && disconn_cb_)
disconn_cb_(pid, disconn_data_);
}
auto raw = parcel.GetRaw();
int ret = channel->Send(reinterpret_cast<void*>(&raw[0]), raw.size());
- if (ret != 0)
+ if (ret != 0) {
+ _E("Socket will be closed, pid(%d)", channel->GetPid());
+ channel->Close();
return ret;
+ }
if (callback)
channel->Push(std::make_shared<ResultCb>(callback, user_data));
parcel.WriteInt32(AUL_SOCK_ASYNC);
auto raw = parcel.GetRaw();
int ret = channel->Send(reinterpret_cast<void*>(&raw[0]), raw.size());
- if (ret != 0)
+ if (ret != 0) {
+ _E("Socket will be closed. pid(%d)", pid);
+ channel->Close();
return ret;
+ }
broker.AddClientChannel(pid, channel);
return 0;
.data = data
};
- if (!_app_status_socket_exists(_app_status_find(pid)))
- return -ECOMM;
-
info = __create_reply_info(pid, uid, cmd, clifd, data);
if (!info)
return -ENOMEM;
#include <unistd.h>
namespace amd {
+namespace {
+
+constexpr const int MAX_RETRY_CNT = 10;
+
+} // namespace
ClientSocket::ClientSocket() {
fd_ = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
int ClientSocket::Send(const void* buf, unsigned int size) {
const unsigned char* buffer = static_cast<const unsigned char*>(buf);
size_t len = size;
+ int retry_cnt = MAX_RETRY_CNT;
while (len) {
- ssize_t bytes = send(fd_, buffer, len, MSG_NOSIGNAL);
+ ssize_t bytes = send(fd_, buffer, len, MSG_NOSIGNAL | MSG_DONTWAIT);
if (bytes < 0) {
+ if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
+ if (retry_cnt > 0) {
+ retry_cnt--;
+ _E("send(): fd(%d), errno(%d). sleep and retry ...", fd_, errno);
+ usleep(2 * 1000);
+ continue;
+ }
+ }
+
int ret = -errno;
_E("send() is failed. fd(%d), errno(%d)", fd_, errno);
return ret;