472 30.ACrossPlatformMultithreadingFramework
we want to discuss is the possibility of a Mac OS X port. The source code pro-
vided on the website is basically ready to be built on a Mac, but there are a few
things to consider. The first one is that the Mac OS X kernel only supports a total
of 10 System V semaphores, using the
SEM_UNDO flag, in the whole system
[Huyler 2003]. This means that if no other application is using a System V sema-
phore, we can have a maximum of three named semaphores, mutexes, or events
with our framework on Mac OS X. A simple solution to this problem is to use
only POSIX semaphores for both named and unnamed synchronization objects
on Mac OS X platforms. However, a problem that is introduced by this fix is that
the named auto-reset event implementation in our framework requires the flexi-
bility of System V’s
semop() function. A POSIX implementation could be made
similar to the one for an unnamed event, but it has to keep the signal flag in a
shared memory segment. Another problem we experienced on Mac OS X was
that the
sem_init() function always failed with an ENOSYS error. This is because
the POSIX semaphores implementation on Mac OS X only supports named sem-
aphores and does not implement
sem_init() [Jew 2004]. Apart from these limi-
tations, the framework should already work perfectly on Mac OS X, without
requiring any code changes.
In this chapter, we also showed how to implement a wait function similar to
the Windows API
WaitForMultipleObjects() function. However, our imple-
mentation currently only works with unnamed events. This limitation is caused
by the condition variable used to signal that an object has been unlocked, which
is only visible to a single process. This means that if a named mutex is unlocked
in process A, our wait function in process B won’t be notified of the state change
and will remain blocked. A possible solution to this problem is to use a System V
semaphore to signal a state change across process boundaries. However, this
should be used with care since our processes might end up receiving many notifi-
cations, resulting in a lot of polling in the
WaitList. On Windows, you can also
specify whether you want to wait for any or all objects in the
WaitList. Our cur-
rent implementation only supports the first case, but adding support for the se-
cond case should be straightforward. Finally, if you are really concerned about
performance, you might want to add a
BasicWaitList class that works with the
basic synchronization classes, instead of
WaitObject-derived ones.
The last potential pitfall that we want to highlight occurs when using named
mutexes. On Windows, mutexes can be locked by the same thread multiple times
without blocking. With Pthreads, you can specify whether the mutex should be
recursive using the
PTHREAD_MUTEX_RECURSIVE type. Unfortunately, our imple-
mentation does not offer this functionality using our System V semaphore with-
out introducing additional overhead to keep track of the current thread and its
30.4FutureExtensions 473
lock count. Therefore, if you really require recursive mutexes, then you should
try to avoid using named mutex instances. One more thing left to do when inte-
grating the framework into your own projects is to implement logging. If you
search through the code, you will find some comments containing
TRACE state-
ments. These lines should be replaced with your engine’s own logging facilities.
30.4FutureExtensions
We believe that our framework can be extended in many useful ways. In the code
on the website, we show two examples in the
WaitObjectEx.* files. The first is
a small class that derives from
WaitObject and encapsulates the thread stop
event found in
ThreadInfo. Using this class, we can construct a thread wait ob-
ject from a
ThreadInfo instance, which can be used in a WaitForMultiple-
Objects()
call to wait for a thread to exit. Additionally, it also enables wait state
tracking for thread events. The second example is a simple last-in-first-out queue
that is in the signaled state when elements are in the queue and in the nonsignaled
state when the queue is empty. The class is derived from
WaitEvent, which
means that the queue can also be used with a
WaitList.
Another possibility to enhance the threading framework is offered by the
ThreadInfo class. In our system, we are using an exception-based error handling
framework that is tightly integrated into the threading framework. If an exception
occurs in a thread, then we have a generic exception handler in our thread start
procedure (in the
ThreadInfo class) that collects the exception information for
any uncaught exception and stores it in the thread’s
ThreadInfo. The parent
thread is then able to retrieve the exact error information from that same
Thread-
Info
and use it for proper error reporting.
References
[Meyers 1995] Scott Meyers. More Effective C++: 35 New Ways to Improve Your
Programs and Designs. Reading, MA: Addison-Wesley, 1995.
[Sandler 2009] Alexander Sandler. “pthread mutex vs pthread spinlock.” Alex on Linux,
May 17, 2009. Available at http://www.alexonlinux.com/pthread-mutex-vs-
pthread-spinlock.
[Nagarajayya and Gupta 2000] Nagendra Nagarajayya and Alka Gupta. “Porting of
Win32 API WaitFor to Solaris.” September 2000. Available at http://developers.
sun.com/solaris/articles/waitfor_api.pdf.
474 30.ACrossPlatformMultithreadingFramework
[Huyler 2003] Christopher Huyler. “SEM_UNDO and SEMUME kernel value issues.”
osdir.com, June 2003. Available at http://osdir.com/ml/macosx.devel/2003-06/
msg00215.html.
[Jew 2004] Matthew Jew. “semaphore not initialized - Question on how to implement.”
FreeRADIUS Mailing List, October 28, 2004. Available at http://lists.cistron.nl/
pipermail/freeradius-devel/2004-October/007620.html.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.189.186.109