Make it possible to run same binary against relay with relay heartbeat

and direct with comms heartbeat.  This mostly means changing ifdefs.
This commit is contained in:
ehouse 2009-02-01 15:50:58 +00:00
parent 1a99dc7e1c
commit c672fcfafd
9 changed files with 138 additions and 74 deletions

View file

@ -1,4 +1,4 @@
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
/* -*- compile-command: "cd ../linux && make MEMDEBUG=TRUE"; -*- */
/*
* Copyright 2001-2009 by Eric House (xwords@eehouse.org). All rights
* reserved.
@ -36,10 +36,6 @@
#ifndef XWFEATURE_STANDALONE_ONLY
#if defined RELAY_HEARTBEAT && defined COMMS_HEARTBEAT
compilation_error_here( "Choose one or the other or none." );
#endif
#ifdef COMMS_HEARTBEAT
/* It might make sense for this to be a parameter or somehow tied to the
platform and transport. But in that case it'd have to be passed across
@ -109,9 +105,12 @@ struct CommsCtxt {
#ifdef COMMS_HEARTBEAT
XP_Bool doHeartbeat;
XP_Bool hbTimerPending;
XP_U32 lastMsgRcvdTime;
#endif
#if defined XWFEATURE_RELAY || defined COMMS_HEARTBEAT
XP_Bool hbTimerPending;
XP_Bool reconTimerPending;
#endif
/* The following fields, down to isServer, are only used if
XWFEATURE_RELAY is defined, but I'm leaving them in here so apps built
@ -172,14 +171,16 @@ static XP_U16 countAddrRecs( const CommsCtxt* comms );
static void sendConnect( CommsCtxt* comms );
#ifdef XWFEATURE_RELAY
static void relayConnect( CommsCtxt* comms );
static XP_Bool relayConnect( CommsCtxt* comms );
static void relayDisconnect( CommsCtxt* comms );
static XP_Bool send_via_relay( CommsCtxt* comms, XWRELAY_Cmd cmd,
XWHostID destID, void* data, int dlen );
static XWHostID getDestID( CommsCtxt* comms, XP_PlayerAddr channelNo );
static void set_reset_timer( CommsCtxt* comms );
#endif
#if defined RELAY_HEARTBEAT || defined COMMS_HEARTBEAT
#if defined XWFEATURE_RELAY || defined COMMS_HEARTBEAT
static void setHeartbeatTimer( CommsCtxt* comms );
#else
# define setHeartbeatTimer( comms )
#endif
@ -273,11 +274,57 @@ comms_reset( CommsCtxt* comms, XP_Bool isServer,
comms->r.cookieID = COOKIE_ID_NONE;
comms->r.nPlayersHere = nPlayersHere;
comms->r.nPlayersTotal = nPlayersTotal;
relayConnect( comms );
(void)relayConnect( comms );
#endif
LOG_RETURN_VOID();
} /* comms_reset */
#ifdef XWFEATURE_RELAY
static XP_Bool
p_comms_resetTimer( void* closure, XWTimerReason XP_UNUSED_DBG(why) )
{
CommsCtxt* comms = (CommsCtxt*)closure;
XP_Bool success;
LOG_FUNC();
XP_ASSERT( why == TIMER_COMMS );
success = relayConnect( comms );
if ( success ) {
comms->reconTimerPending = XP_FALSE;
setHeartbeatTimer( comms ); /* in case we killed it with this
one.... */
} else {
set_reset_timer( comms );
}
return XP_FALSE;
} /* p_comms_resetTimer */
static void
set_reset_timer( CommsCtxt* comms )
{
/* This timer is allowed to overwrite a heartbeat timer, but not
vice-versa. Make sure we can restart it. */
comms->hbTimerPending = XP_FALSE;
util_setTimer( comms->util, TIMER_COMMS, 15, /* five seconds */
p_comms_resetTimer, comms );
comms->reconTimerPending = XP_TRUE;
}
void
comms_transportFailed( CommsCtxt* comms )
{
LOG_FUNC();
if ( COMMS_CONN_RELAY == comms->addr.conType ) {
relayDisconnect( comms );
set_reset_timer( comms );
}
LOG_RETURN_VOID();
}
#endif /* XWFEATURE_RELAY */
void
comms_destroy( CommsCtxt* comms )
{
@ -693,7 +740,7 @@ makeElemWithID( CommsCtxt* comms, MsgID msgID, AddressRecord* rec,
NULL, 0,
(MemStreamCloseCallback)NULL );
stream_open( msgStream );
XP_LOGF( "%s: putting connID %ld", __func__, comms->connID );
XP_LOGF( "%s: putting connID %lx", __func__, comms->connID );
stream_putU32( msgStream, comms->connID );
stream_putU16( msgStream, channelNo );
@ -1122,7 +1169,8 @@ getRecordFor( CommsCtxt* comms, const CommsAddrRec* addr,
* it invalid
*/
static AddressRecord*
validateInitialMessage( CommsCtxt* comms, XP_Bool hasPayload,
validateInitialMessage( CommsCtxt* comms,
XP_Bool XP_UNUSED_HEARTBEAT(hasPayload),
const CommsAddrRec* addr, XWHostID senderID,
XP_PlayerAddr* channelNo )
{
@ -1335,21 +1383,22 @@ heartbeat_checks( CommsCtxt* comms )
} /* heartbeat_checks */
#endif
#if defined RELAY_HEARTBEAT || defined COMMS_HEARTBEAT
#if defined XWFEATURE_RELAY || defined COMMS_HEARTBEAT
static XP_Bool
p_comms_timerFired( void* closure, XWTimerReason XP_UNUSED_DBG(why) )
{
CommsCtxt* comms = (CommsCtxt*)closure;
XP_ASSERT( why == TIMER_HEARTBEAT );
XP_ASSERT( why == TIMER_COMMS );
LOG_FUNC();
comms->hbTimerPending = XP_FALSE;
if (0 ) {
#ifdef RELAY_HEARTBEAT
#ifdef XWFEATURE_RELAY
} else if ( (comms->addr.conType == COMMS_CONN_RELAY )
&& (comms->r.heartbeat != HEARTBEAT_NONE) ) {
send_via_relay( comms, XWRELAY_HEARTBEAT, HOST_ID_NONE, NULL, 0 );
/* No need to reset timer. send_via_relay does that. */
#elif defined COMMS_HEARTBEAT
#endif
#ifdef COMMS_HEARTBEAT
} else {
XP_ASSERT( comms->doHeartbeat );
heartbeat_checks( comms );
@ -1363,27 +1412,29 @@ setHeartbeatTimer( CommsCtxt* comms )
{
LOG_FUNC();
XP_ASSERT( !!comms );
if ( !comms->hbTimerPending ) {
if ( comms->hbTimerPending ) {
XP_LOGF( "%s: skipping b/c hbTimerPending", __func__ );
} else if ( comms->reconTimerPending ) {
XP_LOGF( "%s: skipping b/c reconTimerPending", __func__ );
} else {
XP_U16 when = 0;
#ifdef RELAY_HEARTBEAT
#ifdef XWFEATURE_RELAY
if ( comms->addr.conType == COMMS_CONN_RELAY ) {
when = comms->r.heartbeat;
}
#elif defined COMMS_HEARTBEAT
#endif
#ifdef COMMS_HEARTBEAT
if ( comms->doHeartbeat ) {
XP_LOGF( "%s: calling util_setTimer", __func__ );
when = HB_INTERVAL;
} else {
XP_LOGF( "%s: doHeartbeat not set", __func__ );
}
#endif
if ( when != 0 ) {
util_setTimer( comms->util, TIMER_HEARTBEAT, when,
util_setTimer( comms->util, TIMER_COMMS, when,
p_comms_timerFired, comms );
comms->hbTimerPending = XP_TRUE;
}
} else {
XP_LOGF( "%s: skipping b/c pending", __func__ );
}
} /* setHeartbeatTimer */
#endif
@ -1474,7 +1525,9 @@ static void
updateChannelAddress( AddressRecord* rec, const CommsAddrRec* addr )
{
XP_ASSERT( !!rec );
XP_MEMCPY( &rec->addr, addr, sizeof(rec->addr) );
if ( !!addr ) {
XP_MEMCPY( &rec->addr, addr, sizeof(rec->addr) );
}
} /* updateChannelAddress */
static XP_Bool
@ -1570,7 +1623,7 @@ send_via_relay( CommsCtxt* comms, XWRELAY_Cmd cmd, XWHostID destID,
stream_putU8( tmpStream, comms->r.myHostID );
break;
#ifdef RELAY_HEARTBEAT
#ifdef XWFEATURE_RELAY
case XWRELAY_HEARTBEAT:
/* Add these for grins. Server can assert they match the IP
address it expects 'em on. */
@ -1606,18 +1659,20 @@ send_via_relay( CommsCtxt* comms, XWRELAY_Cmd cmd, XWHostID destID,
* relay, and tells it our hostID and cookie so that it can associatate it
* with a socket. In the CONNECT_RESP we should get back what?
*/
static void
static XP_Bool
relayConnect( CommsCtxt* comms )
{
XP_Bool success = XP_TRUE;
LOG_FUNC();
if ( comms->addr.conType == COMMS_CONN_RELAY && !comms->r.connecting ) {
comms->r.connecting = XP_TRUE;
send_via_relay( comms,
comms->r.connName[0] == '\0' ?
XWRELAY_GAME_CONNECT:XWRELAY_GAME_RECONNECT,
comms->r.myHostID, NULL, 0 );
success = send_via_relay( comms,
comms->r.connName[0] == '\0' ?
XWRELAY_GAME_CONNECT:XWRELAY_GAME_RECONNECT,
comms->r.myHostID, NULL, 0 );
comms->r.connecting = XP_FALSE;
}
return success;
} /* relayConnect */
#endif

View file

@ -1,6 +1,7 @@
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
/*
* Copyright 2001 by Eric House (xwords@eehouse.org). All rights reserved.
* Copyright 2001-2009 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -107,6 +108,8 @@ CommsCtxt* comms_make( MPFORMAL XW_UtilCtxt* util,
void comms_reset( CommsCtxt* comms, XP_Bool isServer,
XP_U16 nPlayersHere, XP_U16 nPlayersTotal );
void comms_transportFailed( CommsCtxt* comms );
void comms_destroy( CommsCtxt* comms );
void comms_setConnID( CommsCtxt* comms, XP_U32 connID );

View file

@ -104,10 +104,9 @@ typedef XP_S16 XP_PlayerAddr;
typedef enum {
TIMER_PENDOWN = 1, /* ARM doesn't like ids of 0... */
TIMER_TIMERTICK,
#if defined XWFEATURE_RELAY || defined COMMS_HEARTBEAT
TIMER_HEARTBEAT,
#ifndef XWFEATURE_STANDALONE_ONLY
TIMER_COMMS,
#endif
NUM_TIMERS_PLUS_ONE /* must be last */
} XWTimerReason;
@ -217,6 +216,12 @@ typedef struct CommonPrefs {
# define XP_UNUSED_RELAY(x) UNUSED__ ## x __attribute__((unused))
#endif
#ifdef COMMS_HEARTBEAT
# define XP_UNUSED_HEARTBEAT(x) x
#else
# define XP_UNUSED_HEARTBEAT(x) UNUSED__ ## x __attribute__((unused))
#endif
#ifdef XWFEATURE_BLUETOOTH
# define XP_UNUSED_BT(x) x
#else

View file

@ -94,13 +94,13 @@ DEFINES += -DXWFEATURE_SMS
# Support device-to-device connection via UDP, e.g. using wifi on a
# LAN or where the host/server isn't behind a firewall.
DEFINES += -DXWFEATURE_IP_DIRECT
# DEFINES += -DXWFEATURE_IP_DIRECT
# Choose one of these. RELAY_HEARTBEAT means relay (must be compiled
# with same -D) works with comms on heartbeat. Works only with relay.
# COMMS_HEARTBEAT should work on any comms transport (even IR, but
# user experience will be very bad!). Is particularly useful with BT.
# DEFINES += -DRELAY_HEARTBEAT
# RELAY_HEARTBEAT means relay (must be compiled with same -D) works
# with comms on heartbeat. Works only with relay. COMMS_HEARTBEAT
# should work on any comms transport (even IR, but user experience
# will be very bad!). Is particularly useful with BT. Is not used
# for relay.
DEFINES += -DCOMMS_HEARTBEAT
endif
DEFINES += $(STANDALONE)

View file

@ -894,12 +894,12 @@ curses_socket_acceptor( int listener, Acceptor func, CommonGlobals* cGlobals,
cursesListenOnSocket( globals, listener );
}
#ifdef RELAY_HEARTBEAT
#ifdef XWFEATURE_RELAY
static int
figureTimeout( CursesAppGlobals* globals )
{
int result = INFINITE_TIMEOUT;
if ( globals->cGlobals.timerProcs[TIMER_HEARTBEAT] != 0 ) {
if ( globals->cGlobals.timerProcs[TIMER_COMMS] != 0 ) {
XP_U32 now = util_getCurSeconds( globals->cGlobals.params->util );
XP_U32 then = globals->nextTimer;
if ( now >= then ) {
@ -929,10 +929,8 @@ blocking_gotEvent( CursesAppGlobals* globals, int* ch )
numEvents = poll( globals->fdArray, globals->fdCount, timeout );
if ( timeout != INFINITE_TIMEOUT && numEvents == 0 ) {
#ifdef RELAY_HEARTBEAT
if ( !globals->cGlobals.params->noHeartbeat ) {
linuxFireTimer( &globals->cGlobals, TIMER_HEARTBEAT );
}
#ifdef XWFEATURE_RELAY
linuxFireTimer( &globals->cGlobals, TIMER_COMMS );
#endif
} else if ( numEvents > 0 ) {

View file

@ -562,6 +562,7 @@ quit( void* XP_UNUSED(dunno), GtkAppGlobals* globals )
#ifdef XWFEATURE_IP_DIRECT
linux_udp_close( &globals->cGlobals );
#endif
vtmgr_destroy( MEMPOOL globals->cGlobals.params->vtMgr );
mpool_destroy( globals->cGlobals.params->util->mpool );
@ -1223,15 +1224,13 @@ score_timer_func( gpointer data )
return XP_FALSE;
} /* score_timer_func */
#if defined RELAY_HEARTBEAT || defined COMMS_HEARTBEAT
#ifndef XWFEATURE_STANDALONE_ONLY
static gint
heartbeat_timer_func( gpointer data )
comms_timer_func( gpointer data )
{
GtkAppGlobals* globals = (GtkAppGlobals*)data;
if ( !globals->cGlobals.params->noHeartbeat ) {
linuxFireTimer( &globals->cGlobals, TIMER_HEARTBEAT );
}
linuxFireTimer( &globals->cGlobals, TIMER_COMMS );
return (gint)0;
}
@ -1260,9 +1259,9 @@ gtk_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why,
(void)gettimeofday( &globals->scoreTv, NULL );
newSrc = g_timeout_add( 1000, score_timer_func, globals );
#if defined RELAY_HEARTBEAT || defined COMMS_HEARTBEAT
} else if ( why == TIMER_HEARTBEAT ) {
newSrc = g_timeout_add( 1000 * when, heartbeat_timer_func, globals );
#ifndef XWFEATURE_STANDALONE_ONLY
} else if ( why == TIMER_COMMS ) {
newSrc = g_timeout_add( 1000 * when, comms_timer_func, globals );
#endif
} else {
XP_ASSERT( 0 );
@ -1589,7 +1588,7 @@ newConnectionInput( GIOChannel *source,
int sock = g_io_channel_unix_get_fd( source );
GtkAppGlobals* globals = (GtkAppGlobals*)data;
XP_LOGF( "%s:condition = 0x%x", __func__, (int)condition );
XP_LOGF( "%s(%p):condition = 0x%x", __func__, source, (int)condition );
/* XP_ASSERT( sock == globals->cGlobals.socket ); */
@ -1614,14 +1613,16 @@ newConnectionInput( GIOChannel *source,
} else if ( (condition & G_IO_IN) != 0 ) {
ssize_t nRead;
unsigned char buf[512];
CommsAddrRec addr;
CommsAddrRec* addrp = NULL;
#if defined XWFEATURE_IP_DIRECT || defined XWFEATURE_SMS
CommsAddrRec addr;
#endif
switch ( globals->cGlobals.params->conType ) {
#ifdef XWFEATURE_RELAY
case COMMS_CONN_RELAY:
nRead = linux_relay_receive( &globals->cGlobals,
buf, sizeof(buf) );
XP_ASSERT( globals->cGlobals.socket == sock );
nRead = linux_relay_receive( &globals->cGlobals, buf, sizeof(buf) );
break;
#endif
#ifdef XWFEATURE_BLUETOOTH
@ -1726,7 +1727,7 @@ gtk_socket_changed( void* closure, int oldSock, int newSock, void** storage )
comms_resendAll( comms );
}
LOG_RETURN_VOID();
}
} /* gtk_socket_changed */
static gboolean
acceptorInput( GIOChannel* source, GIOCondition condition, gpointer data )
@ -1792,11 +1793,10 @@ gtk_socket_acceptor( int listener, Acceptor func, CommonGlobals* globals,
static void
sendOnClose( XWStreamCtxt* stream, void* closure )
{
XP_S16 result;
GtkAppGlobals* globals = closure;
XP_LOGF( "sendOnClose called" );
result = comms_send( globals->cGlobals.game.comms, stream );
(void)comms_send( globals->cGlobals.game.comms, stream );
} /* sendOnClose */
static void

View file

@ -302,7 +302,6 @@ linShiftFocus( CommonGlobals* cGlobals, XP_Key key, const BoardObjectType* order
} /* linShiftFocus */
#endif
#ifndef XWFEATURE_STANDALONE_ONLY
#ifdef XWFEATURE_RELAY
static int
linux_init_relay_socket( CommonGlobals* cGlobals )
@ -351,7 +350,6 @@ linux_init_relay_socket( CommonGlobals* cGlobals )
static XP_S16
linux_tcp_send( const XP_U8* buf, XP_U16 buflen,
const CommsAddrRec* XP_UNUSED(addrRec),
CommonGlobals* globals )
{
XP_S16 result = 0;
@ -384,15 +382,16 @@ linux_tcp_send( const XP_U8* buf, XP_U16 buflen,
globals->socket = -1;
}
XP_STATUSF( "linux_tcp_send: send returned %d of %d (err=%d)",
result, buflen, errno );
XP_STATUSF( "%s: send(sock=%d) returned %d of %d (err=%d)",
__func__, socket, result, buflen, errno );
}
return result;
} /* linux_tcp_send */
#endif /* XWFEATURE_RELAY */
#ifdef XWFEATURE_RELAY
#ifdef COMMS_HEARTBEAT
# ifdef XWFEATURE_RELAY
static void
linux_tcp_reset( CommonGlobals* globals )
{
@ -402,9 +401,8 @@ linux_tcp_reset( CommonGlobals* globals )
globals->socket = -1;
}
}
#endif
# endif
#ifdef COMMS_HEARTBEAT
void
linux_reset( void* closure )
{
@ -446,7 +444,7 @@ linux_send( const XP_U8* buf, XP_U16 buflen,
if ( 0 ) {
#ifdef XWFEATURE_RELAY
} else if ( conType == COMMS_CONN_RELAY ) {
nSent = linux_tcp_send( buf, buflen, addrRec, globals );
nSent = linux_tcp_send( buf, buflen, globals );
#endif
#if defined XWFEATURE_BLUETOOTH
} else if ( conType == COMMS_CONN_BT ) {
@ -482,7 +480,11 @@ static void
linux_close_socket( CommonGlobals* cGlobals )
{
int socket = cGlobals->socket;
cGlobals->socket = -1;
(*cGlobals->socketChanged)( cGlobals->socketChangedClosure,
socket, -1, &cGlobals->storage );
XP_ASSERT( -1 == cGlobals->socket );
XP_LOGF( "linux_close_socket" );
close( socket );
@ -498,6 +500,7 @@ linux_relay_receive( CommonGlobals* cGlobals, unsigned char* buf, int bufSize )
if ( nRead != 2 ) {
XP_LOGF( "recv => %d, errno=%d", nRead, errno );
linux_close_socket( cGlobals );
comms_transportFailed( cGlobals->game.comms );
nRead = -1;
} else {
@ -511,7 +514,6 @@ linux_relay_receive( CommonGlobals* cGlobals, unsigned char* buf, int bufSize )
return nRead;
} /* linuxReceive */
#endif /* XWFEATURE_RELAY */
#endif /* XWFEATURE_STANDALONE_ONLY */
/* Create a stream for the incoming message buffer, and read in any
information specific to our platform's comms layer (return address, say)
@ -859,6 +861,7 @@ main( int argc, char** argv )
break;
case 'H':
mainParams.noHeartbeat = XP_TRUE;
XP_ASSERT(0); /* not implemented!!! Needs to talk to comms... */
break;
case 'a':
/* mainParams.info.clientInfo.serverName = */

View file

@ -3870,7 +3870,7 @@ palm_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why,
now += PALM_TIMER_DELAY;
} else if ( why == TIMER_TIMERTICK ) {
now += SysTicksPerSecond();
#if defined RELAY_HEARTBEAT || defined COMMS_HEARTBEAT
#if defined XWFEATURE_RELAY || defined COMMS_HEARTBEAT
} else if ( why == TIMER_HEARTBEAT ) {
now += (secsFromNow * SysTicksPerSecond());
#endif

View file

@ -2013,7 +2013,7 @@ checkFireLateKeyTimer( CEAppGlobals* globals )
{
XP_Bool drop = XP_FALSE;
XWTimerReason whys[] = { TIMER_PENDOWN, TIMER_TIMERTICK
#if defined RELAY_HEARTBEAT || defined COMMS_HEARTBEAT
#if defined XWFEATURE_RELAY || defined COMMS_HEARTBEAT
, TIMER_HEARTBEAT
#endif
};
@ -2476,7 +2476,7 @@ WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_TIMER:
why = (XWTimerReason)wParam;
if ( why == TIMER_PENDOWN || why == TIMER_TIMERTICK
#if defined RELAY_HEARTBEAT || defined COMMS_HEARTBEAT
#if defined XWFEATURE_RELAY || defined COMMS_HEARTBEAT
|| why == TIMER_HEARTBEAT
#endif
) {