HRESULT __stdcall DpReadChannelData(CHANNEL_HANDLE handle, char * buf, int lenBuf, int * pLenRead) { Lock(&viewerMain.spinLockChannelTable); Channel * channel = (Channel *)viewerMain.channelHandleTable.Get((int)handle); Unlock(&viewerMain.spinLockChannelTable); if (channel == 0) { if (pLenRead != 0) *pLenRead = 0; return E_INVALID_CHANNEL_HANDLE; } int lenRead = channel->Read(buf, lenBuf); if (pLenRead != 0) *pLenRead = lenRead; if (lenRead < lenBuf) { if (!channel->IsWriterAlive()) return E_CHANNEL_CLOSED; } return S_OK; }
/** * FrameProxy::MessageHandlerListener */ DWORD FrameProxy::MessageHandlerListener(LPVOID param) { logger->debug(L"FrameProxy::MessageHandlerListener" L" -> " + boost::lexical_cast<wstring>(param)); Channel *channel = (Channel*)param; char buffer[Channel::SECTION_SIZE]; while (channel->Read(buffer, Channel::SECTION_SIZE)) { UINTX type = *(UINTX*)buffer; logger->debug(L"FrameProxy::MessageHandlerListener type" L" -> " + boost::lexical_cast<wstring>(type)); switch(type) { case ForwardedMessage::COMMAND_TYPE: { logger->debug(L"FrameProxy::MessageHandlerListener ForwardedMessage"); ForwardedMessage *message = (ForwardedMessage*)buffer; FrameProxy *proxy = (FrameProxy*)message->proxy; LRESULT result; proxy->WndProcTarget(&result, message->msg, message->wparam, message->lparam); } break; case button_onClickCommand::COMMAND_TYPE: { logger->debug(L"FrameProxy::MessageHandlerListener button_onClickCommand"); button_onClickCommand *command = (button_onClickCommand*)buffer; command->exec(); } break; default: logger->debug(L"FrameProxy::MessageHandlerListener unknown type" L" -> " + boost::lexical_cast<wstring>(type)); ForwardedMessage *message = (ForwardedMessage*)buffer; FrameProxy *proxy = (FrameProxy*)message->proxy; LRESULT result; proxy->WndProcTarget(&result, message->msg, message->wparam, message->lparam); break; } } return 0; }
void fibonacci(std::uint16_t n, Channel < std::pair<std::uint16_t, std::uint64_t> > chan, Channel<int> stopchan){ // First fibonacci is 0 // So go ahead and write that as our first value auto fut = chan.Write({ 0, 0 }); auto stopfut = stopchan.Read(); // A vector to hold our intermediate calculations std::vector<std::uint64_t> fibs(n+1); if (n == 0){ return; } if (n == 1){ chan.Write({ 1, 1 }); return; } // Set the 0th and 1st fibonacci numbers fibs[0] = 0; fibs[1] = 1; // Calculate all the fibonacci numbers up to and including n for (std::uint16_t i = 2; i <= n; ++i){ // Fibonacci forumula fibs[i] = fibs[i - 2] + fibs[i - 1]; // fut (the Future from chan.Write, will become ready when somebody reads the channel // that is a trigger that we need to write the latest value to the channel // Also, if we are done calculating (i==n) we write the value to the channel if (fut.Ready() || i==n || stopfut.Ready()){ fut = chan.Write({ i, fibs[i] }); // Check if we were called to stop if (stopfut.Ready()){ return; } } // Slow us down so it looks like a long calculation, otherwise it runs too fast std::this_thread::sleep_for(std::chrono::milliseconds(500)); } }
void tcp_echo_server(int port, Channel<int> stopchan, use<ITty> out, awaiter await){ // stopfut will become ready when someone writes to the channel auto stopfut = stopchan.Read(); // Set up our Tcp Server at the specified port TcpStream server; auto server_addr = Uv::Ip4Addr("0.0.0.0", port); server.Bind(server_addr); // We use this to tell the client connections they should stop auto stopclientchan = make_channel<int>(); // Start listening server.Listen(1, resumable([stopclientchan](use<IUvStream> is, int, awaiter await){ // This is the function that handles the client auto stopfut = stopclientchan.Read(); TcpStream client; is.Accept(client); // Get the read channel auto readchan = client.ReadStartWithChannel(); // Loop and read the channel, as long as while ( !stopfut.Ready()){ // Get the readfuture from the channel auto readfut = readchan.Read(); // Wait for either some data available to read, or else we were told to stop await(when_any(readfut,stopfut)); // Check that the read future is the cause as opposed to being told to stop if (readfut.Ready()){ // Get the buffer auto buf = readfut.Get(); // Generate the http response // In this case we are echoing back using http std::stringstream strstream; strstream << "HTTP/1.1 200 OK\r\n" "Content-Type: text/plain\r\n" "Content-Length: " << buf.Size() << "\r\n" "\r\n"; strstream.write(buf.Begin(), buf.Size()); strstream << "\r\n\r\n"; // Write to the client await(client.Write(strstream.str())); } } })); // as opposed to await.operator(), await.as_future returns the future // This is useful if you don't want to throw an exception on an error in the future await.as_future(stopfut); // This will close out all the attempted reads on the channel with an error stopclientchan.Complete(); }