Threading mechanism of Libjingle

Source: Internet
Author: User
Tags message queue

Debug Discovery Win32socketserver::P UMP was executed several times, but Message_queue_->dispatch (&msg); function was executed once, that is, response videocapturer::o The Nmessage function responds to the Msg_state_change message. The constructors of the Videocapturer class are executed two times, one representing the local side, the class member variable talk_base::thread* Thread_ in the constructor, the main thread is assigned, and the other represents the remote, the member variable Thread_; is assigned to the Signaling_thread_ created in the Peerconnectionfactory class because it is done in the thread's message processing. Specifically , the Conductor::onmessagefrompeer function (the main thread run) of the conductor.cc file is called Peer_connection_->setremotedescription , and Peer_connection_ is called peerconnectionfactory in the Conductor::initializepeerconnection function: The Createpeerconnection function creates a Peerconnectionproxy object that encapsulates a thread that is Peerconnectionfactory::createpeerconnection_ The Signaling_thread set in the S function. So in the main thread call Peer_connection_->setremotedescription, because of the role of the agent (specifically see Proxy.h file), call this function is to send a message with Signaling_thread, and binds the message to its implementation, the Setremotedescription method of the Peerconnection class associated with the proxy class, so that the message response of the thread eventually calls Peerconnection::setremotedescription.

This function will eventually call Videocapturer's constructor for the second time, so the second assignment to Videocapturer's member variable thread_ is signaling_thread in the Peerconnectionfactory class.

Both class Physicalsocketserver and class Win32socketserver inherit from the Socketserver class, where the wait and wakeup methods are defined, one to wait for the message, and the other to wake up to wait for the message to respond. In Win32socketserver, for example, the GetMessage wait message is called in the function win32socketserver::wait because "GetMessage does not receive messages belonging to other threads or applications. After a successful message is obtained, the thread deletes the message from the message queue. The function waits until a message arrives to return a value. ", so it waits until there is a message when the function returns, and the outer function wait is returned. The Peerconnectionfactory::initialize function in the main thread calls Signaling_thread_->send to send the msg_init_factory message.

The Talk_base::thread class in Libjingle, which runs Peerconnection, calls six constructor Thread::thread, two of which parse the DNS address, one resolves localhost, The other is the domain name that resolves stun. The other four are the Talk_base::win32thread objects in the main function that inherit from the thread class, and the constructor Threadmanager::threadmanager that gets the Threadmanager singleton object. A thread object is then created in the constructor. The other two are the two variables defined in the Peerconnectionfactory class: Talk_base::thread* Signaling_thread_, and talk_base::thread* worker_thread_;.

Where the Win32thread object is set to the main thread in the main function by calling Threadmanager::setcurrentthread. Note the TlsGetValue and TlsSetValue in the Threadmanager class use the local storage of the thread.

In fact, the two thread variables in the Peerconnectionfactory class are passed to some of the underlying classes, and if the classes need to send messages, call send or post directly. Take the signaling_thread_->send in the Peerconnectionfactory::initialize function (this, msg_init_factory, &result); for example, When the main thread executes the above statement, the main thread will always block the response to the msg_init_factory message, that is, the response msg_init_factory in the Signaling_thread_ thread's message loop. In the response to this message, Worker_thread_->send is called again, but it is called by Talk_base::thread::invoke.

The

thread::send and win32socketserver::wakeup two functions as entry points to understand how the Talk_base::thread works. First look at the Thread::send function, take Signaling_thread_->send (This, msg_init_factory, &result), send the message as an example, By iscurrent to determine if the current thread is processed directly, such as in the Signaling_thread_ thread's message response function and call Signaling_thread_->send, the message will be processed directly. Otherwise, when the msg_init_factory message is sent, Thread::current () is called to get the main thread assignment to Current_thread, which can be interpreted as the parent thread. The msg_init_factory message is then placed in the member variable std::list<_sendmessage> sendlist_ of the Signaling_thread_, Since its member variables Signaling_thread_ and Worker_thread_ are called immediately in the constructor of the Peerconnectionfactory class, the method calls the Start method, which eventually calls thread:: The ProcessMessages function, which executes a thread's message response in a while loop of this function.

Next, take the message loop of the main thread as an example, because the Ignaling_thread_ and worker_thread_ two threads of the parent class MessageQueue the constructor to its variable socketserver* ss_; The Physicalsocketserver type is assigned, and the main thread win32thread in its constructor by calling Messagequeue::set_ The Socketserver function socketserver* Ss_ The MessageQueue variables of the ancestor class, and assigns the Win32socketserver type. So in the Talk_base::thread message loop, Thread::P rocessmessages while loop, call Messagequeue::get to get the message, if get the message to exit, If you do not get the message, call the socketserver::wait function to wait, based on the above analysis, so the main function is to execute the win32socketserver::wait function.

There is a problem with the analysis above about calling win32socketserver::wait. In fact, since Win32thread inherits from the Talk_base::thread class, it does not invoke the Start method like Signaling_thread_ and Worker_thread_ two threads, that is, the message loop is not started. Win32socketserver::wait is called when Signaling_thread_->send, that is, when the main thread calls this function to send a message, because the main thread is the parent of Signaling_thread_, the thread: : The Send function is called, and the second argument passed by wait process_io to false, while Signaling_thread_ and worker_thread_ two threads in the message loop, call MessageQueue:: The third parameter is the default parameter when get, so when physicalsocketserver::wait is called, the second argument is Process_io true.

Then go back to the Thread::send function, also with signaling_thread_->send (this, msg_init_factory, &result); For example, will Msg_init_ After the factory message is placed into the SIGNALING_THREAD_ member variable std::list<_sendmessage> sendlist_, the Signaling_thread_ in the previous analysis It is possible to call Ss_->wakeup () because it is blocked waiting for the arrival of the message, and here is the Physicalsocketserver::wakeup () function. The next step is to use a bool variable, bool waited = False, to mark whether the current message has been processed, and if not, the current thread (the parent thread of the thread that sent the message) will always block in the while loop, in signaling_thread_- >send (This, msg_init_factory, &result); In this case, the main thread is blocking itself by calling Win32socketserver::wait. Until the message response function finishes executing the return before jumping out of the while loop, then the main thread can continue executing the function and continue executing the statement following signaling_thread_->send. So this send is similar to the Windows function SendMessage function. is not returned until the current message response is complete.

In the Thread::receivesends function, the messages sent by the thread are processed by traversing the threads class member variable std::list<_sendmessage> sendlist_. Each send message is responded to in a timely manner, so there is at most one element in Sendlist_ that represents the message being sent.

Threading mechanism of Libjingle

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.