Ejemplo n.º 1
2
Socket_Stream Socket_Listener_accept(Socket_Listener self) {
    // Waits for a client to connect, then returns a pointer to the established
    // connection.  The code below is a bit tricky, because Windows expects the
    // call to accept() to happen before the I/O event can be triggered.  For
    // Unix systems, the wait happens first, and then accept() is used to
    // receive the incoming socket afterwards.
    Socket_Stream stream = 0;

    // Begin the call to accept() by creating a new socket and issuing a call 
    // to AcceptEx.
    char buffer[(sizeof(struct sockaddr_in)+16)*2];
    DWORD socklen = sizeof(struct sockaddr_in)+16;
    DWORD read = 0;
    DWORD code = SIO_GET_EXTENSION_FUNCTION_POINTER;
    GUID guid = WSAID_ACCEPTEX;
    LPFN_ACCEPTEX AcceptEx = 0;
    DWORD bytes = 0;
    DWORD len = sizeof(AcceptEx);
    Io_Overlapped op;
    OVERLAPPED* evt = &op.overlapped;

    // Create a new socket for AcceptEx to use when a peer connects.
    SOCKET ls = self->handle;
    SOCKET sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sd < 0) {
        Boot_abort();
    }

    // Get a pointer to the AcceptEx() function.
    WSAIoctl(sd, code, &guid, sizeof(guid), &AcceptEx, len, &bytes, 0, 0);
    
    // Initialize the OVERLAPPED structure that contains the user I/O data used
    // to resume the coroutine when AcceptEx completes. 
    memset(&op, 0, sizeof(op));
    op.coroutine = Coroutine__current;

    // Now call ConnectEx to begin accepting peer connections.  The call will
    // return immediately, allowing this function to yield to the I/O manager.
    if (!AcceptEx(ls, sd, buffer, 0, socklen, socklen, &read, evt)) {
        while (ERROR_IO_PENDING == GetLastError()) {
            // Wait for the I/O manager to yield after polling the I/O
            // completion port, and then get the result.
            Coroutine__iowait();
            SetLastError(ERROR_SUCCESS);
            GetOverlappedResult((HANDLE)sd, evt, &bytes, 1);
        } 
        if (ERROR_SUCCESS != GetLastError()) {
            Boot_abort();
        }
    }
    
    // The following setsockopt() call is needed when calling AcceptEx.  From
    // the MSDN documentation: 
    //
    // When the AcceptEx function returns, the socket sAcceptSocket is in the
    // default state for a connected socket. The socket sAcceptSocket does not
    // inherit the properties of the socket associated with sListenSocket
    // parameter until SO_UPDATE_ACCEPT_CONTEXT is set on the socket. Use the
    // setsockopt function to set the SO_UPDATE_ACCEPT_CONTEXT option,
    // specifying sAcceptSocket as the socket handle and sListenSocket as the
    // option value.
    if (setsockopt(sd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char const*)&ls, sizeof(ls))) {
        Boot_abort();
    }

    stream = Socket_Stream__init();
    stream->stream = Io_Stream__init(sd, Io_StreamType_SOCKET);
    return stream;
}
Ejemplo n.º 2
0
co_rc_t co_win32_overlapped_read_completed(co_win32_overlapped_t *overlapped)
{
	BOOL result;

	result = GetOverlappedResult(
		overlapped->handle,
		&overlapped->read_overlapped,
		&overlapped->size,
		FALSE);

	if (result) {
		co_win32_overlapped_read_received(overlapped);
		co_win32_overlapped_read_async(overlapped);
	} else {
		if (GetLastError() == ERROR_BROKEN_PIPE) {
			co_debug("Pipe broken, exiting\n");
			return CO_RC(ERROR);
		}

		co_debug("GetOverlappedResult error %d\n", GetLastError());
	}
	 
	return CO_RC(OK);
}
Ejemplo n.º 3
0
bool
LocalServer::read_data(void* buffer, int len)
{
	OVERLAPPED overlapped;
	overlapped.Offset = 0;
	overlapped.OffsetHigh = 0;
	overlapped.hEvent = 0;
	DWORD bytes;
	BOOL done = ReadFile(m_pipe, buffer, len, &bytes, &overlapped);
	if (done == FALSE) {
		DWORD error = GetLastError();
		if (error != ERROR_IO_PENDING) {
			dprintf(D_ALWAYS, "ReadFileError: %u\n", error);
			return false;
		}
		if (GetOverlappedResult(m_pipe, &overlapped, &bytes, TRUE) == FALSE) {
			dprintf(D_ALWAYS, "GetOverlappedResult error: %u\n", GetLastError());
			return false;
		}
	}
	ASSERT(bytes == len);

	return true;
}
Ejemplo n.º 4
0
		int wait(HANDLE file, error_code& ec)
		{
			if (ol.hEvent != INVALID_HANDLE_VALUE
				&& WaitForSingleObject(ol.hEvent, INFINITE) == WAIT_FAILED)
			{
				ec.assign(GetLastError(), system_category());
				return -1;
			}

			DWORD ret;
			if (GetOverlappedResult(file, &ol, &ret, false) == 0)
			{
				DWORD last_error = GetLastError();
				if (last_error != ERROR_HANDLE_EOF)
				{
#ifdef ERROR_CANT_WAIT
					TORRENT_ASSERT(last_error != ERROR_CANT_WAIT);
#endif
					ec.assign(last_error, system_category());
					return -1;
				}
			}
			return ret;
		}
Ejemplo n.º 5
0
//
// Character received. Inform the owner
//
void CSerialPort::ReceiveChar(CSerialPort* port)
{
    BOOL  bRead = TRUE;
    BOOL  bResult = TRUE;
    DWORD dwError = 0;
    DWORD BytesRead = 0;
    COMSTAT comstat;
    unsigned char RXBuff;

    for (;;)
    {
        //add by liquanhai 2011-11-06  防止死锁
        if(WaitForSingleObject(port->m_hShutdownEvent,0)==WAIT_OBJECT_0)
            return;

        // Gain ownership of the comm port critical section.
        // This process guarantees no other part of this program
        // is using the port object.

        EnterCriticalSection(&port->m_csCommunicationSync);

        // ClearCommError() will update the COMSTAT structure and
        // clear any other errors.
        ///更新COMSTAT

        bResult = ClearCommError(port->m_hComm, &dwError, &comstat);

        LeaveCriticalSection(&port->m_csCommunicationSync);

        // start forever loop.  I use this type of loop because I
        // do not know at runtime how many loops this will have to
        // run. My solution is to start a forever loop and to
        // break out of it when I have processed all of the
        // data available.  Be careful with this approach and
        // be sure your loop will exit.
        // My reasons for this are not as clear in this sample
        // as it is in my production code, but I have found this
        // solutiion to be the most efficient way to do this.

        ///所有字符均被读出,中断循环
        if (comstat.cbInQue == 0)
        {
            // break out when all bytes have been read
            break;
        }

        EnterCriticalSection(&port->m_csCommunicationSync);

        if (bRead)
        {
            ///串口读出,读出缓冲区中字节
            bResult = ReadFile(port->m_hComm,		// Handle to COMM port
                               &RXBuff,				// RX Buffer Pointer
                               1,					// Read one byte
                               &BytesRead,			// Stores number of bytes read
                               &port->m_ov);		// pointer to the m_ov structure
            // deal with the error code
            ///若返回错误,错误处理
            if (!bResult)
            {
                switch (dwError = GetLastError())
                {
                case ERROR_IO_PENDING:
                {
                    // asynchronous i/o is still in progress
                    // Proceed on to GetOverlappedResults();
                    ///异步IO仍在进行
                    bRead = FALSE;
                    break;
                }
                default:
                {
                    // Another error has occured.  Process this error.
                    port->ProcessErrorMessage("ReadFile()");
                    break;
                    //return;///防止读写数据时,串口非正常断开导致死循环一直执行。add by itas109 2014-01-09 与上面liquanhai添加防死锁的代码差不多
                }
                }
            }
            else///ReadFile返回TRUE
            {
                // ReadFile() returned complete. It is not necessary to call GetOverlappedResults()
                bRead = TRUE;
            }
        }  // close if (bRead)

        ///异步IO操作仍在进行,需要调用GetOverlappedResult查询
        if (!bRead)
        {
            bRead = TRUE;
            bResult = GetOverlappedResult(port->m_hComm,	// Handle to COMM port
                                          &port->m_ov,		// Overlapped structure
                                          &BytesRead,		// Stores number of bytes read
                                          TRUE); 			// Wait flag

            // deal with the error code
            if (!bResult)
            {
                port->ProcessErrorMessage("GetOverlappedResults() in ReadFile()");
            }
        }  // close if (!bRead)

        LeaveCriticalSection(&port->m_csCommunicationSync);

        // notify parent that a byte was received
        ::SendMessage((port->m_pOwner), WM_COMM_RXCHAR, (WPARAM) RXBuff, (LPARAM) port->m_nPortNr);
    } // end forever loop

}
    std::size_t Win32NamedPipeClientTransport::implRead(
        const ByteBuffer &byteBuffer,
        std::size_t bytesRequested)
    {
        // For now, can't go back to sync calls after doing an async call.
        // Limitations with Windows IOCP.
        RCF_ASSERT(!mAsyncMode);

        std::size_t bytesToRead = RCF_MIN(bytesRequested, byteBuffer.getLength());

        BOOL ok = ResetEvent(mhEvent);
        DWORD dwErr = GetLastError();
        RCF_VERIFY(ok, Exception(_RcfError_Pipe(), dwErr));

        OVERLAPPED overlapped = {0};
        overlapped.hEvent = mhEvent;

        DWORD dwRead = 0;
        DWORD dwBytesToRead = static_cast<DWORD>(bytesToRead);

        ok = ReadFile(
            mhPipe, 
            byteBuffer.getPtr(), 
            dwBytesToRead, 
            &dwRead, 
            &overlapped);
        
        dwErr = GetLastError();

        if (!ok)
        {
            RCF_VERIFY( 
                dwErr == ERROR_IO_PENDING ||
                dwErr == WSA_IO_PENDING ||
                dwErr == ERROR_MORE_DATA,
                Exception(_RcfError_ClientReadFail(), dwErr));
        }

        ClientStub & clientStub = *getTlsClientStubPtr();

        DWORD dwRet = WAIT_TIMEOUT;
        while (dwRet == WAIT_TIMEOUT)
        {
            boost::uint32_t timeoutMs = generateTimeoutMs(mEndTimeMs);
            timeoutMs = clientStub.generatePollingTimeout(timeoutMs);

            dwRet = WaitForSingleObject(overlapped.hEvent, timeoutMs);
            dwErr = GetLastError();

            RCF_VERIFY( 
                dwRet == WAIT_OBJECT_0 || dwRet == WAIT_TIMEOUT, 
                Exception(_RcfError_Pipe(), dwErr));

            RCF_VERIFY(
                generateTimeoutMs(mEndTimeMs),
                Exception(_RcfError_ClientReadTimeout()))
                (mEndTimeMs)(bytesToRead);

            if (dwRet == WAIT_TIMEOUT)
            {
                clientStub.onPollingTimeout();
            }
        }
        RCF_ASSERT_EQ(dwRet , WAIT_OBJECT_0);

        dwRead = 0;
        ok = GetOverlappedResult(mhPipe, &overlapped, &dwRead, FALSE);
        dwErr = GetLastError();
        RCF_VERIFY(ok && dwRead > 0, Exception(_RcfError_Pipe(), dwErr));

        onTimedRecvCompleted(dwRead, 0);

        return dwRead;
    }
Ejemplo n.º 7
0
//    Entry Point
void *OCP_DataStreamInput_Thread::Entry()
{
    wxString msg;
    OVERLAPPED osReader = {0};
    OVERLAPPED osWriter = {0};
    
    m_launcher->SetSecThreadActive();               // I am alive
    
    wxSleep(1);         //  allow Bluetooth SPP connections to re-cycle after the parent's test for existence.
                        //  In the MS Bluetooth stack, there is apparently a minimum time required
                        //  between CloseHandle() and CreateFile() on the same port.
                        // FS#1008

    bool not_done;
    HANDLE hSerialComm = (HANDLE)(-1);

       //    Request the com port from the comm manager
    if ((m_gps_fd = OpenComPortPhysical(m_PortName, m_baud)) < 0)
    {
        wxString msg(_T("NMEA input device initial open failed: "));
        msg.Append(m_PortName);
        wxString msg_error;
        msg_error.Printf(_T("...GetLastError():  %d"), GetLastError());
        msg.Append(msg_error);

        ThreadMessage(msg);
        m_gps_fd = NULL;
//        goto thread_exit;
    }

    hSerialComm = (HANDLE)m_gps_fd;

    int n_reopen_wait = 2000;
    
    COMMTIMEOUTS timeouts;

    //  Short read timeout for faster response
    timeouts.ReadIntervalTimeout = 1;
    timeouts.ReadTotalTimeoutMultiplier = 0;
    timeouts.ReadTotalTimeoutConstant = 0;
    timeouts.WriteTotalTimeoutMultiplier = 0;
    timeouts.WriteTotalTimeoutConstant = 500; 
    
    
    if(m_gps_fd){
        if (!SetCommTimeouts(hSerialComm, &timeouts)){ // Error setting time-outs.
            CloseComPortPhysical(m_gps_fd);
            m_gps_fd = NULL;
        }            
    }

      // Create the reader overlapped event.
    osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    // Create the writer overlapped event.
    osWriter.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    
      
    not_done = true;

#define READ_BUF_SIZE 200
    char szBuf[READ_BUF_SIZE];
    
#define READ_TIMEOUT      50      // milliseconds
    
    DWORD dwRead;
    DWORD dwWritten;
    DWORD dwRes;
    DWORD dwToWrite;

    int n_timeout = 0;
    int max_timeout = 100;
    
    bool fWaitingOnRead = false;
    bool fWaitingOnWrite = false;
    
    
//    The main loop

    while(not_done)
    {
        if(TestDestroy())
            not_done = false;                               // smooth exit

       //    Was port closed due to error condition?
        while(!m_gps_fd)
        {
            if((TestDestroy()) || (m_launcher->m_Thread_run_flag == 0))
                goto thread_exit;                               // smooth exit

            if(n_reopen_wait){
                int nrwd10 = wxMax(1, n_reopen_wait /10);

                while(n_reopen_wait > 0){
                    wxThread::Sleep(nrwd10);                        // stall for a bit
                    
                    if((TestDestroy()) || (m_launcher->m_Thread_run_flag == 0))
                        goto thread_exit;                               // smooth exit
                    
                    n_reopen_wait -= nrwd10;
                }
                        
                n_reopen_wait = 0;
            }


            if ((m_gps_fd = OpenComPortPhysical(m_PortName, m_baud)) > 0)
            {
                hSerialComm = (HANDLE)m_gps_fd;

                wxThread::Sleep(100);                        // stall for a bit
                
                if (!SetCommTimeouts(hSerialComm, &timeouts)){ // Error setting time-outs.
                      int errt = GetLastError();                // so just retry
                      CloseComPortPhysical(m_gps_fd);
                      m_gps_fd = NULL;
                      
                }
                
                fWaitingOnWrite = FALSE;
                fWaitingOnRead = FALSE;
                n_timeout = 0;
                
            }
            else
            {
                m_gps_fd = 0;
                
                int nwait = 2000;
                while(nwait > 0){
                    wxThread::Sleep(200);                        // stall for a bit
                    
                    if((TestDestroy()) || (m_launcher->m_Thread_run_flag == 0))
                        goto thread_exit;                               // smooth exit
                        
                    nwait -= 200;
                }
            }
        }

        if( (m_io_select == DS_TYPE_INPUT_OUTPUT) || (m_io_select == DS_TYPE_OUTPUT) ) {
                m_outCritical.Enter();
                bool b_qdata = !out_que.empty();
                    
                bool b_break = false;
                while(!b_break && b_qdata){
                    char msg[MAX_OUT_QUEUE_MESSAGE_LENGTH];
                    
//                    printf("wl %d\n", out_que.size());
                    {
                        
                        if(fWaitingOnWrite){
//                            printf("wow\n");
                            dwRes = WaitForSingleObject(osWriter.hEvent, INFINITE);
                            
                            switch(dwRes)
                            {
                                case WAIT_OBJECT_0:
                                    if (!GetOverlappedResult(hSerialComm, &osWriter, &dwWritten, FALSE)) {
                                        if (GetLastError() == ERROR_OPERATION_ABORTED){
                                            //    UpdateStatus("Write aborted\r\n");
                                        }
                                        else{
                                            b_break = true;
                                        }
                                    }
                                    
                                    if (dwWritten != dwToWrite) {
                                        //ErrorReporter("Error writing data to port (overlapped)");
                                    }
                                    else {
                                        // Delayed write completed
                                        fWaitingOnWrite = false;
//                                        printf("-wow\n");
                                    }
                                    break;
                                    
                                //                
                                // wait timed out
                                //
                                case WAIT_TIMEOUT:
                                    break;
                                    
                                case WAIT_FAILED:
                                default:
                                    break;
                            }
                            
                        }
                        if(!fWaitingOnWrite){          // not waiting on Write, OK to issue another
                        
                        //  Take a copy of message
                            char *qmsg = out_que.front();
                            strncpy( msg, qmsg, MAX_OUT_QUEUE_MESSAGE_LENGTH-1 );
                            out_que.pop();
                            free(qmsg);
 
                            dwToWrite = strlen(msg);
                            //
                            // issue write
                            //
                            n_timeout = 0;
                            
//                            printf("w\n");
                            if (!WriteFile(hSerialComm, msg, dwToWrite, &dwWritten, &osWriter)) {
                                if (GetLastError() == ERROR_IO_PENDING) { 
                                //
                                // write is delayed
                                //
                                    fWaitingOnWrite = true;
//                                    printf("+wow\n");
                                }
                                else{
                                    b_break = true;
                                }
                            }
                            else {
                            //
                            // writefile returned immediately
                            //
                            }

                            b_qdata = !out_que.empty();
                            
                        }
                    }
                    
                } //while b_qdata
                

            
                m_outCritical.Leave();
        }
        
        
        //
        // if no read is outstanding, then issue another one
        //
//        printf("r\n");
        if (!fWaitingOnRead) {
            if (!ReadFile(hSerialComm, szBuf, READ_BUF_SIZE, &dwRead, &osReader)) {
                if (GetLastError() != ERROR_IO_PENDING) {  // read not delayed?
                        CloseComPortPhysical(m_gps_fd);
                        m_gps_fd = NULL;
                        fWaitingOnRead = FALSE;
                        n_reopen_wait = 2000;
                }
                else
                    fWaitingOnRead = TRUE;
            }
            else {    // read completed immediately
                n_timeout = 0;
                
                if (dwRead)
                    HandleASuccessfulRead(szBuf, dwRead);
            }
        }
        
        //
        // wait for pending operations to complete
        //
        if ( fWaitingOnRead ) {
            dwRes = WaitForSingleObject(osReader.hEvent, READ_TIMEOUT);
            
            switch(dwRes)
            {
                //
                // read completed
                //
                case WAIT_OBJECT_0:
                    if (!GetOverlappedResult(hSerialComm, &osReader, &dwRead, FALSE)) {
                        int err = GetLastError();
                        if (GetLastError() == ERROR_OPERATION_ABORTED){
                        }
                        else{
                                //      Some other error
                            n_reopen_wait = 2000;
                            CloseComPortPhysical(m_gps_fd);
                            m_gps_fd = 0;
                        }
                    }
                    else {      // read completed successfully
                        if (dwRead)
                            HandleASuccessfulRead(szBuf, dwRead);
                    }
                    
                    fWaitingOnRead = FALSE;
                    n_timeout = 0;
                    
                    break;
                    
                case WAIT_TIMEOUT:
                    n_timeout++;
                        
                    break;                       
                    
                default:                // error of some kind with handles
                    fWaitingOnRead = FALSE;
                    break;
            }
        }
        
        if(m_launcher->m_Thread_run_flag <= 0)
            not_done = false;
        
    }           // the big while...



thread_exit:

//          Close the port cleanly
    CloseComPortPhysical(m_gps_fd);

    m_launcher->SetSecThreadInActive();             // I am dead
    m_launcher->m_Thread_run_flag = -1;

    return 0;

}
Ejemplo n.º 8
0
int ADIOI_NTFS_ReadDone(ADIO_Request *request, ADIO_Status *status,
			int *error_code)
{
    DWORD ret_val;
    int done = 0;
    static char myname[] = "ADIOI_NTFS_ReadDone";

    if (*request == ADIO_REQUEST_NULL)
    {
	*error_code = MPI_SUCCESS;
	return 1;
    }

    if ((*request)->queued) 
    {
	(*request)->nbytes = 0;
	ret_val = GetOverlappedResult((*request)->fd, (*request)->handle, &(*request)->nbytes, FALSE);

	if (!ret_val)
	{
	    /* --BEGIN ERROR HANDLING-- */
	    ret_val = GetLastError();
	    if (ret_val == ERROR_IO_INCOMPLETE)
	    {
		done = 0;
		*error_code = MPI_SUCCESS;
	    }
	    else
	    {
		*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
		    myname, __LINE__, MPI_ERR_IO,
		    "**io", "**io %s", ADIOI_NTFS_Strerror(ret_val));
	    }
	    /* --END ERROR HANDLING-- */
	}
	else 
	{
	    done = 1;		
	    *error_code = MPI_SUCCESS;
	}
    }
    else
    {
	done = 1;
	*error_code = MPI_SUCCESS;
    }
#ifdef HAVE_STATUS_SET_BYTES
    if (done && ((*request)->nbytes != -1))
	MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes);
#endif
    
    if (done) 
    {
	/* if request is still queued in the system, it is also there
	   on ADIOI_Async_list. Delete it from there. */
	if ((*request)->queued) ADIOI_Del_req_from_list(request);
	
	(*request)->fd->async_count--;
	if ((*request)->handle) 
	{
	    if (!CloseHandle(((OVERLAPPED*)((*request)->handle))->hEvent))
	    {
		ret_val = GetLastError();
		*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
		    myname, __LINE__, MPI_ERR_IO,
		    "**io", "**io %s", ADIOI_NTFS_Strerror(ret_val));
	    }
	    ADIOI_Free((*request)->handle);
	}
	ADIOI_Free_request((ADIOI_Req_node *) (*request));
	*request = ADIO_REQUEST_NULL;
    }
    return done;
}
Ejemplo n.º 9
0
DWORD WINAPI
rx_thread(void *lpParameter_)
{
    DWORD dwWaitResult, e;
    char rx_pipe_name[32];
    BOOL b, bReadFail;

    for (;;) {
        int nbytes;
        DWORD NumberOfBytesRead;
        //printf("rx_thread waiting for rx start...\n");
        dbg_rx_state = RS__WAITING_FOR_RXSTART;
    
        dwWaitResult = WaitForSingleObject(ghRxStartEvent, INFINITE);
        if (dwWaitResult != WAIT_OBJECT_0) {
            printf("ghRxStartEvent wait fail %ld, %ld\n", dwWaitResult, GetLastError());
            Sleep(50);
            continue;
        }

        //printf("rx_thread notified\n");
        ResetEvent(ghRxStartEvent);

        if (g_timeout_ms == 0) {
            /* some events on the pipe might cause spurious event */
            //printf("rx_thread: zero timeout\n");
            radio_pipe_close();
            continue;
        }

        sprintf(rx_pipe_name, "%s%02x", pipe_name_prefix, gsid);
create_pipe:
        ghRxPipe = CreateNamedPipe(
            /*LPCTSTR lpName*/rx_pipe_name,
            /*DWORD dwOpenMode*/PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
            /*DWORD dwPipeMode*/PIPE_TYPE_MESSAGE,
            /*DWORD nMaxInstances*/1,  // XXX each receiver on its own pipe XXX
            /*DWORD nOutBufferSize*/0,
            /*DWORD nInBufferSize*/632,
            /*DWORD nDefaultTimeOut*/g_timeout_ms,
            /*LPSECURITY_ATTRIBUTES lpSecurityAttributes*/NULL
        );
        if (ghRxPipe == INVALID_HANDLE_VALUE) {
            e = GetLastError();
            ghRxPipe = NULL;
            if (e == ERROR_PIPE_BUSY) {
                //printf("CreateNamedPipe(): somebody else already receiving  %d\n", g_timeout_ms);
                if (g_timeout_ms > 20) {
                    g_timeout_ms -= 20;
                    Sleep(20);
                    goto create_pipe;
                }
            } else {
                if (e == ERROR_INVALID_HANDLE) {
                    printf("CreateNamedPipe(): ERROR_INVALID_HANDLE\n");
                } else {
                    printf("CreateNamedPipe(): %ld\n", e);
                }
                radio.evtdone(RM2_ERR_GENERIC, 0);
                g_timeout_ms = 0;
            }
            continue;
        }

        // create manual reset event object
        goConnect.hEvent = CreateEvent(
            /*LPSECURITY_ATTRIBUTES lpEventAttributes*/NULL,
            /*BOOL bManualReset*/TRUE,
            /*BOOL bInitialState*/FALSE,
            /*LPCTSTR lpName*/"foo"
        );
        if (goConnect.hEvent == NULL) {
            printf("CreateEvent() %ld\n", GetLastError());
            break;
        }

        b = ConnectNamedPipe(
            /*HANDLE hNamedPipe*/ghRxPipe,
            /*LPOVERLAPPED lpOverlapped*/&goConnect
        );
        if (b != 0) {
            printf("%d = ConnectNamedPipe()\n", b); // unexpected
            break;
        }

#ifdef RADIO_DEBUG
        printf("rx_thread wait %d for connect %s\n", g_timeout_ms, rx_pipe_name);
#endif
        dbg_rx_state = RS__WAITING_FOR_CONNECT;
        dwWaitResult = WaitForSingleObject(goConnect.hEvent, g_timeout_ms);
        if (dwWaitResult == WAIT_TIMEOUT) {
            /* nobody transmitted within timeout period */
#ifdef RADIO_DEBUG
            printf("rx_thread ConnectNamedPipe() WAIT_TIMEOUT\n");
#endif
            radio_pipe_close();
            continue;
        } else if (dwWaitResult != WAIT_OBJECT_0) {
            printf("connect wait failed %ld\n", GetLastError());
            radio_pipe_close();
            continue;
        }

        /* transmitting side has connected */

        bReadFail = FALSE;
        nbytes = em2_remaining_bytes();
        do { // while (nbytes > 0)...
            if (nbytes > (RX_BUF_SIZE-1))
                nbytes = (RX_BUF_SIZE-1);

            dbg_rx_state = RS__READFILE;
            /* this read is blocking: we're in our own thread */
            b = ReadFile(
                /*HANDLE hFile*/ghRxPipe,
                /*LPVOID lpBuffer*/&rx_buf,
                /*DWORD nNumberOfBytesToRead*/nbytes,
                /*LPDWORD lpNumberOfBytesRead*/&NumberOfBytesRead,
                /*LPOVERLAPPED lpOverlapped*/&goConnect
            );

            if (b == 0) {
                DWORD nbt;
                DWORD e = GetLastError();
                if (e == ERROR_PIPE_LISTENING) {
                    bReadFail = TRUE;
                    printf("ReadFile(): write side disconnected\n");
                    radio_pipe_close();
                    break;
                } else if (e == ERROR_IO_PENDING) {
                    /* read operation is completing asynchronously */
                    b = GetOverlappedResult(
                        /*HANDLE hFile*/ghRxPipe,
                        /*LPOVERLAPPED lpOverlapped*/&goConnect,
                        /*LPDWORD lpNumberOfBytesTransferred*/&nbt,
                        /*BOOL bWait*/TRUE /* blocking */
                    );
                    if (b) {
                        rx_buf_in_idx = nbt;
                    } else {
                        e = GetLastError();
                        printf("GetOverlappedResult() failed %ld\n", e);
                        radio_pipe_close();
                        bReadFail = TRUE;
                        break;
                    }
                } else {
                    if (e == ERROR_INVALID_HANDLE) {
                        /* this likely occurs because rx pipe was closed */
                        printf("ReadFile() ERROR_INVALID_HANDLE\n");
                        radio_pipe_close();
                        bReadFail = TRUE;
                        break;
                    } else {
                        printf("ReadFile() failed %ld\n", e);
                        radio_pipe_close();
                        bReadFail = TRUE;
                        break;
                    }
                }
            } else {
                // read operation completed synchronously
                rx_buf_in_idx = NumberOfBytesRead;
            }

            rx_buf_out_idx = 0;
            em2_decode_data();

            nbytes = em2_remaining_bytes();
        } while (nbytes > 0);

        if (bReadFail)
            radio.evtdone(RM2_ERR_GENERIC, 0);
        else
            rx_done_isr(0);

        if (ghRxPipe != NULL) {
            printf("thread: rx handle open\n");
            break;
        }
    } // ...for (;;)

    dbg_rx_state = RS__EXITED;
    printf("rx_thread stop\n");
    return -1;
#if 0
#endif /* #if 0 */

}
Ejemplo n.º 10
0
// Read from the serial port.  Returns only the bytes that are
// already received, up to count.  This always returns without delay,
// returning 0 if nothing has been received
int Serial::Read(void *ptr, int count)
{
	if (!port_is_open) return -1;
	if (count <= 0) return 0;
#if defined(LINUX)
	int n, bits;
	n = read(port_fd, ptr, count);
	if (n < 0 && (errno == EAGAIN || errno == EINTR)) return 0;
	if (n == 0 && ioctl(port_fd, TIOCMGET, &bits) < 0) return -99;
	return n;
#elif defined(MACOSX)
	int n;
	n = read(port_fd, ptr, count);
	if (n < 0 && (errno == EAGAIN || errno == EINTR)) return 0;
	return n;
#elif defined(WINDOWS)
	// first, we'll find out how many bytes have been received
	// and are currently waiting for us in the receive buffer.
	//   http://msdn.microsoft.com/en-us/library/ms885167.aspx
	//   http://msdn.microsoft.com/en-us/library/ms885173.aspx
	//   http://source.winehq.org/WineAPI/ClearCommError.html
	COMSTAT st;
	DWORD errmask=0, num_read, num_request;
	OVERLAPPED ov;
	int r;
	if (!ClearCommError(port_handle, &errmask, &st)) return -1;
	//printf("Read, %d requested, %lu buffered\n", count, st.cbInQue);
	if (st.cbInQue <= 0) return 0;
	// now do a ReadFile, now that we know how much we can read
	// a blocking (non-overlapped) read would be simple, but win32
	// is all-or-nothing on async I/O and we must have it enabled
	// because it's the only way to get a timeout for WaitCommEvent
	num_request = ((DWORD)count < st.cbInQue) ? (DWORD)count : st.cbInQue;
	ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (ov.hEvent == NULL) return -1;
	ov.Internal = ov.InternalHigh = 0;
	ov.Offset = ov.OffsetHigh = 0;
	if (ReadFile(port_handle, ptr, num_request, &num_read, &ov)) {
		// this should usually be the result, since we asked for
		// data we knew was already buffered
		//printf("Read, immediate complete, num_read=%lu\n", num_read);
		r = num_read;
	} else {
		if (GetLastError() == ERROR_IO_PENDING) {
			if (GetOverlappedResult(port_handle, &ov, &num_read, TRUE)) {
				//printf("Read, delayed, num_read=%lu\n", num_read);
				r = num_read;
			} else {
				//printf("Read, delayed error\n");
				r = -1;
			}
		} else {
			//printf("Read, error\n");
			r = -1;
		}
	}
	CloseHandle(ov.hEvent);
	// TODO: how much overhead does creating new event objects on
	// every I/O request really cost?  Would it be better to create
	// just 3 when we open the port, and reset/reuse them every time?
	// Would mutexes or critical sections be needed to protect them?
	return r;
#endif
}
Ejemplo n.º 11
0
Archivo: try.cpp Proyecto: LevGit/Rep
int main(int argc, char *argv[])
{
SDL_DisplayMode displayMode;
if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
    std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
    return 1;
}
int request = SDL_GetDesktopDisplayMode(0,&displayMode);
SDL_Window *win = SDL_CreateWindow("Hello World!", 0, 0, 333,227, SDL_WINDOW_SHOWN);
if (win == NULL){
    std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
    return 1;
}
SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (ren == NULL){
    std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
    return 1;
}
SDL_Rect player_RECT;
        player_RECT.x = 0;   //Смещение полотна по Х
        player_RECT.y = 0;   //Смещение полотна по Y
        player_RECT.w = 333; //Ширина полотна
        player_RECT.h = 227; //Высота полотна

SDL_Rect background_RECT;
        background_RECT.x = 0;
        background_RECT.y = 0;
        background_RECT.w = 333;
        background_RECT.h = 227;

            char bufrd[255], bufwt[255];
            HANDLE ComPort;
            OVERLAPPED olread;
            OVERLAPPED olwrite;
            COMSTAT comstat;
            DWORD mask, tempwrite, tempread, bytesread;


// Block of port openning

int NumofCom = 1;
char NameofCom[5] = "COM1";
char NumofComc[2];
ComPort = CreateFile(NameofCom, GENERIC_READ|GENERIC_WRITE, 0, NULL,OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
olread.hEvent = CreateEvent(NULL,true,true,NULL);

while(ComPort==INVALID_HANDLE_VALUE&&NumofCom<20)
{
    NumofCom++;
    strcpy(NameofCom, "COM");
    itoa(NumofCom,NumofComc, 10);
    strcat(NameofCom, NumofComc);
    ComPort = CreateFile(NameofCom, GENERIC_READ|GENERIC_WRITE, 0, NULL,OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
olread.hEvent = CreateEvent(NULL,true,true,NULL);
}
::std::cout<<NameofCom;

//

if(NumofCom <20)
{

olwrite.hEvent = CreateEvent(NULL,TRUE,TRUE,NULL);
olwrite.Internal = 0;
olwrite.InternalHigh = 0;
strcpy(bufwt, "Hello");
WriteFile(ComPort,bufwt, strlen(bufwt),&tempwrite, &olwrite);
DWORD signal = WaitForSingleObject(olwrite.hEvent, INFINITE);
bool fl;
 //если операция завершилась успешно, установить соответствующий флажок
 if((signal == WAIT_OBJECT_0) && (GetOverlappedResult(ComPort, &olwrite, &tempwrite, true))) fl = true;
 else fl = false;
//вывести состояние операции в строке состояния
 CloseHandle(olwrite.hEvent);
::std::cout<<"Writed!"<<MB_ICONERROR<<" "<<tempwrite<<" "<<fl;

//while()
::std::cout<<"Reading Begin";
olread.hEvent = CreateEvent(NULL,TRUE,TRUE,NULL);
olread.Internal = 0;
olread.InternalHigh = 0;
SetCommMask(ComPort, EV_RXCHAR);
WaitCommEvent(ComPort, &mask, &olread);
::std::cout<<"Char received!";

//problem is here!
signal=WaitForSingleObject(olread.hEvent, INFINITE);
::std::cout<<"Single object received!";

if(signal==WAIT_OBJECT_0)
{
    if(GetOverlappedResult(ComPort, &olread, &tempread, true))
{
      if(mask&EV_RXCHAR)
{
        ::std::cout<<"Start reading!";
    ClearCommError(ComPort, &tempread, &comstat);
    bytesread = comstat.cbInQue;
    if(bytesread)
    ReadFile(ComPort, bufrd, bytesread, &tempread, &olread);
    ::std::cout<<"Readed!" <<bufrd <<" " <<strlen(bufrd) <<" " <<&olread <<" " <<GetLastError  <<bytesread;
}
}
}




CloseHandle(olread.hEvent);
CloseHandle(ComPort);
}
else
    ::std::cout<<"No port found";
::std::cout<<"End";

//


bool running = 1;
while(running)
{

            SDL_Event event;
            while(SDL_PollEvent(&event) == 1)
            {
                if(event.type == SDL_QUIT)
                {
                    running = false;
                }
                else if(event.type == SDL_KEYDOWN)
                {
                    switch(event.key.keysym.sym)
                    {
                    case SDLK_ESCAPE:
                        running = false;
                        break;
                    }
                }
            }
}

SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
SDL_Quit();
return 0;
}
unsigned _stdcall VideoExcelReportPipeInstanceProc(void *arg)
{
	try
	{
		int i=0;
		DWORD dwResult   = 0;
		DWORD Pipe = 0;
		BOOL  bReadEvent = FALSE;

		OVERLAPPED Ovlap;
		const DWORD dwEventNum = 3;
		DWORD BytesTransferred = 0;
		HANDLE Event[dwEventNum];

		char  strReadBuf[VIDOE_EXCEL_REPORT_PIPE_MAX_BUF];
		memset(strReadBuf,0,sizeof(strReadBuf));

		Event[0] = g_hVideoExcelReportPipeRead;
		Event[1] = g_hVideoExcelReportPipeWrite;
		Event[2] = g_hVideoExcelReportPipeExit;

		// 创建命名管道
		if ((g_hVideoExcelReportPipeHandle = CreateNamedPipe(VIDEO_EXCEL_REPORT_PIPE_NAME,
			PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
			PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 1,
			VIDOE_EXCEL_REPORT_PIPE_MAX_BUF, VIDOE_EXCEL_REPORT_PIPE_MAX_BUF, 1000, NULL)) == INVALID_HANDLE_VALUE)
		{
			TRACE("创建视频巡视报表管道%d失败,错误码:%d\n", i, GetLastError());
			return 1;
		}

		memset(&Ovlap,0,sizeof(Ovlap));
		Ovlap.hEvent = Event[0];

		// Listen for client connections using ConnectNamedPipe()
		if (ConnectNamedPipe(g_hVideoExcelReportPipeHandle, &Ovlap) == 0)
		{
			if (GetLastError() != ERROR_IO_PENDING)
			{
				TRACE("ConnectNamedPipe for pipe %d failed with error %d\n", i, GetLastError());

				CloseHandle(g_hVideoExcelReportPipeHandle);
				g_hVideoExcelReportPipeHandle = NULL;

				CloseHandle(g_hVideoExcelReportPipeRead);
				g_hVideoExcelReportPipeRead = NULL;

				CloseHandle(g_hVideoExcelReportPipeWrite);
				g_hVideoExcelReportPipeWrite = NULL;

				CloseHandle(g_hVideoExcelReportPipeExit);
				g_hVideoExcelReportPipeExit = NULL;

				return 3;
			}
		}

		TRACE("Server is now running\n");

		// Read and echo data back to Named Pipe clients forever
		while(true) 
		{
			dwResult = WaitForMultipleObjects(dwEventNum, Event, FALSE, INFINITE);
			if (dwResult == WAIT_FAILED)
			{
				TRACE("WaitForMultipleObjects failed with error %d\n",GetLastError());
				g_bVideoExcelReportPipeConnected = false;

				CloseHandle(g_hVideoExcelReportPipeHandle);
				g_hVideoExcelReportPipeHandle = NULL;

				CloseHandle(g_hVideoExcelReportPipeRead);
				g_hVideoExcelReportPipeRead = NULL;

				CloseHandle(g_hVideoExcelReportPipeWrite);
				g_hVideoExcelReportPipeWrite = NULL;

				CloseHandle(g_hVideoExcelReportPipeExit);
				g_hVideoExcelReportPipeExit = NULL;

				return 4;
			}

			if (dwResult == WAIT_OBJECT_0)//读
			{
				TRACE("\nReceived data or connection request!");
				bReadEvent = FALSE;
			}
			else if (dwResult == WAIT_OBJECT_0 + 1)//写
			{
				TRACE("\nWrite data!");
			}
			else //WAIT_OBJECT_2:application exit - close handle  default:error
			{
				break;
			}

			//重置事件
			ResetEvent(Event[dwResult-WAIT_OBJECT_0]);

			// Check overlapped results, and if they fail, reestablish 
			// communication for a new client; otherwise, process read 
			// and write operations with the client
			if (GetOverlappedResult(g_hVideoExcelReportPipeHandle, &Ovlap,&BytesTransferred, TRUE) == 0)
			{
				g_bVideoExcelReportPipeConnected = false;

				TRACE("GetOverlapped result failed %d start over\n", GetLastError());

				if (DisconnectNamedPipe(g_hVideoExcelReportPipeHandle) == 0)
				{
					TRACE("DisconnectNamedPipe failed with error %d\n",GetLastError());
					break;
				}

				if (ConnectNamedPipe(g_hVideoExcelReportPipeHandle,&Ovlap) == 0)
				{
					if (GetLastError() != ERROR_IO_PENDING)
					{
						// Severe error on pipe. Close this handle forever.
						TRACE("ConnectNamedPipe for pipe %d failed with error %d\n", i, GetLastError());
						break;
					}
				}
			} 
			else
			{
				g_bVideoExcelReportPipeConnected = true;

				if (!bReadEvent)//读
				{
					//收到连接请求或者客户端数据,重新设置阻塞
					TRACE("Received %d bytes, echo bytes back\n",BytesTransferred);

					if (ReadFile(g_hVideoExcelReportPipeHandle, strReadBuf,VIDOE_EXCEL_REPORT_PIPE_MAX_BUF, NULL, &Ovlap) == 0)
					{
						if (GetLastError() != ERROR_IO_PENDING)
						{
							TRACE("\nReadFile failed with error %d", GetLastError());
						}
					}
				}
				bReadEvent = TRUE;
			}
		}		

		g_bVideoExcelReportPipeConnected = false;

		if (g_hVideoExcelReportPipeHandle != NULL)
		{
			CloseHandle(g_hVideoExcelReportPipeHandle);
			g_hVideoExcelReportPipeHandle = NULL;
		}

		if (g_hVideoExcelReportPipeRead != NULL)
		{
			CloseHandle(g_hVideoExcelReportPipeRead);
			g_hVideoExcelReportPipeRead = NULL;
		}

		if (g_hVideoExcelReportPipeWrite != NULL)
		{
			CloseHandle(g_hVideoExcelReportPipeWrite);
			g_hVideoExcelReportPipeWrite = NULL;
		}

		return 10;
	}
	catch(...)
	{

	}
	return 11;
}
Ejemplo n.º 13
0
static void *readchanges_thread(void *arg) {
  w_root_t *root = arg;
  struct winwatch_root_state *state = root->watch;
  DWORD size = WATCHMAN_BATCH_LIMIT * (sizeof(FILE_NOTIFY_INFORMATION) + 512);
  char *buf;
  DWORD err, filter;
  OVERLAPPED olap;
  BOOL initiate_read = true;
  HANDLE handles[2] = { state->olap, state->ping };
  DWORD bytes;

  w_set_thread_name("readchange %.*s",
      root->root_path->len, root->root_path->buf);

  // Block until winmatch_root_st is waiting for our initialization
  pthread_mutex_lock(&state->mtx);

  filter = FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME|
    FILE_NOTIFY_CHANGE_ATTRIBUTES|FILE_NOTIFY_CHANGE_SIZE|
    FILE_NOTIFY_CHANGE_LAST_WRITE;

  memset(&olap, 0, sizeof(olap));
  olap.hEvent = state->olap;

  buf = malloc(size);
  if (!buf) {
    w_log(W_LOG_ERR, "failed to allocate %u bytes for dirchanges buf\n", size);
    goto out;
  }

  if (!ReadDirectoryChangesW(state->dir_handle, buf, size,
        TRUE, filter, NULL, &olap, NULL)) {
    err = GetLastError();
    w_log(W_LOG_ERR,
        "ReadDirectoryChangesW: failed, cancel watch. %s\n",
        win32_strerror(err));
    w_root_lock(root);
    w_root_cancel(root);
    w_root_unlock(root);
    goto out;
  }
  // Signal that we are done with init.  We MUST do this AFTER our first
  // successful ReadDirectoryChangesW, otherwise there is a race condition
  // where we'll miss observing the cookie for a query that comes in
  // after we've crawled but before the watch is established.
  w_log(W_LOG_DBG, "ReadDirectoryChangesW signalling as init done");
  pthread_cond_signal(&state->cond);
  pthread_mutex_unlock(&state->mtx);
  initiate_read = false;

  // The state->mutex must not be held when we enter the loop
  while (!root->cancelled) {
    if (initiate_read) {
      if (!ReadDirectoryChangesW(state->dir_handle,
            buf, size, TRUE, filter, NULL, &olap, NULL)) {
        err = GetLastError();
        w_log(W_LOG_ERR,
            "ReadDirectoryChangesW: failed, cancel watch. %s\n",
            win32_strerror(err));
        w_root_lock(root);
        w_root_cancel(root);
        w_root_unlock(root);
        break;
      } else {
        initiate_read = false;
      }
    }

    w_log(W_LOG_DBG, "waiting for change notifications");
    DWORD status = WaitForMultipleObjects(2, handles, FALSE, INFINITE);

    if (status == WAIT_OBJECT_0) {
      bytes = 0;
      if (!GetOverlappedResult(state->dir_handle, &olap,
            &bytes, FALSE)) {
        err = GetLastError();
        w_log(W_LOG_ERR, "overlapped ReadDirectoryChangesW(%s): 0x%x %s\n",
            root->root_path->buf,
            err, win32_strerror(err));

        if (err == ERROR_INVALID_PARAMETER && size > NETWORK_BUF_SIZE) {
          // May be a network buffer related size issue; the docs say that
          // we can hit this when watching a UNC path. Let's downsize and
          // retry the read just one time
          w_log(W_LOG_ERR, "retrying watch for possible network location %s "
              "with smaller buffer\n", root->root_path->buf);
          size = NETWORK_BUF_SIZE;
          initiate_read = true;
          continue;
        }

        if (err == ERROR_NOTIFY_ENUM_DIR) {
          w_root_schedule_recrawl(root, "ERROR_NOTIFY_ENUM_DIR");
        } else {
          w_log(W_LOG_ERR, "Cancelling watch for %s\n",
              root->root_path->buf);
          w_root_lock(root);
          w_root_cancel(root);
          w_root_unlock(root);
          break;
        }
      } else {
        PFILE_NOTIFY_INFORMATION not = (PFILE_NOTIFY_INFORMATION)buf;
        struct winwatch_changed_item *head = NULL, *tail = NULL;
        while (true) {
          struct winwatch_changed_item *item;
          DWORD n_chars;
          w_string_t *name, *full;

          // FileNameLength is in BYTES, but FileName is WCHAR
          n_chars = not->FileNameLength / sizeof(not->FileName[0]);
          name = w_string_new_wchar(not->FileName, n_chars);

          full = w_string_path_cat(root->root_path, name);
          w_string_delref(name);

          if (w_is_ignored(root, full->buf, full->len)) {
            w_string_delref(full);
          } else {
            item = calloc(1, sizeof(*item));
            item->name = full;

            if (tail) {
              tail->next = item;
            } else {
              head = item;
            }
            tail = item;
          }

          // Advance to next item
          if (not->NextEntryOffset == 0) {
            break;
          }
          not = (PFILE_NOTIFY_INFORMATION)(not->NextEntryOffset + (char*)not);
        }

        if (tail) {
          pthread_mutex_lock(&state->mtx);
          if (state->tail) {
            state->tail->next = head;
          } else {
            state->head = head;
          }
          state->tail = tail;
          pthread_mutex_unlock(&state->mtx);
          pthread_cond_signal(&state->cond);
        }
        ResetEvent(state->olap);
        initiate_read = true;
      }
    } else if (status == WAIT_OBJECT_0 + 1) {
      w_log(W_LOG_ERR, "signalled\n");
      break;
    } else {
      w_log(W_LOG_ERR, "impossible wait status=%d\n",
          status);
      break;
    }
  }

  pthread_mutex_lock(&state->mtx);
out:
  // Signal to winwatch_root_start that we're done initializing in
  // the failure path.  We'll also do this after we've completed
  // the run loop in the success path; it's a spurious wakeup but
  // harmless and saves us from adding and setting a control flag
  // in each of the failure `goto` statements. winwatch_root_dtor
  // will `pthread_join` us before `state` is freed.
  pthread_cond_signal(&state->cond);
  pthread_mutex_unlock(&state->mtx);

  if (buf) {
    free(buf);
  }
  w_log(W_LOG_DBG, "done\n");
  w_root_delref(root);
  return NULL;
}
Ejemplo n.º 14
0
bool CCacheDlg::GetStatusFromRemoteCache(const CTGitPath& Path, bool bRecursive)
{
	if(!EnsurePipeOpen())
	{
		STARTUPINFO startup = { 0 };
		PROCESS_INFORMATION process = { 0 };
		startup.cb = sizeof(startup);

		CString sCachePath = L"TGitCache.exe";
		if (CreateProcess(sCachePath.GetBuffer(sCachePath.GetLength() + 1), L"", nullptr, nullptr, FALSE, 0, nullptr, nullptr, &startup, &process) == 0)
		{
			// It's not appropriate to do a message box here, because there may be hundreds of calls
			sCachePath.ReleaseBuffer();
			ATLTRACE("Failed to start cache\n");
			return false;
		}
		sCachePath.ReleaseBuffer();

		// Wait for the cache to open
		ULONGLONG endTime = GetTickCount64()+1000;
		while(!EnsurePipeOpen())
		{
			if((GetTickCount64() - endTime) > 0)
			{
				return false;
			}
		}
	}


	DWORD nBytesRead;
	TGITCacheRequest request;
	request.flags = TGITCACHE_FLAGS_NONOTIFICATIONS;
	if(bRecursive)
	{
		request.flags |= TGITCACHE_FLAGS_RECUSIVE_STATUS;
	}
	wcsncpy_s(request.path, Path.GetWinPath(), MAX_PATH);
	SecureZeroMemory(&m_Overlapped, sizeof(OVERLAPPED));
	m_Overlapped.hEvent = m_hEvent;
	// Do the transaction in overlapped mode.
	// That way, if anything happens which might block this call
	// we still can get out of it. We NEVER MUST BLOCK THE SHELL!
	// A blocked shell is a very bad user impression, because users
	// who don't know why it's blocked might find the only solution
	// to such a problem is a reboot and therefore they might loose
	// valuable data.
	// Sure, it would be better to have no situations where the shell
	// even can get blocked, but the timeout of 5 seconds is long enough
	// so that users still recognize that something might be wrong and
	// report back to us so we can investigate further.

	TGITCacheResponse ReturnedStatus;
	BOOL fSuccess = TransactNamedPipe(m_hPipe,
		&request, sizeof(request),
		&ReturnedStatus, sizeof(ReturnedStatus),
		&nBytesRead, &m_Overlapped);

	if (!fSuccess)
	{
		if (GetLastError()!=ERROR_IO_PENDING)
		{
			ClosePipe();
			return false;
		}

		// TransactNamedPipe is working in an overlapped operation.
		// Wait for it to finish
		DWORD dwWait = WaitForSingleObject(m_hEvent, INFINITE);
		if (dwWait == WAIT_OBJECT_0)
		{
			fSuccess = GetOverlappedResult(m_hPipe, &m_Overlapped, &nBytesRead, FALSE);
			return TRUE;
		}
		else
			fSuccess = FALSE;
	}

	ClosePipe();
	return false;
}
Ejemplo n.º 15
0
int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length)
{
	DWORD bytes_read;
	BOOL res;

	HANDLE ev;
	ev = CreateEvent(NULL, FALSE, FALSE /*inital state f=nonsignaled*/, NULL);

	OVERLAPPED ol;
	memset(&ol, 0, sizeof(ol));
	ol.hEvent = ev;

	// Limit the data to be returned. This ensures we get
	// only one report returned per call to hid_read().
	length = (length < dev->input_report_length)? length: dev->input_report_length;

	res = ReadFile(dev->device_handle, data, length, &bytes_read, &ol);
	
	
	if (!res) {
		if (GetLastError() != ERROR_IO_PENDING) {
			// ReadFile() has failed.
			// Clean up and return error.
			CloseHandle(ev);
			goto end_of_function;
		}
	}

	if (!dev->blocking) {
		// See if there is any data yet.
		res = WaitForSingleObject(ev, 0);
		CloseHandle(ev);
		if (res != WAIT_OBJECT_0) {
			// There was no data. Cancel this read and return.
			CancelIo(dev->device_handle);
			// Zero bytes available.
			return 0;
		}
	}

	// Either WaitForSingleObject() told us that ReadFile has completed, or
	// we are in non-blocking mode. Get the number of bytes read. The actual
	// data has been copied to the data[] array which was passed to ReadFile().
	res = GetOverlappedResult(dev->device_handle, &ol, &bytes_read, TRUE/*wait*/);

	if (bytes_read > 0 && data[0] == 0x0) {
		/* If report numbers aren't being used, but Windows sticks a report
		   number (0x0) on the beginning of the report anyway. To make this
		   work like the other platforms, and to make it work more like the
		   HID spec, we'll skip over this byte. */
		bytes_read--;
		memmove(data, data+1, bytes_read);
	}
	
end_of_function:
	if (!res) {
		register_error(dev, "ReadFile");
		return -1;
	}
	
	return bytes_read;
}
Ejemplo n.º 16
0
void serial_loop()
{
    char buff[SERIAL_BUFFER];
    int pos = 0;
#ifdef __WIN32__
    DWORD state, len_in = 0;
    BOOL fWaitingOnRead = FALSE;
    OVERLAPPED osReader = {0};
    osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if(osReader.hEvent == NULL)
    {
        server_log(LOG_ERR, "serial_loop: CreateEvent");
        exit(EXIT_FAILURE);
    }
    while(1)
    {
        if(!fWaitingOnRead)
        {
            if(!ReadFile(server.serialfd, &buff[pos], 1, &len_in, &osReader))
            {
                if(GetLastError() != ERROR_IO_PENDING)
                {
                    CloseHandle(osReader.hEvent);
                    break;
                }
                else
                    fWaitingOnRead = TRUE;
            }
        }
        if(fWaitingOnRead)
        {
            state = WaitForSingleObject(osReader.hEvent, 200);
            if(state == WAIT_TIMEOUT)
                continue;
            if(state != WAIT_OBJECT_0 ||
               !GetOverlappedResult(server.serialfd, &osReader, &len_in, FALSE))
            {
                CloseHandle(osReader.hEvent);
                break;
            }
            fWaitingOnRead = FALSE;
        }
        if(len_in != 1)
            continue;
#else
    fd_set input;
    FD_ZERO(&input);
    FD_SET(server.serialfd, &input);
    while(select(server.serialfd+1, &input, NULL, NULL, NULL) > 0)
    {
        if(read(server.serialfd, &buff[pos], 1) <= 0)
            break;
#endif
        if(buff[pos] != '\n') /* If this command is too long to fit into a buffer, clip it */
        {
            if(pos != SERIAL_BUFFER-1)
                pos++;
            continue;
        }
        buff[pos] = 0;
        if(pos)
            msg_parse_serial(buff[0], buff+1);
        buff[pos] = '\n';
        msg_send(buff, pos+1);
        pos = 0;
    }
#ifdef __WIN32__
    CloseHandle(server.serialfd);
#else
    close(server.serialfd);
#endif
}

void serial_write(char* msg, int len)
{
    pthread_mutex_lock(&server.mutex_s);
#ifdef __WIN32__
    OVERLAPPED osWrite = {0};
    DWORD dwWritten;

    osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if(osWrite.hEvent == NULL)
    {
        server_log(LOG_ERR, "server_conn: CreateEvent");
        exit(EXIT_FAILURE);
    }

    if(!WriteFile(server.serialfd, msg, len, &dwWritten, &osWrite))
        if(GetLastError() == ERROR_IO_PENDING)
            if(WaitForSingleObject(osWrite.hEvent, INFINITE) == WAIT_OBJECT_0)
                GetOverlappedResult(server.serialfd, &osWrite, &dwWritten, FALSE);
    CloseHandle(osWrite.hEvent);
#else
    write(server.serialfd, msg, len);
#endif
    pthread_mutex_unlock(&server.mutex_s);
}
Ejemplo n.º 17
0
void EIO_WatchPort(uv_work_t* req) {
  WatchPortBaton* data = static_cast<WatchPortBaton*>(req->data);
  data->bytesRead = 0;
  data->disconnected = false;

  // Event used by GetOverlappedResult(..., TRUE) to wait for incoming data or timeout
  // Event MUST be used if program has several simultaneous asynchronous operations
  // on the same handle (i.e. ReadFile and WriteFile)
  HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

  while (true) {
    OVERLAPPED ov = {0};
    ov.hEvent = hEvent;

    // Start read operation - synchrounous or asynchronous
    DWORD bytesReadSync = 0;
    if (!ReadFile((HANDLE)data->fd, data->buffer, bufferSize, &bytesReadSync, &ov)) {
      data->errorCode = GetLastError();
      if (data->errorCode != ERROR_IO_PENDING) {
        // Read operation error
        if (data->errorCode == ERROR_OPERATION_ABORTED) {
          data->disconnected = true;
        } else {
          ErrorCodeToString("Reading from COM port (ReadFile)", data->errorCode, data->errorString);
          CloseHandle(hEvent);
          return;
        }
        break;
      }

      // Read operation is asynchronous and is pending
      // We MUST wait for operation completion before deallocation of OVERLAPPED struct
      // or read data buffer

      // Wait for async read operation completion or timeout
      DWORD bytesReadAsync = 0;
      if (!GetOverlappedResult((HANDLE)data->fd, &ov, &bytesReadAsync, TRUE)) {
        // Read operation error
        data->errorCode = GetLastError();
        if (data->errorCode == ERROR_OPERATION_ABORTED) {
          data->disconnected = true;
        } else {
          ErrorCodeToString("Reading from COM port (GetOverlappedResult)", data->errorCode, data->errorString);
          CloseHandle(hEvent);
          return;
        }
        break;
      } else {
        // Read operation completed asynchronously
        data->bytesRead = bytesReadAsync;
      }
    } else {
      // Read operation completed synchronously
      data->bytesRead = bytesReadSync;
    }

    // Return data received if any
    if (data->bytesRead > 0) {
      break;
    }
  }

  CloseHandle(hEvent);
}
Ejemplo n.º 18
0
int UsbSerial::usbRead( char* buffer, int length )
{
  // make sure we're open
  if( !deviceOpen )
  {
    UsbStatus portIsOpen = usbOpen( );
    if( portIsOpen != OK )
		{
			usbClose( );
			return NOT_OPEN;
		}
  }
	
	QMutexLocker locker( &usbMutex );
  
  // Linux Only
  #if (defined(Q_WS_LINUX))
  // make sure we're open
  //if( !deviceOpen )
    return NOT_OPEN;
  #endif

  //Mac-only
	#ifdef Q_WS_MAC
	int count;
		
	count = ::read( deviceHandle, buffer, length );
	if( count > 1 )
		return count;
	else
	{
		switch ( count )
		{
			case 0:
			return ERROR_CLOSE; // EOF; possibly file was closed
				break;

			case -1:
				if ( errno == EAGAIN )
					return NOTHING_AVAILABLE;
				else
					return IO_ERROR;
				break;
		}
	}
	return 0; // should never get here
	#endif //Mac-only UsbSerial::read( )
	
  //Windows-only///////////////////////////////////////////////////////////////////////
  #ifdef Q_WS_WIN
  DWORD count;
  int retval = -1;
  DWORD numTransferred;
    
  retval = OK;  
  readInProgress = false;
  overlappedRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

  // reset the read overlapped structure
  overlappedRead.Offset = overlappedRead.OffsetHigh = 0;
  
  if ( !ReadFile( deviceHandle, buffer, length, &count, &overlappedRead ) )
  {
  	DWORD lastError = GetLastError();
		// messageInterface->message( 1, "USB Read Error: %d \n", lastError );
	  if ( lastError != ERROR_IO_PENDING)     // read not delayed?
	  {
	    usbClose( );
	    //messageInterface->message( 1, "Closed trying to read the file\n" );
	    retval = -1; //UNKNOWN_ERROR;
	  }
	  else
	    readInProgress = true;
  }
  else          	
  	retval = count;


  if( readInProgress )
  {
  	DWORD r;
	  do
	  {
	    r = WaitForSingleObject( overlappedRead.hEvent, 1000 );	 
	  } while ( r == WAIT_TIMEOUT );
	  switch( r )
		{
		  case WAIT_FAILED:
		    usbClose( );
		    retval = -1; //UNKNOWN_ERROR;
	      break;
		  case WAIT_TIMEOUT:
		    retval = -1; // NOTHING_AVAILABLE;
		    break;
		  case WAIT_OBJECT_0:
	  		// check to see if the pending operation completed
        	if( !GetOverlappedResult( deviceHandle, &overlappedRead, &numTransferred, FALSE )  ) // don't wait
			{
		      usbClose( );
		      SetEvent( overlappedRead.hEvent );
		      retval = -1; //IO_ERROR;
		      break;
			}
  			retval = numTransferred;
			  break; 
		  case WAIT_ABANDONED:
		  default:
		    usbClose( );
		    retval = -1; //IO_ERROR;
			  break;
		} // end of switch
  }
  
  CloseHandle( overlappedRead.hEvent );
  return retval;
  	
  #endif //Windows-only UsbSerial::read( )//////////////////////////////////////////////////////////////
}
Ejemplo n.º 19
0
/* Relay data between a socket and a process until the process dies or stops
   sending or receiving data. The socket descriptor and process pipe handles
   are in the data argument, which must be a pointer to struct subprocess_info.

   This function is a workaround for the fact that we can't just run a process
   after redirecting its input handles to a socket. If the process, for
   example, redirects its own stdin, it somehow confuses the socket and stdout
   stops working. This is exactly what ncat does (as part of the Windows stdin
   workaround), so it can't be ignored.

   This function can be invoked through CreateThread to simulate fork+exec, or
   called directly to simulate exec. It frees the subprocess_info struct and
   closes the socket and pipe handles before returning. Returns the exit code
   of the subprocess. */
static DWORD WINAPI subprocess_thread_func(void *data)
{
    struct subprocess_info *info;
    char pipe_buffer[BUFSIZ];
    OVERLAPPED overlap = { 0 };
    HANDLE events[3];
    DWORD ret, rc;
    int crlf_state = 0;

    info = (struct subprocess_info *) data;

    /* Three events we watch for: socket read, pipe read, and process end. */
    events[0] = (HANDLE) WSACreateEvent();
    WSAEventSelect(info->fdn.fd, events[0], FD_READ | FD_CLOSE);
    events[1] = info->child_out_r;
    events[2] = info->proc;

    /* To avoid blocking or polling, we use asynchronous I/O, or what Microsoft
       calls "overlapped" I/O, on the process pipe. WaitForMultipleObjects
       reports when the read operation is complete. */
    ReadFile(info->child_out_r, pipe_buffer, sizeof(pipe_buffer), NULL, &overlap);

    /* Loop until EOF or error. */
    for (;;) {
        DWORD n, nwritten;
        int i;

        i = WaitForMultipleObjects(3, events, FALSE, INFINITE);
        if (i == WAIT_OBJECT_0) {
            /* Read from socket, write to process. */
            char buffer[BUFSIZ];
            int pending;

            ResetEvent(events[0]);
            do {
                n = ncat_recv(&info->fdn, buffer, sizeof(buffer), &pending);
                if (n <= 0)
                    goto loop_end;
                if (WriteFile(info->child_in_w, buffer, n, &nwritten, NULL) == 0)
                    break;
                if (nwritten != n)
                    goto loop_end;
            } while (pending);
        } else if (i == WAIT_OBJECT_0 + 1) {
            char *crlf = NULL, *wbuf;
            /* Read from process, write to socket. */
            if (GetOverlappedResult(info->child_out_r, &overlap, &n, FALSE)) {
                int n_r;

                wbuf = pipe_buffer;
                n_r = n;
                if (o.crlf) {
                    if (fix_line_endings((char *) pipe_buffer, &n_r, &crlf, &crlf_state))
                        wbuf = crlf;
                }
                /* The above call to WSAEventSelect puts the socket in
                   non-blocking mode, but we want this send to block, not
                   potentially return WSAEWOULDBLOCK. We call block_socket, but
                   first we must clear out the select event. */
                WSAEventSelect(info->fdn.fd, events[0], 0);
                block_socket(info->fdn.fd);
                nwritten = ncat_send(&info->fdn, wbuf, n_r);
                if (crlf != NULL)
                    free(crlf);
                if (nwritten != n_r)
                    break;
                /* Restore the select event (and non-block the socket again.) */
                WSAEventSelect(info->fdn.fd, events[0], FD_READ | FD_CLOSE);
                /* Queue another ansychronous read. */
                ReadFile(info->child_out_r, pipe_buffer, sizeof(pipe_buffer), NULL, &overlap);
            } else {
                if (GetLastError() != ERROR_IO_PENDING)
                    /* Error or end of file. */
                    break;
            }
        } else if (i == WAIT_OBJECT_0 + 2) {
            /* The child died. There are no more writes left in the pipe
               because WaitForMultipleObjects guarantees events with lower
               indexes are handled first. */
            break;
        } else {
            break;
        }
    }

loop_end:

    WSACloseEvent(events[0]);

    rc = unregister_subprocess(info->proc);
    ncat_assert(rc != -1);

    GetExitCodeProcess(info->proc, &ret);
    if (ret == STILL_ACTIVE) {
        if (o.debug > 1)
            logdebug("Subprocess still running, terminating it.\n");
        rc = TerminateProcess(info->proc, 0);
        if (rc == 0) {
            if (o.debug > 1)
                logdebug("TerminateProcess failed with code %d.\n", rc);
        }
    }
    GetExitCodeProcess(info->proc, &ret);
    if (o.debug > 1)
        logdebug("Subprocess ended with exit code %d.\n", ret);

    shutdown(info->fdn.fd, 2);
    subprocess_info_close(info);
    free(info);

    rc = WaitForSingleObject(pseudo_sigchld_mutex, INFINITE);
    ncat_assert(rc == WAIT_OBJECT_0);
    if (pseudo_sigchld_handler != NULL)
        pseudo_sigchld_handler();
    rc = ReleaseMutex(pseudo_sigchld_mutex);
    ncat_assert(rc != 0);

    return ret;
}
Ejemplo n.º 20
0
UsbSerial::UsbStatus UsbSerial::usbWrite( char* buffer, int length )
{
  if( !deviceOpen )
  {
    UsbStatus portIsOpen = usbOpen( );
    if( portIsOpen != OK )
		{
				usbClose( );
			return NOT_OPEN;
		}
  }
  
	QMutexLocker locker( &usbMutex );
	
  // Linux Only
  #if (defined(Q_WS_LINUX))
    return NOT_OPEN;
  #endif

  //Mac-only
	#ifdef Q_WS_MAC
 
	int size = ::write( deviceHandle, buffer, length );
	if ( length == size )
    return OK;
	else if( errno == EAGAIN )
	  return NOTHING_AVAILABLE;
  else
    return IO_ERROR;
	
	#endif //Mac-only UsbSerial::write( )

  //Windows-only
  #ifdef Q_WS_WIN
  DWORD cout, ret, numWritten;
  bool success;
  UsbSerial::UsbStatus retval = OK;
  
  overlappedWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  
	// reset the write overlapped structure
  overlappedWrite.Offset = overlappedWrite.OffsetHigh = 0;
  
  success = WriteFile( deviceHandle, buffer, length, &cout, &overlappedWrite );
  if( !success )
  {
  	if ( GetLastError() == ERROR_IO_PENDING)
	  {
	  	int waitCount = 0;
		  do
		  {
	  		if( waitCount++ > 5 )
	  			break;
		  	ret = WaitForSingleObject( overlappedWrite.hEvent, 100 );
		  }  while ( ret == WAIT_TIMEOUT );
	
	    if ( ret == WAIT_OBJECT_0 )
	    {			
				//do
				//{
					GetOverlappedResult( deviceHandle, &overlappedWrite, &numWritten, TRUE);
					//read = numWritten;
				//} while( read != length );
				if( numWritten == (DWORD)length )
					retval = OK;
				else
				  retval = IO_ERROR;
	    }
	    else
	      retval = IO_ERROR;
	  }
	  else
	  {
	    //usbClose( );
	    retval = IO_ERROR;
	  }
  }
  
  CloseHandle( overlappedWrite.hEvent );
  return retval;
  
  #endif //Windows-only UsbSerial::write( )
}
Ejemplo n.º 21
0
GstFlowReturn
gst_ks_video_device_read_frame (GstKsVideoDevice * self, guint8 * buf,
    gulong buf_size, gulong * bytes_read, GstClockTime * presentation_time,
    gulong * error_code, gchar ** error_str)
{
  GstKsVideoDevicePrivate *priv = GST_KS_VIDEO_DEVICE_GET_PRIVATE (self);
  guint req_idx;
  DWORD wait_ret;
  BOOL success;
  DWORD bytes_returned;

  g_assert (priv->cur_media_type != NULL);

  /* First time we're called, submit the requests. */
  if (G_UNLIKELY (!priv->requests_submitted)) {
    priv->requests_submitted = TRUE;

    for (req_idx = 0; req_idx < priv->num_requests; req_idx++) {
      ReadRequest *req = &g_array_index (priv->requests, ReadRequest, req_idx);

      if (!gst_ks_video_device_request_frame (self, req, error_code, error_str))
        goto error_request_failed;
    }
  }

  do {
    /* Wait for either a request to complete, a cancel or a timeout */
    wait_ret = WaitForMultipleObjects (priv->request_events->len,
        (HANDLE *) priv->request_events->data, FALSE, READ_TIMEOUT);
    if (wait_ret == WAIT_TIMEOUT)
      goto error_timeout;
    else if (wait_ret == WAIT_FAILED)
      goto error_wait;

    /* Stopped? */
    if (WaitForSingleObject (priv->cancel_event, 0) == WAIT_OBJECT_0)
      goto error_cancel;

    *bytes_read = 0;

    /* Find the last ReadRequest that finished and get the result, immediately
     * re-issuing each request that has completed. */
    for (req_idx = wait_ret - WAIT_OBJECT_0;
        req_idx < priv->num_requests; req_idx++) {
      ReadRequest *req = &g_array_index (priv->requests, ReadRequest, req_idx);

      /*
       * Completed? WaitForMultipleObjects() returns the lowest index if
       * multiple objects are in the signaled state, and we know that requests
       * are processed one by one so there's no point in looking further once
       * we've found the first that's non-signaled.
       */
      if (WaitForSingleObject (req->overlapped.hEvent, 0) != WAIT_OBJECT_0)
        break;

      success = GetOverlappedResult (priv->pin_handle, &req->overlapped,
          &bytes_returned, TRUE);

      ResetEvent (req->overlapped.hEvent);

      if (success) {
        KSSTREAM_HEADER *hdr = &req->params.header;
        KS_FRAME_INFO *frame_info = &req->params.frame_info;
        GstClockTime timestamp = GST_CLOCK_TIME_NONE;
        GstClockTime duration = GST_CLOCK_TIME_NONE;

        if (hdr->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TIMEVALID)
          timestamp = hdr->PresentationTime.Time * 100;

        if (hdr->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_DURATIONVALID)
          duration = hdr->Duration * 100;

        /* Assume it's a good frame */
        *bytes_read = hdr->DataUsed;

        if (G_LIKELY (presentation_time != NULL))
          *presentation_time = timestamp;

        if (G_UNLIKELY (GST_DEBUG_IS_ENABLED ())) {
          gchar *options_flags_str =
              ks_options_flags_to_string (hdr->OptionsFlags);

          GST_DEBUG ("PictureNumber=%" G_GUINT64_FORMAT ", DropCount=%"
              G_GUINT64_FORMAT ", PresentationTime=%" GST_TIME_FORMAT
              ", Duration=%" GST_TIME_FORMAT ", OptionsFlags=%s: %d bytes",
              frame_info->PictureNumber, frame_info->DropCount,
              GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration),
              options_flags_str, hdr->DataUsed);

          g_free (options_flags_str);
        }

        /* Protect against old frames. This should never happen, see previous
         * comment on last_timestamp. */
        if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (timestamp))) {
          if (G_UNLIKELY (GST_CLOCK_TIME_IS_VALID (priv->last_timestamp) &&
                  timestamp < priv->last_timestamp)) {
            GST_WARNING ("got an old frame (last_timestamp=%" GST_TIME_FORMAT
                ", timestamp=%" GST_TIME_FORMAT ")",
                GST_TIME_ARGS (priv->last_timestamp),
                GST_TIME_ARGS (timestamp));
            *bytes_read = 0;
          } else {
            priv->last_timestamp = timestamp;
          }
        }

        if (*bytes_read > 0) {
          /* Grab the frame data */
          g_assert (buf_size >= hdr->DataUsed);
          memcpy (buf, req->buf, hdr->DataUsed);

          if (priv->is_mjpeg) {
            /*
             * Workaround for cameras/drivers that intermittently provide us
             * with incomplete or corrupted MJPEG frames.
             *
             * Happens with for instance Microsoft LifeCam VX-7000.
             */

            gboolean valid = FALSE;
            guint padding = 0;

            /* JFIF SOI marker */
            if (*bytes_read > MJPEG_MAX_PADDING
                && buf[0] == 0xff && buf[1] == 0xd8) {
              guint8 *p = buf + *bytes_read - 2;

              /* JFIF EOI marker (but skip any padding) */
              while (padding < MJPEG_MAX_PADDING - 1 - 2 && !valid) {
                if (p[0] == 0xff && p[1] == 0xd9) {
                  valid = TRUE;
                } else {
                  padding++;
                  p--;
                }
              }
            }

            if (valid)
              *bytes_read -= padding;
            else
              *bytes_read = 0;
          }
        }
      } else if (GetLastError () != ERROR_OPERATION_ABORTED)
        goto error_get_result;

      /* Submit a new request immediately */
      if (!gst_ks_video_device_request_frame (self, req, error_code, error_str))
        goto error_request_failed;
    }
  } while (*bytes_read == 0);

  return GST_FLOW_OK;

  /* ERRORS */
error_request_failed:
  {
    return GST_FLOW_ERROR;
  }
error_timeout:
  {
    GST_DEBUG ("IOCTL_KS_READ_STREAM timed out");

    if (error_code != NULL)
      *error_code = 0;
    if (error_str != NULL)
      *error_str = NULL;

    return GST_FLOW_UNEXPECTED;
  }
error_wait:
  {
    gst_ks_video_device_parse_win32_error ("WaitForMultipleObjects",
        GetLastError (), error_code, error_str);

    return GST_FLOW_ERROR;
  }
error_cancel:
  {
    if (error_code != NULL)
      *error_code = 0;
    if (error_str != NULL)
      *error_str = NULL;

    return GST_FLOW_WRONG_STATE;
  }
error_get_result:
  {
    gst_ks_video_device_parse_win32_error ("GetOverlappedResult",
        GetLastError (), error_code, error_str);

    return GST_FLOW_ERROR;
  }
}
Ejemplo n.º 22
0
//----------------------------------------------------------------------------
/* static */ void CSerialPort::receiveChar(CSerialPort* port, COMSTAT comstat){
//----------------------------------------------------------------------------
	BOOL  bRead = TRUE; 
	BOOL  bResult = TRUE;
	DWORD dwError = 0;
	DWORD BytesRead = 0;
	unsigned char RXBuff;

	for (;;) 	{ 
		// Gain ownership of the comm port critical section.
		// This process guarantees no other part of this program 
		// is using the port object. 
		
		EnterCriticalSection(&port->m_csCommunicationSync);

		// ClearCommError() will update the COMSTAT structure and
		// clear any other errors.
		
		bResult = ClearCommError(port->m_hComm, &dwError, &comstat);

		LeaveCriticalSection(&port->m_csCommunicationSync);

		// start forever loop.  I use this type of loop because I
		// do not know at runtime how many loops this will have to
		// run. My solution is to start a forever loop and to
		// break out of it when I have processed all of the
		// data available.  Be careful with this approach and
		// be sure your loop will exit.
		// My reasons for this are not as clear in this sample 
		// as it is in my production code, but I have found this 
		// solutiion to be the most efficient way to do this.
		
		if (comstat.cbInQue == 0){
			// break out when all bytes have been read
			break;
		}
						
		EnterCriticalSection(&port->m_csCommunicationSync);

		if (bRead){
			bResult = ReadFile(port->m_hComm,		// Handle to COMM port 
							   &RXBuff,				// RX Buffer Pointer
							   1,					// Read one byte
							   &BytesRead,			// Stores number of bytes read
							   &port->m_ov);		// pointer to the m_ov structure
			// deal with the error code 
			if (!bResult){ 
				switch (dwError = GetLastError()){ 
					case ERROR_IO_PENDING: 	
						// asynchronous i/o is still in progress 
						// Proceed on to GetOverlappedResults();
						bRead = FALSE;
						break;
					default:
						// Another error has occured.  Process this error.
						port->processErrorMessage("ReadFile()");
						break;
				}
			}
			else{
				// ReadFile() returned complete. It is not necessary to call GetOverlappedResults()
				bRead = TRUE;
			}
		}  // close if (bRead)

		if (!bRead)	{
			bRead = TRUE;
			bResult = GetOverlappedResult(port->m_hComm,	// Handle to COMM port 
										  &port->m_ov,		// Overlapped structure
										  &BytesRead,		// Stores number of bytes read
										  TRUE); 			// Wait flag

			// deal with the error code 
			if (!bResult){
				port->processErrorMessage("GetOverlappedResults() in ReadFile()");
			}	
		}  // close if (!bRead)
				
      port->m_readQueue.push(RXBuff);
		LeaveCriticalSection(&port->m_csCommunicationSync);
		// notify parent that a byte was received
   } // end forever loop

}
int l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto,
		   const u8 *buf, size_t len)
{
	BOOL res;
	DWORD written;
	struct l2_ethhdr *eth;
#ifndef _WIN32_WCE
	OVERLAPPED overlapped;
#endif /* _WIN32_WCE */
	OVERLAPPED *o;

	if (l2 == NULL)
		return -1;

#ifdef _WIN32_WCE
	o = NULL;
#else /* _WIN32_WCE */
	os_memset(&overlapped, 0, sizeof(overlapped));
	o = &overlapped;
#endif /* _WIN32_WCE */

	if (l2->l2_hdr) {
		res = WriteFile(driver_ndis_get_ndisuio_handle(), buf, len,
				&written, o);
	} else {
		size_t mlen = sizeof(*eth) + len;
		eth = os_malloc(mlen);
		if (eth == NULL)
			return -1;

		os_memcpy(eth->h_dest, dst_addr, ETH_ALEN);
		os_memcpy(eth->h_source, l2->own_addr, ETH_ALEN);
		eth->h_proto = htons(proto);
		os_memcpy(eth + 1, buf, len);
		res = WriteFile(driver_ndis_get_ndisuio_handle(), eth, mlen,
				&written, o);
		os_free(eth);
	}

	if (!res) {
		DWORD err = GetLastError();
#ifndef _WIN32_WCE
		if (err == ERROR_IO_PENDING) {
			wpa_printf(MSG_DEBUG, "L2(NDISUIO): Wait for pending "
				   "write to complete");
			res = GetOverlappedResult(
				driver_ndis_get_ndisuio_handle(), &overlapped,
				&written, TRUE);
			if (!res) {
				wpa_printf(MSG_DEBUG, "L2(NDISUIO): "
					   "GetOverlappedResult failed: %d",
					   (int) GetLastError());
				return -1;
			}
			return 0;
		}
#endif /* _WIN32_WCE */
		wpa_printf(MSG_DEBUG, "L2(NDISUIO): WriteFile failed: %d",
			   (int) GetLastError());
		return -1;
	}

	return 0;
}
Ejemplo n.º 24
0
static void *uaenet_trap_thread (void *arg)
{
	struct uaenetdatawin32 *sd = arg;
	HANDLE handles[4];
	int cnt, towrite;
	int readactive, writeactive;
	DWORD actual;

	uae_set_thread_priority (NULL, 2);
	sd->threadactive = 1;
	uae_sem_post (&sd->sync_sem);
	readactive = 0;
	writeactive = 0;
	while (sd->threadactive == 1) {
		int donotwait = 0;

		uae_sem_wait (&sd->change_sem);

		if (readactive) {
			if (GetOverlappedResult (sd->hCom, &sd->olr, &actual, FALSE)) {
				readactive = 0;
				uaenet_gotdata (sd->user, sd->readbuffer, actual);
				donotwait = 1;
			}
		}
		if (writeactive) {
			if (GetOverlappedResult (sd->hCom, &sd->olw, &actual, FALSE)) {
				writeactive = 0;
				donotwait = 1;
			}
		}

		if (!readactive) {
			if (!ReadFile (sd->hCom, sd->readbuffer, sd->mtu, &actual, &sd->olr)) {
				DWORD err = GetLastError();
				if (err == ERROR_IO_PENDING)
					readactive = 1;
			} else {
				uaenet_gotdata (sd->user, sd->readbuffer, actual);
				donotwait = 1;
			}
		}

		towrite = 0;
		if (!writeactive && uaenet_getdata (sd->user, sd->writebuffer, &towrite)) {
			donotwait = 1;
			if (!WriteFile (sd->hCom, sd->writebuffer, towrite, &actual, &sd->olw)) {
				DWORD err = GetLastError();
				if (err == ERROR_IO_PENDING)
					writeactive = 1;
			}
		}

		uae_sem_post (&sd->change_sem);

		if (!donotwait) {
			cnt = 0;
			handles[cnt++] = sd->evtt;
			if (readactive)
				handles[cnt++] = sd->olr.hEvent;
			if (writeactive)
				handles[cnt++] = sd->olw.hEvent;
			WaitForMultipleObjects(cnt, handles, FALSE, INFINITE);
		}


	}
	sd->threadactive = 0;
	uae_sem_post (&sd->sync_sem);
	return 0;
}
Ejemplo n.º 25
0
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
{
	DWORD bytes_read = 0;
	BOOL res;

	/* Copy the handle for convenience. */
	HANDLE ev = dev->ol.hEvent;

	if (!dev->read_pending) {
		/* Start an Overlapped I/O read. */
		dev->read_pending = TRUE;
		memset(dev->read_buf, 0, dev->input_report_length);
		ResetEvent(ev);
		res = ReadFile(dev->device_handle, dev->read_buf, dev->input_report_length, &bytes_read, &dev->ol);
		
		if (!res) {
			if (GetLastError() != ERROR_IO_PENDING) {
				/* ReadFile() has failed.
				   Clean up and return error. */
				CancelIo(dev->device_handle);
				dev->read_pending = FALSE;
				goto end_of_function;
			}
		}
	}

	if (milliseconds >= 0) {
		/* See if there is any data yet. */
		res = WaitForSingleObject(ev, milliseconds);
		if (res != WAIT_OBJECT_0) {
			/* There was no data this time. Return zero bytes available,
			   but leave the Overlapped I/O running. */
			return 0;
		}
	}

	/* Either WaitForSingleObject() told us that ReadFile has completed, or
	   we are in non-blocking mode. Get the number of bytes read. The actual
	   data has been copied to the data[] array which was passed to ReadFile(). */
	res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/);
	
	/* Set pending back to false, even if GetOverlappedResult() returned error. */
	dev->read_pending = FALSE;

	if (res && bytes_read > 0) {
		if (dev->read_buf[0] == 0x0) {
			/* If report numbers aren't being used, but Windows sticks a report
			   number (0x0) on the beginning of the report anyway. To make this
			   work like the other platforms, and to make it work more like the
			   HID spec, we'll skip over this byte. */
			size_t copy_len;
			bytes_read--;
			copy_len = length > bytes_read ? bytes_read : length;
			memcpy(data, dev->read_buf+1, copy_len);
		}
		else {
			/* Copy the whole buffer, report number and all. */
			size_t copy_len = length > bytes_read ? bytes_read : length;
			memcpy(data, dev->read_buf, copy_len);
		}
	}
	
end_of_function:
	if (!res) {
		register_error(dev, "GetOverlappedResult");
		return -1;
	}
	
	return bytes_read;
}
Ejemplo n.º 26
0
int _cdecl
main (int argc, CHAR **argv) {
    DWORD   rc;
    BOOL    Server;

    if (argc<2) {
        printf (USAGE(argv[0]));
        return 0;
    }

    if (_stricmp (argv[1], "s")==0)
        Server = TRUE;
    else if (_stricmp (argv[1], "c")==0)
        Server = FALSE;
    else {
        printf ("Must specify s(erver) or c(lient).\n");
        printf (USAGE(argv[0]));
        return -1;
    }

    if ((rc=WahOpenNotificationHandleHelper (&hHelper))!=NO_ERROR) {
        printf ("WahOpenNotificationHandleHelper failed, err: %ld.\n", rc);
        return -1;
    }

    if (Server) {
        HANDLE  hSync, hApc, hAEvent, hAPort, hANoPort;
        OVERLAPPED  oApc, oEvent, oPort, oNoPort;
        LPOVERLAPPED lpo;
        HANDLE  hPort;
        HANDLE  hEvent;
        DWORD   count, key;

        hPort = CreateIoCompletionPort (
                    INVALID_HANDLE_VALUE,
                    NULL,
                    0,
                    0
                    );

        if (hPort==INVALID_HANDLE_VALUE) {
            printf ("CreateIoCompletionPort (create) failed, err: %ld.\n", GetLastError ());
            return -1;
        }

        hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
        if (hEvent==NULL) {
            printf ("CreateEvent failed, err: %ld.\n", GetLastError ());
            return -1;
        }

        rc = WahCreateNotificationHandle (hHelper, &hSync);
        if (rc!=0) {
            printf ("WahCreateNotificationHandle failed, err: %ld.\n", rc);
            return -1;
        }

        rc = WahCreateNotificationHandle (hHelper, &hApc);
        if (rc!=0) {
            printf ("WahCreateNotificationHandle failed, err: %ld.\n", rc);
            return -1;
        }
        oApc.hEvent = NULL;

        rc = WahCreateNotificationHandle (hHelper, &hAEvent);
        if (rc!=0) {
            printf ("WahCreateNotificationHandle failed, err: %ld.\n", rc);
            return -1;
        }
        oEvent.hEvent = hEvent;

        rc = WahCreateNotificationHandle (hHelper, &hAPort);
        if (rc!=0) {
            printf ("WahCreateNotificationHandle failed, err: %ld.\n", rc);
            return -1;
        }
        if (CreateIoCompletionPort (hAPort, hPort, (DWORD)hAPort, 0)
               == INVALID_HANDLE_VALUE) {
            printf ("CreateIoCompletionPort (associate) failed, err: %ld.\n", GetLastError ());
            return -1;
        }
        oPort.hEvent = NULL;

        rc = WahCreateNotificationHandle (hHelper, &hANoPort);
        if (rc!=0) {
            printf ("WahCreateNotificationHandle failed, err: %ld.\n", rc);
            return -1;
        }
        if (CreateIoCompletionPort (hANoPort, hPort, (DWORD)hANoPort, 0)
               == INVALID_HANDLE_VALUE) {
            printf ("CreateIoCompletionPort (associate) failed, err: %ld.\n", GetLastError ());
            return -1;
        }
        oNoPort.hEvent = (HANDLE)1;

        while (1) {
            printf ("Posting apc wait.\n");
            rc = WahWaitForNotification (hHelper, hApc, &oApc, WsCompletion);
            if ((rc!=0) && (rc!=WSA_IO_PENDING)) {
                printf ("WahWaitForNotification(apc) failed, err: %ld.\n", rc);
                return -1;
            }

            printf ("Posting event wait.\n");
            rc = WahWaitForNotification (hHelper, hAEvent, &oEvent, NULL);
            if ((rc!=0) && (rc!=WSA_IO_PENDING)) {
                printf ("WahWaitForNotification(event) failed, err: %ld.\n", rc);
                return -1;
            }

            printf ("Posting port wait.\n");
            rc = WahWaitForNotification (hHelper, hAPort, &oPort, NULL);
            if ((rc!=0) && (rc!=WSA_IO_PENDING)) {
                printf ("WahWaitForNotification(port) failed, err: %ld.\n", rc);
                return -1;
            }

            printf ("Posting noport wait.\n");
            rc = WahWaitForNotification (hHelper, hANoPort, &oNoPort, NULL);
            if ((rc!=0) && (rc!=WSA_IO_PENDING)) {
                printf ("WahWaitForNotification(port) failed, err: %ld.\n", rc);
                return -1;
            }

            printf ("Posting sync wait.\n");
            memset (&ovlp, 0, sizeof (ovlp));
            rc = WahWaitForNotification (hHelper, hSync, NULL, NULL);
            if (rc!=0) {
                printf ("WahWaitForNotification failed, err: %ld.\n", rc);
                return -1;
            }

            printf ("Waiting for apc\n");
            rc = SleepEx (INFINITE, TRUE);
            if (rc!=WAIT_IO_COMPLETION) {
                printf ("Unexpected result on wait for apc: %ld.\n", rc);
                return rc;
            }

            printf ("Waiting for port\n");
            if (GetQueuedCompletionStatus (hPort, &count, &key, &lpo, INFINITE)) {
                rc = 0;
            }
            else if (lpo) {
                rc = GetLastError ();
                if (rc==0)
                    printf ("No error code for failed GetQueuedCompletionStatus.\n");
            }
            else {
                printf ("GetQueuedCompletionStatus failed, err: %ld.\n", GetLastError ());
                return -1;
            }
            if (key!=(DWORD)hAPort)
                printf ("Wrong completion key: %lx (expected : %lx)", key, hAPort);
            WsCompletion (rc, count, lpo, 0);

            printf ("Waiting for noport\n");
            oNoPort.hEvent = NULL;
            if (GetOverlappedResult (hANoPort, &oNoPort, &count, TRUE)) {
                rc = 0;
            }
            else {
                rc = GetLastError ();
                if (rc==0)
                    printf ("No error code for failed GetOverlappedResult.\n");
            }
            WsCompletion (rc, count, &oNoPort, 0);

            printf ("Waiting for event\n");
            if (GetOverlappedResult (hAEvent, &oEvent, &count, TRUE)) {
                rc = 0;
            }
            else {
                rc = GetLastError ();
                if (rc==0)
                    printf ("No error code for failed GetOverlappedResult.\n");
            }
            WsCompletion (rc, count, &oEvent, 0);
        }
        CloseHandle (hSync);
        CloseHandle (hANoPort);
        CloseHandle (hAPort);
        CloseHandle (hAEvent);
        CloseHandle (hApc);

        CloseHandle (hPort);
        CloseHandle (hEvent);
    }
    else if (argc<3) {
        rc = WahNotifyAllProcesses (hHelper);
        if (rc==0) {
            printf ("Notified all ok.\n");
        }
        else {
            printf ("WahNotifyAllProcesses failed, err: %ld.\n", rc);
        }
    }
    else if (argc>=5) {
        HANDLE          hPipe;
        DWORD           id = GetCurrentProcessId (), count;
        WCHAR           name[MAX_PATH];


        //
        // Create client and of the pipe that matched the
        // pattern
        //
        wsprintfW (name, L"\\\\%hs\\pipe\\Winsock2\\CatalogChangeListener-%hs-%hs", 
                    argv[2], argv[3], argv[4]);

        hPipe =  CreateFileW (name, 
                                GENERIC_WRITE, 
                                FILE_SHARE_READ, 
                                (LPSECURITY_ATTRIBUTES) NULL, 
                                OPEN_EXISTING, 
                                FILE_ATTRIBUTE_NORMAL, 
                                (HANDLE) NULL);
        if (hPipe!=INVALID_HANDLE_VALUE) {
            printf ("Opened pipe %ls.\n", name);
            CloseHandle (hPipe);
        }
        else {
            printf ("Could not open pipe %ls, err: %ld\n",
                name, GetLastError ());
        }
    }
    else
        printf (USAGE(argv[0]));

    WahCloseNotificationHandleHelper (hHelper);
    return 0;
}
Ejemplo n.º 27
0
//
// Write a character.
//
void CSerialPort::WriteChar(CSerialPort* port)
{
    BOOL bWrite = TRUE;
    BOOL bResult = TRUE;

    DWORD BytesSent = 0;
    DWORD SendLen   = port->m_nWriteSize;
    ResetEvent(port->m_hWriteEvent);


    // Gain ownership of the critical section
    EnterCriticalSection(&port->m_csCommunicationSync);

    if (bWrite)
    {
        // Initailize variables
        port->m_ov.Offset = 0;
        port->m_ov.OffsetHigh = 0;

        // Clear buffer
        PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

        bResult = WriteFile(port->m_hComm,							// Handle to COMM Port
                            port->m_szWriteBuffer,					// Pointer to message buffer in calling finction
                            SendLen,	// add by mrlong
                            //strlen((char*)port->m_szWriteBuffer),	// Length of message to send
                            &BytesSent,								// Where to store the number of bytes sent
                            &port->m_ov);							// Overlapped structure

        // deal with any error codes
        if (!bResult)
        {
            DWORD dwError = GetLastError();
            switch (dwError)
            {
            case ERROR_IO_PENDING:
            {
                // continue to GetOverlappedResults()
                BytesSent = 0;
                bWrite = FALSE;
                break;
            }
            default:
            {
                // all other error codes
                port->ProcessErrorMessage("WriteFile()");
            }
            }
        }
        else
        {
            LeaveCriticalSection(&port->m_csCommunicationSync);
        }
    } // end if(bWrite)

    if (!bWrite)
    {
        bWrite = TRUE;

        bResult = GetOverlappedResult(port->m_hComm,	// Handle to COMM port
                                      &port->m_ov,		// Overlapped structure
                                      &BytesSent,		// Stores number of bytes sent
                                      TRUE); 			// Wait flag

        LeaveCriticalSection(&port->m_csCommunicationSync);

        // deal with the error code
        if (!bResult)
        {
            port->ProcessErrorMessage("GetOverlappedResults() in WriteFile()");
        }
    } // end if (!bWrite)

    // Verify that the data size send equals what we tried to send
    if (BytesSent != SendLen /*strlen((char*)port->m_szWriteBuffer)*/)  // add by
    {
        //TRACE("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)port->m_szWriteBuffer));
    }
}
Ejemplo n.º 28
0
/*
 * The actual thread procedure for an input thread.
 */
static DWORD WINAPI handle_input_threadfunc(void *param)
{
    struct handle_input *ctx = (struct handle_input *) param;
    OVERLAPPED ovl, *povl;
    HANDLE oev = 0;
    int readret, readlen, finished;

    if (ctx->flags & HANDLE_FLAG_OVERLAPPED) {
	povl = &ovl;
	oev = CreateEvent(NULL, TRUE, FALSE, NULL);
    } else {
	povl = NULL;
    }

    if (ctx->flags & HANDLE_FLAG_UNITBUFFER)
	readlen = 1;
    else
	readlen = sizeof(ctx->buffer);

    while (1) {
	if (povl) {
	    memset(povl, 0, sizeof(OVERLAPPED));
	    povl->hEvent = oev;
	}
	readret = ReadFile(ctx->h, ctx->buffer,readlen, &ctx->len, povl);
	if (!readret)
	    ctx->readerr = GetLastError();
	else
	    ctx->readerr = 0;
	if (povl && !readret && ctx->readerr == ERROR_IO_PENDING) {
	    WaitForSingleObject(povl->hEvent, INFINITE);
	    readret = GetOverlappedResult(ctx->h, povl, &ctx->len, FALSE);
	    if (!readret)
		ctx->readerr = GetLastError();
	    else
		ctx->readerr = 0;
	}

	if (!readret) {
	    /*
	     * Windows apparently sends ERROR_BROKEN_PIPE when a
	     * pipe we're reading from is closed normally from the
	     * writing end. This is ludicrous; if that situation
	     * isn't a natural EOF, _nothing_ is. So if we get that
	     * particular error, we pretend it's EOF.
	     */
	    if (ctx->readerr == ERROR_BROKEN_PIPE)
		ctx->readerr = 0;
	    ctx->len = 0;
	}

	if (readret && ctx->len == 0 &&
	    (ctx->flags & HANDLE_FLAG_IGNOREEOF))
	    continue;

        /*
         * If we just set ctx->len to 0, that means the read operation
         * has returned end-of-file. Telling that to the main thread
         * will cause it to set its 'defunct' flag and dispose of the
         * handle structure at the next opportunity, in which case we
         * mustn't touch ctx at all after the SetEvent. (Hence we do
         * even _this_ check before the SetEvent.)
         */
        finished = (ctx->len == 0);

	SetEvent(ctx->ev_to_main);

	if (finished)
	    break;

	WaitForSingleObject(ctx->ev_from_main, INFINITE);
	if (ctx->done) {
            /*
             * The main thread has asked us to shut down. Send back an
             * event indicating that we've done so. Hereafter we must
             * not touch ctx at all, because the main thread might
             * have freed it.
             */
            SetEvent(ctx->ev_to_main);
            break;
        }
    }

    if (povl)
	CloseHandle(oev);

    return 0;
}
Ejemplo n.º 29
0
HRESULT CMyHttpModule::ReadFileChunk(HTTP_DATA_CHUNK *chunk, char *buf)
{
    OVERLAPPED ovl;
    DWORD dwDataStartOffset;
    ULONGLONG bytesTotal = 0;
	BYTE *	pIoBuffer = NULL;
	HANDLE	hIoEvent = INVALID_HANDLE_VALUE;
	HRESULT hr = S_OK;

    pIoBuffer = (BYTE *)VirtualAlloc(NULL,
                                        1,
                                        MEM_COMMIT | MEM_RESERVE,
                                        PAGE_READWRITE);
    if (pIoBuffer == NULL)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
		goto Done;
    }

    hIoEvent = CreateEvent(NULL,  // security attr
                                FALSE, // manual reset
                                FALSE, // initial state
                                NULL); // name
    if (hIoEvent == NULL)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
		goto Done;
    }

	while(bytesTotal < chunk->FromFileHandle.ByteRange.Length.QuadPart)
	{
		DWORD bytesRead = 0;
		int was_eof = 0;
		ULONGLONG offset = chunk->FromFileHandle.ByteRange.StartingOffset.QuadPart + bytesTotal;

		ZeroMemory(&ovl, sizeof ovl);
		ovl.hEvent     = hIoEvent;
		ovl.Offset = (DWORD)offset;
		dwDataStartOffset = ovl.Offset & (m_dwPageSize - 1);
		ovl.Offset &= ~(m_dwPageSize - 1);
		ovl.OffsetHigh = offset >> 32;

		if (!ReadFile(chunk->FromFileHandle.FileHandle,
					  pIoBuffer,
					  m_dwPageSize,
					  &bytesRead,
					  &ovl))
		{
			DWORD dwErr = GetLastError();

			switch (dwErr)
			{
			case ERROR_IO_PENDING:
				//
				// GetOverlappedResult can return without waiting for the
				// event thus leaving it signalled and causing problems
				// with future use of that event handle, so just wait ourselves
				//
				WaitForSingleObject(ovl.hEvent, INFINITE); // == WAIT_OBJECT_0);

				if (!GetOverlappedResult(
						 chunk->FromFileHandle.FileHandle,
						 &ovl,
						 &bytesRead,
						 TRUE))
				{
					dwErr = GetLastError();

					switch(dwErr)
					{
					case ERROR_HANDLE_EOF:
						was_eof = 1;
						break;

					default:
						hr = HRESULT_FROM_WIN32(dwErr);
						goto Done;
					}
				}
				break;

			case ERROR_HANDLE_EOF:
				was_eof = 1;
				break;

			default:
				hr = HRESULT_FROM_WIN32(dwErr);
				goto Done;
			}
		}

		bytesRead -= dwDataStartOffset;

		if (bytesRead > chunk->FromFileHandle.ByteRange.Length.QuadPart)
		{
			bytesRead = (DWORD)chunk->FromFileHandle.ByteRange.Length.QuadPart;
		}
		if ((bytesTotal + bytesRead) > chunk->FromFileHandle.ByteRange.Length.QuadPart)
		{ 
			bytesRead = chunk->FromFileHandle.ByteRange.Length.QuadPart - bytesTotal; 
		}

		memcpy(buf, pIoBuffer + dwDataStartOffset, bytesRead);

		buf += bytesRead;
		bytesTotal += bytesRead;

		if(was_eof != 0)
			chunk->FromFileHandle.ByteRange.Length.QuadPart = bytesTotal;
	}

Done:
	if(NULL != pIoBuffer)
	{
		VirtualFree(pIoBuffer, 0, MEM_RELEASE);
	}

	if(INVALID_HANDLE_VALUE != hIoEvent)
	{
		CloseHandle(hIoEvent);
	}

	return hr;
}
Ejemplo n.º 30
0
static DWORD WINAPI handle_output_threadfunc(void *param)
{
    struct handle_output *ctx = (struct handle_output *) param;
    OVERLAPPED ovl, *povl;
    HANDLE oev;
    int writeret;

    if (ctx->flags & HANDLE_FLAG_OVERLAPPED) {
	povl = &ovl;
	oev = CreateEvent(NULL, TRUE, FALSE, NULL);
    } else {
	povl = NULL;
    }

    while (1) {
	WaitForSingleObject(ctx->ev_from_main, INFINITE);
	if (ctx->done) {
            /*
             * The main thread has asked us to shut down. Send back an
             * event indicating that we've done so. Hereafter we must
             * not touch ctx at all, because the main thread might
             * have freed it.
             */
	    SetEvent(ctx->ev_to_main);
	    break;
	}
	if (povl) {
	    memset(povl, 0, sizeof(OVERLAPPED));
	    povl->hEvent = oev;
	}

	writeret = WriteFile(ctx->h, ctx->buffer, ctx->len,
			     &ctx->lenwritten, povl);
	if (!writeret)
	    ctx->writeerr = GetLastError();
	else
	    ctx->writeerr = 0;
	if (povl && !writeret && GetLastError() == ERROR_IO_PENDING) {
	    writeret = GetOverlappedResult(ctx->h, povl,
					   &ctx->lenwritten, TRUE);
	    if (!writeret)
		ctx->writeerr = GetLastError();
	    else
		ctx->writeerr = 0;
	}

	SetEvent(ctx->ev_to_main);
	if (!writeret) {
            /*
             * The write operation has suffered an error. Telling that
             * to the main thread will cause it to set its 'defunct'
             * flag and dispose of the handle structure at the next
             * opportunity, so we must not touch ctx at all after
             * this.
             */
	    break;
        }
    }

    if (povl)
	CloseHandle(oev);

    return 0;
}