using apple run loops in externals

Feb 1, 2007 at 7:44pm

using apple run loops in externals

Hi,

I am working on an external in which I need to receive an event from the OS (Mac OSX 10.4).

This is done through retreiving the current application’s run loop and adding a source for it such that the event can be captured (CFGetCurrentRunLoop() and CFAddRunLoopSource() or something similar)..

Normally after setting it up one would call CFRunLoopRun() to enter the runloop and process the events. However, I cannot do this for obvious reasons in the Main() or object creation function of my external.If I did it would block the external and maybe max/msp too. Any ideas?

Thanks,
Bert

#30073
Feb 1, 2007 at 8:09pm

You’re stepping into glaven territory here, but it would seem to me
that you’d want to kick off a thread and create a runloop on that
thread. I would imagine that you’d want a separate thread for each
instance of the object, unless you want to be tricky and maintain a
global dispatch table of objects.
Recall that you can only have one runloop per mach-task (thread).
The next question would be, do you want to communicate the event to
the main (scheduler) thread? If so, then you’ve got to record the
event into your object and peek at the event queue every time Max
runs you. If you don’t need to communicate, but instead would like
to enqueue an outbound message every time you get an event, then you
may be able to simply make an outlet call from your event-handling
thread. I’m presuming that the outlet call will enqueue and the
scheduler will pick up the outbound message on the next sweep.

_Mark

On Feb 1, 2007, at 11:44 AM, bert wrote:

>
> Hi,
>
> I am working on an external in which I need to receive an event
> from the OS (Mac OSX 10.4).
>
> This is done through retreiving the current application’s run loop
> and adding a source for it such that the event can be captured
> (CFGetCurrentRunLoop() and CFAddRunLoopSource() or something
> similar)..
>
> Normally after setting it up one would call CFRunLoopRun() to enter
> the runloop and process the events. However, I cannot do this for
> obvious reasons in the Main() or object creation function of my
> external.If I did it would block the external and maybe max/msp
> too. Any ideas?
>
> Thanks,
> Bert

#95257
Feb 2, 2007 at 6:16am

Thanks for your reply.

I just want to receive a notification message from the OS in my main thread and I’d prefer not to create a thread just for catching this notification message.

On windows, I do this by installing a wrapper for the window callback function which normally receives all messages from the operating system. I don’t have to call any function to make the run loop handle my message since the wrapper works as some kind of “filter”.

So I guess I would like to know : why do I need to manually call CFRunLoopRun() to make the thread catch the notification message? the run loop is supposed to run all the time?

Bert

#95258
Feb 2, 2007 at 9:07pm

I’m guessing that this is because the “main” thread is not really the
main thread. I would bet that max spawns a separate thread for the
Max event scheduler, and the window / gui stuff is truly handled on
the main thread. In general, on OS X, it’s bad to do anything that
could block (like say executing arbitrary code loaded from plugins)
on the main thread, that will give you a nice little psychedelic
pinwheel. If you want proof, put a while(1) or something in your
setup, run a patch with your external in the Max Runtime, and sample
that process (in bash: “sample Max”).

I dunno how to make sure code of yours is called on the main thread,
but that would be the way to get sources into the main runloop.

_Mark

On Feb 1, 2007, at 10:16 PM, bert wrote:

>
> Thanks for your reply.
>
> I just want to receive a notification message from the OS in my
> main thread and I’d prefer not to create a thread just for catching
> this notification message.
>
> On windows, I do this by installing a wrapper for the window
> callback function which normally receives all messages from the
> operating system. I don’t have to call any function to make the run
> loop handle my message since the wrapper works as some kind of
> “filter”.
>
> So I guess I would like to know : why do I need to manually call
> CFRunLoopRun() to make the thread catch the notification message?
> the run loop is supposed to run all the time?
>
> Bert
>

#95259

You must be logged in to reply to this topic.