Setting Up Your Own Objects

Creating a PPS object is as easy as making an open() call on a file under /pps with the O_CREAT flag, which will create the PPS object if it doesn't already exist. Opening, closing, reading from, and writing to PPS objects will use the exact same mechanisms as opening, closing, reading from, and writing to files on the filesystem. As shown in "Overview of the PPS Service" in this guide, as long as the data you write conforms to the format PPS expects, you can write anything to your PPS objects.

Note: We recommend that you use the libpps API for encoding/decoding PPS data. These library functions make handling data easier, faster, and more reliable than using standard libc functions. For more information, see "PPS API reference" in the Persistent Publish/Subscribe Developer's Guide.

Guidelines

You could design your program to interact with PPS objects in any variety of ways. Your design will include decisions such as whether to read objects in delta mode, how frequently to read, what data to write, whether or not you receive notifications in the form of pulses, and so on. Even more decisions come into play if you're designing a system that communicates through PPS using server objects.

Here are the basic steps for setting up your own PPS objects, whether you're designing a new program that interacts with PPS objects or adding that capability to an existing program:

  1. Make sure your program includes the <fcntl.h> and <sys/pps.h> header files.
  2. Open the PPS object as if it were a file. For example, to make an open call on an existing object:

    open("/pps/myobject", O_RDWR);

    This will open myobject with read and write privileges.

    If you're opening a PPS object that doesn't already exist, include the O_CREAT flag:

     open("/pps/an-object", O_RDWR | O_CREAT); 

    Here we're including both O_RDWR and O_CREAT in one field with the bitwise OR operation.

  3. If you need to make a new directory, you can use the mkdir() function. For example, to create a directory called myservice under /pps/services/:

    mkdir("/pps/services/myservice", S_IWUSR | S_IWGRP | S_IWOTH | S_IRUSR
           | S_IRGRP | S_IROTH); 

    This will create your directory and assign read and write privileges for all users.

  4. Now you probably want to perform a read or write. Remember to use the pps_encoder_*() and pps_decoder_*() functions for handling your data.
  5. Eventually you'll need to close the PPS object before your program terminates. You can do this simply by calling close().

Interacting with your PPS objects

The basic "building blocks" you'll use for interacting with PPS objects are relatively few:

But you'll find many possibilities of combining these together, combining them with synchronization techniques (mutual exclusion locks, condition variables, etc...), and employing various ways to perform the same tasks. Again, see the Persistent Publish/Subscribe Developer's Guide for guidance.

How you'll use mutexes and other synchronization tools is up to you and depends on the needs of your program. Mutexes are used to ensure coherence between two parallel threads: one is writing new data from PPS while the other is using existing data to perform a function. In this case, mutexes are used so that one thread doesn't try to change attributes that the other thread is trying to use. Naturally, the synchronization needs of your programs may be different.