mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 00:57:44 -04:00
Merge branch 'master' of https://github.com/water111/jak-project into w/ir
This commit is contained in:
commit
f0328dcc92
|
@ -43,6 +43,9 @@ add_subdirectory(asset_tool)
|
|||
# build type_system library for compiler/decompiler
|
||||
add_subdirectory(common/type_system)
|
||||
|
||||
# build cross platform socket library
|
||||
add_subdirectory(common/cross_sockets)
|
||||
|
||||
# build decompiler
|
||||
add_subdirectory(decompiler)
|
||||
|
||||
|
|
|
@ -154,13 +154,9 @@ where the `~~ HACK ~~` message is from code in `KERNEL.CGO`.
|
|||
## TODOs
|
||||
|
||||
- Build on Windows!
|
||||
- Networking
|
||||
- File paths
|
||||
- Timer
|
||||
- CMake?
|
||||
- Assembly
|
||||
- Windows calling convention for assembly stuff
|
||||
- pthreads (can probably replace with `std::thread`, I don't remember why I used `pthread`s)
|
||||
- performance stats for `SystemThread` (probably just get rid of these performance stats completely)
|
||||
- `mmap`ing executable memory
|
||||
- line input library (appears windows compatible?)
|
||||
|
|
12
common/cross_sockets/CMakeLists.txt
Normal file
12
common/cross_sockets/CMakeLists.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
add_library(cross_sockets
|
||||
SHARED
|
||||
"xsocket.h"
|
||||
"xsocket.cpp")
|
||||
|
||||
IF (WIN32)
|
||||
# set stuff for windows
|
||||
target_link_libraries(cross_sockets wsock32 ws2_32)
|
||||
ELSE()
|
||||
# set stuff for other systems
|
||||
target_link_libraries(cross_sockets)
|
||||
ENDIF()
|
88
common/cross_sockets/xsocket.cpp
Normal file
88
common/cross_sockets/xsocket.cpp
Normal file
|
@ -0,0 +1,88 @@
|
|||
#ifdef __linux
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <unistd.h>
|
||||
#elif _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <WinSock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int open_socket(int af, int type, int protocol) {
|
||||
#ifdef __linux
|
||||
return socket(af, type, protocol);
|
||||
#elif _WIN32
|
||||
WSADATA wsaData = {0};
|
||||
int iResult = 0;
|
||||
// Initialize Winsock
|
||||
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
if (iResult != 0) {
|
||||
printf("WSAStartup failed: %d\n", iResult);
|
||||
return 1;
|
||||
}
|
||||
return socket(af, type, protocol);
|
||||
#endif
|
||||
}
|
||||
|
||||
void close_socket(int sock) {
|
||||
if (sock < 0) {
|
||||
return;
|
||||
}
|
||||
#ifdef __linux
|
||||
close(sock);
|
||||
#elif _WIN32
|
||||
closesocket(sock);
|
||||
WSACleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
int set_socket_option(int socket, int level, int optname, const void* optval, int optlen) {
|
||||
int ret = setsockopt(socket, level, optname, (char*)&optval, optlen);
|
||||
if (ret < 0) {
|
||||
printf("Failed to setsockopt(%d, %d, %d, _, _) - Error: %s\n", socket, level, optname,
|
||||
strerror(errno));
|
||||
}
|
||||
#ifdef _WIN32
|
||||
if (ret < 0) {
|
||||
int err = WSAGetLastError();
|
||||
printf("WSAGetLastError: %d\n", err);
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
int set_socket_timeout(int socket, long microSeconds) {
|
||||
#ifdef __linux
|
||||
struct timeval timeout = {};
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = microSeconds;
|
||||
int ret = setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (struct timeval*)&timeout, sizeof(timeout));
|
||||
if (ret < 0) {
|
||||
printf("Failed to setsockopt(%d, %d, %d, _, _) - Error: %s\n", socket, SOL_SOCKET, SO_RCVTIMEO,
|
||||
strerror(errno));
|
||||
}
|
||||
return ret;
|
||||
#elif _WIN32
|
||||
unsigned long timeout = microSeconds / 1000; // milliseconds
|
||||
return set_socket_option(socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
|
||||
#endif
|
||||
}
|
||||
|
||||
int write_to_socket(int socket, const char* buf, int len) {
|
||||
#ifdef __linux
|
||||
return write(socket, buf, len);
|
||||
#elif _WIN32
|
||||
return send(socket, buf, len, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
int read_from_socket(int socket, char* buf, int len) {
|
||||
#ifdef __linux
|
||||
return read(socket, buf, len);
|
||||
#elif _WIN32
|
||||
return recv(socket, buf, len, 0);
|
||||
#endif
|
||||
}
|
20
common/cross_sockets/xsocket.h
Normal file
20
common/cross_sockets/xsocket.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifdef __linux
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <unistd.h>
|
||||
#elif _WIN32
|
||||
#include <WinSock2.h>
|
||||
#endif
|
||||
|
||||
#ifdef __linux
|
||||
const int TCP_SOCKET_LEVEL = SOL_TCP;
|
||||
#elif _WIN32
|
||||
const int TCP_SOCKET_LEVEL = IPPROTO_TCP;
|
||||
#endif
|
||||
|
||||
int open_socket(int af, int type, int protocol);
|
||||
void close_socket(int sock);
|
||||
int set_socket_option(int socket, int level, int optname, const void* optval, int optlen);
|
||||
int set_socket_timeout(int socket, long microSeconds);
|
||||
int write_to_socket(int socket, const char* buf, int len);
|
||||
int read_from_socket(int socket, char* buf, int len);
|
|
@ -76,11 +76,10 @@ add_executable(gk ${RUNTIME_SOURCE} main.cpp)
|
|||
# can be used to test other things.
|
||||
add_library(runtime ${RUNTIME_SOURCE})
|
||||
|
||||
|
||||
IF (WIN32)
|
||||
# set stuff for windows
|
||||
target_link_libraries(gk mman)
|
||||
target_link_libraries(gk cross_sockets mman)
|
||||
ELSE()
|
||||
# set stuff for other systems
|
||||
target_link_libraries(gk pthread)
|
||||
target_link_libraries(gk cross_sockets pthread)
|
||||
ENDIF()
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
*/
|
||||
|
||||
#include <cstring>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "game/sce/libscf.h"
|
||||
#include "kboot.h"
|
||||
|
@ -152,21 +155,14 @@ void KernelCheckAndDispatch() {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
ClearPending();
|
||||
#endif
|
||||
|
||||
// if the listener function changed, it means the kernel ran it, so we should notify compiler.
|
||||
if (MasterDebug && ListenerFunction->value != old_listener) {
|
||||
SendAck();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
Sleep(1000); // todo - remove this
|
||||
#elif __linux__
|
||||
usleep(1000);
|
||||
#endif
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(1000));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,8 +27,6 @@ void kdsnetm_init_globals() {
|
|||
protoBlock.reset();
|
||||
}
|
||||
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
/*!
|
||||
* Register GOAL DECI2 Protocol Driver with DECI2 service
|
||||
* DONE, EXACT
|
||||
|
@ -222,4 +220,3 @@ void GoalProtoStatus() {
|
|||
Msg(6, "gproto: got %d %d\n", protoBlock.most_recent_event, protoBlock.most_recent_param);
|
||||
Msg(6, "gproto: %d %d\n", protoBlock.last_receive_size, protoBlock.send_remaining);
|
||||
}
|
||||
#endif
|
|
@ -51,8 +51,6 @@ extern GoalProtoBlock protoBlock;
|
|||
*/
|
||||
void kdsnetm_init_globals();
|
||||
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
/*!
|
||||
* Register GOAL DECI2 Protocol Driver with DECI2 service
|
||||
* DONE, EXACT
|
||||
|
@ -65,8 +63,6 @@ void InitGoalProto();
|
|||
*/
|
||||
void ShutdownGoalProto();
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Handle a DECI2 Protocol Event for the GOAL Proto.
|
||||
* Called by the DECI2 Protocol driver
|
||||
|
@ -74,8 +70,6 @@ void ShutdownGoalProto();
|
|||
*/
|
||||
void GoalProtoHandler(int event, int param, void* data);
|
||||
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
/*!
|
||||
* Low level DECI2 send
|
||||
* Will block until send is complete.
|
||||
|
@ -83,7 +77,6 @@ void GoalProtoHandler(int event, int param, void* data);
|
|||
* removed
|
||||
*/
|
||||
s32 SendFromBufferD(s32 p1, u64 p2, char* data, s32 size);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Print GOAL Protocol status
|
||||
|
|
|
@ -71,10 +71,7 @@ void ClearPending() {
|
|||
Ptr<char> msg = OutputBufArea.cast<char>() + sizeof(GoalMessageHeader);
|
||||
auto size = strlen(msg.c());
|
||||
// note - if size is ever greater than 2^16 this will cause an issue.
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
SendFromBuffer(msg.c(), size);
|
||||
#endif
|
||||
clear_output();
|
||||
}
|
||||
|
||||
|
@ -87,10 +84,7 @@ void ClearPending() {
|
|||
if (send_size > 64000) {
|
||||
send_size = 64000;
|
||||
}
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
SendFromBufferD(2, 0, msg, send_size);
|
||||
#endif
|
||||
size -= send_size;
|
||||
msg += send_size;
|
||||
}
|
||||
|
@ -109,11 +103,9 @@ void ClearPending() {
|
|||
*/
|
||||
void SendAck() {
|
||||
if (MasterDebug) {
|
||||
#ifdef __linux__
|
||||
SendFromBufferD(u16(ListenerMessageKind::MSG_ACK), protoBlock.msg_id,
|
||||
AckBufArea + sizeof(GoalMessageHeader),
|
||||
strlen(AckBufArea + sizeof(GoalMessageHeader)));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,4 +156,4 @@ void ProcessListenerMessage(Ptr<char> msg) {
|
|||
break;
|
||||
}
|
||||
SendAck();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -329,10 +329,7 @@ int InitMachine() {
|
|||
// }
|
||||
|
||||
if (MasterDebug) { // connect to GOAL compiler
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
InitGoalProto();
|
||||
#endif
|
||||
}
|
||||
|
||||
printf("InitSound\n");
|
||||
|
@ -362,10 +359,7 @@ int ShutdownMachine() {
|
|||
StopIOP();
|
||||
CloseListener();
|
||||
ShutdownSound();
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
ShutdownGoalProto();
|
||||
#endif
|
||||
Msg(6, "kernel: machine shutdown");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -52,8 +52,6 @@ u32 ReceiveToBuffer(char* buff) {
|
|||
return msg_size;
|
||||
}
|
||||
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
/*!
|
||||
* Do a DECI2 send and block until it is complete.
|
||||
* The message type is OUTPUT
|
||||
|
@ -62,7 +60,6 @@ u32 ReceiveToBuffer(char* buff) {
|
|||
s32 SendFromBuffer(char* buff, s32 size) {
|
||||
return SendFromBufferD(u16(ListenerMessageKind::MSG_OUTPUT), 0, buff, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Just prepare the Ack buffer, doesn't actually connect.
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
|
||||
#include "runtime.h"
|
||||
#include "system/SystemThread.h"
|
||||
|
@ -45,11 +47,6 @@
|
|||
|
||||
u8* g_ee_main_mem = nullptr;
|
||||
|
||||
/*!
|
||||
* TODO-WINDOWS
|
||||
* runtime.cpp - Deci2Listener has been disabled for now, pending rewriting for Windows.
|
||||
*/
|
||||
|
||||
namespace {
|
||||
|
||||
/*!
|
||||
|
@ -57,8 +54,6 @@ namespace {
|
|||
*/
|
||||
|
||||
void deci2_runner(SystemThreadInterface& iface) {
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
// callback function so the server knows when to give up and shutdown
|
||||
std::function<bool()> shutdown_callback = [&]() { return iface.get_want_exit(); };
|
||||
|
||||
|
@ -89,10 +84,9 @@ void deci2_runner(SystemThreadInterface& iface) {
|
|||
server.run();
|
||||
} else {
|
||||
// no connection yet. Do a sleep so we don't spam checking the listener.
|
||||
usleep(50000);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(50000));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// EE System
|
||||
|
@ -236,10 +230,7 @@ u32 exec_runtime(int argc, char** argv) {
|
|||
// step 1: sce library prep
|
||||
iop::LIBRARY_INIT();
|
||||
ee::LIBRARY_INIT_sceCd();
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
ee::LIBRARY_INIT_sceDeci2();
|
||||
#endif
|
||||
ee::LIBRARY_INIT_sceSif();
|
||||
|
||||
// step 2: system prep
|
||||
|
|
|
@ -12,14 +12,11 @@
|
|||
namespace ee {
|
||||
|
||||
namespace {
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
constexpr int MAX_DECI2_PROTOCOLS = 4;
|
||||
Deci2Driver protocols[MAX_DECI2_PROTOCOLS]; // info for each deci2 protocol registered
|
||||
int protocol_count; // number of registered protocols
|
||||
Deci2Driver* sending_driver; // currently sending protocol driver
|
||||
::Deci2Server* server; // the server to send data to
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -27,8 +24,6 @@ Deci2Driver* sending_driver; // currently sending protocol drive
|
|||
* Initialize the library.
|
||||
*/
|
||||
void LIBRARY_INIT_sceDeci2() {
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
// reset protocols
|
||||
for (auto& p : protocols) {
|
||||
p = Deci2Driver();
|
||||
|
@ -36,15 +31,12 @@ void LIBRARY_INIT_sceDeci2() {
|
|||
protocol_count = 0;
|
||||
server = nullptr;
|
||||
sending_driver = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* Run any pending requested sends.
|
||||
*/
|
||||
void LIBRARY_sceDeci2_run_sends() {
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
for (auto& prot : protocols) {
|
||||
if (prot.active && prot.pending_send == 'H') {
|
||||
sending_driver = &prot;
|
||||
|
@ -54,17 +46,13 @@ void LIBRARY_sceDeci2_run_sends() {
|
|||
(prot.handler)(DECI2_WRITEDONE, 0, prot.opt);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* Register a Deci2Server with this library.
|
||||
*/
|
||||
void LIBRARY_sceDeci2_register(::Deci2Server* s) {
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
server = s;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -73,8 +61,6 @@ void LIBRARY_sceDeci2_register(::Deci2Server* s) {
|
|||
* I don't know why it's like this.
|
||||
*/
|
||||
s32 sceDeci2Open(u16 protocol, void* opt, void (*handler)(s32 event, s32 param, void* opt)) {
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
server->lock();
|
||||
Deci2Driver drv;
|
||||
drv.protocol = protocol;
|
||||
|
@ -93,20 +79,14 @@ s32 sceDeci2Open(u16 protocol, void* opt, void (*handler)(s32 event, s32 param,
|
|||
}
|
||||
|
||||
return drv.id;
|
||||
#elif _WIN32
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* Deactivate a DECI2 protocol by socket descriptor.
|
||||
*/
|
||||
s32 sceDeci2Close(s32 s) {
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
assert(s - 1 < protocol_count);
|
||||
protocols[s - 1].active = false;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -114,12 +94,9 @@ s32 sceDeci2Close(s32 s) {
|
|||
* Start a send.
|
||||
*/
|
||||
s32 sceDeci2ReqSend(s32 s, char dest) {
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
assert(s - 1 < protocol_count);
|
||||
auto& proto = protocols[s - 1];
|
||||
proto.pending_send = dest;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -128,8 +105,6 @@ s32 sceDeci2ReqSend(s32 s, char dest) {
|
|||
* Returns after data is copied.
|
||||
*/
|
||||
s32 sceDeci2ExRecv(s32 s, void* buf, u16 len) {
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
assert(s - 1 < protocol_count);
|
||||
protocols[s - 1].recv_size = len;
|
||||
auto avail = protocols[s - 1].available_to_receive;
|
||||
|
@ -140,17 +115,12 @@ s32 sceDeci2ExRecv(s32 s, void* buf, u16 len) {
|
|||
printf("[DECI2] Error: ExRecv %d, only %d available!\n", len, avail);
|
||||
return -1;
|
||||
}
|
||||
#elif _WIN32
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* Do a send.
|
||||
*/
|
||||
s32 sceDeci2ExSend(s32 s, void* buf, u16 len) {
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
assert(s - 1 < protocol_count);
|
||||
if (!sending_driver) {
|
||||
printf("sceDeci2ExSend called at illegal time!\n");
|
||||
|
@ -162,8 +132,5 @@ s32 sceDeci2ExSend(s32 s, void* buf, u16 len) {
|
|||
|
||||
server->send_data(buf, len);
|
||||
return len;
|
||||
#elif _WIN32
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
} // namespace ee
|
||||
|
|
|
@ -4,15 +4,22 @@
|
|||
* Works with deci2.cpp (sceDeci2) to implement the networking on target
|
||||
*/
|
||||
|
||||
// TODO-WINDOWS
|
||||
#ifdef __linux__
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
|
||||
// TODO - i think im not including the dependency right..?
|
||||
#include "common/cross_sockets/xsocket.h"
|
||||
|
||||
#ifdef __linux
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <unistd.h>
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
#elif _WIN32
|
||||
#include <Windows.h>
|
||||
#include <WinSock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
#endif
|
||||
|
||||
#include "common/listener_common.h"
|
||||
#include "common/versions.h"
|
||||
|
@ -33,67 +40,58 @@ Deci2Server::~Deci2Server() {
|
|||
|
||||
delete[] buffer;
|
||||
|
||||
if (server_fd >= 0) {
|
||||
close(server_fd);
|
||||
}
|
||||
|
||||
if (new_sock >= 0) {
|
||||
close(new_sock);
|
||||
}
|
||||
close_server_socket();
|
||||
close_socket(new_sock);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Start waiting for the Listener to connect
|
||||
*/
|
||||
bool Deci2Server::init() {
|
||||
server_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (server_fd < 0) {
|
||||
server_fd = -1;
|
||||
server_socket = open_socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (server_socket < 0) {
|
||||
server_socket = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef __linux
|
||||
int server_socket_opt = SO_REUSEADDR | SO_REUSEPORT;
|
||||
#elif _WIN32
|
||||
int server_socket_opt = SO_EXCLUSIVEADDRUSE;
|
||||
#endif
|
||||
|
||||
int opt = 1;
|
||||
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
|
||||
printf("[Deci2Server] Failed to setsockopt 1\n");
|
||||
close(server_fd);
|
||||
server_fd = -1;
|
||||
if (set_socket_option(server_socket, SOL_SOCKET, server_socket_opt, &opt, sizeof(opt)) < 0) {
|
||||
close_server_socket();
|
||||
return false;
|
||||
}
|
||||
printf("[Deci2Server] Created Socket Options\n");
|
||||
|
||||
int one = 1;
|
||||
if (setsockopt(server_fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one))) {
|
||||
printf("[Deci2Server] Failed to setsockopt 2\n");
|
||||
close(server_fd);
|
||||
server_fd = -1;
|
||||
if (set_socket_option(server_socket, TCP_SOCKET_LEVEL, TCP_NODELAY, &opt, sizeof(opt)) < 0) {
|
||||
close_server_socket();
|
||||
return false;
|
||||
}
|
||||
printf("[Deci2Server] Created TCP Socket Options\n");
|
||||
|
||||
timeval timeout = {};
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 100000;
|
||||
|
||||
if (setsockopt(server_fd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) < 0) {
|
||||
printf("[Deci2Server] Failed to setsockopt 3\n");
|
||||
close(server_fd);
|
||||
server_fd = -1;
|
||||
if (set_socket_timeout(server_socket, 100000) < 0) {
|
||||
close_server_socket();
|
||||
return false;
|
||||
}
|
||||
printf("[Deci2Server] Created Socket Timeout\n");
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
addr.sin_port = htons(DECI2_PORT);
|
||||
|
||||
if (bind(server_fd, (sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||
if (bind(server_socket, (sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||
printf("[Deci2Server] Failed to bind\n");
|
||||
close(server_fd);
|
||||
server_fd = -1;
|
||||
close_server_socket();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (listen(server_fd, 0) < 0) {
|
||||
if (listen(server_socket, 0) < 0) {
|
||||
printf("[Deci2Server] Failed to listen\n");
|
||||
close(server_fd);
|
||||
server_fd = -1;
|
||||
close_server_socket();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -104,6 +102,11 @@ bool Deci2Server::init() {
|
|||
return true;
|
||||
}
|
||||
|
||||
void Deci2Server::close_server_socket() {
|
||||
close_socket(server_socket);
|
||||
server_socket = -1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Return true if the listener is connected.
|
||||
*/
|
||||
|
@ -129,7 +132,7 @@ void Deci2Server::send_data(void* buf, u16 len) {
|
|||
} else {
|
||||
uint16_t prog = 0;
|
||||
while (prog < len) {
|
||||
auto wrote = write(new_sock, (char*)(buf) + prog, len - prog);
|
||||
int wrote = write_to_socket(new_sock, (char*)(buf) + prog, len - prog);
|
||||
prog += wrote;
|
||||
if (!server_connected || want_exit()) {
|
||||
unlock();
|
||||
|
@ -186,7 +189,7 @@ void Deci2Server::run() {
|
|||
|
||||
while (got < desired_size) {
|
||||
assert(got + desired_size < BUFFER_SIZE);
|
||||
auto x = read(new_sock, buffer + got, desired_size - got);
|
||||
auto x = read_from_socket(new_sock, buffer + got, desired_size - got);
|
||||
if (want_exit()) {
|
||||
return;
|
||||
}
|
||||
|
@ -237,7 +240,7 @@ void Deci2Server::run() {
|
|||
|
||||
// receive from network
|
||||
if (hdr->rsvd < hdr->len) {
|
||||
auto x = read(new_sock, buffer + hdr->rsvd, hdr->len - hdr->rsvd);
|
||||
auto x = read_from_socket(new_sock, buffer + hdr->rsvd, hdr->len - hdr->rsvd);
|
||||
if (want_exit()) {
|
||||
return;
|
||||
}
|
||||
|
@ -256,13 +259,14 @@ void Deci2Server::run() {
|
|||
void Deci2Server::accept_thread_func() {
|
||||
socklen_t l = sizeof(addr);
|
||||
while (!kill_accept_thread) {
|
||||
new_sock = accept(server_fd, (sockaddr*)&addr, &l);
|
||||
// TODO - might want to do a WSAStartUp call here as well, else it won't be balanced on the
|
||||
// close
|
||||
new_sock = accept(server_socket, (sockaddr*)&addr, &l);
|
||||
if (new_sock >= 0) {
|
||||
u32 versions[2] = {versions::GOAL_VERSION_MAJOR, versions::GOAL_VERSION_MINOR};
|
||||
send(new_sock, &versions, 8, 0); // todo, check result?
|
||||
write_to_socket(new_sock, (char*)&versions, 8); // todo, check result?
|
||||
server_connected = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -4,11 +4,14 @@
|
|||
* Works with deci2.cpp (sceDeci2) to implement the networking on target
|
||||
*/
|
||||
|
||||
#ifdef __linux__
|
||||
#ifndef JAK1_DECI2SERVER_H
|
||||
#define JAK1_DECI2SERVER_H
|
||||
|
||||
#ifdef __linux
|
||||
#include <netinet/in.h>
|
||||
#elif _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
@ -32,11 +35,12 @@ class Deci2Server {
|
|||
void run();
|
||||
|
||||
private:
|
||||
void close_server_socket();
|
||||
void accept_thread_func();
|
||||
bool kill_accept_thread = false;
|
||||
char* buffer = nullptr;
|
||||
int server_fd = -1;
|
||||
sockaddr_in addr;
|
||||
int server_socket = -1;
|
||||
struct sockaddr_in addr = {};
|
||||
int new_sock = -1;
|
||||
bool server_initialized = false;
|
||||
bool accept_thread_running = false;
|
||||
|
@ -52,4 +56,3 @@ class Deci2Server {
|
|||
};
|
||||
|
||||
#endif // JAK1_DECI2SERVER_H
|
||||
#endif
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
add_subdirectory(util)
|
||||
add_subdirectory(goos)
|
||||
|
||||
IF (WIN32)
|
||||
# TODO - implement windows listener
|
||||
message("Windows Listener Not Implemented!")
|
||||
ELSE ()
|
||||
add_subdirectory(listener)
|
||||
ENDIF ()
|
||||
add_subdirectory(listener)
|
||||
|
||||
add_library(compiler
|
||||
SHARED
|
||||
|
@ -29,15 +23,12 @@ add_library(compiler
|
|||
regalloc/IRegister.cpp
|
||||
regalloc/Allocator.cpp
|
||||
regalloc/allocate.cpp
|
||||
compiler/Compiler.cpp
|
||||
)
|
||||
compiler/Compiler.cpp)
|
||||
|
||||
add_executable(goalc main.cpp
|
||||
)
|
||||
add_executable(goalc main.cpp)
|
||||
|
||||
IF (WIN32)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
target_link_libraries(compiler util goos type_system mman)
|
||||
target_link_libraries(compiler util goos type_system listener mman)
|
||||
|
||||
ELSE ()
|
||||
target_link_libraries(compiler util goos type_system listener)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
add_library(listener SHARED
|
||||
Listener.cpp)
|
||||
add_library(listener SHARED Listener.cpp)
|
||||
|
||||
IF (WIN32)
|
||||
#
|
||||
target_link_libraries(listener cross_sockets)
|
||||
ELSE ()
|
||||
target_link_libraries(listener pthread)
|
||||
target_link_libraries(listener cross_sockets pthread)
|
||||
ENDIF ()
|
|
@ -5,15 +5,25 @@
|
|||
* TODO - msg ID?
|
||||
*/
|
||||
|
||||
// TODO-Windows
|
||||
#ifdef __linux__
|
||||
|
||||
#include <stdexcept>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#elif _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <WinSock2.h>
|
||||
#include <WS2tcpip.h>
|
||||
#endif
|
||||
|
||||
// TODO - i think im not including the dependency right..?
|
||||
#include "common/cross_sockets/xsocket.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include "Listener.h"
|
||||
#include "common/versions.h"
|
||||
|
||||
|
@ -30,8 +40,8 @@ Listener::~Listener() {
|
|||
disconnect();
|
||||
|
||||
delete[] m_buffer;
|
||||
if (socket_fd >= 0) {
|
||||
close(socket_fd);
|
||||
if (listen_socket >= 0) {
|
||||
close_socket(listen_socket);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,35 +67,29 @@ bool Listener::connect_to_target(int n_tries, const std::string& ip, int port) {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (socket_fd >= 0) {
|
||||
close(socket_fd);
|
||||
if (listen_socket >= 0) {
|
||||
close_socket(listen_socket);
|
||||
}
|
||||
|
||||
// construct socket
|
||||
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (socket_fd < 0) {
|
||||
listen_socket = open_socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (listen_socket < 0) {
|
||||
printf("[Listener] Failed to create socket.\n");
|
||||
socket_fd = -1;
|
||||
listen_socket = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// set timeout for receive
|
||||
timeval timeout = {};
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 100000;
|
||||
if (setsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) < 0) {
|
||||
printf("[Listener] setsockopt failed\n");
|
||||
close(socket_fd);
|
||||
socket_fd = -1;
|
||||
if (set_socket_timeout(listen_socket, 100000) < 0) {
|
||||
close_socket(listen_socket);
|
||||
listen_socket = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// set nodelay, which makes small rapid messages faster, but large messages slower
|
||||
int one = 1;
|
||||
if (setsockopt(socket_fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one))) {
|
||||
printf("[Listener] failed to TCP_NODELAY\n");
|
||||
close(socket_fd);
|
||||
socket_fd = -1;
|
||||
if (set_socket_option(listen_socket, TCP_SOCKET_LEVEL, TCP_NODELAY, &one, sizeof(one))) {
|
||||
close_socket(listen_socket);
|
||||
listen_socket = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -95,24 +99,24 @@ bool Listener::connect_to_target(int n_tries, const std::string& ip, int port) {
|
|||
server_address.sin_port = htons(port);
|
||||
if (inet_pton(AF_INET, ip.c_str(), &server_address.sin_addr) <= 0) {
|
||||
printf("[Listener] Invalid IP address.\n");
|
||||
close(socket_fd);
|
||||
socket_fd = -1;
|
||||
close_socket(listen_socket);
|
||||
listen_socket = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// connect!
|
||||
int rv, i;
|
||||
for (i = 0; i < n_tries; i++) {
|
||||
rv = connect(socket_fd, (sockaddr*)&server_address, sizeof(server_address));
|
||||
rv = connect(listen_socket, (sockaddr*)&server_address, sizeof(server_address));
|
||||
if (rv >= 0) {
|
||||
break;
|
||||
}
|
||||
usleep(100000);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(100000));
|
||||
}
|
||||
if (rv < 0) {
|
||||
printf("[Listener] Failed to connect\n");
|
||||
close(socket_fd);
|
||||
socket_fd = -1;
|
||||
close_socket(listen_socket);
|
||||
listen_socket = -1;
|
||||
return false;
|
||||
} else {
|
||||
printf("[Listener] Socket connected established! (took %d tries)\n", i);
|
||||
|
@ -124,7 +128,7 @@ bool Listener::connect_to_target(int n_tries, const std::string& ip, int port) {
|
|||
int prog = 0;
|
||||
bool ok = true;
|
||||
while (prog < 8) {
|
||||
auto r = read(socket_fd, version_buffer + prog, 8 - prog);
|
||||
auto r = read_from_socket(listen_socket, (char*)version_buffer + prog, 8 - prog);
|
||||
if (r < 0) {
|
||||
ok = false;
|
||||
break;
|
||||
|
@ -138,8 +142,8 @@ bool Listener::connect_to_target(int n_tries, const std::string& ip, int port) {
|
|||
}
|
||||
if (!ok) {
|
||||
printf("[Listener] Failed to get version number\n");
|
||||
close(socket_fd);
|
||||
socket_fd = -1;
|
||||
close_socket(listen_socket);
|
||||
listen_socket = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -152,8 +156,8 @@ bool Listener::connect_to_target(int n_tries, const std::string& ip, int port) {
|
|||
return true;
|
||||
} else {
|
||||
printf(", expected %d.%d. Cannot connect.\n", GOAL_VERSION_MAJOR, GOAL_VERSION_MINOR);
|
||||
close(socket_fd);
|
||||
socket_fd = -1;
|
||||
close_socket(listen_socket);
|
||||
listen_socket = -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +173,7 @@ void Listener::receive_func() {
|
|||
int rcvd_desired = sizeof(ListenerMessageHeader);
|
||||
char buff[sizeof(ListenerMessageHeader)];
|
||||
while (rcvd < rcvd_desired) {
|
||||
auto got = read(socket_fd, buff + rcvd, rcvd_desired - rcvd);
|
||||
auto got = read_from_socket(listen_socket, buff + rcvd, rcvd_desired - rcvd);
|
||||
rcvd += got > 0 ? got : 0;
|
||||
|
||||
// kick us out if we got a bogus read result
|
||||
|
@ -202,7 +206,8 @@ void Listener::receive_func() {
|
|||
while (rcvd < hdr->deci2_header.len) {
|
||||
if (!m_connected)
|
||||
return;
|
||||
int got = read(socket_fd, ack_recv_buff + ack_recv_prog, hdr->deci2_header.len - rcvd);
|
||||
int got = read_from_socket(listen_socket, ack_recv_buff + ack_recv_prog,
|
||||
hdr->deci2_header.len - rcvd);
|
||||
got = got > 0 ? got : 0;
|
||||
rcvd += got;
|
||||
ack_recv_prog += got;
|
||||
|
@ -224,7 +229,8 @@ void Listener::receive_func() {
|
|||
return;
|
||||
}
|
||||
|
||||
int got = read(socket_fd, str_buff + msg_prog, hdr->deci2_header.len - rcvd);
|
||||
int got =
|
||||
read_from_socket(listen_socket, str_buff + msg_prog, hdr->deci2_header.len - rcvd);
|
||||
got = got > 0 ? got : 0;
|
||||
rcvd += got;
|
||||
msg_prog += got;
|
||||
|
@ -309,7 +315,7 @@ void Listener::send_reset(bool shutdown) {
|
|||
header->u8 = shutdown ? UINT64_MAX : 0;
|
||||
send_buffer(sizeof(ListenerMessageHeader));
|
||||
disconnect();
|
||||
close(socket_fd);
|
||||
close_socket(listen_socket);
|
||||
printf("closed connection to target\n");
|
||||
}
|
||||
|
||||
|
@ -342,7 +348,7 @@ void Listener::send_buffer(int sz) {
|
|||
waiting_for_ack = true;
|
||||
while (wrote < sz) {
|
||||
auto to_send = std::min(512, sz - wrote);
|
||||
auto x = write(socket_fd, m_buffer + wrote, to_send);
|
||||
auto x = write_to_socket(listen_socket, m_buffer + wrote, to_send);
|
||||
wrote += x;
|
||||
}
|
||||
|
||||
|
@ -378,4 +384,3 @@ bool Listener::wait_for_ack() {
|
|||
}
|
||||
|
||||
} // namespace listener
|
||||
#endif
|
||||
|
|
|
@ -38,7 +38,7 @@ class Listener {
|
|||
char* m_buffer = nullptr; //! buffer for incoming messages
|
||||
bool m_connected = false; //! do we think we are connected?
|
||||
bool receive_thread_running = false; //! is the receive thread unjoined?
|
||||
int socket_fd = -1; //! socket
|
||||
int listen_socket = -1; //! socket
|
||||
bool got_ack = false;
|
||||
bool waiting_for_ack = false;
|
||||
|
||||
|
|
|
@ -19,9 +19,8 @@ add_executable(goalc-test
|
|||
|
||||
IF (WIN32)
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
# TODO - implement windows listener
|
||||
message("Windows Listener Not Implemented!")
|
||||
target_link_libraries(goalc-test mman goos util runtime compiler type_system gtest)
|
||||
# TODO - split out these declarations for platform specific includes
|
||||
target_link_libraries(goalc-test cross_sockets listener mman goos util runtime compiler type_system gtest)
|
||||
ELSE()
|
||||
target_link_libraries(goalc-test goos util listener runtime compiler type_system gtest)
|
||||
target_link_libraries(goalc-test cross_sockets goos util listener runtime compiler type_system gtest)
|
||||
ENDIF()
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#ifdef __linux__
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "goalc/listener/Listener.h"
|
||||
#include "game/system/Deci2Server.h"
|
||||
|
@ -25,12 +23,6 @@ TEST(Listener, DeciInit) {
|
|||
EXPECT_TRUE(s.init());
|
||||
}
|
||||
|
||||
// TEST(Listener, TwoDeciServers) {
|
||||
// Deci2Server s1, s2;
|
||||
// EXPECT_TRUE(s1.init());
|
||||
// EXPECT_TRUE(s2.init());
|
||||
//}
|
||||
|
||||
/*!
|
||||
* Try to connect when no Deci2Server is running
|
||||
*/
|
||||
|
@ -63,10 +55,10 @@ TEST(Listener, DeciThenListener) {
|
|||
Listener l;
|
||||
EXPECT_FALSE(s.check_for_listener());
|
||||
EXPECT_FALSE(s.check_for_listener());
|
||||
EXPECT_TRUE(l.connect_to_target());
|
||||
// kind of a hack.
|
||||
while (!s.check_for_listener()) {
|
||||
// printf("...\n");
|
||||
bool connected = l.connect_to_target();
|
||||
EXPECT_TRUE(connected);
|
||||
// TODO - some sort of backoff and retry would be better
|
||||
while (connected && !s.check_for_listener()) {
|
||||
}
|
||||
|
||||
EXPECT_TRUE(s.check_for_listener());
|
||||
|
@ -94,37 +86,10 @@ TEST(Listener, ListenerThenDeci) {
|
|||
Deci2Server s(always_false);
|
||||
EXPECT_TRUE(s.init());
|
||||
EXPECT_FALSE(s.check_for_listener());
|
||||
EXPECT_TRUE(l.connect_to_target());
|
||||
while (!s.check_for_listener()) {
|
||||
// printf("...\n");
|
||||
bool connected = l.connect_to_target();
|
||||
EXPECT_TRUE(connected);
|
||||
// TODO - some sort of backoff and retry would be better
|
||||
while (connected && !s.check_for_listener()) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Listener, ListenerMultipleDecis) {
|
||||
Listener l;
|
||||
EXPECT_FALSE(l.connect_to_target());
|
||||
{
|
||||
Deci2Server s(always_false);
|
||||
EXPECT_TRUE(s.init());
|
||||
EXPECT_FALSE(s.check_for_listener());
|
||||
EXPECT_TRUE(l.connect_to_target());
|
||||
while (!s.check_for_listener()) {
|
||||
// printf("...\n");
|
||||
}
|
||||
l.disconnect();
|
||||
}
|
||||
|
||||
{
|
||||
Deci2Server s(always_false);
|
||||
EXPECT_TRUE(s.init());
|
||||
EXPECT_FALSE(s.check_for_listener());
|
||||
EXPECT_TRUE(l.connect_to_target());
|
||||
while (!s.check_for_listener()) {
|
||||
// printf("...\n");
|
||||
}
|
||||
l.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue