Jump to content
The simFlight Network Forums

Programm Freeze is FSX shutdown first


Recommended Posts

Hello Pete and everyone else,

I have a Problem with my Programm which I write in Delphi (don't know if that matters)

I start FSX, then the Programm and everything works fine.

But when I close FSX before closing the programm, the programm just feezes completely when running on the same PC.

When I run it on another PC via WideFS it slows down quit a bit but at least it doesn't freeze completely. Probably has something to do with WideFS saving the last data it got from the FS.

Is there anyway to work around that? I tried to stop all Read or Writes to/from FS when it isn't responding but that doesn't work when the programm feezes completely.

Thanks

Christoph

Link to comment
Share on other sites

But when I close FSX before closing the programm, the programm just feezes completely when running on the same PC.

Sounds like you aren't handling the error conditions? The SendMessageTimeOut sent to FSUIPC should time out or fail when FS closes. Have you tried using the Delphi debugger to see where it is hanging?

I didn't write the Delphi interface program, but as far as I know all the source is there so you should be able to figure it out. Programs like FSInterrogate are written in Delphi, and manage to detect when FS closes and rejoin when it restarts.

Regards

Pete

Link to comment
Share on other sites

Sounds like you aren't handling the error conditions? The SendMessageTimeOut sent to FSUIPC should time out or fail when FS closes. Have you tried using the Delphi debugger to see where it is hanging?

I didn't write the Delphi interface program, but as far as I know all the source is there so you should be able to figure it out. Programs like FSInterrogate are written in Delphi, and manage to detect when FS closes and rejoin when it restarts.

Regards

Pete

Hey Pete,

thanks I'll take a closer look at it!

Sorry for posting twice, please delete one of the topics.

Christoph

Link to comment
Share on other sites

Hey Pete

I found the "Problem": FPCuser.pas Lines 245 ff

  // send the request (allow up to 9 tries)
  while (i < 10) and ((SendMessageTimeout(
                      	m_hWnd,          	// FS6 window handle
                      	m_msg,   			// our registered message id
                      	m_atom,          	// wParam: name of file-mapping object
                      	0,       			// lParam: offset of request into file-mapping obj
                      	SMTO_BLOCK,      	// halt this thread until we get a response
                      	2000,           		// time out interval
                      	dwError)) = 0) do
  begin  // return value
	Inc(i);
	Sleep(100); // Allow for things to happen
  end;

  if (i >= 10) then
  begin  // Failed all tries
	if GetLastError = 0 then dwResult := FSUIPC_ERR_TIMEOUT
                    	else dwResult := FSUIPC_ERR_SENDMSG;
	Result := FALSE;
	Exit;
  end;

The Programm didn't freeze, but I had so many Request that it seemed so. With a sleep time of 100ms and 10 retries every failed request makes up 1 sec.

I modified these lines a little but and my programm too.

I had many timers requesting data every 500ms or so. With many timers that "freeze time" add up pretty quick. Now I check at the beginning of each timer and exit the function if not connected any more.

I changed the lines mentioned above to the following:

  // send the request (allow up to 9 tries)
  while (i < 1) and ((SendMessageTimeout(
                      	m_hWnd,          	// FS6 window handle
                      	m_msg,   			// our registered message id
                      	m_atom,          	// wParam: name of file-mapping object
                      	0,       			// lParam: offset of request into file-mapping obj
                      	SMTO_BLOCK,      	// halt this thread until we get a response
                      	50,             		// time out interval
                      	dwError)) = 0) do
  begin  // return value
	Inc(i);
  end;

  if (i >= 1) then
  begin  // Failed all tries
	if GetLastError = 0 then dwResult := FSUIPC_ERR_TIMEOUT
                    	else dwResult := FSUIPC_ERR_SENDMSG;
	Result := FALSE;
	Exit;
  end;

Do you think that could be a problem? I didn't find any problems while testing it.

Hope others having same problems can solve them too!

Thanks again

Christoph

Link to comment
Share on other sites

The Programm didn't freeze, but I had so many Request that it seemed so. With a sleep time of 100ms and 10 retries every failed request makes up 1 sec.

I modified these lines a little but and my programm too.

...

I had many timers requesting data every 500ms or so. With many timers that "freeze time" add up pretty quick.

If you are only requesting data once every 500 mSecs I don't see how there could be a problem. Many programs make requests every 30 or 50 mSecs and don't have problems! Obviously they don't "hang" for more than the one second it takes for those timed-out retries, then they can report the failure. How can those be accumulated to make it appear completely hung? I'm afraid I don't understand.

But perhaps you mean you have lots of asynchronous "FSUIPC_Process" calls, each only requesting one or two items of data? If so, that is a very inefficient, way of doing things. You should be accumulating all reads and writes into one regular batch which is sent at regular intervals (and only needing one timer). That's why the "Process" call is separated from the "Read" and "Write" calls. The latter two merely build up a request package. The request package sent by the FSUIPC_Process routine should be regular.

Regards

Pete

Link to comment
Share on other sites

But perhaps you mean you have lots of asynchronous "FSUIPC_Process" calls, each only requesting one or two items of data? If so, that is a very inefficient, way of doing things. You should be accumulating all reads and writes into one regular batch which is sent at regular intervals (and only needing one timer). That's why the "Process" call is separated from the "Read" and "Write" calls. The latter two merely build up a request package. The request package sent by the FSUIPC_Process routine should be regular.

Hey

Yes I have many asynchronous "FSUIPC_Process" calls, because I "exported" all procedures reading or writing from fsx into a dll to get the source code out of my programm. I really need a lot of items and don't know if i can realize that all in one FSUIPC_Process routine. But maybe I'll try. Is there any other possible way?

I would need own variables for every fsuipc item and update them every 50ms or how ever often i need it. Is that what you mean?

Thanks

Christoph

Link to comment
Share on other sites

I really need a lot of items and don't know if i can realize that all in one FSUIPC_Process routine.

Why not? You can accumulate up to 30 kbytes worth of requests for any one Process call. I've never heard of any application even coming close to that. There's only 65k bytes worth of data available, maximum, in any case, and a lot isn't used yet.

I would need own variables for every fsuipc item and update them every 50ms or how ever often i need it. Is that what you mean?

No. I means that you should request all the data you want in one regular Process call. It doesn't matter where or how many or how often you do FSUIPC_Read and FSUIPC_Write calls. It's only the Process call which is switching control from your program to FS and back. Doing that for every little bit of individual data is insanely inefficient.

Regards

Pete

Link to comment
Share on other sites

No. I means that you should request all the data you want in one regular Process call. It doesn't matter where or how many or how often you do FSUIPC_Read and FSUIPC_Write calls. It's only the Process call which is switching control from your program to FS and back. Doing that for every little bit of individual data is insanely inefficient.

Regards

Pete

Hey Pete

Sorry but I don't really understand.

I need a Process call after a Read Call before I can display the data oder do whatever. Is that correct?

Now when I need the airspeed for example. I do a Read Call for airspeed and then a Process Call. And when I need the Altitude I do a Read Call for altitude and then a Process Call. Sure I could do both Read calls and after both of them 1 Process Call but then I would need to save the data until I really need it?!

Right now I have a function ReadAirspeed and ReadAltitude which return the Value and exported them into a dll.

Christoph

Link to comment
Share on other sites

I need a Process call after a Read Call before I can display the data oder do whatever. Is that correct?

Yes, of course. But you would be better off doing all your displays after all your reads, and ONE process. That's all I mean.

Now when I need the airspeed for example. I do a Read Call for airspeed and then a Process Call. And when I need the Altitude I do a Read Call for altitude and then a Process Call. Sure I could do both Read calls and after both of them 1 Process Call but then I would need to save the data until I really need it?!

I'm not sure here what you mean by "need it". But one way of implementing things efficiently is to have a thread which reads everything you need every so often (eg. every 50 or 100 or 250 mSecs), with the one process call needed, and stores them all ready for access. Your other threads simply read the values they need, when they need them. They will never be more than 50, 100, or 250 mSecs out of date, whatever.

If what you have works wel, and, importantly, doesn't slow FS or interfere with other programs, then don't re-design everything for this. I am only trying to point out ways of making things really efficient. There is more time spent in process switches because of "FSUIPC_Process" than anything else you might be doing. If performance is not "of the essence" I wouldn't worry too much.

Regards

Pete

Link to comment
Share on other sites

Yes, of course. But you would be better off doing all your displays after all your reads, and ONE process. That's all I mean.

I'm not sure here what you mean by "need it". But one way of implementing things efficiently is to have a thread which reads everything you need every so often (eg. every 50 or 100 or 250 mSecs), with the one process call needed, and stores them all ready for access. Your other threads simply read the values they need, when they need them. They will never be more than 50, 100, or 250 mSecs out of date, whatever.

If what you have works wel, and, importantly, doesn't slow FS or interfere with other programs, then don't re-design everything for this. I am only trying to point out ways of making things really efficient. There is more time spent in process switches because of "FSUIPC_Process" than anything else you might be doing. If performance is not "of the essence" I wouldn't worry too much.

Regards

Pete

Hey Pete

Thanks for your answer. Performance is allways important ;-) I'll take a look at it, and probably going to re-design it if it isn't too much work.

Thanks again!

Christoph

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.