dunno Temat założony przez niniejszego użytkownika |
» 2022-10-03 19:15:05 Ok, dodałem i chyba w zbyt wielu miejscach dodałem bo lagowało serwer, ale już jest stabilnie. Tylko dalej nie wiem czy dodałem te locki w poprawnych miejscach. Jak to zrozumić ze np: w Game::creatureOnPrepareMagicAttack nie wymaga locka bool Game::creatureOnPrepareMagicAttack( Creature * creature, Position pos, const MagicEffectClass * me ) { if( !me->offensive || me->isIndirect() || creatureOnPrepareAttack( creature, pos ) ) { Player * player = dynamic_cast < Player * >( creature ); if( player ) { if( player->access < g_config.ACCESS_PROTECT ) { if( player->exhaustedTicks >= 1000 && me->causeExhaustion( true ) ) { if( me->offensive ) { player->sendTextMessage( MSG_SMALLINFO, "You are exhausted.", player->pos, NM_ME_PUFF ); player->exhaustedTicks += g_config.EXHAUSTED_ADD; } return false; } else if( player->mana < me->manaCost ) { player->sendTextMessage( MSG_SMALLINFO, "You do not have enough mana.", player->pos, NM_ME_PUFF ); return false; } else player->mana -=( int64_t ) me->manaCost; player->addManaSpent(( int64_t ) me->manaCost ); } } return true; } return false; }
a np. w creatureThrowRune bool Game::creatureThrowRune( Creature * creature, const Position & centerpos, const MagicEffectClass & me ) { OTSYS_THREAD_LOCK_CLASS lockClass( gameLock, "Game::creatureThrowRune()" ); bool ret = false; if( creature->pos.z != centerpos.z ) { creature->sendCancel( "You need to be on the same floor." ); } else if( map->canThrowObjectTo( creature->pos, centerpos, BLOCK_PROJECTILE ) != RET_NOERROR ) { creature->sendCancel( "You cannot throw there." ); } else ret = creatureMakeMagic( creature, centerpos, & me ); return ret; } juz wymaga locka. |
|
pekfos |
» 2022-10-03 23:31:42 Jak to zrozumić ze np: w Game::creatureOnPrepareMagicAttack nie wymaga locka Jedyne użycie creatureOnPrepareMagicAttack jest w creatureMakeMagic, gdzie lock już jest. a np. w creatureThrowRune juz wymaga locka. To że jest, nie znaczy że jest wymagany. Mógł być potrzebny w przeszłości, albo dodany bez powodu. Tylko dalej nie wiem czy dodałem te locki w poprawnych miejscach. A zidentyfikowałeś jakieś problemy, czy po prostu dodawałeś? |
|
dunno Temat założony przez niniejszego użytkownika |
» 2022-10-04 18:54:44 A zidentyfikowałeś jakieś problemy, czy po prostu dodawałeś? Wiem, że nie robie tego poprawnie - po prostu dodawałem. Gdy dodałem np. tu void Game::parseMove( Player * player, const Direction & dir ) { player->notAfk(); int64_t delay = player->getSleepTicks(); if( delay > 0 ) { player->sleepProtocol( delay ); } internalMovePlayer( player, dir ); }
bool Game::internalMovePlayer( Player * player, const Direction & dir ) { Position pos = player->pos; bool diagonalMove = changePosByDir( dir, pos ); if( diagonalMove ) { player->lastmove = OTSYS_TIME() + player->getStepDuration(); } else { player->lastmove = OTSYS_TIME(); } thingMove( player, player, pos.x, pos.y, pos.z, 1 ); return true; } co odpowiada za chodzenie gracza, to tak zawieszało gracza, ze w tych miejscach musiałem zakomentować. ale już np. w tej modzie void Game::addBlood( Creature * attackedCreature, Position & bloodPos, bool dead ) { #ifdef DODATKOWE_LOCKI OTSYS_THREAD_LOCK_CLASS lockClass( gameLock, "Game::addBlood()" ); #endif if( attackedCreature->bloodsplash != 255 ) { Player * attackedplayer = dynamic_cast < Player * >( attackedCreature ); Item * splash = Item::CreateItem( dead ? ITEM_POOL: ITEM_SPLASH, attackedCreature->bloodsplash ); addThing( NULL, bloodPos, splash ); startDecay( splash ); if( attackedplayer && dead ) attackedplayer->onThingAppear( splash ); updateTile( bloodPos ); } } zostawiłem locka (jak i w kilku innych). W ogóle zastanawia mnie dlaczego w parseMove i internalMovePlayer nie moze byc locka bo zamula gracza, przecież i tu może się zdarzyć że "dwa fragmenty kodu będą wykonywały się jednocześnie" gdy nie ma locka. Raczej to robie metodą prób i błędów. Wiem, że to prymitywne rozwiązywanie problemu, ale inaczej ciężko jest mi z tym sobie na ten moment poradzić. Gdy problem będzie się będzie powtarzał to skopiuje sobie core dumpa zeby mi sie nie nadpisal i wtedy wrzucę jakieś dodatkowe logi. |
|
pekfos |
» 2022-10-05 18:59:13 tak zawieszało gracza, ze w tych miejscach musiałem zakomentować. To nie jest bez kosztu wydajnościowego. Kompilujesz to z __DEBUG_CRITICALSECTION__? Te makro włącza logowanie każdego locka i sam mechanizm logowania nie jest bezpieczny. Dostęp do OTSYS_THREAD_LOCK_CLASS::loglist nie jest synchronizowany. W ogóle zastanawia mnie dlaczego w parseMove i internalMovePlayer nie moze byc locka bo zamula gracza, przecież i tu może się zdarzyć że "dwa fragmenty kodu będą wykonywały się jednocześnie" gdy nie ma locka. Nie mam w kodzie takich nazw, ale jakby faktycznie tak się mogło zdarzyć, to by znaczyło że jednak znalazłeś jakieś problemy. |
|
dunno Temat założony przez niniejszego użytkownika |
» 2022-10-05 19:52:05 To nie jest bez kosztu wydajnościowego. Kompilujesz to z __DEBUG_CRITICALSECTION__? Te makro włącza logowanie każdego locka i sam mechanizm logowania nie jest bezpieczny. Dostęp do OTSYS_THREAD_LOCK_CLASS::loglist nie jest synchronizowany. Ostatnio próbowałem skompilować z -D__DEBUG_CRITICALSECTION__ ale sypneło mi wieloma błędami In file included from database.h:5, from actions.cpp:5: otsystem.h:263:21: error: âlogBlockâ was not declared in this scope typedef std::list< logBlock > LogList; ^~~~~~~~ otsystem.h:263:21: note: suggested alternative: âsigblockâ typedef std::list< logBlock > LogList; ^~~~~~~~ sigblock otsystem.h:263:30: error: template argument 1 is invalid typedef std::list< logBlock > LogList; ^ otsystem.h:263:30: error: template argument 2 is invalid otsystem.h: In static member function âstatic void OTSYS_THREAD_LOCK_CLASS::addL og(OTSYS_THREAD_LOCKVAR*, const char*, bool)â: otsystem.h:242:5: error: âlogBlockâ was not declared in this scope logBlock lb; ^~~~~~~~ otsystem.h:242:5: note: suggested alternative: âsigblockâ logBlock lb; ^~~~~~~~ sigblock otsystem.h:243:3: error: âlbâ was not declared in this scope lb.mutexaddr = (unsigned long)(a); ^~ otsystem.h:247:17: error: âGetCurrentThreadIdâ was not declared in this scope lb.threadid = GetCurrentThreadId(); ^~~~~~~~~~~~~~~~~~ otsystem.h:247:17: note: suggested alternative: âxmlGetThreadIdâ lb.threadid = GetCurrentThreadId(); ^~~~~~~~~~~~~~~~~~ xmlGetThreadId otsystem.h:249:36: error: request for member âpush_backâ in âOTSYS_THREAD_LOCK_C LASS::loglistâ, which is of non-class type âOTSYS_THREAD_LOCK_CLASS::LogListâ {a ka âintâ} OTSYS_THREAD_LOCK_CLASS::loglist.push_back(lb); ^~~~~~~~~ otsystem.h:251:39: error: request for member âsizeâ in âOTSYS_THREAD_LOCK_CLASS: :loglistâ, which is of non-class type âOTSYS_THREAD_LOCK_CLASS::LogListâ {aka âi ntâ} if(OTSYS_THREAD_LOCK_CLASS::loglist.size() > 1000) { ^~~~ otsystem.h:252:37: error: request for member âpop_frontâ in âOTSYS_THREAD_LOCK_C LASS::loglistâ, which is of non-class type âOTSYS_THREAD_LOCK_CLASS::LogListâ {a ka âintâ} OTSYS_THREAD_LOCK_CLASS::loglist.pop_front(); ^~~~~~~~~
Więc kompiluje bez tego. na ten moment uruchamiam bez logowania crashy przez gdb tj; ENDFLAGS=-Werror -O2 -Winvalid-pch -include "preheaders.h" wtedy gracze nie narzekają, ze ich zacina a jak pojawiają sie problemy to kompiluje z gdb ENDFLAGS=-Werror -g -ggdb -Winvalid-pch -include "preheaders.h" Nie mam w kodzie takich nazw, ale jakby faktycznie tak się mogło zdarzyć, to by znaczyło że jednak znalazłeś jakieś problemy. Niby tak, ale nie jestem przekonany że to ma jakikolwiek wpływ, ponieważ właściwie na zmianę korzystam z dwóch silników. Innymi słowy - raz uruchamiam jeden serwer gry na jednym silniku, raz na drugim (w którym akurat nie ma tych funkcji). I problem tego typu crashy występował na jednym i drugim. Edit: jeszcze wyjaśnie - oczywiście "raz uruchamiam jeden serwer gry na jednym silniku, raz na drugim" - miałem na myśli, że np. jeden silnik jest używany przez 3 miesiące, a drugi przez miesiąc, pół roku - różnie. I tak na zmianę. Nie że jednego dnia ten silnik, a drugiego dnia sobie zmieniam bo to by nie miało sensu. |
|
1 2 « 3 » |