server/game/src/main.cpp

919 lines
20 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "stdafx.h"
#include "constants.h"
#include "config.h"
#include "event.h"
#include "packet.h"
#include "desc_manager.h"
#include "item_manager.h"
#include "char.h"
#include "char_manager.h"
#include "mob_manager.h"
#include "motion.h"
#include "sectree_manager.h"
#include "shop_manager.h"
#include "regen.h"
#include "text_file_loader.h"
#include "skill.h"
#include "pvp.h"
#include "party.h"
#include "questmanager.h"
#include "profiler.h"
#include "lzo_manager.h"
#include "messenger_manager.h"
#include "db.h"
#include "log.h"
#include "p2p.h"
#include "guild_manager.h"
#include "dungeon.h"
#include "cmd.h"
#include "refine.h"
#include "banword.h"
#include "priv_manager.h"
#include "war_map.h"
#include "building.h"
#include "login_sim.h"
#include "target.h"
#include "marriage.h"
#include "wedding.h"
#include "fishing.h"
#include "item_addon.h"
#include "TrafficProfiler.h"
#include "locale_service.h"
#include "arena.h"
#include "OXEvent.h"
#include "monarch.h"
#include "polymorph.h"
#include "blend_item.h"
#include "castle.h"
#include "passpod.h"
#include "ani.h"
#include "BattleArena.h"
#include "over9refine.h"
#include "horsename_manager.h"
#include "pcbang.h"
#include "MarkManager.h"
#include "spam.h"
#include "panama.h"
#include "threeway_war.h"
#include "DragonLair.h"
#include "skill_power.h"
#include "SpeedServer.h"
#include "DragonSoul.h"
#include <boost/bind.hpp>
#ifdef __AUCTION__
#include "auction_manager.h"
#endif
#ifdef USE_STACKTRACE
#include <execinfo.h>
#endif
extern void WriteVersion();
//extern const char * _malloc_options;
#if defined(__FreeBSD__) && defined(DEBUG_ALLOC)
extern void (*_malloc_message)(const char* p1, const char* p2, const char* p3, const char* p4);
// FreeBSD _malloc_message replacement
void WriteMallocMessage(const char* p1, const char* p2, const char* p3, const char* p4) {
FILE* fp = ::fopen(DBGALLOC_LOG_FILENAME, "a");
if (fp == NULL) {
return;
}
::fprintf(fp, "%s %s %s %s\n", p1, p2, p3, p4);
::fclose(fp);
}
#endif
// TRAFFIC_PROFILER
static const DWORD TRAFFIC_PROFILE_FLUSH_CYCLE = 3600; ///< TrafficProfiler <20><> Flush cycle. 1<>ð<EFBFBD> <20><><EFBFBD><EFBFBD>
// END_OF_TRAFFIC_PROFILER
// <20><><EFBFBD>Ӱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD>
volatile int num_events_called = 0;
int max_bytes_written = 0;
int current_bytes_written = 0;
int total_bytes_written = 0;
BYTE g_bLogLevel = 0;
socket_t tcp_socket = 0;
socket_t udp_socket = 0;
socket_t p2p_socket = 0;
LPFDWATCH main_fdw = NULL;
int io_loop(LPFDWATCH fdw);
int start(int argc, char **argv);
int idle();
void destroy();
enum EProfile
{
PROF_EVENT,
PROF_CHR_UPDATE,
PROF_IO,
PROF_HEARTBEAT,
PROF_MAX_NUM
};
static DWORD s_dwProfiler[PROF_MAX_NUM];
int g_shutdown_disconnect_pulse;
int g_shutdown_disconnect_force_pulse;
int g_shutdown_core_pulse;
bool g_bShutdown=false;
extern int speed_server;
#ifdef __AUCTION__
extern int auction_server;
#endif
extern void CancelReloadSpamEvent();
void ContinueOnFatalError()
{
#ifdef USE_STACKTRACE
void* array[200];
std::size_t size;
char** symbols;
size = backtrace(array, 200);
symbols = backtrace_symbols(array, size);
std::ostringstream oss;
oss << std::endl;
for (std::size_t i = 0; i < size; ++i) {
oss << " Stack> " << symbols[i] << std::endl;
}
free(symbols);
sys_err("FatalError on %s", oss.str().c_str());
#else
sys_err("FatalError");
#endif
}
void ShutdownOnFatalError()
{
if (!g_bShutdown)
{
sys_err("ShutdownOnFatalError!!!!!!!!!!");
{
char buf[256];
strncpy(buf, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ġ<><C4A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>߻<EFBFBD><DFBB>Ͽ<EFBFBD> <20>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>õ˴ϴ<CBB4>."), sizeof(buf));
SendNotice(buf);
strncpy(buf, LC_TEXT("10<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǹ<EFBFBD>,"), sizeof(buf));
SendNotice(buf);
strncpy(buf, LC_TEXT("5<EFBFBD><EFBFBD> <20>Ŀ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϽǼ<CFBD> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>."), sizeof(buf));
SendNotice(buf);
}
g_bShutdown = true;
g_bNoMoreClient = true;
g_shutdown_disconnect_pulse = thecore_pulse() + PASSES_PER_SEC(10);
g_shutdown_disconnect_force_pulse = thecore_pulse() + PASSES_PER_SEC(20);
g_shutdown_core_pulse = thecore_pulse() + PASSES_PER_SEC(30);
}
}
namespace
{
struct SendDisconnectFunc
{
void operator () (LPDESC d)
{
if (d->GetCharacter())
{
if (d->GetCharacter()->GetGMLevel() == GM_PLAYER)
d->GetCharacter()->ChatPacket(CHAT_TYPE_COMMAND, "quit Shutdown(SendDisconnectFunc)");
}
}
};
struct DisconnectFunc
{
void operator () (LPDESC d)
{
if (d->GetType() == DESC_TYPE_CONNECTOR)
return;
if (d->IsPhase(PHASE_P2P))
return;
d->SetPhase(PHASE_CLOSE);
}
};
}
extern std::map<DWORD, CLoginSim *> g_sim; // first: AID
extern std::map<DWORD, CLoginSim *> g_simByPID;
extern std::vector<TPlayerTable> g_vec_save;
unsigned int save_idx = 0;
void heartbeat(LPHEART ht, int pulse)
{
DWORD t;
t = get_dword_time();
num_events_called += event_process(pulse);
s_dwProfiler[PROF_EVENT] += (get_dword_time() - t);
t = get_dword_time();
// 1<>ʸ<EFBFBD><CAB8><EFBFBD>
if (!(pulse % ht->passes_per_sec))
{
if (!g_bAuthServer)
{
TPlayerCountPacket pack;
pack.dwCount = DESC_MANAGER::instance().GetLocalUserCount();
db_clientdesc->DBPacket(HEADER_GD_PLAYER_COUNT, 0, &pack, sizeof(TPlayerCountPacket));
}
else
{
DESC_MANAGER::instance().ProcessExpiredLoginKey();
DBManager::instance().FlushBilling();
/*
if (!(pulse % (ht->passes_per_sec * 600)))
DBManager::instance().CheckBilling();
*/
}
{
int count = 0;
itertype(g_sim) it = g_sim.begin();
while (it != g_sim.end())
{
if (!it->second->IsCheck())
{
it->second->SendLogin();
if (++count > 50)
{
sys_log(0, "FLUSH_SENT");
break;
}
}
it++;
}
if (save_idx < g_vec_save.size())
{
count = MIN(100, g_vec_save.size() - save_idx);
for (int i = 0; i < count; ++i, ++save_idx)
db_clientdesc->DBPacket(HEADER_GD_PLAYER_SAVE, 0, &g_vec_save[save_idx], sizeof(TPlayerTable));
sys_log(0, "SAVE_FLUSH %d", count);
}
}
}
//
// 25 PPS(Pulse per second) <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>
//
// <20><> 1.16<EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD>
if (!(pulse % (passes_per_sec + 4)))
CHARACTER_MANAGER::instance().ProcessDelayedSave();
// <20><> 5.08<EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD>
if (!(pulse % (passes_per_sec * 5 + 2)))
{
ITEM_MANAGER::instance().Update();
DESC_MANAGER::instance().UpdateLocalUserCount();
}
s_dwProfiler[PROF_HEARTBEAT] += (get_dword_time() - t);
DBManager::instance().Process();
AccountDB::instance().Process();
CPVPManager::instance().Process();
if (g_bShutdown)
{
if (thecore_pulse() > g_shutdown_disconnect_pulse)
{
const DESC_MANAGER::DESC_SET & c_set_desc = DESC_MANAGER::instance().GetClientSet();
std::for_each(c_set_desc.begin(), c_set_desc.end(), ::SendDisconnectFunc());
g_shutdown_disconnect_pulse = INT_MAX;
}
else if (thecore_pulse() > g_shutdown_disconnect_force_pulse)
{
const DESC_MANAGER::DESC_SET & c_set_desc = DESC_MANAGER::instance().GetClientSet();
std::for_each(c_set_desc.begin(), c_set_desc.end(), ::DisconnectFunc());
}
else if (thecore_pulse() > g_shutdown_disconnect_force_pulse + PASSES_PER_SEC(5))
{
thecore_shutdown();
}
}
}
static void CleanUpForEarlyExit() {
CancelReloadSpamEvent();
}
int main(int argc, char **argv)
{
#ifdef DEBUG_ALLOC
DebugAllocator::StaticSetUp();
#endif
ilInit(); // DevIL Initialize
WriteVersion();
SECTREE_MANAGER sectree_manager;
CHARACTER_MANAGER char_manager;
ITEM_MANAGER item_manager;
CShopManager shop_manager;
CMobManager mob_manager;
CMotionManager motion_manager;
CPartyManager party_manager;
CSkillManager skill_manager;
CPVPManager pvp_manager;
LZOManager lzo_manager;
DBManager db_manager;
AccountDB account_db;
LogManager log_manager;
MessengerManager messenger_manager;
P2P_MANAGER p2p_manager;
CGuildManager guild_manager;
CGuildMarkManager mark_manager;
CDungeonManager dungeon_manager;
CRefineManager refine_manager;
CBanwordManager banword_manager;
CPrivManager priv_manager;
CWarMapManager war_map_manager;
building::CManager building_manager;
CTargetManager target_manager;
marriage::CManager marriage_manager;
marriage::WeddingManager wedding_manager;
CItemAddonManager item_addon_manager;
CArenaManager arena_manager;
COXEventManager OXEvent_manager;
CMonarch Monarch;
CHorseNameManager horsename_manager;
CPCBangManager pcbang_manager;
DESC_MANAGER desc_manager;
TrafficProfiler trafficProfiler;
CTableBySkill SkillPowerByLevel;
CPolymorphUtils polymorph_utils;
CProfiler profiler;
CPasspod passpod;
CBattleArena ba;
COver9RefineManager o9r;
SpamManager spam_mgr;
CThreeWayWar threeway_war;
CDragonLairManager dl_manager;
CSpeedServerManager SSManager;
DSManager dsManager;
#ifdef __AUCTION__
AuctionManager auctionManager;
#endif
if (!start(argc, argv)) {
CleanUpForEarlyExit();
return 0;
}
quest::CQuestManager quest_manager;
if (!quest_manager.Initialize()) {
CleanUpForEarlyExit();
return 0;
}
MessengerManager::instance().Initialize();
CGuildManager::instance().Initialize();
fishing::Initialize();
OXEvent_manager.Initialize();
if (speed_server)
CSpeedServerManager::instance().Initialize();
Cube_init();
Blend_Item_init();
ani_init();
PanamaLoad();
if ( g_bTrafficProfileOn )
TrafficProfiler::instance().Initialize( TRAFFIC_PROFILE_FLUSH_CYCLE, "ProfileLog" );
// Client PackageCrypt
//TODO : make it config
const std::string strPackageCryptInfoDir = "package/";
if( !desc_manager.LoadClientPackageCryptInfo( strPackageCryptInfoDir.c_str() ) )
{
sys_err("Failed to Load ClientPackageCryptInfo File(%s)", strPackageCryptInfoDir.c_str());
}
while (idle());
sys_log(0, "<shutdown> Starting...");
g_bShutdown = true;
g_bNoMoreClient = true;
if (g_bAuthServer)
{
DBManager::instance().FlushBilling(true);
int iLimit = DBManager::instance().CountQuery() / 50;
int i = 0;
do
{
DWORD dwCount = DBManager::instance().CountQuery();
sys_log(0, "Queries %u", dwCount);
if (dwCount == 0)
break;
usleep(500000);
if (++i >= iLimit)
if (dwCount == DBManager::instance().CountQuery())
break;
} while (1);
}
sys_log(0, "<shutdown> Destroying CArenaManager...");
arena_manager.Destroy();
sys_log(0, "<shutdown> Destroying COXEventManager...");
OXEvent_manager.Destroy();
sys_log(0, "<shutdown> Disabling signal timer...");
signal_timer_disable();
sys_log(0, "<shutdown> Shutting down CHARACTER_MANAGER...");
char_manager.GracefulShutdown();
sys_log(0, "<shutdown> Shutting down ITEM_MANAGER...");
item_manager.GracefulShutdown();
sys_log(0, "<shutdown> Flushing db_clientdesc...");
db_clientdesc->FlushOutput();
sys_log(0, "<shutdown> Flushing p2p_manager...");
p2p_manager.FlushOutput();
sys_log(0, "<shutdown> Destroying CShopManager...");
shop_manager.Destroy();
sys_log(0, "<shutdown> Destroying CHARACTER_MANAGER...");
char_manager.Destroy();
sys_log(0, "<shutdown> Destroying ITEM_MANAGER...");
item_manager.Destroy();
sys_log(0, "<shutdown> Destroying DESC_MANAGER...");
desc_manager.Destroy();
sys_log(0, "<shutdown> Destroying quest::CQuestManager...");
quest_manager.Destroy();
sys_log(0, "<shutdown> Destroying building::CManager...");
building_manager.Destroy();
sys_log(0, "<shutdown> Flushing TrafficProfiler...");
trafficProfiler.Flush();
destroy();
#ifdef DEBUG_ALLOC
DebugAllocator::StaticTearDown();
#endif
return 1;
}
void usage()
{
printf("Option list\n"
"-p <port> : bind port number (port must be over 1024)\n"
"-l <level> : sets log level\n"
"-v : log to stdout\n"
"-r : do not load regen tables\n"
"-t : traffic proflie on\n");
}
int start(int argc, char **argv)
{
std::string st_localeServiceName;
bool bVerbose = false;
char ch;
//_malloc_options = "A";
#if defined(__FreeBSD__) && defined(DEBUG_ALLOC)
_malloc_message = WriteMallocMessage;
#endif
while ((ch = getopt(argc, argv, "npverltI")) != -1)
{
char* ep = NULL;
switch (ch)
{
case 'I': // IP
strncpy(g_szPublicIP, argv[optind], sizeof(g_szPublicIP));
printf("IP %s\n", g_szPublicIP);
optind = 0;
break;
case 'p': // port
mother_port = strtol(argv[optind], &ep, 10);
if (mother_port <= 1024)
{
usage();
return 0;
}
printf("port %d\n", mother_port);
optind = 0;
break;
case 'l':
{
long l = strtol(argv[optind], &ep, 10);
log_set_level(l);
optind = 0;
}
break;
// LOCALE_SERVICE
case 'n':
{
if (optind < argc)
{
st_localeServiceName = argv[optind];
optind = 0;
}
}
break;
// END_OF_LOCALE_SERVICE
case 'v': // verbose
bVerbose = true;
break;
case 'r':
g_bNoRegen = true;
break;
// TRAFFIC_PROFILER
case 't':
g_bTrafficProfileOn = true;
break;
// END_OF_TRAFFIC_PROFILER
}
}
// LOCALE_SERVICE
config_init(st_localeServiceName);
// END_OF_LOCALE_SERVICE
#ifdef __WIN32__
// In Windows dev mode, "verbose" option is [on] by default.
bVerbose = true;
#endif
if (!bVerbose)
freopen("stdout", "a", stdout);
bool is_thecore_initialized = thecore_init(25, heartbeat);
if (!is_thecore_initialized)
{
fprintf(stderr, "Could not initialize thecore, check owner of pid, syslog\n");
exit(0);
}
if (false == CThreeWayWar::instance().LoadSetting("forkedmapindex.txt"))
{
if (false == g_bAuthServer)
{
fprintf(stderr, "Could not Load ThreeWayWar Setting file");
exit(0);
}
}
signal_timer_disable();
main_fdw = fdwatch_new(4096);
if ((tcp_socket = socket_tcp_bind(g_szPublicIP, mother_port)) == INVALID_SOCKET)
{
perror("socket_tcp_bind: tcp_socket");
return 0;
}
#ifndef __UDP_BLOCK__
if ((udp_socket = socket_udp_bind(g_szPublicIP, mother_port)) == INVALID_SOCKET)
{
perror("socket_udp_bind: udp_socket");
return 0;
}
#endif
// if internal ip exists, p2p socket uses internal ip, if not use public ip
//if ((p2p_socket = socket_tcp_bind(*g_szInternalIP ? g_szInternalIP : g_szPublicIP, p2p_port)) == INVALID_SOCKET)
if ((p2p_socket = socket_tcp_bind(g_szPublicIP, p2p_port)) == INVALID_SOCKET)
{
perror("socket_tcp_bind: p2p_socket");
return 0;
}
fdwatch_add_fd(main_fdw, tcp_socket, NULL, FDW_READ, false);
#ifndef __UDP_BLOCK__
fdwatch_add_fd(main_fdw, udp_socket, NULL, FDW_READ, false);
#endif
fdwatch_add_fd(main_fdw, p2p_socket, NULL, FDW_READ, false);
db_clientdesc = DESC_MANAGER::instance().CreateConnectionDesc(main_fdw, db_addr, db_port, PHASE_DBCLIENT, true);
if (!g_bAuthServer) {
db_clientdesc->UpdateChannelStatus(0, true);
}
if (g_bAuthServer)
{
if (g_stAuthMasterIP.length() != 0)
{
fprintf(stderr, "SlaveAuth");
g_pkAuthMasterDesc = DESC_MANAGER::instance().CreateConnectionDesc(main_fdw, g_stAuthMasterIP.c_str(), g_wAuthMasterPort, PHASE_P2P, true);
P2P_MANAGER::instance().RegisterConnector(g_pkAuthMasterDesc);
g_pkAuthMasterDesc->SetP2P(g_stAuthMasterIP.c_str(), g_wAuthMasterPort, g_bChannel);
}
else
{
fprintf(stderr, "MasterAuth %d", LC_GetLocalType());
}
}
/* game server to teen server */
else
{
if (teen_addr[0] && teen_port)
g_TeenDesc = DESC_MANAGER::instance().CreateConnectionDesc(main_fdw, teen_addr, teen_port, PHASE_TEEN, true);
extern unsigned int g_uiSpamBlockDuration;
extern unsigned int g_uiSpamBlockScore;
extern unsigned int g_uiSpamReloadCycle;
sys_log(0, "SPAM_CONFIG: duration %u score %u reload cycle %u\n",
g_uiSpamBlockDuration, g_uiSpamBlockScore, g_uiSpamReloadCycle);
extern void LoadSpamDB();
LoadSpamDB();
}
signal_timer_enable(30);
return 1;
}
void destroy()
{
sys_log(0, "<shutdown> Canceling ReloadSpamEvent...");
CancelReloadSpamEvent();
sys_log(0, "<shutdown> regen_free()...");
regen_free();
sys_log(0, "<shutdown> Closing sockets...");
socket_close(tcp_socket);
#ifndef __UDP_BLOCK__
socket_close(udp_socket);
#endif
socket_close(p2p_socket);
sys_log(0, "<shutdown> fdwatch_delete()...");
fdwatch_delete(main_fdw);
sys_log(0, "<shutdown> event_destroy()...");
event_destroy();
sys_log(0, "<shutdown> CTextFileLoader::DestroySystem()...");
CTextFileLoader::DestroySystem();
sys_log(0, "<shutdown> thecore_destroy()...");
thecore_destroy();
}
int idle()
{
static struct timeval pta = { 0, 0 };
static int process_time_count = 0;
struct timeval now;
if (pta.tv_sec == 0)
gettimeofday(&pta, (struct timezone *) 0);
int passed_pulses;
if (!(passed_pulses = thecore_idle()))
return 0;
assert(passed_pulses > 0);
DWORD t;
while (passed_pulses--) {
heartbeat(thecore_heart, ++thecore_heart->pulse);
// To reduce the possibility of abort() in checkpointing
thecore_tick();
}
t = get_dword_time();
CHARACTER_MANAGER::instance().Update(thecore_heart->pulse);
db_clientdesc->Update(t);
s_dwProfiler[PROF_CHR_UPDATE] += (get_dword_time() - t);
t = get_dword_time();
if (!io_loop(main_fdw)) return 0;
s_dwProfiler[PROF_IO] += (get_dword_time() - t);
log_rotate();
gettimeofday(&now, (struct timezone *) 0);
++process_time_count;
if (now.tv_sec - pta.tv_sec > 0)
{
pt_log("[%3d] event %5d/%-5d idle %-4ld event %-4ld heartbeat %-4ld I/O %-4ld chrUpate %-4ld | WRITE: %-7d | PULSE: %d",
process_time_count,
num_events_called,
event_count(),
thecore_profiler[PF_IDLE],
s_dwProfiler[PROF_EVENT],
s_dwProfiler[PROF_HEARTBEAT],
s_dwProfiler[PROF_IO],
s_dwProfiler[PROF_CHR_UPDATE],
current_bytes_written,
thecore_pulse());
num_events_called = 0;
current_bytes_written = 0;
process_time_count = 0;
gettimeofday(&pta, (struct timezone *) 0);
memset(&thecore_profiler[0], 0, sizeof(thecore_profiler));
memset(&s_dwProfiler[0], 0, sizeof(s_dwProfiler));
}
#ifdef __WIN32__
if (_kbhit()) {
int c = _getch();
switch (c) {
case 0x1b: // Esc
return 0; // shutdown
break;
default:
break;
}
}
#endif
return 1;
}
int io_loop(LPFDWATCH fdw)
{
LPDESC d;
int num_events, event_idx;
DESC_MANAGER::instance().DestroyClosed(); // PHASE_CLOSE<53><45> <20><><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
DESC_MANAGER::instance().TryConnect();
if ((num_events = fdwatch(fdw, 0)) < 0)
return 0;
for (event_idx = 0; event_idx < num_events; ++event_idx)
{
d = (LPDESC) fdwatch_get_client_data(fdw, event_idx);
if (!d)
{
if (FDW_READ == fdwatch_check_event(fdw, tcp_socket, event_idx))
{
DESC_MANAGER::instance().AcceptDesc(fdw, tcp_socket);
fdwatch_clear_event(fdw, tcp_socket, event_idx);
}
else if (FDW_READ == fdwatch_check_event(fdw, p2p_socket, event_idx))
{
DESC_MANAGER::instance().AcceptP2PDesc(fdw, p2p_socket);
fdwatch_clear_event(fdw, p2p_socket, event_idx);
}
/*
else if (FDW_READ == fdwatch_check_event(fdw, udp_socket, event_idx))
{
char buf[256];
struct sockaddr_in cliaddr;
socklen_t socklen = sizeof(cliaddr);
int iBytesRead;
if ((iBytesRead = socket_udp_read(udp_socket, buf, 256, (struct sockaddr *) &cliaddr, &socklen)) > 0)
{
static CInputUDP s_inputUDP;
s_inputUDP.SetSockAddr(cliaddr);
int iBytesProceed;
s_inputUDP.Process(NULL, buf, iBytesRead, iBytesProceed);
}
fdwatch_clear_event(fdw, udp_socket, event_idx);
}
*/
continue;
}
int iRet = fdwatch_check_event(fdw, d->GetSocket(), event_idx);
switch (iRet)
{
case FDW_READ:
if (db_clientdesc == d)
{
int size = d->ProcessInput();
if (size)
sys_log(1, "DB_BYTES_READ: %d", size);
if (size < 0)
{
d->SetPhase(PHASE_CLOSE);
}
}
else if (d->ProcessInput() < 0)
{
d->SetPhase(PHASE_CLOSE);
}
break;
case FDW_WRITE:
if (db_clientdesc == d)
{
int buf_size = buffer_size(d->GetOutputBuffer());
int sock_buf_size = fdwatch_get_buffer_size(fdw, d->GetSocket());
int ret = d->ProcessOutput();
if (ret < 0)
{
d->SetPhase(PHASE_CLOSE);
}
if (buf_size)
sys_log(1, "DB_BYTES_WRITE: size %d sock_buf %d ret %d", buf_size, sock_buf_size, ret);
}
else if (d->ProcessOutput() < 0)
{
d->SetPhase(PHASE_CLOSE);
}
else if (g_TeenDesc==d)
{
int buf_size = buffer_size(d->GetOutputBuffer());
int sock_buf_size = fdwatch_get_buffer_size(fdw, d->GetSocket());
int ret = d->ProcessOutput();
if (ret < 0)
{
d->SetPhase(PHASE_CLOSE);
}
if (buf_size)
sys_log(0, "TEEN::Send(size %d sock_buf %d ret %d)", buf_size, sock_buf_size, ret);
}
break;
case FDW_EOF:
{
d->SetPhase(PHASE_CLOSE);
}
break;
default:
sys_err("fdwatch_check_event returned unknown %d", iRet);
d->SetPhase(PHASE_CLOSE);
break;
}
}
return 1;
}