- Linux/Wine: windows app starts windows console command and waits when on windows does not wait on linux: how to fix?
- Correct way to wait for VBLANK on windows 10 in windowed mode
- CALL command vs. START with /WAIT option
- 6 Answers 6
- Differences
- Addendum:
- Wait Functions
- Single-object Wait Functions
- Multiple-object Wait Functions
- Alertable Wait Functions
- Registered Wait Functions
- Waiting on an Address
- Wait Functions and Time-out Intervals
- Wait Functions and Synchronization Objects
- Wait Functions and Creating Windows
Linux/Wine: windows app starts windows console command and waits when on windows does not wait on linux: how to fix?
I am successfully running a Windows program using Wine apart from one feature. The program can be set up to start pdflatex in a texlive distribution, and when it does it waits to see if the result is successful or not, and then copies/moves files. But on Linux I cannot arrange for it to wait for pdflatex to complete the way it does on Windows and so files are copied/moved prematurely and pdflatex fails to find them.
There’s a dialog I can use to save an arbitrary command that will be executed when I push the pdflatex button in the app. I point this dialog at C:\texlive\2020\bin\win32\pdflatex.exe on Windows and it works. I successfully put this command so as to run pdflatex using wine on Linux apart from the problem of not waiting.
Z:/usr/bin/gnome-terminal —wait — /home/nonnull/bin/runlatex/runlatex.sh «%f»
By having the last command in runlatex.sh be exec /bin/bash the terminal remains open, so I can see all the output from pdflatex and know it is being run with the correct file which runlatex.sh has to figure out by converting the windows path passed to it into its actual path. pdflatex complains variously that a file it created right there and then doesn’t exist during the run. And even though the terminal is open and so not done executing, the app complains that pdflatex did not complete correctly before even the output text from pdflatex has finished scrolling down the terminal.The behavior of the app doesn’t change when I omit the exec command when the terminal closes immediately pdflatex is done.
What is going on with Wine that the command doesn’t remain attached until it has finished running? And what can I do about it? Any suggestions for a command or mechanism that might bypass this difficulty? I’m up for writing a win32 program to mediate if that’s what it would take.
Correct way to wait for VBLANK on windows 10 in windowed mode
What is the correct way to wait for VBLANK to present on windows 10 in windowed mode? Currently I’m doing the following:
However this leads to occasional stutter. My current theory on the stutter is the following:
DWM completes composition at some time before the VBLANK event and then during the VBLANK interval, DWM tries to write to the front buffer as fast as possible. Therefore if Present is called in the VBLANK interval it possibly occurs after the DWM has written to the front buffer. This is the picture in my head:
So a more correct method would be call Present(1, 0) before VBLANK to queue the window’s back buffer with DWM. Then call D3DKMTWaitForVerticalBlankEvent to wait until the next VBLANK. That is:
With corresponding picture: This second method seems to work perfectly, there is no longer any stutter.
My question is: What is the correct way to present in the VBLANK interval and is my theory correct or is there something more complicated/simple happening? Also are there any resources to learn more about this interaction?
Edit: Not sure if this should be an answer or edit. After some googling I found this explanation by Nicholas Steel which seems align with my theory
There is no sure fire way to detect exactly when VBlank will occur because Windows doesn’t expose a VBlank interrupt, and displays/GPU aren’t necessarily required to generate one anyway (in addition, ‘current scanline’ information as given by e.g. IDirect3DDevice9::GetRasterStatus may not be accurate). As a result, programs generally poll for VBlank or rely on Direct3D/OpenGL to do it for them.
Programs present video frames during VBlank to avoid tearing, since the monitor will happily switch to the new frame mid-draw. With the compositor in Windows Vista and later versions of Windows, these programs will still detect VBlank and only present frames during it, as they think they are presenting video frames directly, when in reality the video frames are feeding into the compositor first. Frames sent to the compositor (from any running programs on the PC) will be queued up by the compositor, and merged together to be swapped/copied into place during VBlank.
Problems that can occur with this system:
1) A program polling for VBlank may miss composition. This will cause the frame to be queued up for the next composition, meaning the previous frame will be shown twice as long.
2) Worse, the next frame may not miss composition, and end up overwriting the previously queued up frame — so you end up with a duplicate frame followed by a skipped frame.
3) The program’s VSync implementation may naturally fail to detect VBlank (which has only a short duration), causing it to wait until the next VBlank and risk problems 1 and/or 2.
4) These problems may even combine to generate a ‘perfect storm’ of duplicate and/or missed frames.
As you can see, this polling setup is not ideal, and far worse when a compositor is present. There are multiple problems that can cause a new video frame to fail to be displayed, causing a previous frame to be displayed for longer than intended and potentially skipping the new frame altogether!
The solution is to work with the compositor instead of against it. Present a new video frame immediately and afterward, call a command that will block until the compositor has completed it’s task (DwmFlush). This will ensure that at most 1 new video frame is presented to the compositor between each VBlank period. As long as the compositor is active, you also won’t have to worry about polling for VBlank yourself anymore.
So the best thing to do is:
Another edit: For future readers there is are two other ways to wait for VBLANK that I wasn’t aware of they are IDXGIOutput::WaitForVBlank and IDirectDraw7::WaitForVerticalBlank the latter being deprecated.
CALL command vs. START with /WAIT option
How is the START command with a WAIT option
. any different from using a CALL command?
Is there a situation where one may behave differently that the other dependending on what is being executed?
6 Answers 6
For exe files, I suppose the differences are nearly unimportant.
But to start an exe you don’t even need CALL .
When starting another batch it’s a big difference,
as CALL will start it in the same window and the called batch has access to the same variable context.
So it can also change variables which affects the caller.
START will create a new cmd.exe for the called batch and without /b it will open a new window.
As it’s a new context, variables can’t be shared.
Differences
Using start /wait
— Changes of environment variables are lost when the
ends
— The caller waits until the
Using call
— For exe it can be ommited, because it’s equal to just starting
— For an exe-prog the caller batch waits or starts the exe asynchronous, but the behaviour depends on the exe itself.
— For batch files, the caller batch continues, when the called finishes, WITHOUT call the control will not return to the caller batch
Addendum:
Using CALL can change the parameters (for batch and exe files), but only when they contain carets or percent signs.
Will be expanded to (from within an batch file)
I think that they should perform generally the same, but there are some differences. START is generally used to start applications or to start the default application for a given file type. That way if you START http://mywebsite.com it doesn’t do START iexplore.exe http://mywebsite.com .
START myworddoc.docx would start Microsoft Word and open myworddoc.docx. CALL myworddoc.docx does the same thing. however START provides more options for the window state and things of that nature. It also allows process priority and affinity to be set.
In short, given the additional options provided by start, it should be your tool of choice.
There is a useful difference between call and start /wait when calling regsvr32.exe /s for example, also referenced by Gary in in his answer to how-do-i-get-the-application-exit-code-from-a-windows-command-line
will always return 0 but
will return the error level from regsvr32.exe
This is what I found while running batch files in parallel (multiple instances of the same bat file at the same time with different input parameters) :
Lets say that you have an exe file that performs a long task called LongRunningTask.exe
If you call the exe directly from the bat file, only the first call to the LongRunningTask will succed, while the rest will get an OS error «File is already in use by the process»
If you use this command:
start /B /WAIT «» «LongRunningTask.exe» «parameters»
You will be able to run multiple instances of the bat and exe, while still waiting for the task to finish before the bat continues executing the remaining commands. The /B option is to avoid creating another window, the empty quotes are needed in order to the command to work, see the reference below.
Note that if you don´t use the /WAIT in the start, the LongRunningTask will be executed at the same time than the remaining commands in the batch file, so it might create problems if one of these commands requires the output of the LongRunningTask
This can´t run in parallel :
This will run in parallel and will be ok as far as there are no data dependencies between the output of the command and the rest of the bat file :
- start /B «» «LongRunningTask.exe» «parameters»
This will run in parallel and wait for the task to finish, so you can use the output :
Wait Functions
Wait functions allow a thread to block its own execution. The wait functions do not return until the specified criteria have been met. The type of wait function determines the set of criteria used. When a wait function is called, it checks whether the wait criteria have been met. If the criteria have not been met, the calling thread enters the wait state until the conditions of the wait criteria have been met or the specified time-out interval elapses.
Single-object Wait Functions
The SignalObjectAndWait, WaitForSingleObject, and WaitForSingleObjectEx functions require a handle to one synchronization object. These functions return when one of the following occurs:
- The specified object is in the signaled state.
- The time-out interval elapses. The time-out interval can be set to INFINITE to specify that the wait will not time out.
The SignalObjectAndWait function enables the calling thread to atomically set the state of an object to signaled and wait for the state of another object to be set to signaled.
Multiple-object Wait Functions
The WaitForMultipleObjects, WaitForMultipleObjectsEx, MsgWaitForMultipleObjects, and MsgWaitForMultipleObjectsEx functions enable the calling thread to specify an array containing one or more synchronization object handles. These functions return when one of the following occurs:
- The state of any one of the specified objects is set to signaled or the states of all objects have been set to signaled. You control whether one or all of the states will be used in the function call.
- The time-out interval elapses. The time-out interval can be set to INFINITE to specify that the wait will not time out.
The MsgWaitForMultipleObjects and MsgWaitForMultipleObjectsEx function allow you to specify input event objects in the object handle array. This is done when you specify the type of input to wait for in the thread’s input queue. For example, a thread could use MsgWaitForMultipleObjects to block its execution until the state of a specified object has been set to signaled and there is mouse input available in the thread’s input queue. The thread can use the GetMessage or PeekMessageA or PeekMessageW function to retrieve the input.
When waiting for the states of all objects to be set to signaled, these multiple-object functions do not modify the states of the specified objects until the states of all objects have been set signaled. For example, the state of a mutex object can be signaled, but the calling thread does not get ownership until the states of the other objects specified in the array have also been set to signaled. In the meantime, some other thread may get ownership of the mutex object, thereby setting its state to nonsignaled.
When waiting for the state of a single object to be set to signaled, these multiple-object functions check the handles in the array in order starting with index 0, until one of the objects is signaled. If multiple objects become signaled, the function returns the index of the first handle in the array whose object was signaled.
Alertable Wait Functions
The MsgWaitForMultipleObjectsEx, SignalObjectAndWait, WaitForMultipleObjectsEx, and WaitForSingleObjectEx functions differ from the other wait functions in that they can optionally perform an alertable wait operation. In an alertable wait operation, the function can return when the specified conditions are met, but it can also return if the system queues an I/O completion routine or an APC for execution by the waiting thread. For more information about alertable wait operations and I/O completion routines, see Synchronization and Overlapped Input and Output. For more information about APCs, see Asynchronous Procedure Calls.
Registered Wait Functions
The RegisterWaitForSingleObject function differs from the other wait functions in that the wait operation is performed by a thread from the thread pool. When the specified conditions are met, the callback function is executed by a worker thread from the thread pool.
By default, a registered wait operation is a multiple-wait operation. The system resets the timer every time the event is signaled (or the time-out interval elapses) until you call the UnregisterWaitEx function to cancel the operation. To specify that a wait operation should be executed only once, set the dwFlags parameter of RegisterWaitForSingleObject to WT_EXECUTEONLYONCE.
If the thread calls functions that use APCs, set the dwFlags parameter of RegisterWaitForSingleObject to WT_EXECUTEINPERSISTENTTHREAD.
Waiting on an Address
A thread can use the WaitOnAddress function to wait for the value of a target address to change from some undesired value to any other value. This enables threads to wait for a value to change without having to spin or handle the synchronization problems that can arise when the thread captures an undesired value but the value changes before the thread can wait.
WaitOnAddress returns when code that modifies the target value signals the change by calling WakeByAddressSingle to wake a single waiting thread or WakeByAddressAll to wake all waiting threads. If a time-out interval is specified with WaitOnAddress and no thread calls a wake function, the function returns when the time-out interval elapses. If no time-out interval is specified, the thread waits indefinitely.
Wait Functions and Time-out Intervals
The accuracy of the specified time-out interval depends on the resolution of the system clock. The system clock «ticks» at a constant rate. If the time-out interval is less than the resolution of the system clock, the wait may time out in less than the specified length of time. If the time-out interval is greater than one tick but less than two, the wait can be anywhere between one and two ticks, and so on.
To increase the accuracy of the time-out interval for the wait functions, call the timeGetDevCaps function to determine the supported minimum timer resolution and the timeBeginPeriod function to set the timer resolution to its minimum. Use caution when calling timeBeginPeriod, as frequent calls can significantly affect the system clock, system power usage, and the scheduler. If you call timeBeginPeriod, call it one time early in the application and be sure to call the timeEndPeriod function at the very end of the application.
Wait Functions and Synchronization Objects
The wait functions can modify the states of some types of synchronization objects. Modification occurs only for the object or objects whose signaled state caused the function to return. Wait functions can modify the states of synchronization objects as follows:
- The count of a semaphore object decreases by one, and the state of the semaphore is set to nonsignaled if its count is zero.
- The states of mutex, auto-reset event, and change-notification objects are set to nonsignaled.
- The state of a synchronization timer is set to nonsignaled.
- The states of manual-reset event, manual-reset timer, process, thread, and console input objects are not affected by a wait function.
Wait Functions and Creating Windows
You have to be careful when using the wait functions and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. If you have a thread that uses a wait function with no time-out interval, the system will deadlock. Two examples of code that indirectly creates windows are DDE and the CoInitialize function. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than the other wait functions.