5.1. PiaTransport Overview

This chapter describes an overview of PiaTransport and the details of its internal operations.

Protocols Overview

Several communications formats (such as UDP, TCP, and IP telephony) of different characters exist even though they are all using the same communications channels. Pia provides protocols for each format to enable efficient communications.

The transport::Protocol class is available as a base class for Pia protocols, and there are different derived classes for each of the different types of communications (such as transport::UnreliableProtocol, transport::ReliableProtocol, and chat::VoiceProtocol).

When an application communicates between stations, it creates an instance of the appropriate Pia protocol, and calls the send and receive APIs of that instance.

Relationship Between the Send and Receive APIs and the Send and Receive Threads of the Protocol

When PiaTransport is set up, send and receive threads are created. The relationship between these threads and the send and receive APIs for each protocol as called by the application thread is indicated in the following figure.

Figure 5-1. Application Thread and Send Thread

In simple terms, the send operations are as follows.

  1. The application thread calls the nn::pia::xxx::ProtocolN::Send() function, directing data to be sent.
  2. The send data is stored in the send buffer of PiaTransport.
  3. Pia's send thread takes the data from the send buffer.
  4. That data is passed to the send API for the respective library in the SDK and is then sent.
Figure 5-2. Application Thread and Receive Thread

Similarly, receive operations are summarized as follows.

  1. Pia's receive thread calls the receive API for the respective libraries in the SDK, and the data is received.
  2. The received data is stored in the receive buffer of PiaTransport.
  3. The application thread calls the nn::pia::xxx::ProtocolN::Receive() function, directing data to be received.
  4. Data is taken from the receive buffer and passed to the application.

Generally speaking, API calls that cause I/O access tend to block for long periods of time. As mentioned previously, however, with PiaTransport, the send and receive threads call SDK send and receive APIs. As a result, the application thread does not block by the SDK send and receive API calls.

Details of Internal Operations

The previous description was a summary. This section describes a detailed description of the dispatch function and the send and receive processes and threads as they occur in PiaTransport.

Dispatch Function Operations

PiaTransport includes a dispatch function that is responsible for the following processes.

  • The passing of data back and forth between the send and receive threads and buffers
  • Packet generation
  • Packet parsing
  • Other protocol processes
  • Detecting a disconnected network

This dispatch function is implicitly called from the nn::pia::common::Scheduler::Dispatch() function. Pia does not work normally unless dispatching occurs at regular intervals. The application must call the nn::pia::common::Scheduler::Dispatch() function at an interval of once or twice each frame.

Details of Send Operations

Send processes occur as follows.

  • The application runs the Protocol0::Send() function. Data is copied to an internal Pia packet-generating buffer.
  • The application runs the Protocol1::Send() function. Data is copied to an internal Pia packet-generating buffer.
  • ...
  • The application runs the ProtocolN::Send() function. Data is copied to an internal Pia packet-generating buffer.
  • When the dispatch function is executed, the data groups are efficiently collected in packets (packet bundling) using the packet-generation process, and these packets are passed to a send thread.
  • The send thread submits the packet to the network.

Details of Receive Operations

The corresponding receive processes occur as follows.

  • The receive thread gets packets from the network.
  • When the dispatch function is executed, the packets obtained by the receive thread are passed to a buffer for packet parsing. The packets are then unbundled, and the data is restored.
  • The application runs the Protocol0::Receive() function. Restored data is passed to the application.
  • The application runs the Protocol1::Receive() function. Restored data is passed to the application.
  • ...
  • The application runs the ProtocolN::Receive() function. Restored data is passed to the application.

Send and Receive Thread Operations

The operations of the send and receive threads are indicated in the following pseudocode.

Code 5-1. Operations of the Send Thread
while(true)
{
    if(isSendPacketExist())
    {
        // Continues to call the send function as long as there are packets to send.
        send(packet);
    }
    else
    {
        // Puts the send thread to sleep when there are no longer any packets to send.
        sleep(sendThreadSleepSpan);
    }
}
Code 5-2. Operations of the Receive Thread
while(true)
{
    if(isReceivePacketExist())
    {
        // Continues to call the receive function as long as there are packets to receive.
        receive(&packet);
    }
    else
    {
        // Puts the receive thread to sleep when there are no longer any packets to receive.
        sleep(receiveThreadSleepSpan);
    }
}

The send and receive threads have relatively high priorities, so they send and receive packets on a regular basis. Sending and receiving block the thread, so the execution right is passed to the lower priority threads (such as the main thread). In addition, when there are no longer any packets to send or receive, the send and receive threads go to sleep, and thread execution rights shift to another thread.

You can specify the sleep intervals for the send and receive threads with the transport::ThreadStreamManager::SetSendThreadSleepTimeSpan() and transport::ThreadStreamManager::SetReceiveThreadSleepTimeSpan() functions. Setting a shorter sleep interval reduces the time that data can store up, and might improve the program's responsiveness. Frequent thread switching, however, can increase the overall load on the CPU.

Warning:

Any delay in assigning a CPU to the Pia sending and receiving threads could have a negative effect on Pia system operations.

The application can specify a different priority for the send and receive threads. Normally, however, set the priority higher than the priority of the thread that the application uses to call the Pia APIs. If the application creates any threads with a higher priority than the Pia sending and receiving threads, you must exercise caution to avoid monopolizing the CPU for an extended period of time.