Browse Source

ENGINE-187 reworked timeout impl and added remaining time return when timeout interrupted by message

PYADPT-55
Edouard Tisserant 8 years ago
parent
commit
9518ea78d1
  1. 70
      src/sync_mixin.cc
  2. 17
      src/sync_mixin.hh
  3. 1
      test/multipEp.py

70
src/sync_mixin.cc

@ -70,21 +70,30 @@ namespace pEp {
jmp_buf SyncMixIn::env; jmp_buf SyncMixIn::env;
void *SyncMixIn::_msg; void *SyncMixIn::_msg;
bool SyncMixIn::running_timeout = false;
bool SyncMixIn::expiring_timeout = false; timeout_state_t SyncMixIn::timeout_state = timeout_stopped;
bool SyncMixIn::last_turn = false;
time_t SyncMixIn::remaining_time = 0;
int SyncMixIn::inject_sync_msg(void *msg, void *management) int SyncMixIn::inject_sync_msg(void *msg, void *management)
{ {
assert(timeout_state != timeout_canceling);
if(timeout_state == timeout_canceling) return 0;
assert(timeout_state != timeout_expiring);
if(timeout_state == timeout_expiring) return 0;
_msg = msg; _msg = msg;
int val = setjmp(env); int val = setjmp(env);
if (!val){ if (!val){
if(running_timeout){ if(timeout_state == timeout_running){
// call python timeout timer cancel // call python timeout timer cancel
auto that = dynamic_cast< SyncMixIn_callback * >( auto that = dynamic_cast< SyncMixIn_callback * >(
static_cast< SyncMixIn * > (management)); static_cast< SyncMixIn * > (management));
that->cancelTimeout(); remaining_time = that->cancelTimeout();
running_timeout = false; timeout_state = timeout_canceling;
} }
last_turn = false;
do_sync_protocol(session, management); do_sync_protocol(session, management);
} }
return 0; return 0;
@ -92,21 +101,39 @@ namespace pEp {
void *SyncMixIn::retrieve_next_sync_msg(void *management, time_t *timeout) void *SyncMixIn::retrieve_next_sync_msg(void *management, time_t *timeout)
{ {
static int twice = 1; if (!last_turn){
twice = !twice;
assert(timeout_state != timeout_running);
if (!twice){ if(timeout_state == timeout_running) return NULL;
if (expiring_timeout){
switch(timeout_state){
case timeout_canceling :
*timeout = remaining_time;
break;
case timeout_expiring :
// "1" is arbitrary value !=0, since we don't
// have original timeout value anymore
*timeout = 1; *timeout = 1;
expiring_timeout = true; break;
} else if (_msg != NULL && *timeout != 0){ }
timeout_state = timeout_stopped;
last_turn = true;
return (void *) _msg;
} else {
assert(timeout_state == timeout_stopped);
if(timeout_state != timeout_stopped) return NULL;
if (*timeout != 0) {
// call python timeout timer start // call python timeout timer start
auto that = dynamic_cast< SyncMixIn_callback * >( auto that = dynamic_cast< SyncMixIn_callback * >(
static_cast< SyncMixIn * > (management)); static_cast< SyncMixIn * > (management));
that->setTimeout(*timeout); that->setTimeout(*timeout);
running_timeout = true; timeout_state = timeout_running;
} }
return (void *) _msg;
} }
longjmp(env, 1); longjmp(env, 1);
return (void *) 23; return (void *) 23;
@ -114,12 +141,19 @@ namespace pEp {
// to be called from python timeout timer - may GIL protect us // to be called from python timeout timer - may GIL protect us
void SyncMixIn::onTimeout(){ void SyncMixIn::onTimeout(){
assert(timeout_state != timeout_canceling);
if(timeout_state == timeout_canceling) return;
assert(timeout_state != timeout_expiring);
if(timeout_state == timeout_expiring) return;
_msg = NULL; _msg = NULL;
int val = setjmp(env); int val = setjmp(env);
if (!val){ if (!val){
expiring_timeout = true; timeout_state = timeout_expiring;
last_turn = false;
do_sync_protocol(session, (void*)this); do_sync_protocol(session, (void*)this);
running_timeout = false;
} }
} }
@ -139,9 +173,9 @@ namespace pEp {
call_method< void >(_self, "setTimeout", timeout); call_method< void >(_self, "setTimeout", timeout);
} }
void SyncMixIn_callback::cancelTimeout() time_t SyncMixIn_callback::cancelTimeout()
{ {
call_method< void >(_self, "cancelTimeout"); return call_method< time_t >(_self, "cancelTimeout");
} }
} }
} }

17
src/sync_mixin.hh

@ -6,6 +6,14 @@
namespace pEp { namespace pEp {
namespace PythonAdapter { namespace PythonAdapter {
typedef enum _timeout_state_t {
timeout_stopped,
timeout_running,
timeout_canceling,
timeout_expiring
} timeout_state_t;
class SyncMixIn { class SyncMixIn {
public: public:
SyncMixIn() { } SyncMixIn() { }
@ -34,7 +42,7 @@ namespace pEp {
throw runtime_error("override this method"); throw runtime_error("override this method");
} }
virtual void cancelTimeout(){ virtual time_t cancelTimeout(){
throw runtime_error("override this method"); throw runtime_error("override this method");
} }
@ -46,9 +54,10 @@ namespace pEp {
pEp_identity *me, pEp_identity *partner, sync_handshake_signal signal); pEp_identity *me, pEp_identity *partner, sync_handshake_signal signal);
static jmp_buf env; static jmp_buf env;
static bool running_timeout;
static bool expiring_timeout;
static void *_msg; static void *_msg;
static timeout_state_t timeout_state;
static bool last_turn;
static time_t remaining_time;
static int inject_sync_msg(void *msg, void *management); static int inject_sync_msg(void *msg, void *management);
static void *retrieve_next_sync_msg(void *management, time_t *timeout); static void *retrieve_next_sync_msg(void *management, time_t *timeout);
}; };
@ -67,7 +76,7 @@ namespace pEp {
sync_handshake_signal signal); sync_handshake_signal signal);
void setTimeout(time_t timeout); void setTimeout(time_t timeout);
void cancelTimeout(); time_t cancelTimeout();
}; };
} }
} }

1
test/multipEp.py

@ -303,6 +303,7 @@ def pEp_instance_run(iname, _own_addresses, conn, _msgs_folders, _handshakes_see
def cancelTimeout(self): def cancelTimeout(self):
printi("CANCEL TIMEOUT") printi("CANCEL TIMEOUT")
return 42
if not disable_sync: if not disable_sync:
sync_handler = Handler() sync_handler = Handler()

Loading…
Cancel
Save