Application still doing things after it has ended

Application still doing things after it has ended

I have an application that launches a completely separate 64-bit Intel Fortran EXE and waits for it to complete before taking control again. It all works well except that after the Fortran EXE has finished, it stays in the Windows Task Manager with a status of "Terminated" for about 30 seconds before it finally disappears completely.

The problem is that If my application tries to re-launch it while it is still in this "Terminated" state it has problems because it still seems to have files open from the previous launch even though they were all closed properly. If I do the re-launch after it has disappeared from task manager then all is well. I assume that it is still flushing buffers and whatnot while it is in the "Terminated" state even though it looks like it has ended.

Is there anything I can do to make it disappear from task manager as soon as it finishes rather than going into this limbo state for 30 seconds? If it is flushing buffers can I turn this behaviour off?

13 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Are the files you attach on a network drive?

Could this be an interaction with your Anti-Virus system? IOW it is not finished scanning your output.

Fortran OPEN has a USEROPEN specifier. You can use this to substitute your own file open routine, perhaps setting FILE_FLAG_WRITE_THROUGH attribute. Your function will return the file handle. This handle can also be used in a call to FlushFileBuffers.

Additional information

http://msdn.microsoft.com/en-us/library/windows/desktop/aa364218(v=vs.85).aspx
File Caching

http://msdn.microsoft.com/en-us/library/windows/desktop/aa364439(v=vs.85).aspx

BOOL WINAPI FlushFileBuffers(
  _In_  HANDLE hFile
);

Jim Dempsey

 

www.quickthreadprogramming.com

Anthony, no everything is on my C drive.

Jim, I don't have an anti-virus system active because I don't like the way it monitors everything and slows everything down. I just run a scan manually every now and then. The Fortran EXE does read and write some rather large files and so it may be flushing buffers.

How exactly are you waiting for the program to complete? (And how are you starting it?)

Terminating a process has many steps - all of the DLLs' termination handlers have to be called. Maybe there's some extended cleanup being done.

Steve - Intel Developer Support

The 64-bit Fortran EXE is being launched from a 32-bit VB.NET application using Process.Start as shown below. I have put an "End of Fortran EXE" message in the Fotran code at the very end of the EXE so that I know when it gets to the end. The VB.NET application gets the Process.HasExited = True straight after that and gets out of its wait loop, but the Fortran EXE stays in Task Manager as "Terminated" for 30 seconds after that.

      Public Function LaunchProcessAndWaitForCompletion(ExecutableFileName As String, CommandLine As String, _
                                                        Optional ByRef ExitCode As Integer = 0) As Boolean

         LaunchProcessAndWaitForCompletion = False
         Dim Process As Process = Nothing
         Try

                  '// Start the process
                  Process = Process.Start(ExecutableFileName, CommandLine)

                  While Not Process.HasExited
                     '// Need to wait for the process to be finished

                     '// Discard cached information about the process
                     Process.Refresh()

                     '// Allow the normal window to update
                     Windows.Forms.Application.DoEvents()

                  End While

                  '// Get the exit code from the process
                  ExitCode = Process.ExitCode

                  '// The process has finished successfully
                  LaunchProcessAndWaitForCompletion = True

         Catch ex As Exception
            [Error].Runtime("LaunchProcess", ex)
         Finally
            '// Free the resources associated with the process
            If Process IsNot Nothing Then
               Process.Close()
            End If
         End Try

      End Function

 

Try to monitor Fortran.EXE with Process Explorer and ProcMon also handle.exe could be helpful in order to look for not closed handles.You can also look for TerminateThread and/or TerminateProcess functions are being actually called.

VB.NET aplication main thread should probably call TerminateProcess so with the help of Process Explorer search through the VB app threads TerminateProcess function call.I suppose that 30 sec delay can be accounted for some cleanup activity in kernel mode.

Maybe as an easy work around....

After the Fortran.exe "completes" by returning to your VB.NET launcher, the VB.NET program can

  { openFiles exclusive waiting till you get it or timeout }; close files

Assuming you know what the files the Fortran program wrote.

Also,  I don't know if this will work, (Assuming you know what the files the Fortran program wrote),have the VB.NET reopen the file (?shared?), now having handle to file, call FlushFileBuffers. IOW in the absence of the FileFlushBuffers in the Fortran .exe, perform it in the VB.NET.

Steve, I notice GETHWNDQQ can be used to convert a window unit number to Windows handle. Is there a way to get the Windows file handle from an I/O unit number? If so then just prior to close,


	ISTAT = FileFlushBuffers(GETWFILEHANDLQQ(IOUNIT))

	CLOSE(IOUNIT)

	

Where GETWFILEHANDLQQ is the supposed function name

Jim Dempsey

 

www.quickthreadprogramming.com

GETHWNDQQ is for QuickWin windows mapped to unit numbers. Won't help with files. My guess is that this is not really file related but that the process has not finished its rundown. Do you explicitly close the unit before exiting? Add that if you can.

Does it help if you link the Fortran EXE against the static Multithreaded (not Multithread DLL) libraries? I don't know how VB actually handles the process start and exit functions - it could be that "process exit" is not the same as the process being terminated.

Steve - Intel Developer Support

Probably by calling Win API thread and process functions.

Steve, what do you mean by "close the unit"? I am closing all the file units. Is there a program unit I should be closing? My Fortran application is structured as follows:

function WinMain( hInstance, hPrevInstance, lpszCmdLine, nCmdShow )
!DEC$ IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS : '_WinMain@16' :: WinMain
!DEC$ ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS : 'WinMain' :: WinMain
!DEC$ ENDIF

    use user32
    use kernel32
    use iflogm
    use SGSolverGlobals

    implicit none

    integer(SINT) :: WinMain
    integer(HANDLE) hInstance
    integer(HANDLE) hPrevInstance
    integer(LPWSTR) lpszCmdLine
    integer(SINT)   nCmdShow

       CALL SGSolver(lpszCmdLine)  ! The main call to my solver

    WinMain = 0
    return

end

Surprisinly (to you), what you have there is not a Fotran .exe. program. Rather you have there a Win32 program compiled with Fortran.

A Fortran .exe begins with PROGRAM.

To do what you want to do requires that you call for_rtl_init_ at the beginning of the non-PROGRAM "main", and also call for_rtl_finish_ at the end of the non-PROGRAM "main".

Look under "Summary of Mixed-Languages Issues" in the IVF documentation:

...
When the main program is written in Fortran, the Fortran compiler automatically creates any code needed to initialize the Fortran Run-time Library (RTL). The RTL provides the Fortran environment for input/output and exception handling. When the main program is written in C/C++, the C main program needs to call for_rtl_init_ to initialize the Fortran RTL and for_rtl_finish_ at the end of the C main program to shut down the Fortran RTL gracefully. With the Fortran RTL initialized, Fortran I/O and error handling will work correctly even when C/C++ routines are called.
...

In your case, although "WinMain" is written in Fortran, and you could argue "the main program is written in Fortran", technically (according to Fortran) it is not because the program does not contain a Fortran compilation unit containing PROGRAM.

Jim Dempsey

www.quickthreadprogramming.com

As to if this fixes you issue... give it a try by inserting

CALL for_rtl_init_(argcount, actarg)
....your code here...
result = for_rtl_finish_()

Jim Dempsey

www.quickthreadprogramming.com

Leave a Comment

Please sign in to add a comment. Not a member? Join today