⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hxnetapi.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	}    }    if (m_bReusePort)    {	if (m_pData->reuse_port(m_bReusePort) != HXR_OK)	{	    // err...what do we need to do?	    HX_ASSERT(!"reuse_port() failed");	}    }#ifdef _UNIX    m_pData->SetAsyncDNSPref( ReadAsyncDNSPref((IUnknown*)m_pContext) );#endif    // XXXST -- local addr binding stuff, removed dependency to m_nLocalPort    // 0 for local port will make the system choose a free port    theErr = m_pData->init(ulLocalAddr, nPort);    if (theErr)    {	theErr = ConvertNetworkError(theErr);	if (theErr)	{	    m_pData->done();	    m_pData->Release();	    m_pData = 0;	    return theErr;	}    }    m_pData->nonblocking();    m_pData->set_receive_buf_size(DESIRED_RCV_BUFSIZE);    if (!m_pCallback)    {	m_pCallback = new UDPSocketCallback;	m_pCallback->m_pContext = this;    }    m_pData->set_callback(m_pCallback);#ifdef _WINDOWS#if defined (_WIN32)    ulPlatformData = (UINT32)GetModuleHandle(NULL);#elif defined (_WIN16)    ulPlatformData = (UINT32)(int)g_hInstance;#endif    m_pData->SetWindowHandle(ulPlatformData);#endif /* defined (_WINDOWS) */    if (m_pSchedulerReadCallback)    {	    m_pSchedulerReadCallback->ScheduleCallback(UDP_BIND_COMMAND, m_pScheduler, SCHED_GRANULARITY);    }    m_bInitComplete = TRUE;    return theErr;}STDMETHODIMP HXUDPSocket::Read(UINT16 nBytes){    if (!m_bInitComplete)    {	HX_RESULT ret = Bind(HXR_INADDR_ANY, 0);	if (HXR_OK != ret)	    return HXR_UNEXPECTED;    }    HX_RESULT theErr = HXR_OK;    if(m_bReadPending)    {	return HXR_UNEXPECTED;    }    m_bReadPending = TRUE;    if (m_bInRead)    {	return HXR_OK;    }    m_bInRead = TRUE;    m_pMutex->Lock();    UINT16 uNumIterations = 0;    do    {	theErr = DoRead();	uNumIterations++;    } while (m_bReadPending && !theErr && m_ReadBuffers.GetCount() > 0 && uNumIterations < MAX_ITERATION_COUNT);    m_pMutex->Unlock();    theErr = ConvertNetworkError(theErr);    if (m_bReadPending && m_pSchedulerReadCallback)	    m_pSchedulerReadCallback->ScheduleCallback(UDP_READ_COMMAND, m_pScheduler, SCHED_GRANULARITY);    m_bInRead = FALSE;    return theErr;}STDMETHODIMP HXUDPSocket::Write(IHXBuffer* pBuffer){    if (!m_bInitComplete)    {	HX_RESULT ret = Bind(HXR_INADDR_ANY, 0);	if (HXR_OK != ret)	    return HXR_UNEXPECTED;    }    HX_RESULT theErr = HXR_OK;    HX_RESULT lResult = HXR_OK;#if 0    struct in_addr in;    in.s_addr = m_sockAddr.sin_addr.s_addr;    char* address = inet_ntoa(in);    printf("address = %s:", address);    UINT32 port = ntohl(m_sockAddr.sin_port);    printf("%d\n", port);#endif /* 0 */#ifdef _MACINTOSH	if (m_pInterruptSafeMacWriteQueue)		m_pInterruptSafeMacWriteQueue->AddTail(pBuffer); // AddRef called inside#else	pBuffer->AddRef();	m_WriteBuffers.AddTail((void*) pBuffer);#endif    m_pMutex->Lock();    theErr = DoWrite();    m_pMutex->Unlock();    lResult = ConvertNetworkError(theErr);    return lResult;}STDMETHODIMP HXUDPSocket::WriteTo(ULONG32 ulAddr,    UINT16 nPort, IHXBuffer* pBuffer){    if (!m_bInitComplete)    {	HX_RESULT ret = Bind(HXR_INADDR_ANY, 0);	if (HXR_OK != ret)	    return HXR_UNEXPECTED;    }    m_sockAddr.sin_family	= AF_INET;    m_sockAddr.sin_addr.s_addr	= DwToNet(ulAddr);   //*(long*)&ulAddr;    m_sockAddr.sin_port		= WToNet(nPort);    return (Write(pBuffer));}STDMETHODIMP HXUDPSocket::GetLocalPort(UINT16& nPort){    // Get the local port from the socket info    nPort = m_pData->get_local_port();    return (INT16)nPort < 0 ? HXR_OK : HXR_FAIL;}STDMETHODIMP HXUDPSocket::JoinMulticastGroup(    ULONG32	    ulMulticastAddr,    ULONG32	    ulInterfaceAddr){#if defined(HELIX_FEATURE_TRANSPORT_MULTICAST)    HX_RESULT theErr = HXR_OK;    HX_RESULT lResult = HXR_OK;    m_pMutex->Lock();    theErr = m_pData->join_multicast_group(ulMulticastAddr, ulInterfaceAddr);    lResult = ConvertNetworkError(theErr);    m_pMutex->Unlock();    return lResult;#else    return HXR_NOTIMPL;#endif /* HELIX_FEATURE_TRANSPORT_MULTICAST */}STDMETHODIMP HXUDPSocket::LeaveMulticastGroup(    ULONG32	    ulMulticastAddr,    ULONG32	    ulInterfaceAddr){#if defined(HELIX_FEATURE_TRANSPORT_MULTICAST)    HX_RESULT theErr = HXR_OK;    HX_RESULT lResult = HXR_OK;    m_pMutex->Lock();    theErr = m_pData->leave_multicast_group(ulMulticastAddr, ulInterfaceAddr);    while (!m_ReadBuffers.IsEmpty())    {	UDP_PACKET* pPacket = (UDP_PACKET*)m_ReadBuffers.RemoveHead();	HX_RELEASE(pPacket->pBuffer);	HX_DELETE(pPacket);    }    lResult = ConvertNetworkError(theErr);    m_pMutex->Unlock();    return lResult;#else    return HXR_NOTIMPL;#endif /* HELIX_FEATURE_TRANSPORT_MULTICAST */}HX_RESULTHXUDPSocket::DoRead(){#ifdef _MACINTOSH	if (m_bInDoRead)		return HXR_OK; // whatever needs to be done will be done by the caller that's already here.	// xxxbobclark the m_bInDoRead flag is hacked around calling ReadDone(), because	//             ReadDone() may call Read() which in turn calls us here, and we do	//             not want to bail out in that instance. (Otherwise we only remove	//             one packet at a time, which, given the scheduler granularity and	//             high bit rates, implies that our bandwidth would be too low.)#endif	m_bInDoRead = TRUE;    HX_RESULT theErr = HXR_OK;    IHXBuffer* pBuffer = 0;    UINT32  ulAddress = 0;    UINT16  ulPort = 0;    UINT16  count = 0;    do    {	/*	 * Must reset count before every read	 */	count = TCP_BUF_SIZE;	theErr = m_pData->readfrom(pBuffer, ulAddress, ulPort);	if (!theErr && pBuffer)	{	    UDP_PACKET* pPacket = new UDP_PACKET;	    pPacket->pBuffer = pBuffer;	    pPacket->ulAddress = ulAddress;	    pPacket->ulPort = ulPort;	    m_ReadBuffers.AddTail((void*)pPacket);	}	else	{	    count = 0;	}    } while (!theErr && count > 0);    if (m_bReadPending && m_ReadBuffers.GetCount() > 0)    {	/* If we are at interrupt time and the response object is not	 * interrupt safe, schedule a callback to return back the data	 */	if (!IsSafe())	{		m_bInDoRead = FALSE;	    return HXR_AT_INTERRUPT;	}	m_bReadPending = FALSE;	UDP_PACKET* pPacket = (UDP_PACKET*)m_ReadBuffers.RemoveHead();	pBuffer = pPacket->pBuffer;	ulAddress = pPacket->ulAddress;	ulPort = pPacket->ulPort;	AddRef();	m_bInDoRead = FALSE;	m_pUDPResponse->ReadDone(HXR_OK, pBuffer, ulAddress, ulPort);	m_bInDoRead = TRUE;	HX_RELEASE(pBuffer);	HX_DELETE(pPacket);	Release();	m_bInDoRead = FALSE;	return HXR_OK;    }    /* if we called from within Read(), we will schedule a callback there, if necessary */    if (!m_bInRead && m_pSchedulerReadCallback)	    m_pSchedulerReadCallback->ScheduleCallback(UDP_READ_COMMAND, m_pScheduler, SCHED_GRANULARITY);	m_bInDoRead = FALSE;	return theErr;}HX_RESULTHXUDPSocket::DoWrite(){    HX_RESULT theErr = HXR_OK;    if (m_bInWrite) return HXR_OK;    m_bInWrite = TRUE;#ifdef _MACINTOSH	if (m_pInterruptSafeMacWriteQueue)		m_pInterruptSafeMacWriteQueue->TransferToSimpleList(m_WriteBuffers);#endif    while (!theErr && m_WriteBuffers.GetCount() > 0)    {	IHXBuffer* pBuffer = (IHXBuffer*) m_WriteBuffers.GetHead();	UINT16 uLength = (UINT16) pBuffer->GetSize();	theErr = m_pData->writeto(  pBuffer->GetBuffer(),   // sendto				    &uLength,				    (UINT32) m_sockAddr.sin_addr.s_addr,				    WToHost(m_sockAddr.sin_port));	if (!theErr)	{	    pBuffer->Release();	    m_WriteBuffers.RemoveHead();	}    }    if (m_pSchedulerWriteCallback &&	m_WriteBuffers.GetCount() > 0)    {	    m_pSchedulerWriteCallback->ScheduleCallback(UDP_WRITE_COMMAND, m_pScheduler, SCHED_GRANULARITY);    }    m_bInWrite = FALSE;    return theErr;}/* If we are at interrupt time and the response object is not interrupt safe, * schedule a callback to return back the data */BOOLHXUDPSocket::IsSafe(){    if (m_pInterruptState && m_pInterruptState->AtInterruptTime() &&	(!m_pResponseInterruptSafe ||	 !m_pResponseInterruptSafe->IsInterruptSafe()))    {	if (m_pNonInterruptReadCallback){		m_pNonInterruptReadCallback->ScheduleCallback(UDP_READ_COMMAND, m_pScheduler, 0);	}	return FALSE;    }    return TRUE;}STDMETHODIMP HXUDPSocket::HandleCallback(INT32  theCommand, HX_RESULT theError){    HX_RESULT theErr = HXR_OK;    if (!m_bInDestructor)    {	AddRef();	m_pMutex->Lock();	if (!m_bInDestructor)	{		switch(theCommand)		{			case UDP_READ_COMMAND:			    theErr = DoRead();			    break;			case UDP_WRITE_COMMAND:			    theErr = DoWrite();  // protected from re-entry by m_bInWrite			    break;			default:			    theErr = DoRead();                            if( theErr == HXR_OK )                            {			        theErr = DoWrite();                            }			    break;	   	}	}	m_pMutex->Unlock();	Release();    }    return theErr;}HX_RESULT HXUDPSocket::UDPSocketCallback::Func(NotificationType Type,					       BOOL bSuccess, conn* pConn){    if(m_pContext)    {	switch (Type)	{	case READ_NOTIFICATION:#if defined(_UNIX_THREADED_NETWORK_IO)            if( !ReadNetworkThreadingPref((IUnknown*)(m_pContext->m_pContext)) )            {                m_pContext->AddRef();                m_pContext->m_pMutex->Lock();                m_pContext->DoRead();                m_pContext->m_pMutex->Unlock();                m_pContext->Release();            }#elif !defined (THREADS_SUPPORTED) && !defined(_MACINTOSH)	    m_pContext->AddRef();	    m_pContext->m_pMutex->Lock();	    m_pContext->DoRead();	    m_pContext->m_pMutex->Unlock();	    m_pContext->Release();#endif	    break;	case WRITE_NOTIFICATION:#if defined(_UNIX_THREADED_NETWORK_IO)            if( !ReadNetworkThreadingPref((IUnknown*)(m_pContext->m_pContext)) )            {                m_pContext->AddRef();                m_pContext->m_pMutex->Lock();                m_pContext->DoWrite();                m_pContext->m_pMutex->Unlock();                m_pContext->Release();            }#elif !defined (THREADS_SUPPORTED) && !defined(_MACINTOSH)	    m_pContext->AddRef();	    m_pContext->m_pMutex->Lock();	    m_pContext->DoWrite();	    m_pContext->m_pMutex->Unlock();	    m_pContext->Release();#endif	    break;	case CONNECT_NOTIFICATION:	default:	    break;	}    }    return HXR_OK;}STDMETHODIMPHXUDPSocket::SetOption(HX_SOCKET_OPTION option, UINT32 ulValue){    HX_RESULT res = HXR_OK;    switch(option)    {    case HX_SOCKOPT_REUSE_ADDR:	m_bReuseAddr = (BOOL)ulValue;    break;    case HX_SOCKOPT_REUSE_PORT:	m_bReusePort = (BOOL)ulValue;    break;	case HX_SOCKOPT_BROADCAST:	{	HX_RESULT theErr = HXR_OK;	if(m_pData)	{		m_pMutex->Lock();		theErr = m_pData->set_broadcast(ulValue);		res = ConvertNetworkError(theErr);		m_pMutex->Unlock();	}	}	break;    case HX_SOCKOPT_MULTICAST_IF:	if (m_pData)	{	    res = m_pData->set_multicast_if(ulValue);	}	break;    case HX_SOCKOPT_SET_SENDBUF_SIZE:    {      if (m_pData)      {          HX_RESULT theErr = HXR_OK;           m_pMutex->Lock();           theErr = m_pData->set_send_size(ulValue);           res = ConvertNetworkError(theErr);           m_pMutex->Unlock();      }      break;    }    default:	HX_ASSERT(!"I don't know this option");	res = HXR_FAIL;    }    return res;}STDMETHODIMPHXUDPSocket::SetOption(HX_PRIVATE_SOCKET_OPTION option, UINT32 ulValue){    HX_RESULT res = HXR_OK;    switch(option)    {    case HX_PRIVATE_SOCKOPT_IGNORE_WSAECONNRESET:    {	if (m_pData)	{	    m_pMutex->Lock();	    m_pData->IgnoreWSAECONNRESET((BOOL)ulValue);	    m_pMutex->Unlock();	}	break;    }    default:	HX_ASSERT(!"I don't know this option");	res = HXR_FAIL;    }    return HXR_OK;}#ifdef _MACINTOSH/////////////////////////////////////////////////////////////////////////////	InterruptSafeMacQueue////	For passing data between an interrupt and anything else (mac only).//InterruptSafeMacQueue::InterruptSafeMacQueue(){ 	mQueueHeader.qFlags=0;	mQueueHeader.qHead=0;	mQueueHeader.qTail=0;	mDestructing = FALSE; // just a safety check}///////////////////////////////////////////////////////////////////////////HX_RESULT InterruptSafeMacQueue::AddTail(IUnknown* pObject){	if (pObject && !mDestructing)	{	    IhxQueueElement * theElement = new IhxQueueElement();	    if (theElement)	    {		    theElement->mNextElementInQueue = NULL;		    theElement->mObject = pObject;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -