EIO_Status CConn_Streambuf::x_Close(bool close) { if (!m_Conn) return close ? eIO_Closed : eIO_Success; EIO_Status status; // flush only if some data pending if (pbase() < pptr()) { if ((status = CONN_Status(m_Conn, eIO_Write)) != eIO_Success) { m_Status = status; if (CONN_Status(m_Conn, eIO_Open) == eIO_Success) { _TRACE(x_Message("Close(): Cannot finalize implicitly" ", data loss may result")); } } else if (sync() != 0) status = m_Status != eIO_Success ? m_Status : eIO_Unknown; } else status = eIO_Success; setg(0, 0, 0); setp(0, 0); CONN c = m_Conn; m_Conn = 0; // NB: no re-entry if (close) { // here: not called from the close callback x_OnClose if (m_CbValid) { SCONN_Callback cb; CONN_SetCallback(c, eCONN_OnClose, &m_Cb, &cb); if ((void*) cb.func != (void*) x_OnClose || cb.data != this) CONN_SetCallback(c, eCONN_OnClose, &cb, 0); } if (m_Close && (m_Status = CONN_Close(c)) != eIO_Success) { _TRACE(x_Message("Close(): CONN_Close() failed")); if (status == eIO_Success) status = m_Status; } } else if (m_CbValid && m_Cb.func) { EIO_Status cbstat = m_Cb.func(c, eCONN_OnClose, m_Cb.data); if (cbstat != eIO_Success) status = cbstat; } return status; }
EIO_Status CConn_IOStream::SetCanceledCallback(const ICanceled* canceled) { CONN conn = GetCONN(); if (!conn) return eIO_Closed; bool isset = m_Canceled.NotNull() ? 1 : 0; if (canceled) { SCONN_Callback cb; m_Canceled = canceled; memset(&cb, 0, sizeof(cb)); cb.func = (FCONN_Callback) x_IsCanceled; cb.data = this; CONN_SetCallback(conn, eCONN_OnRead, &cb, isset ? 0 : &m_CB[0]); CONN_SetCallback(conn, eCONN_OnWrite, &cb, isset ? 0 : &m_CB[1]); CONN_SetCallback(conn, eCONN_OnFlush, &cb, isset ? 0 : &m_CB[2]); } else if (isset) { CONN_SetCallback(conn, eCONN_OnFlush, &m_CB[2], 0); CONN_SetCallback(conn, eCONN_OnWrite, &m_CB[1], 0); CONN_SetCallback(conn, eCONN_OnRead, &m_CB[0], 0); m_Canceled = 0; } return eIO_Success; }
static void s_SetAsnConn_CloseCb(CONN conn, AsnIoPtr aip) { struct SAsnConn_Cbdata* cbdata = (struct SAsnConn_Cbdata*) malloc(sizeof(*cbdata)); assert( aip ); if ( cbdata ) { SCONN_Callback cb; cbdata->aip = aip; cb.func = s_CloseAsnConn; cb.data = cbdata; CONN_SetCallback(conn, eCONN_OnClose, &cb, &cbdata->cb); } else { CORE_LOG_X(1, eLOG_Error, "Cannot create cleanup callback for ASN conn-based stream"); } }
void CConn_Streambuf::x_Init(const STimeout* timeout, size_t buf_size, CConn_IOStream::TConn_Flags flags, CT_CHAR_TYPE* ptr, size_t size) { _ASSERT(m_Status == eIO_Success); if (timeout != kDefaultTimeout) { _VERIFY(CONN_SetTimeout(m_Conn, eIO_Open, timeout) ==eIO_Success); _VERIFY(CONN_SetTimeout(m_Conn, eIO_ReadWrite, timeout) ==eIO_Success); _VERIFY(CONN_SetTimeout(m_Conn, eIO_Close, timeout) ==eIO_Success); } if (!(flags & (CConn_IOStream::fConn_ReadBuffered | CConn_IOStream::fConn_WriteBuffered))) { buf_size = 0; } if (buf_size) { m_WriteBuf = new CT_CHAR_TYPE[buf_size << ((flags & (CConn_IOStream::fConn_ReadBuffered | CConn_IOStream::fConn_WriteBuffered)) == (CConn_IOStream::fConn_ReadBuffered | CConn_IOStream::fConn_WriteBuffered) ? 1 : 0)]; if (flags & CConn_IOStream::fConn_ReadBuffered) m_BufSize = buf_size; if (!(flags & CConn_IOStream::fConn_WriteBuffered)) buf_size = 0; if (flags & CConn_IOStream::fConn_ReadBuffered) m_ReadBuf = m_WriteBuf + buf_size; } /* else see ctor */ if (buf_size) setp(m_WriteBuf, m_WriteBuf + buf_size); /* else setp(0, 0) */ if (ptr) setg(ptr, ptr, ptr + size); // Initial get area else setg(m_ReadBuf, m_ReadBuf, m_ReadBuf); // Empty get area SCONN_Callback cb; cb.func = x_OnClose; /* NCBI_FAKE_WARNING: WorkShop */ cb.data = this; CONN_SetCallback(m_Conn, eCONN_OnClose, &cb, &m_Cb); m_CbValid = true; }