Ankündigung

Einklappen
Keine Ankündigung bisher.

Overlapped I/O mit CreateFile

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Overlapped I/O mit CreateFile

    Hi!
    ich arbeite mich gerade WriteFile und nutze dafür alle I/O-Möglichkeiten von Windows. Momentan bin ich bei Overlapped I/O und nutze Events mit Callback-Routinen. Jetzt habe ich aber ein paar Fragen:

    Um die Serverhauptschleife schlafen zu legen, nutzte ich bisher WSAWaitForMultipleEvents(), welches auf ein bestimmtes Event horcht. Nebenbei wird die Funktion aber auch beendet, wenn irgendeine andere Overlapped-Completion erfolgt und die Completion-Routine ausgeführt wird, oder? Dabei sollte das Event-Objekt aber nicht auf signaled gesetzt werden, da ja z.B. irgendein Write ein anderes Event-Objekt nutzt. Ich hoffe, das stimmt soweit.

    Wie sieht das jetzt mit GetOverlappedResult() aus? Irgendwie erscheint mir diese Funktion noch lokrativer, aber im Netz findet man kaum Infos.

  • #2
    http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx

    Kommentar


    • #3
      Danke, hilft mir aber nicht wirklich weiter.
      Die Seite kannte ich auch schon.

      Kommentar


      • #4
        Zitat von Spypoo Beitrag anzeigen
        Danke, hilft mir aber nicht wirklich weiter.
        Die Seite kannte ich auch schon.
        Servus!

        Ich hab dazu vor 4 monaten schon was geproggt. Viieleicht hilfts.

        PHP-Code:
        #include <windows.h>
        #include <tchar.h>
        #include <stdio.h>
        #include <stdlib.h>

        #define BUF_SIZE    2048
        #define ROUNDS  300

        int globalVar 0;

        LPCTSTR ErrorMessageDWORD error 

        // Routine Description:
        //      Retrieve the system error message for the last-error code


            
        LPVOID lpMsgBuf;

            
        FormatMessage(
                
        FORMAT_MESSAGE_ALLOCATE_BUFFER 
                
        FORMAT_MESSAGE_FROM_SYSTEM |
                
        FORMAT_MESSAGE_IGNORE_INSERTS,
                
        NULL,
                
        error,
                
        MAKELANGID(LANG_NEUTRALSUBLANG_DEFAULT),
                (
        LPTSTR) &lpMsgBuf,
                
        0NULL );

            return((
        LPCTSTR)lpMsgBuf);
        }

        void IncreaseVariable()

        // Routine Description:
        //     Increases a variable when async I/O does
        //     other processing.
        {
            ++
        globalVar;
        }

        DWORD AsyncTestWriteToFile(HANDLE hEventHANDLE hFile)

        // Routine Description:
        //      Demonstrate async WriteFile.

        // Parameters:
        //      hEvent - pre-made manual-reset event.
        //
        //      hFile - pre-opened file handle, overlapped.

        // Return Value:
        //      Number of bytes written.
        {
            
        char lpBuffer[BUF_SIZE];
            
        DWORD nNumberOfBytesToWrite 0;
            
        DWORD lpNumberOfBytesWritten 0;
            
        DWORD dwFileSize GetFileSize(hFileNULL);
            
        OVERLAPPED stOverlapped;
         
            
        DWORD dwError  0;
            
        LPCTSTR errMsg NULL;

            
        nNumberOfBytesToWrite strlen(lpBuffer);

            
        memset(&stOverlapped0sizeof(stOverlapped));
            
        //stOverlapped.Offset = 4096;

            // Set up overlapped structure event. Other members are already 
            // initialized to zero.
            
        stOverlapped.hEvent hEvent

            
        // We will repeat this test 
            
        for(int i 0ROUNDSi++) {

                
        BOOL bResult FALSE;
                
        BOOL bContinue TRUE;
                
        BOOL writeVariable FALSE;
                
        DWORD dCounter 0;
                
        globalVar 0;

                
        strcpy(lpBuffer"Hallo Welt!\r\n");

                
        // Loop and write asynchronously a string to a file.
                // As long as the I/O has not been completed, call IncreaseVariable
                // and check then for I/O completion again.

                
        while(bContinue) {

                    
        // Default to ending the loop.
                    
        bContinue FALSE;
                
                    if(
        writeVariable) {
                        
        // Write variable asynchronously.
                        
        char numBuffer[33];
                        
        itoa(globalVarnumBuffer10);         
                        
        strncat(lpBuffernumBuffer32);
                        
        strncat(lpBuffer"\r\n"2);
                    }

                    
        // Attempt an asynchronous write operation.
                    
        bResult WriteFile(hFile,
                                        
        lpBuffer,
                                        
        strlen(lpBuffer),
                                        &
        lpNumberOfBytesWritten,
                                        &
        stOverlapped); 
             
                    
        // Check for a problem or pending operation. 
                    
        if (!bResult) { 

                        
        dwError GetLastError();

                        switch (
        dwError) {             
                            case 
        ERROR_HANDLE_EOF:
                                {
                                    
        printf("\nWriteFile returned FALSE and EOF condition, async EOF not triggered.\n");
                                    break;
                                }
                            case 
        ERROR_IO_PENDING
                                {
                                    
        BOOL bPending TRUE;

                                    
        // Loop until the I/O is complete, that is: the overlapped 
                                    // event is signaled.

                                    
        while( bPending ) {
                                        
        bPending FALSE;
                                
                                        
        // Pending asynchronous I/O, do something else
                                        // and re-check overlapped structure.
                                        //printf("\nWriteFile operation is pending\n");
             
                                        // Do something else then come back to check. 
                                        
        IncreaseVariable(); 

                                        
        // Check the result of the asynchronous write
                                        // without waiting (forth parameter FALSE). 
                                        
        bResult GetOverlappedResult(hFile,
                                                                      &
        stOverlapped,
                                                                      &
        lpNumberOfBytesWritten,
                                                                      
        FALSE) ; 
             
                                        
        // If bResult is not zero
                                        
        if (!bResult) { 
                                            switch (
        dwError GetLastError()) { 
                                                case 
        ERROR_HANDLE_EOF
                                                    
        // Handle an end of file
                                                    
        printf("GetOverlappedResult found EOF\n");
                                                    break;
                                                case 
        ERROR_IO_INCOMPLETE:
                                                    
        // Operation is still pending, allow while loop
                                                    // to loop again after printing a little progress.
                                                    
        printf("GetOverlappedResult I/O Incomplete\n");
                                                    
        bPending TRUE;
                                                    
        bContinue TRUE;
                                                    break;
                                                default:
                                                    
        // Decode any other errors codes.
                                                    
        errMsg ErrorMessage(dwError);
                                                    
        _tprintf(TEXT("GetOverlappedResult failed (%d): %s\n"), dwErrorerrMsg);
                                                    
        LocalFree((LPVOID)errMsg);
                                            }
                                        } else {
                                            
        printf("WriteFile operation completed\n");

                                            
        // Check if we wrote the variable
                                            
        if(writeVariable == FALSE) {
                                                
        writeVariable TRUE;
                                                
        bContinue TRUE;
                                            }

                                            
        // Manual-reset event should be reset since it is now signaled.
                                            
        ResetEvent(stOverlapped.hEvent);
                                        }
                                    }
                                    break;
                                }
                            default:
                                {
                                    
        // Decode any other errors codes.
                                    
        errMsg ErrorMessage(dwError);
                                    
        printf("WriteFile GLE unhandled (%d): %s\n"dwErrorerrMsg); 
                                    
        LocalFree((LPVOID)errMsg);
                                    break;
                                }
                        }
                    } else {
                        
        // WriteFile return value is nonzero
                        
        printf("WriteFile completed synchronously\n");
                    }

                    
        // The following operation assumes the file is not extremely large, otherwise 
                    // logic would need to be included to adequately account for very large
                    // files and manipulate the OffsetHigh member of the OVERLAPPED structure.

                    
        stOverlapped.Offset += lpNumberOfBytesWritten;
                    if ( 
        stOverlapped.Offset dwFileSize )             
                        
        bContinue TRUE;
                }
            }

            return 
        stOverlapped.Offset;
        }

        int main()
        {
            
        HANDLE hFile;
            
        HANDLE hEvent;
            
        DWORD dwReturnValue;
            
        LPCWSTR fileName L"iofile.txt";

            
        hFile CreateFile(fileName,                    // file to open
                               
        GENERIC_READ|GENERIC_WRITE,    // open for reading and writing
                               
        0,                            // no share
                               
        NULL,                        // default security
                               
        CREATE_NEW,                    // existing file only or new one
                               
        FILE_FLAG_OVERLAPPED|FILE_FLAG_WRITE_THROUGH,        // overlapped operation
                               
        NULL);    
         
            if (
        hFile == INVALID_HANDLE_VALUE)  { 
                
        DWORD dwError GetLastError();
                
        LPCTSTR errMsg ErrorMessage(dwError);
                
        printf("Could not open file (%d): %s\n"dwErrorerrMsg); 
                
        LocalFree((LPVOID)errMsg);
                return -
        1
            }

            
        // Create event. A handle to the event that will be set to a signaled state 
            // by the system when the operation has completed.
            
        hEvent CreateEvent(NULLTRUEFALSENULL);

            if (
        hEvent == NULL) { 
                
        DWORD dwError GetLastError();
                
        LPCTSTR errMsg ErrorMessage(dwError);
                
        printf("Could not CreateEvent: %d %s\n"dwErrorerrMsg); 
                
        LocalFree((LPVOID)errMsg);
                return -
        1
            }   

            
        dwReturnValue AsyncTestWriteToFile(hEventhFile);
            
        printf("\nWrite complete. Last bytes written: %d\n"dwReturnValue);

            
        CloseHandle(hFile);
            
        CloseHandle(hEvent);

            return 
        0;

        Eigentlich müsstest damit das Prinzip von GetOverlappedResult() verstehen.^^

        Gruß

        Fischer

        Kommentar


        • #5
          Sehr schön - etwas zum verschieben.
          Zuletzt geändert von GAGA; 06.05.2010, 09:39.

          Kommentar


          • #6
            @R. Fischer

            Perfekt! Scheint prinzipell dasselbe zu sein wie mit Events.

            Kommentar

            Lädt...
            X