Skip to content

Commit

Permalink
Change fd-socket map to fd-FileOrSocket map.
Browse files Browse the repository at this point in the history
Change-Id: Ib46542f3892efb7c0a2a3bfee2545825c5c4e22a
  • Loading branch information
yjzhang111 committed Feb 28, 2024
1 parent f8e466f commit fef4a40
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 40 deletions.
16 changes: 0 additions & 16 deletions starboard/nplb/posix_compliance/posix_file_open_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,13 @@ void BasicTest(bool existing,
int fd = open(filename.c_str(), open_flags);
if (!expected_success) {
EXPECT_FALSE(fd >= 0) << SB_FILE_OPEN_TEST_CONTEXT;
// EXPECT_EQ(expected_created, created) << SB_FILE_OPEN_TEST_CONTEXT;
// EXPECT_NE(kSbFileOk, error) << SB_FILE_OPEN_TEST_CONTEXT;

// Try to clean up in case test fails.
if (!(fd < 0)) {
close(fd);
}
} else {
EXPECT_TRUE(fd >= 0);
// EXPECT_EQ(expected_created, created) << SB_FILE_OPEN_TEST_CONTEXT;
// EXPECT_EQ(kSbFileOk, error) << SB_FILE_OPEN_TEST_CONTEXT;
if (fd >= 0) {
int result = close(fd);
EXPECT_TRUE(result == 0) << SB_FILE_OPEN_TEST_CONTEXT;
Expand All @@ -73,54 +69,42 @@ void BasicTest(bool existing,
}

TEST(PosixFileOpenTest, OpenOnlyOpensExistingFile) {
// BasicTest(true, kSbFileOpenOnly | kSbFileRead, false, true, __LINE__);
BasicTest(true, O_RDONLY, false, true, __LINE__);
}

TEST(PosixFileOpenTest, OpenOnlyDoesNotOpenNonExistingFile) {
// BasicTest(false, kSbFileOpenOnly | kSbFileRead, false, false, __LINE__);
BasicTest(false, O_RDONLY, false, false, __LINE__);
}

TEST(PosixFileOpenTest, CreateOnlyDoesNotCreateExistingFile) {
// BasicTest(true, kSbFileCreateOnly | kSbFileWrite, false, false, __LINE__);
BasicTest(true, O_CREAT | O_EXCL | O_WRONLY, false, false, __LINE__);
}

TEST(PosixFileOpenTest, CreateOnlyCreatesNonExistingFile) {
// BasicTest(false, kSbFileCreateOnly | kSbFileWrite, true, true, __LINE__);
BasicTest(false, O_CREAT | O_EXCL | O_WRONLY, true, true, __LINE__);
}

TEST(PosixFileOpenTest, OpenAlwaysOpensExistingFile) {
// BasicTest(true, kSbFileOpenAlways | kSbFileWrite, false, true, __LINE__);
BasicTest(true, O_CREAT | O_WRONLY, false, true, __LINE__);
}

TEST(PosixFileOpenTest, OpenAlwaysCreatesNonExistingFile) {
BasicTest(false, kSbFileOpenAlways | kSbFileWrite, true, true, __LINE__);
BasicTest(false, O_CREAT | O_WRONLY, true, true, __LINE__);
}

TEST(PosixFileOpenTest, CreateAlwaysTruncatesExistingFile) {
// BasicTest(true, kSbFileCreateAlways | kSbFileWrite, true, true, __LINE__);
BasicTest(true, O_CREAT | O_TRUNC | O_WRONLY, true, true, __LINE__);
}

TEST(PosixFileOpenTest, CreateAlwaysCreatesNonExistingFile) {
// BasicTest(false, kSbFileCreateAlways | kSbFileWrite, true, true, __LINE__);
BasicTest(false, O_CREAT | O_TRUNC | O_WRONLY, true, true, __LINE__);
}

TEST(PosixFileOpenTest, OpenTruncatedTruncatesExistingFile) {
// BasicTest(true, kSbFileOpenTruncated | kSbFileWrite, false, true,
// __LINE__);
BasicTest(true, O_TRUNC | O_WRONLY, false, true, __LINE__);
}

TEST(PosixFileOpenTest, OpenTruncatedDoesNotCreateNonExistingFile) {
// BasicTest(false, kSbFileOpenTruncated | kSbFileWrite, false, false,
// __LINE__);
BasicTest(false, O_TRUNC | O_WRONLY, false, false, __LINE__);
}

Expand Down
3 changes: 3 additions & 0 deletions starboard/shared/win32/posix_emu/include/fcntl.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
#include <../ucrt/fcntl.h> // The Visual Studio version of this same file
#include <io.h> // Needed for `open`, which is in fcntl.h on POSIX

#undef open
#undef close // in unistd.h on POSIX, and handles both files and sockets

int open(const char* path, int oflag, ...);

#endif // STARBOARD_SHARED_WIN32_POSIX_EMU_INCLUDE_FCNTL_H_
75 changes: 51 additions & 24 deletions starboard/shared/win32/posix_emu/socket.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

// We specifically do not include <sys/socket.h> since the define causes a loop
// #include <file_socket_helper.h> // Needed for FileOrSocket type.
#include <io.h> // Needed for file-specific `_close`.
#include <unistd.h> // Our version that declares generic `close`.
#include <winsock2.h>
Expand All @@ -30,18 +31,24 @@ static int gen_fd() {
return fd;
}

struct FileOrSocket {
bool is_file;
int file;
SOCKET socket;
};

struct CriticalSection {
CriticalSection() { InitializeCriticalSection(&critical_section_); }
CRITICAL_SECTION critical_section_;
};

static std::map<int, SOCKET>* g_map_addr = nullptr;
static std::map<int, FileOrSocket>* g_map_addr = nullptr;
static CriticalSection g_critical_section;

static int handle_db_put(SOCKET socket_handle) {
int handle_db_put(FileOrSocket handle) {
EnterCriticalSection(&g_critical_section.critical_section_);
if (g_map_addr == nullptr) {
g_map_addr = new std::map<int, SOCKET>();
g_map_addr = new std::map<int, FileOrSocket>();
}

int fd = gen_fd();
Expand All @@ -50,33 +57,34 @@ static int handle_db_put(SOCKET socket_handle) {
while (g_map_addr->find(fd) != g_map_addr->end()) {
fd = gen_fd();
}
g_map_addr->insert({fd, handle});

g_map_addr->insert({fd, socket_handle});
LeaveCriticalSection(&g_critical_section.critical_section_);
return fd;
}

static SOCKET handle_db_get(int fd, bool erase) {
static FileOrSocket handle_db_get(int fd, bool erase) {
FileOrSocket invalid_handle = {/*is_file=*/false, -1, INVALID_SOCKET};
if (fd < 0) {
return INVALID_SOCKET;
return invalid_handle;
}
EnterCriticalSection(&g_critical_section.critical_section_);
if (g_map_addr == nullptr) {
g_map_addr = new std::map<int, SOCKET>();
return INVALID_SOCKET;
g_map_addr = new std::map<int, FileOrSocket>();
return invalid_handle;
}

auto itr = g_map_addr->find(fd);
if (itr == g_map_addr->end()) {
return INVALID_SOCKET;
return invalid_handle;
}

SOCKET socket_handle = itr->second;
FileOrSocket handle = itr->second;
if (erase) {
g_map_addr->erase(fd);
}
LeaveCriticalSection(&g_critical_section.critical_section_);
return socket_handle;
return handle;
}

///////////////////////////////////////////////////////////////////////////////
Expand All @@ -94,22 +102,39 @@ int sb_socket(int domain, int type, int protocol) {
return -1;
}

return handle_db_put(socket_handle);
FileOrSocket handle = {/*is_file=*/false, -1, socket_handle};

return handle_db_put(handle);
}

int open(const char* path, int oflag, ...) {
va_list args;
va_start(args, oflag);
int mode = va_arg(args, int);
int fd = _open(path, oflag, mode);
va_end(args);

if (fd < 0) {
return fd;
}

FileOrSocket handle = {/*is_file=*/true, fd, INVALID_SOCKET};
return handle_db_put(handle);
}

int close(int fd) {
SOCKET socket_handle = handle_db_get(fd, true);
FileOrSocket handle = handle_db_get(fd, true);

if (socket_handle != INVALID_SOCKET) {
return closesocket(socket_handle);
if (!handle.is_file) {
return closesocket(handle.socket);
}

// This is then a file handle, so use Windows `_close` API.
return _close(fd);
return _close(handle.file);
}

int sb_bind(int socket, const struct sockaddr* address, socklen_t address_len) {
SOCKET socket_handle = handle_db_get(socket, false);
SOCKET socket_handle = handle_db_get(socket, false).socket;
if (socket_handle == INVALID_SOCKET) {
// TODO: update errno with file operation error
return -1;
Expand All @@ -119,7 +144,7 @@ int sb_bind(int socket, const struct sockaddr* address, socklen_t address_len) {
}

int sb_listen(int socket, int backlog) {
SOCKET socket_handle = handle_db_get(socket, false);
SOCKET socket_handle = handle_db_get(socket, false).socket;
if (socket_handle == INVALID_SOCKET) {
// TODO: update errno with file operation error
return -1;
Expand All @@ -129,7 +154,7 @@ int sb_listen(int socket, int backlog) {
}

int sb_accept(int socket, sockaddr* addr, int* addrlen) {
SOCKET socket_handle = handle_db_get(socket, false);
SOCKET socket_handle = handle_db_get(socket, false).socket;
if (socket_handle == INVALID_SOCKET) {
// TODO: update errno with file operation error
return -1;
Expand All @@ -140,11 +165,13 @@ int sb_accept(int socket, sockaddr* addr, int* addrlen) {
// TODO: update errno with file operation error
return -1;
}
return handle_db_put(accept_handle);

FileOrSocket handle = {/*is_file=*/false, -1, accept_handle};
return handle_db_put(handle);
}

int sb_connect(int socket, sockaddr* name, int namelen) {
SOCKET socket_handle = handle_db_get(socket, false);
SOCKET socket_handle = handle_db_get(socket, false).socket;
if (socket_handle == INVALID_SOCKET) {
// TODO: update errno with file operation error
return -1;
Expand All @@ -158,14 +185,14 @@ int sb_setsockopt(int socket,
int option_name,
const void* option_value,
int option_len) {
SOCKET socket_handle = handle_db_get(socket, false);
FileOrSocket handle = handle_db_get(socket, false);

if (socket_handle == INVALID_SOCKET) {
if (handle.is_file || handle.socket == INVALID_SOCKET) {
return -1;
}

int result =
setsockopt(socket_handle, level, option_name,
setsockopt(handle.socket, level, option_name,
reinterpret_cast<const char*>(option_value), option_len);
// TODO(b/321999529): Windows returns SOCKET_ERROR on failure. The specific
// error code can be retrieved by calling WSAGetLastError(), and Posix returns
Expand Down

0 comments on commit fef4a40

Please sign in to comment.