#include "stdafx.h" #include "SpBase.h" #include "SpMisc.h" #include "SpModule.h" #include "SpEntity.h" #include "SpTransactionContext.h" #include "sp_ses.h" #include SpTransactionContext::SpTransactionContext(sp_ses_uas_t *uas, int info, int method_id, int method_sig, int timeout, iobuffer_t **p_pkt, int tsx_id) : m_pkt(NULL), m_tsx(NULL) { int rc; sp_tsx_uas_callback cb; cb.on_destroy = NULL; cb.user_data = this; rc = sp_tsx_uas_create(uas, tsx_id, &cb, &m_tsx); if (rc == 0) { m_info = info; m_method_id = method_id; m_method_sig = method_sig; m_timeout = timeout; m_expire_time = timeout < 0 ? -1 : ((int)GetTickCount() + timeout); if (p_pkt) { m_pkt = *p_pkt; *p_pkt = NULL; } } } SpTransactionContext::~SpTransactionContext() { if (m_pkt) iobuffer_dec_ref(m_pkt); if (m_tsx) { sp_tsx_uas_close(m_tsx); sp_tsx_uas_destroy(m_tsx); } } bool SpTransactionContext::IsOneWayCall() { return !!m_info; } DWORD SpTransactionContext::GetRequestID() { if (m_tsx) { return (DWORD)sp_tsx_uas_get_id(m_tsx); } else { return -1; } } ErrorCodeEnum SpTransactionContext::GetReceiveBuffer(DWORD &dwMessageID, DWORD &dwMessageSignature, CAutoBuffer &Buffer) { if (m_pkt) { dwMessageID = (DWORD)m_method_id; dwMessageSignature = (DWORD)m_method_sig; int size = iobuffer_get_length(m_pkt); Buffer.Init(size); if (size > 0) { memcpy(&Buffer[0], iobuffer_data(m_pkt, 0), size); } return Error_Succeed; } else { return Error_Unexpect; } } ErrorCodeEnum SpTransactionContext::SendAnswer(CAutoBuffer Buffer, bool bEnd) { if (m_info) { return Error_Bug; } else { iobuffer_t *ans_pkt = iobuffer_create(-1, -1); int rc; int v; v = (int)Error_Succeed; iobuffer_write(ans_pkt, IOBUF_T_I4, &v, 0); // sys error v = 0; iobuffer_write(ans_pkt, IOBUF_T_I4, &v, 0); // user error v = Buffer.GetCount(); if (v > 0) iobuffer_write(ans_pkt, IOBUF_T_BUF, &Buffer[0], v); #if _DEBUG //Dbg("on_ans: tsx_id = %d, method_id = %d, pkt_size = %d", sp_tsx_uas_get_id(m_tsx), m_method_id, iobuffer_get_length(ans_pkt)); #endif rc = sp_tsx_uas_answer(m_tsx, !!bEnd, &ans_pkt); if (ans_pkt) iobuffer_dec_ref(ans_pkt); return SpTranslateError(rc); } } ErrorCodeEnum SpTransactionContext::SendAnswer(ErrorCodeEnum eSysError, DWORD dwUserError) { if (m_info) { return Error_Bug; } else { iobuffer_t *ans_pkt = iobuffer_create(-1, -1); int rc; int v; v = (int)eSysError; iobuffer_write(ans_pkt, IOBUF_T_I4, &v, 0); // sys error iobuffer_write(ans_pkt, IOBUF_T_I4, &dwUserError, 0); // user error #if _DEBUG //Dbg("on_ans: tsx_id = %d, method_id = %d, pkt_size = %d, error = 0x%X", sp_tsx_uas_get_id(m_tsx), m_method_id, iobuffer_get_length(ans_pkt), (int)eErrorCode); #endif rc = sp_tsx_uas_answer(m_tsx, 1, &ans_pkt); if (ans_pkt) iobuffer_dec_ref(ans_pkt); return SpTranslateError(rc); } } DWORD SpTransactionContext::GetExpireLeftTime() { if (m_tsx) { // because the machine will restart every day, so use int for time ticks storage is ok! if (m_expire_time == -1) { return m_expire_time; } else { int now = (int)GetTickCount(); return m_expire_time > now ? (m_expire_time - now) : 0; } } else { return -1; } } ErrorCodeEnum SpTransactionContext::GetExpireTime(DWORD &dwWholeTime,DWORD &dwLeftTime) { if (m_tsx) { if (m_expire_time == -1) { dwWholeTime = dwLeftTime = 0xffffffff; } else { int now = (int)GetTickCount(); dwWholeTime = m_timeout; dwLeftTime = m_expire_time > now ? (m_expire_time - now) : 0; } return Error_Succeed; } else { return Error_Unexpect; } } ErrorCodeEnum SpTransactionContext::SetExpireTime( DWORD dwMS ) { return Error_NotImpl; } // // SpMUITransactionContext // ErrorCodeEnum SpMUITransactionContext::SendAnswer( ErrorCodeEnum eErrorCode, DWORD dwUserError) { if (m_op == OP_START) { m_pEntity->FinishStart(eErrorCode); } else if (m_op == OP_PAUSE) { m_pEntity->FinishPause(eErrorCode); } else if (m_op == OP_SELFTEST) { m_pEntity->FinishSelfTest(eErrorCode); } else if (m_op == OP_CONTINUE) { m_pEntity->FinishContinue(eErrorCode); } else if (m_op == OP_CLOSE) { m_pEntity->FinishClose(eErrorCode); } return Error_Unexpect; }