Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling pjlib from unknown/external thread. You must " "register external threads with pj_thread_register()

Tags:

android

pjsip

I have integrated pjsua2 in my android application. The application crashes when I send an SMS. It doesn't crash every time, it is happening randomly. (once every 10 messages).

MyCode is:

public void sendInstantMessage(String number, String msgBody) {

    String buddy_uri = "<sip:" + number + "@" + mPref.getString(PREF_SIPSERVER, "") + ">";
    Log.e(TAG, "sendInstantMessage ==== "+buddy_uri);

    BuddyConfig bCfg = new BuddyConfig();
    bCfg.setUri(buddy_uri);
    bCfg.setSubscribe(false);

    MyBuddy im = new MyBuddy(bCfg);
    SendInstantMessageParam prm = new SendInstantMessageParam();
    prm.setContent(msgBody);
    prm.setContentType("text/plain; charset=utf-8");

    try {
        im.create(account, bCfg);
        boolean valid1 = im.isValid();
        Log.e(TAG, "valid1 ======= "+valid1);
        im.sendInstantMessage(prm);
    } catch (Exception e) {
        Log.e(TAG, "sendInstantMessage ==== "+e);
        e.printStackTrace();
        return;
    }

}

According to logcat , I have to call pj_thread_register(). But I have got a method libRegisterThread() in endpoint, so I used it like below

MyApp.ep.libRegisterThread("SipApi");

Here is the logcat:

../src/pj/os_core_unix.c:692: pj_thread_this: assertion "!"Calling pjlib from unknown/external thread. You must " "register external threads with pj_thread_register() " "before calling any pjlib functions."" failed
like image 543
Gangadhar Nimballi Avatar asked Jun 18 '15 12:06

Gangadhar Nimballi


2 Answers

(For those of you who are wondering why it solved the problem)

To clarify Gangadhar's solution, the issue was caused by Garbage Collector. As per PJSIP Docs:

There are two problems with Java garbage collector (gc):

  1. it delays the destruction of Java objects (including pjsua2 objects), causing the code in object's destructor to be executed out of order
  2. the gc operation may be run on different thread, not previously registered to PJLIB

The solution was

application MUST immediately destroy pjsua2 objects using object's delete() method, instead of relying on the gc to clean up the object.

as you can see in his solution which called the MyBuddy's delete method:

try {
    myBuddy.create(account, bCfg);
    myBuddy.sendInstantMessage(prm);
    myBuddy.delete();
} catch (Exception e) {
    e.printStackTrace();
    return;
}
like image 51
user1506104 Avatar answered Oct 21 '22 11:10

user1506104


Here is the correct answer.

/**Send message to this number
 * @param String number
 * @param String msgBody*/
public void sendInstantMessage(String number, String msgBody) {
    String sipServer = "aaa.ggg.net";
    String buddy_uri = "<sip:" + number + "@" + sipServer + ">";

    BuddyConfig bCfg = new BuddyConfig();
    bCfg.setUri(buddy_uri);
    bCfg.setSubscribe(false);

    MyBuddy myBuddy = new MyBuddy(bCfg);
    SendInstantMessageParam prm = new SendInstantMessageParam();
    prm.setContent(msgBody);

    try {
        myBuddy.create(account, bCfg);
        myBuddy.sendInstantMessage(prm);
        myBuddy.delete();
    } catch (Exception e) {
        e.printStackTrace();
        return;
    }
}
like image 26
Gangadhar Nimballi Avatar answered Oct 21 '22 12:10

Gangadhar Nimballi