LNE_NAMESPACE_USING void TestClient() { TimeValue tv(3); SockAddr addr("www.google.com:80"); SockConnector *connector = SockConnector::NewInstance(addr, &tv); if(connector == NULL) { printf("connector cannot create\n"); return; } SockPad skpad; if(connector->Connect(skpad) != LNERR_OK) { printf("connector cannot connect\n"); connector->Release(); return; } SockWaves *stream = SockWaves::NewInstance(skpad); const char *query = "GET / HTTP/1.1\r\n\r\n"; DataBlock *block = DataBlock::NewInstance(1024 * 1024); strcpy(block->buffer(), query); block->set_size(static_cast<LNE_UINT>(strlen(block->buffer()))); stream->Send(block); while(stream->Recv(block, tv) == LNERR_OK) { block->buffer()[block->size()] = '\0'; puts(block->buffer()); } block->Release(); SockAddr addr_sock, addr_peer; stream->GetSockAddr(addr_sock); stream->GetPeerAddr(addr_peer); printf("connect %s => %s\n", addr_sock.addr_text(), addr_peer.addr_text()); stream->Release(); connector->Release(); }
void SockSpray::Send(DataBlock *blocks[], LNE_UINT count) { LNE_ASSERT_RETURN_VOID(blocks != NULL && count > 0); bool to_handle = true; // ignore when shutdown shutdown_lock_.Lock(); if(shutdown_state_.already || shutdown_state_.query) to_handle = false; shutdown_lock_.Unlock(); if(!to_handle) return; // append to queue DataBlock *block; send_lock_.Lock(); for(LNE_UINT i = 0; to_handle && i < count; ++i) { block = blocks[i]; block->AddRef(); if(send_blocks_.Append(block) != LNERR_OK) { block->Release(); to_handle = false; } else if(send_blocks_.count() > limit_write_cache_) to_handle = false; } if(!to_handle) { shutdown_lock_.Lock(); shutdown_state_.query = true; shutdown_lock_.Unlock(); } send_lock_.Unlock(); if(to_handle) __HandleWrite(); }
inline void SerialData::Append(SerialData * pIns) { DataNode * pNewNode = new DataNode(pIns->m_pPrev,m_pData,m_pPrev); m_pData->Release(); m_pData = pIns->m_pData; pIns->m_pData->AddRef(); if (m_pPrev) m_pPrev->Release(); m_pPrev = pNewNode; }
LNE_NAMESPACE_USING void TestObject() { LNE_UINT i, v; ObjectList<LNE_UINT> list; for(int i = 0; i < 3; i++) list.PushFront(i + 1); while(list.PopFront(v) == LNERR_OK) { printf("%u\n", v); } DataBlock *block; ObjectQueue<DataBlock *> queue; DataBlockPool *pool = DataBlockPool::NewInstance(); for(i = 0; i < 10000; ++i) queue.Append(pool->Alloc()); i = 0; while(queue.Extract(block) == LNERR_OK) { ++i; block->Release(); } printf("data count: %u\n", i); pool->Release(); }
void SockSpray::__HandleRead(void) { bool to_handle = true; // ignore when shutdown shutdown_lock_.Lock(); if(shutdown_state_.already || shutdown_state_.query) to_handle = false; shutdown_lock_.Unlock(); if(!to_handle) return; // lock recv process recv_lock_.Lock(); if(recv_state_.already) { to_handle = false; recv_state_.ready = true; } else { recv_state_.ready = false; recv_state_.already = true; } recv_lock_.Unlock(); if(!to_handle) return; ssize_t len; DataBlock *block; bool continue_recv = false, to_shutdown = false; recv_data_next: do { block = pool_->Alloc(); if(block == NULL) to_shutdown = true; else { do { len = recv(skpad_.socket(), block->buffer_free(), block->free_size(), 0); if(len > 0) block->set_size(block->size() + len); #if defined(LNE_WIN32) } while(len > 0 && !block->IsFull()); #else } while((len > 0 && !block->IsFull()) || (len < 0 && errno == EINTR)); #endif if(len > 0) continue_recv = true; #if defined(LNE_WIN32) else if(len == 0 || WSAGetLastError() != WSAEWOULDBLOCK) #else else if(len == 0 || errno != EWOULDBLOCK) #endif to_shutdown = true; else continue_recv = false; // process data if(!block->IsEmpty()) handler_->HandleData(this, block); block->Release(); if(continue_recv) { shutdown_lock_.Lock(); if(shutdown_state_.query) { to_shutdown = true; continue_recv = false; } shutdown_lock_.Unlock(); } #if defined(LNE_WIN32) if(!continue_recv && !to_shutdown) { DWORD bytes, flags = 0; iocp_lock_.Lock(); int rc = WSARecv(skpad_.socket(), &iocp_data_.buffer, 1, &bytes, &flags, &iocp_data_.overlap[IOCP_READ], NULL); if(rc == SOCKET_ERROR && WSAGetLastError() != ERROR_IO_PENDING) to_shutdown = true; else ++iocp_data_.count; iocp_lock_.Unlock(); } #endif } } while(continue_recv && !to_shutdown); // check shutdown shutdown_lock_.Lock(); if(!shutdown_state_.already && to_shutdown) __Shutdown(); shutdown_lock_.Unlock(); // lock unlock process to_handle = false; recv_lock_.Lock(); if(!recv_state_.ready || to_shutdown) recv_state_.already = false; else { to_handle = true; recv_state_.ready = false; } recv_lock_.Unlock(); if(to_handle) goto recv_data_next; }