Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

Event Loop problem

Lets say I have a multi-platform application object. It has a method called Run(). Run does NOT return until the application exists. I also have the carbon framework which has the CarbonApp with it's Run which also does not return. I have figured out that if I run the CarbonApp in a thread it does not get any messages (Task monitor shows it as red, not responding). I am now running my app as the thread, but I do not know the full ramifications of this, but it presents a problem.

When my object's Run() returns, the thread exits, but the main app still runs. How do I tell the main thread which is in its Run() to quit? I tried QuitApplicationEventLoop(); from the thread but it doesn't do anything. I just need a way to have the main app exit when my thread exists. Can someone explain to me how to do this?

There is another option, run my own event loop instead of using the default one. I have had limited success with this, because at sometime the event loop starts to spin. I copied some example code to use as my event loop, but as I said, it goes nuts sometimes. The "count" was added by me, but the rest is directly copied from some apple document somewhere.
void EventPump()
{
EventRecord theEvent;

int Count = 0;

// Cycle through all events
while (1 == GetNextEvent(everyEvent, &theEvent))
{
Count++;

// Sometimes we get in an infinit message loop. This will limit message proccessing
// to 100 messages max per call.
if ( 100 == Count )
{
break;
}

AEProcessAppleEvent(&theEvent);
}
}

Most of the time, for hours, sometimes for days, that works fine, but then Ill suddenly see my process at 99% cpu usage and stuck in this loop, and will eventually crash. The crash log is how I know where the problem is. Maybe there is a simple fix or someone can give me another simple event loop that will not lock up.

I need that or a way from my threaded app to cause the main event loop to exit when the thread exits. Any help is greatly appreciated.

EMac, Mac Mini, Mac OS X (10.4.6)

Posted on Jan 26, 2009 8:04 AM

Reply
19 replies

Jan 28, 2009 6:30 AM in response to etresoft

The part that isn't compatible are usually the main() functions, such as the ones I am having difficulty with here. I deal with the apple framework, in this case carbon, to manage whatever apple demands, once again in this case a message pump. It would be nice if when I had started all this, they could have said carbon was out-dated and I should use Cocoa as starting point, but they didn't.

So how does Cocoa deal with non-gui applications non-daemon and daemon applications? If it can be used for daemons, do any of the APIs break once a user logs out? Clearly ones that directly deal with a user and/or GUI can't function, but once a user logs in, will they resume functioning or will certain linkages be broken?

How would it deal with the initial problem? A function, which will not return for a very long time needs to be called, but when it does return the whole application has to exit? From a non-daemon and daemon standpoint?

Will carbon functions be available in Cocoa? I could re-wrap my app in a cocoa framework, but there are some carbon functions used here and there, will I have to re-work them and use Cocoa versions, if they exist?

Jan 28, 2009 10:32 AM in response to TheSilverHammer

TheSilverHammer wrote:
The part that isn't compatible are usually the main() functions, such as the ones I am having difficulty with here. I deal with the apple framework, in this case carbon, to manage whatever apple demands, once again in this case a message pump. It would be nice if when I had started all this, they could have said carbon was out-dated and I should use Cocoa as starting point, but they didn't.


There are political, psychological, and legal aspects to when APIs are officially deprecated. You just have to do research. Many parts of Cocoa are being deprecated. It never stops.

Keep in mind that the code you posted wasn't Carbon. It was obsolete in System 6 circa 1988.

So how does Cocoa deal with non-gui applications non-daemon and daemon applications? If it can be used for daemons, do any of the APIs break once a user logs out? Clearly ones that directly deal with a user and/or GUI can't function, but once a user logs in, will they resume functioning or will certain linkages be broken?


It really isn't much different than anything else. Don't use APIs that require the display or having a user logged in. While it is possible to figure out the exact details of how it all works, it is better to just avoid it. Write a daemon with is guaranteed to work properly even if no one is logged in and there is no monitor connected. Write userspace code that runs at login that will talk to the daemon. Each application has a particular context and they are designed to work within their own context. It isn't advisable to try to change that architecture.

How would it deal with the initial problem? A function, which will not return for a very long time needs to be called, but when it does return the whole application has to exit? From a non-daemon and daemon standpoint?


That is just the main() function. Put a while(running) loop in there and, in your signal handler, set running to false. Your application will quit.

Will carbon functions be available in Cocoa? I could re-wrap my app in a cocoa framework, but there are some carbon functions used here and there, will I have to re-work them and use Cocoa versions, if they exist?


It isn't a question of using one library or the other. Use the library that addresses the problem, isn't obsolete, and is easiest to use. In most cases, that is Cocoa. Sometimes it is Carbon. The operating system doesn't care which one you use. Some parts of Cocoa are objective-C wrappers around Carbon functions and some Carbon functions are C interfaces to Cocoa routines. Cocoa expects certain runtime libraries to be initialized via the NSApplication object. If you aren't writing a full-fledged Cocoa app, you will probably have to call NSApplicationLoad() to bootstrap Cocoa. This is normal for non-GUI Cocoa apps.

Jan 28, 2009 11:12 AM in response to TheSilverHammer

So say you have some legacy code that has some value if slightly extended to run better under OS X, but not enough value to be worth a nearly complete rewrite of a fairly large code base to use current best-practice APIs.

What I might try, to make the port effort as minimal as possible, is to use global boolean flags. A Carbon legacy_main() can poll for an exit flag (and other event flags) inside its wait-next-event-loop, and also set some appropriate flags on return or exit, and other events. On the other side, a Cocoa run loop can have a repeating NSTimer routine that also polls some flags, and at a rate that would make the UI reasonably responsive without wasting a lot of cycles. If either side sees the other's "quit" flag, it can assume the other side had exited, or was ready to exit, and take the appropriate action.

.

Jan 28, 2009 11:51 AM in response to hotpaw2

With carbon, I had tried to use the timer, look for variable quit code, but I could not figure out how to cause it to quit at that time. I do not really remember the names of the functions, but they were like AEExitRunLoop() or PostApplicationExit() and what not. Each timer tick they would be called and the main app would not stop. That is in the past. I got the example etresoft linked to and am using it. The web version didn't say anything about it being old and not to use it. My local help does say its old and not to use it. Currently both the daemon and client are going through a soak test and are still operating normally. Ill give them a few days, and in my spare time Ill read up on Cocoa.

I went through many iterations of methods before posting here and all you had suggested I had already tried. This problem may be solved, but only time will tell. Of the last message loop example I posted, I am wondering if I should just black-hole the messages and not pass them on. There is nothing of mine the receive them. For example what if an AEOpenApplication event comes through and I pass it to AEProcessAppleEvent(&event); I installed no handler. Does that message disappear because there is no handler or does it stay in the event loop and I end up getting over and over. Then more events come and I continue to pass them through and the message queue gets bigger and it takes longer each cycle and eventually blows up.

If I black hole the events, will that cause a problem since I have no interest in any event? I do not know.

Event Loop problem

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.