diff options
| author | fusion32 <marcopuzziello@gmail.com> | 2025-07-19 11:35:11 -0300 |
|---|---|---|
| committer | fusion32 <marcopuzziello@gmail.com> | 2025-07-19 11:35:11 -0300 |
| commit | d359c0af4874534efa810729d47f610a29687e93 (patch) | |
| tree | 9a89b06444819e7e5cef84aa826682b3b01bfd03 /src/connections.cc | |
| parent | 638244fd078fe91971e57b1d06e4499268d99c42 (diff) | |
| download | game-d359c0af4874534efa810729d47f610a29687e93.tar.gz game-d359c0af4874534efa810729d47f610a29687e93.zip | |
THREADING: upgrade from LinuxThreads to NPTL
This was a required change to make the server run on a modern
GLIBC version without resorting to shady shared libraries or
compatibility tricks. It is very straightforward but we should
always keep an eye out for possible bugs.
There was also a problem with the Z loop on field sending
functions that was causing the server to hang in an infinite
loop and should now be fixed.
With these changes it is now possible to login into the game
for a split second before the client asserting.
Diffstat (limited to 'src/connections.cc')
| -rw-r--r-- | src/connections.cc | 62 |
1 files changed, 57 insertions, 5 deletions
diff --git a/src/connections.cc b/src/connections.cc index cef9fa6..84daec6 100644 --- a/src/connections.cc +++ b/src/connections.cc @@ -79,13 +79,64 @@ void TConnection::EmergencyPing(void){ } } -pid_t TConnection::GetPID(void){ +pid_t TConnection::GetThreadID(void){ if(this->State == CONNECTION_FREE){ - error("TConnection::GetPID: Verbindung ist nicht zugewiesen.\n"); + error("TConnection::GetThreadID: Verbindung ist nicht zugewiesen.\n"); return 0; } - return this->PID; + return this->ThreadID; +} + +bool TConnection::SetLoginTimer(int Timeout){ + if(this->State == CONNECTION_FREE){ + error("TConnection::SetLoginTimer: Verbindung ist nicht zugewiesen.\n"); + return false; + } + + if(this->LoginTimer != 0){ + error("TConnection::SetLoginTimer: Timer already set.\n"); + return false; + } + + struct sigevent SigEvent = {}; + SigEvent.sigev_notify = SIGEV_THREAD_ID; + SigEvent.sigev_signo = SIGALRM; + SigEvent.sigev_notify_thread_id = this->ThreadID; + if(timer_create(CLOCK_MONOTONIC, &SigEvent, &this->LoginTimer) == -1){ + error("TConnection::SetLoginTimer: Failed to create timer: (%d) %s\n", + errno, strerrordesc_np(errno)); + return false; + } + + struct itimerspec TimerSpec = {}; + TimerSpec.it_value.tv_sec = Timeout; + if(timer_settime(this->LoginTimer, 0, &TimerSpec, NULL) == -1){ + error("TConnection::SetLoginTimer: Failed to start timer: (%d) %s\n", + errno, strerrordesc_np(errno)); + return false; + } + + return true; +} + +void TConnection::StopLoginTimer(void){ + if(this->State == CONNECTION_FREE){ + error("TConnection::SetLoginTimer: Verbindung ist nicht zugewiesen.\n"); + return; + } + + if(this->LoginTimer == 0){ + error("TConnection::StopLoginTimer: Timer not set.\n"); + return; + } + + if(timer_delete(this->LoginTimer) == -1){ + error("TConnection::StopLoginTimer: Failed to delete timer: (%d) %s\n", + errno, strerrordesc_np(errno)); + } + + this->LoginTimer = 0; } int TConnection::GetSocket(void){ @@ -116,7 +167,8 @@ void TConnection::Assign(void){ } this->State = CONNECTION_ASSIGNED; - this->PID = getpid(); + this->ThreadID = gettid(); + this->LoginTimer = 0; } void TConnection::Connect(int Socket){ @@ -264,7 +316,7 @@ void TConnection::Disconnect(void){ this->ClearKnownCreatureTable(true); this->ConnectionIsOk = false; this->State = CONNECTION_DISCONNECTED; - kill(this->PID, SIGHUP); + tgkill(GetGameProcessID(), this->ThreadID, SIGHUP); } TPlayer *TConnection::GetPlayer(void){ |
