int IOCPNetwork::recv(iocp_key_t key, byte* buf, size_t len, size_t timeout, iocp_proc_t func, void* param) { if( !_inited ) return IOCP_UNINITIALIZED; iocp_context_t* context = reinterpret_cast<iocp_context_t*>(key); /* * 执行WSARecv */ int ret = IOCP_PENDING; if(context->lockPtr) context->lockPtr->rlock(); if(context->status != IOCP_NORMAL) { /* 允许一个接收操作和一个发送操作同时进行 */ ret = context->status; } else if(sessionTimeout(context)) { ret = IOCP_SESSIONTIMEO; } else { assert(context->readOlp.oppType == IOCP_NONE); context->readOlp.oppType = IOCP_RECV; context->readOlp.buf = buf; context->readOlp.len = len; context->readOlp.timeout = timeout; assert(context->readOlp.timer == NULL); context->readOlp.iocpProc = func; context->readOlp.param = param; context->readOlp.realLen = len; /* * 检查是否超出速度限制,如果是,则延时发送/接收 */ size_t delay = 0; if(context->readOlp.speedLmt > 0 && context->readOlp.lastCompleteCounter != 0) { /* * 按照最大速度限制,发送 nSended数据完成应该在 nExpectTime 这个时间点完成. */ __int64 expectTime = _hrt.getCounters(static_cast<__int64>(context->readOlp.transfered * 1.0 / context->readOlp.speedLmt * 1000)); expectTime += context->startCounter; if(expectTime > context->readOlp.lastCompleteCounter) /* 完成的时间点提前,说明速度超标 */ { /* 计算出定时器触发的时间. */ delay = static_cast<size_t>(_hrt.getMs(expectTime - context->readOlp.lastCompleteCounter)); if(delay > IOCP_MAXWAITTIME_ONSPEEDLMT) { /* 超过最长等待时间,下一次发送一个最小包. */ delay = IOCP_MAXWAITTIME_ONSPEEDLMT; if(context->readOlp.len > IOCP_MINBUFLEN_ONSPEEDLMT) { context->readOlp.realLen = IOCP_MINBUFLEN_ONSPEEDLMT; } } else { /* 下一次可以接收一个最大包. */ context->readOlp.realLen = context->readOlp.len; } } } /* * 直接发送或者设置一个定时器延时发送 */ if(delay > 0) { /* * 设置一个延时操作的定时器,并返回成功. 真正操作的结果等定时器到期后再通过回调函数通知. */ context->readOlp.oppType = IOCP_DELAY_READ; context->readOlp.timer = _timerQueue.createTimer(delay, delayRecvProc, context); } else { /* * 设置超时定时器,然后接收 */ if(context->readOlp.timeout > 0) { context->readOlp.timer = _timerQueue.createTimer(context->readOlp.timeout, readTimeoutProc, context); } ret = realRecv(context); /* * 如果接收操作失败,应该恢复现场,以便下一次调用可以成功. */ if(IOCP_PENDING != ret) { cleanOlp(&context->readOlp); } } } if(context->lockPtr) context->lockPtr->unlock(); return ret; }
int IOCPNetwork::accept(iocp_key_t key, SOCKET sockNew, byte* buf, size_t len, size_t timeout, iocp_proc_t func, void* param) { if( !_inited ) return IOCP_UNINITIALIZED; if(len < (sizeof(sockaddr_in) + 16) * 2) return IOCP_BUFFERROR; /* 缓冲区长度不够 */ iocp_context_t* context = reinterpret_cast<iocp_context_t*>(key); assert(IOCP_HANDLE_SOCKET == context->type); /* * 获得AcceptEx()函数指针并调用之,参考MSDN关于AcceptEx的示例代码. */ SOCKET sockListen = reinterpret_cast<SOCKET>(context->h); DWORD dwBytesReceived = 0; GUID GuidAcceptEx = WSAID_ACCEPTEX; LPFN_ACCEPTEX lpfnAcceptEx = NULL; DWORD dwBytes = 0; if( 0 != WSAIoctl(sockListen, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidAcceptEx, sizeof(GuidAcceptEx), &lpfnAcceptEx, sizeof(lpfnAcceptEx), &dwBytes, NULL, NULL) ) { assert(0); _lastErrorCode = WSAGetLastError(); return IOCP_UNDEFINED; } /* * 设置标记,然后调用AcceptEx,加锁以确保同步正确 * 由于发送和接收分别对应不同的重叠结构,所以可以用读写锁同时进行,只要套接字状态正常. */ int ret = IOCP_PENDING; if(context->lockPtr) context->lockPtr->rlock(); if(context->status != IOCP_NORMAL) { ret = context->status; } else if(sessionTimeout(context)) { ret = IOCP_SESSIONTIMEO; } else { /* assert检查:不要同时投递多个同类型的操作,由程序逻辑确保这一点,而不用同步量以提高并发量,否则只能用互斥锁了. */ assert(context->readOlp.oppType == IOCP_NONE); context->readOlp.oppType = IOCP_ACCEPT; context->readOlp.buf = buf; context->readOlp.len = len; context->readOlp.realLen = len; context->readOlp.iocpProc = func; context->readOlp.param = param; context->readOlp.timeout = timeout; if(timeout > 0) { /* 先创建定时器,acceptEx失败再删除是有必要的,尤其是在没有同步的情况下 */ context->readOlp.timer = _timerQueue.createTimer(timeout, readTimeoutProc, context); } if( !lpfnAcceptEx(sockListen, sockNew, buf, len - (sizeof(sockaddr_in) + 16) * 2 , sizeof(sockaddr_in) + 16, sizeof(sockaddr_in) + 16, &dwBytesReceived, reinterpret_cast<LPOVERLAPPED>(&context->readOlp)) ) { if( WSA_IO_PENDING != WSAGetLastError()) { assert(0); _lastErrorCode = WSAGetLastError(); ret = IOCP_UNDEFINED; } } else { assert(0); ret = IOCP_UNDEFINED; } /* * 调用失败,清除标志回收资源 */ if(ret != IOCP_PENDING) { cleanOlp(&context->readOlp); } } if(context->lockPtr) context->lockPtr->unlock(); return ret; }
int IOCPNetwork::connect(iocp_key_t key, sockaddr* addr, byte* buf, size_t len, size_t timeout, iocp_proc_t func, void* param) { if( !_inited ) return IOCP_UNINITIALIZED; iocp_context_t* context = reinterpret_cast<iocp_context_t*>(key); assert(IOCP_HANDLE_SOCKET == context->type); /* * 取得ConnectEx函数指针 */ SOCKET s = reinterpret_cast<SOCKET>(context->h); DWORD dwBytesReceived = 0; GUID GuidConnectEx = WSAID_CONNECTEX; LPFN_CONNECTEX lpfnConnectEx = NULL; DWORD dwBytes = 0; if( 0 != WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidConnectEx, sizeof(GuidConnectEx), &lpfnConnectEx, sizeof(lpfnConnectEx), &dwBytes, NULL, NULL) ) { assert(0); _lastErrorCode = WSAGetLastError(); return IOCP_UNDEFINED; } /* * 执行ConnectEx */ int ret = IOCP_PENDING; DWORD bytesSent = 0; if(context->lockPtr) context->lockPtr->rlock(); if(context->status != IOCP_NORMAL) { ret = context->status; } else if(sessionTimeout(context)) { ret = IOCP_SESSIONTIMEO; } else { assert(context->writeOlp.oppType == IOCP_NONE); context->writeOlp.oppType = IOCP_CONNECT; context->writeOlp.buf = buf; context->writeOlp.len = len; context->writeOlp.iocpProc = func; context->writeOlp.param = param; context->writeOlp.realLen = len; context->writeOlp.timeout = timeout; if(timeout > 0) { context->writeOlp.timer = _timerQueue.createTimer(timeout, writeTimeoutProc, context); } if( !lpfnConnectEx(s, addr, sizeof(sockaddr), buf, len, &bytesSent, reinterpret_cast<LPOVERLAPPED>(&context->writeOlp)) ) { int errorCode = WSAGetLastError(); if( WSA_IO_PENDING != errorCode ) { assert(0); _lastErrorCode = errorCode; ret = IOCP_UNDEFINED; } } else { assert(0); ret = IOCP_UNDEFINED; } /* * 调用失败,清除标志回收资源 */ if(ret != IOCP_PENDING) { cleanOlp(&context->writeOlp); } } if(context->lockPtr) context->lockPtr->unlock(); return ret; }
int IOCPNetwork::send(iocp_key_t key, const byte* buf, size_t len, size_t timeout, iocp_proc_t func, void* param) { if( !_inited ) return IOCP_UNINITIALIZED; iocp_context_t* context = reinterpret_cast<iocp_context_t*>(key); /* * 执行WSARecv */ int ret = IOCP_PENDING; if(context->lockPtr) context->lockPtr->rlock(); if(context->status != IOCP_NORMAL) { /* 允许一个接收操作和一个发送操作同时进行 */ ret = context->status; } else if(sessionTimeout(context)) { ret = IOCP_SESSIONTIMEO; } else { assert(context->writeOlp.oppType == IOCP_NONE); context->writeOlp.oppType = IOCP_SEND; context->writeOlp.buf = const_cast<byte*>(buf); context->writeOlp.len = len; context->writeOlp.timeout = timeout; assert(context->writeOlp.timer == NULL); context->writeOlp.iocpProc = func; context->writeOlp.param = param; context->writeOlp.realLen = len; /* * 检查是否超出速度限制,如果是,则延时发送/接收 * 第一次操作不检查 */ size_t delay = 0; if(context->writeOlp.speedLmt > 0 && context->writeOlp.lastCompleteCounter != 0) { /* * 按照最大速度限制,发送 nSended数据完成应该在 nExpectTime 这个时间点完成. */ __int64 expectTime = _hrt.getCounters(static_cast<__int64>(context->writeOlp.transfered * 1.0 / context->writeOlp.speedLmt * 1000)); expectTime += context->startCounter; if(expectTime > context->writeOlp.lastCompleteCounter) /* 完成的时间点提前,说明速度超标 */ { /* 计算出定时器触发的时间. */ delay = static_cast<size_t>(_hrt.getMs(expectTime - context->writeOlp.lastCompleteCounter)); if(delay > IOCP_MAXWAITTIME_ONSPEEDLMT) { /* 超过最长等待时间,下一次发送一个最小包. */ delay = IOCP_MAXWAITTIME_ONSPEEDLMT; if(context->writeOlp.len > IOCP_MINBUFLEN_ONSPEEDLMT) { context->writeOlp.realLen = IOCP_MINBUFLEN_ONSPEEDLMT; } } else { /* 下一次可以发送一个最大包. */ context->writeOlp.realLen = context->writeOlp.len; } //TRACE(_T("delay send:%dms.\r\n"), delay); } } /* * 直接发送或者设置一个定时器延时发送 */ if(delay > 0) { context->writeOlp.oppType = IOCP_DELAY_WRITE; context->writeOlp.timer = _timerQueue.createTimer(delay, delaySendProc, context); } else { /* * 设置超时定时器,然后发送 */ if(context->writeOlp.timeout > 0) { context->writeOlp.timer = _timerQueue.createTimer(context->writeOlp.timeout, readTimeoutProc, context); } ret = realSend(context); if( ret != IOCP_PENDING) { cleanOlp(&context->writeOlp); } } } if(context->lockPtr) context->lockPtr->unlock(); return ret; }
int ONVIF::AudioEncoderConfiguration::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { if (_id < 13) qt_static_metacall(this, _c, _id, _a); _id -= 13; } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) { if (_id < 13) *reinterpret_cast<int*>(_a[0]) = -1; _id -= 13; } #ifndef QT_NO_PROPERTIES else if (_c == QMetaObject::ReadProperty) { void *_v = _a[0]; switch (_id) { case 0: *reinterpret_cast< QString*>(_v) = token(); break; case 1: *reinterpret_cast< QString*>(_v) = name(); break; case 2: *reinterpret_cast< int*>(_v) = useCount(); break; case 3: *reinterpret_cast< QString*>(_v) = encoding(); break; case 4: *reinterpret_cast< int*>(_v) = bitrate(); break; case 5: *reinterpret_cast< int*>(_v) = sampleRate(); break; case 6: *reinterpret_cast< QString*>(_v) = type(); break; case 7: *reinterpret_cast< QString*>(_v) = ipv4Address(); break; case 8: *reinterpret_cast< QString*>(_v) = ipv6Address(); break; case 9: *reinterpret_cast< int*>(_v) = port(); break; case 10: *reinterpret_cast< int*>(_v) = ttl(); break; case 11: *reinterpret_cast< bool*>(_v) = autoStart(); break; case 12: *reinterpret_cast< QString*>(_v) = sessionTimeout(); break; } _id -= 13; } else if (_c == QMetaObject::WriteProperty) { void *_v = _a[0]; switch (_id) { case 0: setToken(*reinterpret_cast< QString*>(_v)); break; case 1: setName(*reinterpret_cast< QString*>(_v)); break; case 2: setUseCount(*reinterpret_cast< int*>(_v)); break; case 3: setEncoding(*reinterpret_cast< QString*>(_v)); break; case 4: setBitrate(*reinterpret_cast< int*>(_v)); break; case 5: setSampleRate(*reinterpret_cast< int*>(_v)); break; case 6: setType(*reinterpret_cast< QString*>(_v)); break; case 7: setIpv4Address(*reinterpret_cast< QString*>(_v)); break; case 8: setIpv6Address(*reinterpret_cast< QString*>(_v)); break; case 9: setPort(*reinterpret_cast< int*>(_v)); break; case 10: setTtl(*reinterpret_cast< int*>(_v)); break; case 11: setAutoStart(*reinterpret_cast< bool*>(_v)); break; case 12: setSessionTimeout(*reinterpret_cast< QString*>(_v)); break; } _id -= 13; } else if (_c == QMetaObject::ResetProperty) { _id -= 13; } else if (_c == QMetaObject::QueryPropertyDesignable) { _id -= 13; } else if (_c == QMetaObject::QueryPropertyScriptable) { _id -= 13; } else if (_c == QMetaObject::QueryPropertyStored) { _id -= 13; } else if (_c == QMetaObject::QueryPropertyEditable) { _id -= 13; } else if (_c == QMetaObject::QueryPropertyUser) { _id -= 13; } else if (_c == QMetaObject::RegisterPropertyMetaType) { if (_id < 13) *reinterpret_cast<int*>(_a[0]) = -1; _id -= 13; } #endif // QT_NO_PROPERTIES return _id; }
int ONVIF::VideoEncoderConfiguration::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { if (_id < 19) qt_static_metacall(this, _c, _id, _a); _id -= 19; } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) { if (_id < 19) *reinterpret_cast<int*>(_a[0]) = -1; _id -= 19; } #ifndef QT_NO_PROPERTIES else if (_c == QMetaObject::ReadProperty) { void *_v = _a[0]; switch (_id) { case 0: *reinterpret_cast< QString*>(_v) = token(); break; case 1: *reinterpret_cast< QString*>(_v) = name(); break; case 2: *reinterpret_cast< int*>(_v) = useCount(); break; case 3: *reinterpret_cast< QString*>(_v) = encoding(); break; case 4: *reinterpret_cast< int*>(_v) = width(); break; case 5: *reinterpret_cast< int*>(_v) = height(); break; case 6: *reinterpret_cast< int*>(_v) = quality(); break; case 7: *reinterpret_cast< int*>(_v) = frameRateLimit(); break; case 8: *reinterpret_cast< int*>(_v) = encodingInterval(); break; case 9: *reinterpret_cast< int*>(_v) = bitrateLimit(); break; case 10: *reinterpret_cast< int*>(_v) = govLength(); break; case 11: *reinterpret_cast< QString*>(_v) = h264Profile(); break; case 12: *reinterpret_cast< QString*>(_v) = type(); break; case 13: *reinterpret_cast< QString*>(_v) = ipv4Address(); break; case 14: *reinterpret_cast< QString*>(_v) = ipv6Address(); break; case 15: *reinterpret_cast< int*>(_v) = port(); break; case 16: *reinterpret_cast< int*>(_v) = ttl(); break; case 17: *reinterpret_cast< bool*>(_v) = autoStart(); break; case 18: *reinterpret_cast< QString*>(_v) = sessionTimeout(); break; default: break; } _id -= 19; } else if (_c == QMetaObject::WriteProperty) { void *_v = _a[0]; switch (_id) { case 0: setToken(*reinterpret_cast< QString*>(_v)); break; case 1: setName(*reinterpret_cast< QString*>(_v)); break; case 2: setUseCount(*reinterpret_cast< int*>(_v)); break; case 3: setEncoding(*reinterpret_cast< QString*>(_v)); break; case 4: setWidth(*reinterpret_cast< int*>(_v)); break; case 5: setHeight(*reinterpret_cast< int*>(_v)); break; case 6: setQuality(*reinterpret_cast< int*>(_v)); break; case 7: setFrameRateLimit(*reinterpret_cast< int*>(_v)); break; case 8: setEncodingInterval(*reinterpret_cast< int*>(_v)); break; case 9: setBitrateLimit(*reinterpret_cast< int*>(_v)); break; case 10: setGovLength(*reinterpret_cast< int*>(_v)); break; case 11: setH264Profile(*reinterpret_cast< QString*>(_v)); break; case 12: setType(*reinterpret_cast< QString*>(_v)); break; case 13: setIpv4Address(*reinterpret_cast< QString*>(_v)); break; case 14: setIpv6Address(*reinterpret_cast< QString*>(_v)); break; case 15: setPort(*reinterpret_cast< int*>(_v)); break; case 16: setTtl(*reinterpret_cast< int*>(_v)); break; case 17: setAutoStart(*reinterpret_cast< bool*>(_v)); break; case 18: setSessionTimeout(*reinterpret_cast< QString*>(_v)); break; default: break; } _id -= 19; } else if (_c == QMetaObject::ResetProperty) { _id -= 19; } else if (_c == QMetaObject::QueryPropertyDesignable) { _id -= 19; } else if (_c == QMetaObject::QueryPropertyScriptable) { _id -= 19; } else if (_c == QMetaObject::QueryPropertyStored) { _id -= 19; } else if (_c == QMetaObject::QueryPropertyEditable) { _id -= 19; } else if (_c == QMetaObject::QueryPropertyUser) { _id -= 19; } else if (_c == QMetaObject::RegisterPropertyMetaType) { if (_id < 19) *reinterpret_cast<int*>(_a[0]) = -1; _id -= 19; } #endif // QT_NO_PROPERTIES return _id; }