Caution: This version of this document is no longer maintained. For the latest documentation, see http://www.qnx.com/developers/docs.

PtEnter()

Lock the Photon library for use by a single thread

Synopsis:

int PtEnter( int flags );

Arguments:

The value of flags can be 0 or one of:

Pt_EVENT_PROCESS_ALLOW
Consider the calling thread an event reader.
Pt_EVENT_PROCESS_PREVENT
Consider the calling thread a nonreader.

In most cases, it's better to set neither of these bits in flags, in which case the thread's status as event reader or nonreader doesn't change. For more information about changing a thread's event reader status, see Threads in the Parallel Operations chapter of the Photon Programmer's Guide.

You can OR the following into the flags:

Pt_DELAY_EXIT
Prevent another thread from terminating the process by calling PtExit().

Library:

ph

Description:

This function gives the calling thread access to the Photon library by “locking the library.” If another thread has already locked the library, PtEnter() blocks until the library is unlocked.

Since Photon functions aren't thread-safe, any thread other than the one that called PtInit() must call PtEnter() before trying to call any other Photon functions. After you're done, call PtLeave() to give other threads access to the library.

PtProcessEvent() unlocks the library before waiting for an event, and locks it back after. If you're calling PtProcessEvent() or any other function that processes Photon events (like PtBkgdHandlerProcess() or PtModalBlock()), other threads may enter and leave the library while you're waiting for an event. The same applies to PtCondWait() and PtCondTimedWait(), even though these functions don't process Photon events.

Mixing threads and work procedures might cause a minor problem; if one of the other threads adds a workproc while another thread is already waiting for an event, the workproc might not be invoked until you receive an event.

As with other Pt functions, you have to make sure that PtInit() has been called (and succeeded) before you can call PtEnter().


Note: The lock implemented by PtEnter() and PtLeave() isn't recursive (in the way that mutexes can be recursive). If you call PtEnter() twice without calling PtLeave() in between, the second call to PtEnter() fails and returns the negative of EDEADLK.

If another thread has called PtExit() before you call PtEnter(), or calls PtExit() while PtEnter() is waiting for the lock to become available, the Pt_DELAY_EXIT flag ensures that PtExit() will return and allow the calling thread to keep running. Without this flag, PtEnter() does not return if another thread has called PtExit().

Returns:

0
Success. and the state of the thread didn't change.
> 0
Success, and the state of the thread changed. The return value can be a combination of:
< 0
An error occurred; the value is a negative error code.

Errors:

If an error occurs, PtEnter() returns the negative of:

EDEADLK
The library is already locked by the calling thread.
ENOMEM
There wasn't enough memory to satisfy the request.
EINVAL
The parameter flags is an invalid value.

Examples:

You can test whether you have the Photon Library locked by evaluating PtEnter(). If the Photon Library is already locked, PtEnter() will fail with an error of -EDEADLK. When PtLeave() is called with a negative value, it is guaranteed to fail, so in this example the Photon Library has the same lock state as it had before the call to PtEnter():

int eval;
if ((eval = PtEnter(0)) < 0 && eval != -EDEADLK)
  fprintf( stderr, “Couldn't enter: %s\n“,
             strerror( -eval ) );
else
{
  PtSetResource(w, Pt_ARG_WINDOW_TITLE, text, 0);
  PtLeave(eval);  // does nothing if eval == -EDEADLK
}

In this example, the Photon Library is locked elsewhere, and you want to unlock it to perform some lengthy operation, such as in a widget callback where not unlocking the library would “freeze” the GUI for the duration of the operation:

int my_callback(  PtWidget_t * widget, ApInfo_t * apinfo,
                  PtCallbackInfo_t * cbinfo )
{
  int flags;
  if ( ( flags = PtLeave( Pt_EVENT_PROCESS_PREVENT ) ) < 0 )
    fprintf( stderr, “Couldn't leave: %s\n“,
             strerror( -flags ) );
  else {
    do_some_lengthy_stuff();
    /* This will turn your thread back into a reader if it
       was a reader  before: */
    if ( ( flags = PtEnter( flags ) ) < 0 )
        fprintf( stderr, “Couldn't enter: %s\n“,
                 strerror( -flags ) );
    }
    ...
    return( Pt_CONTINUE );
 }

Classification:

Photon

Safety:
Interrupt handler No
Signal handler No
Thread Yes

See also:

PtCondTimedWait(), PtCondWait(), PtExit(), PtInit(), PtLeave(), PtProcessEvent()

pthread_mutex_lock() in the QNX Neutrino Library Reference

Threads in the Parallel Operations chapter of the Photon Programmer's Guide