adb: make fdevent_test, socket_test compile on Windows.
Switch pthread_* to use the adb_thread_* abstractions to allow the fdevent
and socket tests to compile on Win32.
Bug: http://b/27105824
Change-Id: I6541bb1398780b999837e701837d7f86a5eee8ca
(cherry picked from commit 022d447e9e
)
This commit is contained in:
parent
c1d252bec2
commit
b582fa3bd8
|
@ -59,6 +59,8 @@ LIBADB_SRC_FILES := \
|
|||
LIBADB_TEST_SRCS := \
|
||||
adb_io_test.cpp \
|
||||
adb_utils_test.cpp \
|
||||
fdevent_test.cpp \
|
||||
socket_test.cpp \
|
||||
sysdeps_test.cpp \
|
||||
transport_test.cpp \
|
||||
|
||||
|
@ -87,14 +89,6 @@ LIBADB_windows_SRC_FILES := \
|
|||
sysdeps_win32.cpp \
|
||||
usb_windows.cpp \
|
||||
|
||||
LIBADB_TEST_linux_SRCS := \
|
||||
fdevent_test.cpp \
|
||||
socket_test.cpp \
|
||||
|
||||
LIBADB_TEST_darwin_SRCS := \
|
||||
fdevent_test.cpp \
|
||||
socket_test.cpp \
|
||||
|
||||
LIBADB_TEST_windows_SRCS := \
|
||||
sysdeps_win32_test.cpp \
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
@ -70,6 +71,7 @@ struct PollNode {
|
|||
// That's why we don't need a lock for fdevent.
|
||||
static auto& g_poll_node_map = *new std::unordered_map<int, PollNode>();
|
||||
static auto& g_pending_list = *new std::list<fdevent*>();
|
||||
static std::atomic<bool> terminate_loop(false);
|
||||
static bool main_thread_valid;
|
||||
static unsigned long main_thread_id;
|
||||
|
||||
|
@ -364,6 +366,10 @@ void fdevent_loop()
|
|||
#endif // !ADB_HOST
|
||||
|
||||
while (true) {
|
||||
if (terminate_loop) {
|
||||
return;
|
||||
}
|
||||
|
||||
D("--- --- waiting for events");
|
||||
|
||||
fdevent_process();
|
||||
|
@ -376,6 +382,10 @@ void fdevent_loop()
|
|||
}
|
||||
}
|
||||
|
||||
void fdevent_terminate_loop() {
|
||||
terminate_loop = true;
|
||||
}
|
||||
|
||||
size_t fdevent_installed_count() {
|
||||
return g_poll_node_map.size();
|
||||
}
|
||||
|
@ -384,4 +394,5 @@ void fdevent_reset() {
|
|||
g_poll_node_map.clear();
|
||||
g_pending_list.clear();
|
||||
main_thread_valid = false;
|
||||
terminate_loop = false;
|
||||
}
|
||||
|
|
|
@ -76,9 +76,9 @@ void fdevent_set_timeout(fdevent *fde, int64_t timeout_ms);
|
|||
*/
|
||||
void fdevent_loop();
|
||||
|
||||
// For debugging only.
|
||||
// The following functions are used only for tests.
|
||||
void fdevent_terminate_loop();
|
||||
size_t fdevent_installed_count();
|
||||
// For debugging only.
|
||||
void fdevent_reset();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,15 +18,13 @@
|
|||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <limits>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "adb_io.h"
|
||||
#include "fdevent_test.h"
|
||||
|
||||
class FdHandler {
|
||||
public:
|
||||
|
@ -48,7 +46,7 @@ class FdHandler {
|
|||
if (events & FDE_READ) {
|
||||
ASSERT_EQ(fd, handler->read_fd_);
|
||||
char c;
|
||||
ASSERT_EQ(1, read(fd, &c, 1));
|
||||
ASSERT_EQ(1, adb_read(fd, &c, 1));
|
||||
handler->queue_.push(c);
|
||||
fdevent_add(&handler->write_fde_, FDE_WRITE);
|
||||
}
|
||||
|
@ -57,7 +55,7 @@ class FdHandler {
|
|||
ASSERT_FALSE(handler->queue_.empty());
|
||||
char c = handler->queue_.front();
|
||||
handler->queue_.pop();
|
||||
ASSERT_EQ(1, write(fd, &c, 1));
|
||||
ASSERT_EQ(1, adb_write(fd, &c, 1));
|
||||
if (handler->queue_.empty()) {
|
||||
fdevent_del(&handler->write_fde_, FDE_WRITE);
|
||||
}
|
||||
|
@ -72,29 +70,19 @@ class FdHandler {
|
|||
std::queue<char> queue_;
|
||||
};
|
||||
|
||||
static void signal_handler(int) {
|
||||
pthread_exit(nullptr);
|
||||
}
|
||||
|
||||
class FdeventTest : public ::testing::Test {
|
||||
protected:
|
||||
static void SetUpTestCase() {
|
||||
ASSERT_NE(SIG_ERR, signal(SIGUSR1, signal_handler));
|
||||
ASSERT_NE(SIG_ERR, signal(SIGPIPE, SIG_IGN));
|
||||
}
|
||||
|
||||
virtual void SetUp() {
|
||||
fdevent_reset();
|
||||
ASSERT_EQ(0u, fdevent_installed_count());
|
||||
}
|
||||
};
|
||||
|
||||
struct ThreadArg {
|
||||
int first_read_fd;
|
||||
int last_write_fd;
|
||||
size_t middle_pipe_count;
|
||||
};
|
||||
|
||||
TEST_F(FdeventTest, fdevent_terminate) {
|
||||
adb_thread_t thread;
|
||||
PrepareThread();
|
||||
ASSERT_TRUE(adb_thread_create([](void*) { fdevent_loop(); }, nullptr, &thread));
|
||||
TerminateThread(thread);
|
||||
}
|
||||
|
||||
static void FdEventThreadFunc(ThreadArg* arg) {
|
||||
std::vector<int> read_fds;
|
||||
std::vector<int> write_fds;
|
||||
|
@ -102,7 +90,7 @@ static void FdEventThreadFunc(ThreadArg* arg) {
|
|||
read_fds.push_back(arg->first_read_fd);
|
||||
for (size_t i = 0; i < arg->middle_pipe_count; ++i) {
|
||||
int fds[2];
|
||||
ASSERT_EQ(0, pipe(fds));
|
||||
ASSERT_EQ(0, adb_socketpair(fds));
|
||||
read_fds.push_back(fds[0]);
|
||||
write_fds.push_back(fds[1]);
|
||||
}
|
||||
|
@ -122,9 +110,9 @@ TEST_F(FdeventTest, smoke) {
|
|||
const std::string MESSAGE = "fdevent_test";
|
||||
int fd_pair1[2];
|
||||
int fd_pair2[2];
|
||||
ASSERT_EQ(0, pipe(fd_pair1));
|
||||
ASSERT_EQ(0, pipe(fd_pair2));
|
||||
pthread_t thread;
|
||||
ASSERT_EQ(0, adb_socketpair(fd_pair1));
|
||||
ASSERT_EQ(0, adb_socketpair(fd_pair2));
|
||||
adb_thread_t thread;
|
||||
ThreadArg thread_arg;
|
||||
thread_arg.first_read_fd = fd_pair1[0];
|
||||
thread_arg.last_write_fd = fd_pair2[1];
|
||||
|
@ -132,9 +120,9 @@ TEST_F(FdeventTest, smoke) {
|
|||
int writer = fd_pair1[1];
|
||||
int reader = fd_pair2[0];
|
||||
|
||||
ASSERT_EQ(0, pthread_create(&thread, nullptr,
|
||||
reinterpret_cast<void* (*)(void*)>(FdEventThreadFunc),
|
||||
&thread_arg));
|
||||
PrepareThread();
|
||||
ASSERT_TRUE(adb_thread_create(reinterpret_cast<void (*)(void*)>(FdEventThreadFunc), &thread_arg,
|
||||
&thread));
|
||||
|
||||
for (size_t i = 0; i < MESSAGE_LOOP_COUNT; ++i) {
|
||||
std::string read_buffer = MESSAGE;
|
||||
|
@ -144,10 +132,9 @@ TEST_F(FdeventTest, smoke) {
|
|||
ASSERT_EQ(read_buffer, write_buffer);
|
||||
}
|
||||
|
||||
ASSERT_EQ(0, pthread_kill(thread, SIGUSR1));
|
||||
ASSERT_EQ(0, pthread_join(thread, nullptr));
|
||||
ASSERT_EQ(0, close(writer));
|
||||
ASSERT_EQ(0, close(reader));
|
||||
TerminateThread(thread);
|
||||
ASSERT_EQ(0, adb_close(writer));
|
||||
ASSERT_EQ(0, adb_close(reader));
|
||||
}
|
||||
|
||||
struct InvalidFdArg {
|
||||
|
@ -161,7 +148,7 @@ static void InvalidFdEventCallback(int fd, unsigned events, void* userdata) {
|
|||
ASSERT_EQ(arg->expected_events, events);
|
||||
fdevent_remove(&arg->fde);
|
||||
if (++*(arg->happened_event_count) == 2) {
|
||||
pthread_exit(nullptr);
|
||||
fdevent_terminate_loop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,9 +171,7 @@ static void InvalidFdThreadFunc(void*) {
|
|||
}
|
||||
|
||||
TEST_F(FdeventTest, invalid_fd) {
|
||||
pthread_t thread;
|
||||
ASSERT_EQ(0, pthread_create(&thread, nullptr,
|
||||
reinterpret_cast<void* (*)(void*)>(InvalidFdThreadFunc),
|
||||
nullptr));
|
||||
ASSERT_EQ(0, pthread_join(thread, nullptr));
|
||||
adb_thread_t thread;
|
||||
ASSERT_TRUE(adb_thread_create(InvalidFdThreadFunc, nullptr, &thread));
|
||||
ASSERT_TRUE(adb_thread_join(thread));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "socket.h"
|
||||
#include "sysdeps.h"
|
||||
|
||||
class FdeventTest : public ::testing::Test {
|
||||
protected:
|
||||
int dummy = -1;
|
||||
|
||||
static void SetUpTestCase() {
|
||||
#if !defined(_WIN32)
|
||||
ASSERT_NE(SIG_ERR, signal(SIGPIPE, SIG_IGN));
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
fdevent_reset();
|
||||
ASSERT_EQ(0u, fdevent_installed_count());
|
||||
}
|
||||
|
||||
// Register a dummy socket used to wake up the fdevent loop to tell it to die.
|
||||
void PrepareThread() {
|
||||
int dummy_fds[2];
|
||||
if (adb_socketpair(dummy_fds) != 0) {
|
||||
FAIL() << "failed to create socketpair: " << strerror(errno);
|
||||
}
|
||||
|
||||
asocket* dummy_socket = create_local_socket(dummy_fds[1]);
|
||||
if (!dummy_socket) {
|
||||
FAIL() << "failed to create local socket: " << strerror(errno);
|
||||
}
|
||||
dummy_socket->ready(dummy_socket);
|
||||
dummy = dummy_fds[0];
|
||||
}
|
||||
|
||||
void TerminateThread(adb_thread_t thread) {
|
||||
fdevent_terminate_loop();
|
||||
ASSERT_TRUE(WriteFdExactly(dummy, "", 1));
|
||||
ASSERT_TRUE(adb_thread_join(thread));
|
||||
ASSERT_EQ(0, adb_close(dummy));
|
||||
}
|
||||
};
|
|
@ -18,119 +18,89 @@
|
|||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <array>
|
||||
#include <limits>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "adb.h"
|
||||
#include "adb_io.h"
|
||||
#include "fdevent_test.h"
|
||||
#include "socket.h"
|
||||
#include "sysdeps.h"
|
||||
|
||||
static void signal_handler(int) {
|
||||
ASSERT_EQ(1u, fdevent_installed_count());
|
||||
pthread_exit(nullptr);
|
||||
}
|
||||
|
||||
// On host, register a dummy socket, so fdevet_loop() will not abort when previously
|
||||
// registered local sockets are all closed. On device, fdevent_subproc_setup() installs
|
||||
// one fdevent which can be considered as dummy socket.
|
||||
static void InstallDummySocket() {
|
||||
#if ADB_HOST
|
||||
int dummy_fds[2];
|
||||
ASSERT_EQ(0, pipe(dummy_fds));
|
||||
asocket* dummy_socket = create_local_socket(dummy_fds[0]);
|
||||
ASSERT_TRUE(dummy_socket != nullptr);
|
||||
dummy_socket->ready(dummy_socket);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct ThreadArg {
|
||||
int first_read_fd;
|
||||
int last_write_fd;
|
||||
size_t middle_pipe_count;
|
||||
};
|
||||
|
||||
static void FdEventThreadFunc(ThreadArg* arg) {
|
||||
std::vector<int> read_fds;
|
||||
std::vector<int> write_fds;
|
||||
class LocalSocketTest : public FdeventTest {};
|
||||
|
||||
read_fds.push_back(arg->first_read_fd);
|
||||
for (size_t i = 0; i < arg->middle_pipe_count; ++i) {
|
||||
int fds[2];
|
||||
ASSERT_EQ(0, adb_socketpair(fds));
|
||||
read_fds.push_back(fds[0]);
|
||||
write_fds.push_back(fds[1]);
|
||||
}
|
||||
write_fds.push_back(arg->last_write_fd);
|
||||
|
||||
for (size_t i = 0; i < read_fds.size(); ++i) {
|
||||
asocket* reader = create_local_socket(read_fds[i]);
|
||||
ASSERT_TRUE(reader != nullptr);
|
||||
asocket* writer = create_local_socket(write_fds[i]);
|
||||
ASSERT_TRUE(writer != nullptr);
|
||||
reader->peer = writer;
|
||||
writer->peer = reader;
|
||||
reader->ready(reader);
|
||||
}
|
||||
|
||||
InstallDummySocket();
|
||||
static void FdEventThreadFunc(void*) {
|
||||
fdevent_loop();
|
||||
}
|
||||
|
||||
class LocalSocketTest : public ::testing::Test {
|
||||
protected:
|
||||
static void SetUpTestCase() {
|
||||
ASSERT_NE(SIG_ERR, signal(SIGUSR1, signal_handler));
|
||||
ASSERT_NE(SIG_ERR, signal(SIGPIPE, SIG_IGN));
|
||||
}
|
||||
|
||||
virtual void SetUp() {
|
||||
fdevent_reset();
|
||||
ASSERT_EQ(0u, fdevent_installed_count());
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(LocalSocketTest, smoke) {
|
||||
const size_t PIPE_COUNT = 100;
|
||||
const size_t MESSAGE_LOOP_COUNT = 100;
|
||||
// Join two socketpairs with a chain of intermediate socketpairs.
|
||||
int first[2];
|
||||
std::vector<std::array<int, 2>> intermediates;
|
||||
int last[2];
|
||||
|
||||
constexpr size_t INTERMEDIATE_COUNT = 50;
|
||||
constexpr size_t MESSAGE_LOOP_COUNT = 100;
|
||||
const std::string MESSAGE = "socket_test";
|
||||
int fd_pair1[2];
|
||||
int fd_pair2[2];
|
||||
ASSERT_EQ(0, adb_socketpair(fd_pair1));
|
||||
ASSERT_EQ(0, adb_socketpair(fd_pair2));
|
||||
pthread_t thread;
|
||||
ThreadArg thread_arg;
|
||||
thread_arg.first_read_fd = fd_pair1[0];
|
||||
thread_arg.last_write_fd = fd_pair2[1];
|
||||
thread_arg.middle_pipe_count = PIPE_COUNT;
|
||||
int writer = fd_pair1[1];
|
||||
int reader = fd_pair2[0];
|
||||
|
||||
ASSERT_EQ(0, pthread_create(&thread, nullptr,
|
||||
reinterpret_cast<void* (*)(void*)>(FdEventThreadFunc),
|
||||
&thread_arg));
|
||||
intermediates.resize(INTERMEDIATE_COUNT);
|
||||
ASSERT_EQ(0, adb_socketpair(first)) << strerror(errno);
|
||||
ASSERT_EQ(0, adb_socketpair(last)) << strerror(errno);
|
||||
asocket* prev_tail = create_local_socket(first[1]);
|
||||
ASSERT_NE(nullptr, prev_tail);
|
||||
|
||||
auto connect = [](asocket* tail, asocket* head) {
|
||||
tail->peer = head;
|
||||
head->peer = tail;
|
||||
tail->ready(tail);
|
||||
};
|
||||
|
||||
for (auto& intermediate : intermediates) {
|
||||
ASSERT_EQ(0, adb_socketpair(intermediate.data())) << strerror(errno);
|
||||
|
||||
asocket* head = create_local_socket(intermediate[0]);
|
||||
ASSERT_NE(nullptr, head);
|
||||
|
||||
asocket* tail = create_local_socket(intermediate[1]);
|
||||
ASSERT_NE(nullptr, tail);
|
||||
|
||||
connect(prev_tail, head);
|
||||
prev_tail = tail;
|
||||
}
|
||||
|
||||
asocket* end = create_local_socket(last[0]);
|
||||
ASSERT_NE(nullptr, end);
|
||||
connect(prev_tail, end);
|
||||
|
||||
PrepareThread();
|
||||
adb_thread_t thread;
|
||||
ASSERT_TRUE(adb_thread_create(FdEventThreadFunc, nullptr, &thread));
|
||||
|
||||
usleep(1000);
|
||||
for (size_t i = 0; i < MESSAGE_LOOP_COUNT; ++i) {
|
||||
std::string read_buffer = MESSAGE;
|
||||
std::string write_buffer(MESSAGE.size(), 'a');
|
||||
ASSERT_TRUE(WriteFdExactly(writer, read_buffer.c_str(), read_buffer.size()));
|
||||
ASSERT_TRUE(ReadFdExactly(reader, &write_buffer[0], write_buffer.size()));
|
||||
ASSERT_TRUE(WriteFdExactly(first[0], &read_buffer[0], read_buffer.size()));
|
||||
ASSERT_TRUE(ReadFdExactly(last[1], &write_buffer[0], write_buffer.size()));
|
||||
ASSERT_EQ(read_buffer, write_buffer);
|
||||
}
|
||||
ASSERT_EQ(0, adb_close(writer));
|
||||
ASSERT_EQ(0, adb_close(reader));
|
||||
// Wait until the local sockets are closed.
|
||||
sleep(1);
|
||||
|
||||
ASSERT_EQ(0, pthread_kill(thread, SIGUSR1));
|
||||
ASSERT_EQ(0, pthread_join(thread, nullptr));
|
||||
ASSERT_EQ(0, adb_close(first[0]));
|
||||
ASSERT_EQ(0, adb_close(last[1]));
|
||||
|
||||
// Wait until the local sockets are closed.
|
||||
adb_sleep_ms(100);
|
||||
TerminateThread(thread);
|
||||
}
|
||||
|
||||
struct CloseWithPacketArg {
|
||||
|
@ -160,7 +130,6 @@ static void CloseWithPacketThreadFunc(CloseWithPacketArg* arg) {
|
|||
s->peer = cause_close_s;
|
||||
cause_close_s->ready(cause_close_s);
|
||||
|
||||
InstallDummySocket();
|
||||
fdevent_loop();
|
||||
}
|
||||
|
||||
|
@ -176,21 +145,19 @@ TEST_F(LocalSocketTest, close_socket_with_packet) {
|
|||
CloseWithPacketArg arg;
|
||||
arg.socket_fd = socket_fd[1];
|
||||
arg.cause_close_fd = cause_close_fd[1];
|
||||
pthread_t thread;
|
||||
ASSERT_EQ(0, pthread_create(&thread, nullptr,
|
||||
reinterpret_cast<void* (*)(void*)>(CloseWithPacketThreadFunc),
|
||||
&arg));
|
||||
// Wait until the fdevent_loop() starts.
|
||||
sleep(1);
|
||||
ASSERT_EQ(0, adb_close(cause_close_fd[0]));
|
||||
sleep(1);
|
||||
ASSERT_EQ(2u, fdevent_installed_count());
|
||||
ASSERT_EQ(0, adb_close(socket_fd[0]));
|
||||
// Wait until the socket is closed.
|
||||
sleep(1);
|
||||
|
||||
ASSERT_EQ(0, pthread_kill(thread, SIGUSR1));
|
||||
ASSERT_EQ(0, pthread_join(thread, nullptr));
|
||||
PrepareThread();
|
||||
adb_thread_t thread;
|
||||
ASSERT_TRUE(adb_thread_create(reinterpret_cast<void (*)(void*)>(CloseWithPacketThreadFunc),
|
||||
&arg, &thread));
|
||||
// Wait until the fdevent_loop() starts.
|
||||
adb_sleep_ms(100);
|
||||
ASSERT_EQ(0, adb_close(cause_close_fd[0]));
|
||||
adb_sleep_ms(100);
|
||||
EXPECT_EQ(2u, fdevent_installed_count());
|
||||
ASSERT_EQ(0, adb_close(socket_fd[0]));
|
||||
|
||||
TerminateThread(thread);
|
||||
}
|
||||
|
||||
// This test checks if we can read packets from a closing local socket.
|
||||
|
@ -203,26 +170,23 @@ TEST_F(LocalSocketTest, read_from_closing_socket) {
|
|||
arg.socket_fd = socket_fd[1];
|
||||
arg.cause_close_fd = cause_close_fd[1];
|
||||
|
||||
pthread_t thread;
|
||||
ASSERT_EQ(0, pthread_create(&thread, nullptr,
|
||||
reinterpret_cast<void* (*)(void*)>(CloseWithPacketThreadFunc),
|
||||
&arg));
|
||||
PrepareThread();
|
||||
adb_thread_t thread;
|
||||
ASSERT_TRUE(adb_thread_create(reinterpret_cast<void (*)(void*)>(CloseWithPacketThreadFunc),
|
||||
&arg, &thread));
|
||||
// Wait until the fdevent_loop() starts.
|
||||
sleep(1);
|
||||
adb_sleep_ms(100);
|
||||
ASSERT_EQ(0, adb_close(cause_close_fd[0]));
|
||||
sleep(1);
|
||||
ASSERT_EQ(2u, fdevent_installed_count());
|
||||
adb_sleep_ms(100);
|
||||
EXPECT_EQ(2u, fdevent_installed_count());
|
||||
|
||||
// Verify if we can read successfully.
|
||||
std::vector<char> buf(arg.bytes_written);
|
||||
ASSERT_NE(0u, arg.bytes_written);
|
||||
ASSERT_EQ(true, ReadFdExactly(socket_fd[0], buf.data(), buf.size()));
|
||||
ASSERT_EQ(0, adb_close(socket_fd[0]));
|
||||
|
||||
// Wait until the socket is closed.
|
||||
sleep(1);
|
||||
|
||||
ASSERT_EQ(0, pthread_kill(thread, SIGUSR1));
|
||||
ASSERT_EQ(0, pthread_join(thread, nullptr));
|
||||
TerminateThread(thread);
|
||||
}
|
||||
|
||||
// This test checks if we can close local socket in the following situation:
|
||||
|
@ -238,20 +202,17 @@ TEST_F(LocalSocketTest, write_error_when_having_packets) {
|
|||
arg.socket_fd = socket_fd[1];
|
||||
arg.cause_close_fd = cause_close_fd[1];
|
||||
|
||||
pthread_t thread;
|
||||
ASSERT_EQ(0, pthread_create(&thread, nullptr,
|
||||
reinterpret_cast<void* (*)(void*)>(CloseWithPacketThreadFunc),
|
||||
&arg));
|
||||
PrepareThread();
|
||||
adb_thread_t thread;
|
||||
ASSERT_TRUE(adb_thread_create(reinterpret_cast<void (*)(void*)>(CloseWithPacketThreadFunc),
|
||||
&arg, &thread));
|
||||
|
||||
// Wait until the fdevent_loop() starts.
|
||||
sleep(1);
|
||||
ASSERT_EQ(3u, fdevent_installed_count());
|
||||
adb_sleep_ms(100);
|
||||
EXPECT_EQ(3u, fdevent_installed_count());
|
||||
ASSERT_EQ(0, adb_close(socket_fd[0]));
|
||||
|
||||
// Wait until the socket is closed.
|
||||
sleep(1);
|
||||
|
||||
ASSERT_EQ(0, pthread_kill(thread, SIGUSR1));
|
||||
ASSERT_EQ(0, pthread_join(thread, nullptr));
|
||||
TerminateThread(thread);
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
|
@ -260,50 +221,52 @@ static void ClientThreadFunc() {
|
|||
std::string error;
|
||||
int fd = network_loopback_client(5038, SOCK_STREAM, &error);
|
||||
ASSERT_GE(fd, 0) << error;
|
||||
sleep(2);
|
||||
adb_sleep_ms(200);
|
||||
ASSERT_EQ(0, adb_close(fd));
|
||||
}
|
||||
|
||||
struct CloseRdHupSocketArg {
|
||||
int socket_fd;
|
||||
int socket_fd;
|
||||
};
|
||||
|
||||
static void CloseRdHupSocketThreadFunc(CloseRdHupSocketArg* arg) {
|
||||
asocket* s = create_local_socket(arg->socket_fd);
|
||||
ASSERT_TRUE(s != nullptr);
|
||||
asocket* s = create_local_socket(arg->socket_fd);
|
||||
ASSERT_TRUE(s != nullptr);
|
||||
|
||||
InstallDummySocket();
|
||||
fdevent_loop();
|
||||
fdevent_loop();
|
||||
}
|
||||
|
||||
// This test checks if we can close sockets in CLOSE_WAIT state.
|
||||
TEST_F(LocalSocketTest, close_socket_in_CLOSE_WAIT_state) {
|
||||
std::string error;
|
||||
int listen_fd = network_inaddr_any_server(5038, SOCK_STREAM, &error);
|
||||
ASSERT_GE(listen_fd, 0);
|
||||
pthread_t client_thread;
|
||||
ASSERT_EQ(0, pthread_create(&client_thread, nullptr,
|
||||
reinterpret_cast<void* (*)(void*)>(ClientThreadFunc), nullptr));
|
||||
std::string error;
|
||||
int listen_fd = network_inaddr_any_server(5038, SOCK_STREAM, &error);
|
||||
ASSERT_GE(listen_fd, 0);
|
||||
|
||||
struct sockaddr addr;
|
||||
socklen_t alen;
|
||||
alen = sizeof(addr);
|
||||
int accept_fd = adb_socket_accept(listen_fd, &addr, &alen);
|
||||
ASSERT_GE(accept_fd, 0);
|
||||
CloseRdHupSocketArg arg;
|
||||
arg.socket_fd = accept_fd;
|
||||
pthread_t thread;
|
||||
ASSERT_EQ(0, pthread_create(&thread, nullptr,
|
||||
reinterpret_cast<void* (*)(void*)>(CloseRdHupSocketThreadFunc),
|
||||
&arg));
|
||||
// Wait until the fdevent_loop() starts.
|
||||
sleep(1);
|
||||
ASSERT_EQ(2u, fdevent_installed_count());
|
||||
// Wait until the client closes its socket.
|
||||
ASSERT_EQ(0, pthread_join(client_thread, nullptr));
|
||||
sleep(2);
|
||||
ASSERT_EQ(0, pthread_kill(thread, SIGUSR1));
|
||||
ASSERT_EQ(0, pthread_join(thread, nullptr));
|
||||
adb_thread_t client_thread;
|
||||
ASSERT_TRUE(adb_thread_create(reinterpret_cast<void (*)(void*)>(ClientThreadFunc), nullptr,
|
||||
&client_thread));
|
||||
|
||||
struct sockaddr addr;
|
||||
socklen_t alen;
|
||||
alen = sizeof(addr);
|
||||
int accept_fd = adb_socket_accept(listen_fd, &addr, &alen);
|
||||
ASSERT_GE(accept_fd, 0);
|
||||
CloseRdHupSocketArg arg;
|
||||
arg.socket_fd = accept_fd;
|
||||
|
||||
PrepareThread();
|
||||
adb_thread_t thread;
|
||||
ASSERT_TRUE(adb_thread_create(reinterpret_cast<void (*)(void*)>(CloseRdHupSocketThreadFunc),
|
||||
&arg, &thread));
|
||||
|
||||
// Wait until the fdevent_loop() starts.
|
||||
adb_sleep_ms(100);
|
||||
EXPECT_EQ(2u, fdevent_installed_count());
|
||||
|
||||
// Wait until the client closes its socket.
|
||||
ASSERT_TRUE(adb_thread_join(client_thread));
|
||||
|
||||
TerminateThread(thread);
|
||||
}
|
||||
|
||||
#endif // defined(__linux__)
|
||||
|
|
Loading…
Reference in New Issue