Logged in as Guest   Sat, Feb. 14th, 11:21 PM.      
Visitor Map
Recent Entries:
It's Not a Bug, It's a Feature!!!
What I've Been Up To
Debugging Windows Mobile/WinCE Applications Without ActiveSync
LinkedIn
I'm BACK!!!!!!
Code Monkey
Cool 3D Code Snippet From My Former Life
YouTube: The Revival of the Internet Time Killer
WhereMate Released
Palmasaurus Released As Freeware

Archive:
January - 2009
May - 2008
April - 2008
March - 2008
October - 2007
August - 2007
July - 2007
June - 2007
May - 2007
April - 2007
December - 2006
November - 2006
September - 2006
August - 2006
July - 2006
March - 2006
February - 2006
January - 2006
December - 2005
November - 2005
October - 2005
September - 2005
August - 2005
July - 2005
June - 2005
May - 2005
April - 2005
February - 2005
January - 2005
December - 2004
November - 2004
October - 2004
September - 2004
August - 2004
July - 2004
June - 2004
May - 2004
April - 2004
March - 2004

Running as a Background Process on the PalmOS
Overview:
At its core, the PalmOS is multithreaded. However, for all intents and purposes it is generally considered a single threaded OS for application developers. The OS itself is licensed/derived from the KADAK AMX kernel, which has support for threads, however there are no APIs to utilize them. (My guess is because of licensing restrictions, but I don't know for sure.)
One of the questions that repeatedly comes up on the Palm Developer Forums is how to accomplish multi-threading. However, when the question comes up, most developers really just want to know how to run a task in the background, and while there isn't an API to create threads, there are a few ways to implement tasks that run in the background. In this article, I present a high level overview of four of the different techniques that I have used successfully in the past.

Alarms:
Perhaps the easiest way to run a task in the background is to register an event to occur. In order to do that, you must use AlmSetAlarm to create your alarm, and then handle either the sysAppLaunchCmdAlarmTriggered or the sysAppLaunchCmdDisplayAlarm launch codes in your application. A couple caveats exist with these, however. If your application isn't the current application when it receives the alarm events, you don't have access to global variables. Furthermore, you can only use code that is in your first segment. (There are various articles elsewhere on the web detailing these limitations, so I won't go into them here.) The other limitation on this is that the latency on the alarms can be fairly high: it's probably not a good idea to use this method if you need to run more frequently than about every 5 seconds. However, this method is very appropriate if your background task's function is to wake up every so often, look around and then go back to sleep. For more "active" solutions, read on.

Registering For sysNotifyEventDequeuedEvent:
If you need lower latency in your functionality, and you are planning on running only on OS 5 and greater devices, you can register your application to receive sysNotifyEventDequeuedEvent notifications using the SysNotifyRegister function. As with any good solution, there are upsides and downsides. The upside is that you get called back every time any event gets dequeued by any application anywhere in the system. That in itself pretty much guarantees that you will get notified when something significant happens. The other big upside of this method is that since your callback will get called for all events (including NULL events), you can use EvtSetNullEventTick to control the maximum latency of your function without having to insert 'rogue' events into another application's event queue. (Although you can if you want to, but that's another article all together.)
The two downsides of this method are that 1. it is limited to OS5 and greater, and 2. depending on how much work you are doing in your callback, it could diminish the performance of the OS perceptibly. That being said, I have used this method in the past without any noticible degradation in performance.

Setting Traps:
One method that is very similar to registering for sysNotifyEventDequeuedEvent notifications, is setting a system function trap using the SysSetTrapAddress function. This is an older method of overriding the function for a system defined function. However, this functionality has been removed in OS 5, and I won't go into it in detail here since it has been depricated. (If you are looking for a good overview on this, try here.) The basic method would apply as explained in the previous section on using sysNotifyEventDequeuedEvent notifications, however, the execution would be slightly different.

The Sound Streaming Thread:
Another method for running as a background process is to queue up a streaming sound and run in the callback for that streaming sound. The most obvious limitation with this method is that it is only supported by devices that support the streaming sound API. Those are mostly limited to OS 5 devices, but to be safe, make sure to check for the .
There are various other references on the Internet how to do this, but the high level overview is that you create a variable length sound stream by calling
SndStreamCreateExtended . You then must define a callback that conforms to the SndStreamVariableBufferCallback function definition. It is in this callback that you can insert your code to work as a background process.
In case you are wondering, you don't actually have to play a sound. We're just exploiting the Streaming Sound Manager's API for callbacks to provide the functionality that you need.
One thing to note about this method is that in your callback, you don't have access to any of the symbols (i.e. global variables) that you create in your application, so use this with care.

Summary:
The PalmOS is filled with many ways to get around all the different limitations that handheld devices create for developers. The above four methods for running background tasks work very well for a very specific task. There probably are other ways to solve the same problem. These four methods are simply means to an end that I have used successfully in the past. As in any instance, YMMV. If you have used any of these methods or if you have found a different way to accomplish the same task, I'd love to hear about it.

-Jon
Submitted by bosshogg on Friday the 29th of April 2005, at 02:29 pm