Jump to content
  • Advertisement
Sign in to follow this  
Bozebo

[c++] Stop windows command line pausing process while moving/scrolling

This topic is 2693 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

edit: (this isn't sorted yet)


Hi, I am trying to program a game server in Windows that runs as a command line application. It all works nicely, except the windows API is allowing the process to be paused when there is interaction with the command line window, which totally breaks my timing system for network update ticks and the frame rate (I am using the HPET). Is there a way to control the window's properties through C/C++? To make it keep crunching even when being scrolled/moved/resized?

Share this post


Link to post
Share on other sites
Advertisement
Your application appears to hang when the command window is being manipulated, because stdout/stderr are not read at that time. And once the stdout/stderr buffer is full, every attempt to write to stdout/stderr will block until the buffer is being cleared again.

So, one possible solution is to use async io to write to stdout. Another possibility is to do the time critical stuff (or just everything) in a second thread, write output to a buffer and have the main thread read that buffer and write it to stdout/stderr. Or do it the other way round and create a "logger" thread...

I hope that helps!

Share this post


Link to post
Share on other sites

Your application appears to hang when the command window is being manipulated, because stdout/stderr are not read at that time. And once the stdout/stderr buffer is full, every attempt to write to stdout/stderr will block until the buffer is being cleared again.

So, one possible solution is to use async io to write to stdout. Another possibility is to do the time critical stuff (or just everything) in a second thread, write output to a buffer and have the main thread read that buffer and write it to stdout/stderr. Or do it the other way round and create a "logger" thread...

I hope that helps!


The thread that main is called from is indeed paused when the command window is being maniupulated, not just the standard output - because the timing system messes up due to it using the HPET which is handled by the CPU core, rather than something like Clock() which is per-thread. I will have to make a primary thread spawn from within main(). Thanks.

Share this post


Link to post
Share on other sites
OK. This isn't working at all. Windows pauses the entire process whenever there is any interaction with the command line window (it pauses ALL threads). I have used other things in the past that don't freeze up if you manipulate the window (like srcds), there has to be a library with some way to control the command line window and turn that rubbish off. The MSDN is impossible to navigate, I can't actually find anything useful on it at all in relation to this issue.

Share this post


Link to post
Share on other sites

OK. This isn't working at all. Windows pauses the entire process whenever there is any interaction with the command line window (it pauses ALL threads).

Out of interest, how are you determining that this is the case?

Share this post


Link to post
Share on other sites

[quote name='Bozebo' timestamp='1304344142' post='4805422']
OK. This isn't working at all. Windows pauses the entire process whenever there is any interaction with the command line window (it pauses ALL threads).

Out of interest, how are you determining that this is the case?
[/quote]

My timing code does write a string to stdout, but it is the contents of this that show the process is being halted. After manipulating the command line window in some way it presents artifacts in my networking code of only 1 frame being passed between each tick, and ticks occurring incredibly fast until enough ticks have been caught up for over the period of the thread being suspended (remember, it uses the HPET which continues counting on the cpu core).

I have a thread, which is spawned from in main(). This thread is locked to a CPU core (the lowest available; 0 or 1) to keep the HPET timing consistent to that core.

In this thread there is an infinite loop, which counts an unsigned long of frames passed. At the end of each frame, the HPET is queried to see if it is greater than or equal to the HPET count expected for when the next tick should start, if so: some tick/fps/timing info is printed to stdout, it then deals with network in/out buffers and it increases the tick count.

The tick rate is 30Hz. At the start of the thread it queries the HPET resolution in Hz, it can then determine how many HPET ticks should occur each tick (resolution over requested tick rate). The frames occuring each tick sit on or between 930 and 1000 under normal circumstances (on my system, this will vary between machines and current workload of course, the tickrate is the trusted timing figure for mover interpolation etc).

Here is a code extract (the code box won't show my indentation properly for some reason, sorry):


while(stopServer == 0){

/*
per-frame stuff here
*/

QueryPerformanceCounter(&tmpLargeInteger); //get the current HPET count
hpetCurrent = tmpLargeInteger.QuadPart; //get the count into a managable data type (microsoft LONGLONG)
if(hpetCurrent >= hpetNextTick){ //if the next tick has started

//frames passed this tick
int frameDiff = int(frameCount - framesAtLastTick);
framesAtLastTick = frameCount;
printf("Frames passed this tick: %d\n",frameDiff);

//detect fps, sort of - this is just for testing
fps = float(frameDiff*tickRate);
//printf("FPS = %d * %d\n",frameDiff,tickRate);
printf("FPS: %.2f\n",fps);

//loop through all clients, brute force it for now...
for(std::map<SOCKET,ribClient*>::iterator mapIt = clients.begin();
mapIt != clients.end();mapIt ++){
//resolve buffer
mapIt->second->resolveBuffs();
}

hpetNextTick += hpetCountsPerTick; //record when the next tick will start
currentTick ++;
printf("tick: %d\n",currentTick);
}

//increment the frame count
frameCount ++;
} //end of while clause for infinite frame loop

} //end of thread function, ribServer::run


Here is a screenshot of the window when it is working cleanly, I havn't resized, dragged, moved or scrolled it:
servTiming1.png

And here is a screenshot of just after I clicked and held the scroll bar for a short time (to make sure the before and after situations are shown in it). My crude mspaint red circle shows the next output after I released the scroll bar:
servTiming2.png

You can see it got back into timing quite quickly, but the longer I manipulate it for, the longer the process freezes and so the more ticks pass with 1 frame inbetween until it gets back into time. Of course, if it was simply waiting before displaying more stdout there wouldn't be any problems.

Also, if I pass a ping message through my server from the client, it is delayed based on how long I make the process freeze by manipulating the command line window.

I have one solution for now, and that is to leave the command window alone while I test what I have been working on, but you could see why I want to fix this issue

Maby if I ran it on another machine command line access it would not pass on command window manipulations and hence not pause the process, this would also be more like an actual deployment too, not that I am working on anything commercial with this.

Share this post


Link to post
Share on other sites
Redirect stdout to a file and test again with scrolling. My guess is there will be no hickups in the file output.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!