Threading

First, a brief list of things you wish you shouldn't have to know about threads in the C++ Wrapper.
1. SkypeKit API methods can be safely called from your application main thread (the thread in which Skype::init method was called);
2. SkypeKit API callbacks (event and property update callback code) do not execute in your application main thread.
3. Nevertheless, SkypeKit API methods can be callled from SkypeKit API callbacks as well.
4. Calling API methods from multiple application threads is currently not supported.
5. There are a few exceptions to the rule 3 - there are 4 callbacks in which calling API methods is not safe. There is a list below.

The reason for the main thread restriction is that SkypeKit API calls are blocking and asynchronous at the same time. All SkypeKit API methods are remote procedure calls, with execution point in runtime. As the remote procedure call gets passed to the runtime, application thread is put on hold, blocking, until a reply comes back from the runtime side. The wrapper then needs to resume the thread that initiated the call, with new data received from the runtime. For this, the wrapper needs to know which thread to resume. For this to work, you would need to actively maintain the list of API-accessing threads for the wrapper. There are currently no easy tools in the wrapper for you to do so. In future versions, we may expand this so that multiple calling threads could be supported.

With events and property updates, things get a bit more complicated. These are initiated in the runtime and passed to the wrapper. The wrapper has a thread pool for handling such incoming events. Every incoming property update or event callback is executed in one of such threads. Again, incoming property updates and events are handled in separate threads. This means that you will most likely be unable to do GUI updates from such callbacks directly and will need to use appropriate UI synchronization mechanisms. The good news is that you can call other SkypeKit API methods from event/update callbacks.

By default, the wrapper thread pool size is 1. The size can be changed by passing an argument to the Skype class constructor. It is important to understand that setting the thread pool size higher than 1 can break strict sequentiality of events and property updates. In case of property updates, this should not be an issue - as there is only the single OnChange callback for all the properties, you are in any case retrieving the updated value form property cache. The property cache will be updated sequentially regardless of how many threads the wrapper is running. It is only the callbacks that may get fired out of order.

It is also possible to set the thread pool size to zero, forcing completely flat treading model. This would make it somewhat easier to write your UI code - as there would be no need to synchronize GUI updates from within event and property callbacks. On the other hand, this would place restrictions on how long your application can spendd time in such callbacks. Long callbacks could render your application UI less responsive.

In case of flat threading, the wrapper does no event polling on its own and you will need to implement your own protocol loop. Example of this can be found in the command-line skypektclient appllication (in interfaces/skype/cpp_embedded/src/client/cskype.h

int get_socket_fd() {
    return m_connection->get_id();
}

int process_events(int polled) { // polled = true if there is data in socket_fd 
    while (polled || m_protocol->has_buffered_event()) { // or if (polled || has_buffered_events()) : then select loop will be called between each event processing
        process_command(m_main_command_initiator);
        polled = 0;
    }
    return is_server_connected();
}

Finally, there are some callbacks in which calling of SkypeKit API methods is not allowed. Unlike other callbacks, these get executed in the main application thread. These events are:

The reason for this is that these are not parts of the "natural" SkypeKit API. These are parts of the local (runtime-app) data transport system and are thus handled somewhat differently.

And the last exception - Skype::stop(). Skype::stop method is special in a way that it forces all the active event and property update callback threads to join with the main application thread. This changes the situation with treading - as it causes all the incoming update callbacks to be fired in the application thread (instead a thread from wrapper thread pool). This situation should not normally happen - it is expected that Skype::stop is only called after current Account has been logged out and thus no more incoming traffic from runtime can happen.

 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

(c) Skype Technologies S.A. Confidential/Proprietary

Last updated: Fri Jan 27 2012