Threads.h++ 1.4 contained a tricky circular dependency among classes now included as part of the Synchronization and Threading packages. An important design criterion of package-based architectures is to avoid circular dependencies between packages, so the difficult decision was made to fix the problem in Threads.h++ 2.0 at the cost of breaking source compatibility with Threads.h++ 1.4. This change should affect only a small number of users, and the necessary modifications to user code are trivial to implement.
The change affects the automatic servicing of cancellation requests by synchronization objects, as explained in Section 4.5.1.7, "Servicing Cancellation Requests." In Threads.h++ 1.4, synchronization object constructors could be passed an enumerated constant of type RWCancellationState. The choices for this constant were RW_CANCELLATION_ENABLED and RW_CANCELLATION_DISABLED, each having its obvious effect. In addition, after construction, you could turn on or off automatic cancellation servicing via member functions RWSynchObject::enableCancellation(void) and RWSynchObject::disableCancellation(void).
The member function RWSynchObject::enableCancellation(void) has not been retained in Threads.h++ 2.0. Thus, any use of this member function no longer compiles; you have to modify your source code. In its place, Threads.h++ 2.0 includes the member function RWSynchObject::setCancellation(RWCancellationState), which, when passed the macro RW_CANCELLATION_ENABLED as an argument, works exactly the same as the old member function.
For example, existing code such as
RWMutexLock mutexLock; mutexLock.enableCancellation(); // Error: NO LONGER COMPILES!
must be modified to
RWMutexLock mutexLock; mutexLock.setCancellation(RW_CANCELLATION_ENABLED); // The new way to go!
You may have noticed that RW_CANCELLATION_ENABLED was first referred to as an enumerated constant and later as a macro. This is because RWCancellationState is no longer an enumerated type, but a typedef for a function pointer:
typedef void(*RWCancellationState)(void);
Therefore, the former enumerated constants RW_CANCELLATION_ENABLED and RW_CANCELLATION_DISABLED must now be function pointers. When passed to a synchronization object constructor or used with the RWSynchObject::setCancellation() member function, these function pointers are stored away. When it is later time to service a cancellation, if the pointer is not NULL, then the function is called. It is not surprising, then, that the former enumerated constants are now macros with the following definitions:
#define RW_CANCELLATION_DISABLED (RWCancellationState)0 #define RW_CANCELLATION_ENABLED &rwServiceCancellation
RWCancellationState and RW_CANCELLATION_DISABLED are in the Synchronization package, in header file rw\sync\RWCancellationState.h. RW_CANCELLATION_ENABLED is in the Threading package, in header rw\thread\RWCancellation.h. You will rarely have to include these headers directly because they are included for you when using the various synchronization and threading classes.
©Copyright 2000, Rogue Wave Software, Inc.
Contact Rogue Wave about documentation or support issues.