Use reference counting alternative
This commit is contained in:
parent
b50fe8c207
commit
f0af58927c
|
@ -91,44 +91,27 @@ class MyObserver implements MyAppObserver {
|
|||
|
||||
class MyJob extends PendingJob
|
||||
{
|
||||
private MyJobHub hub;
|
||||
public int id;
|
||||
|
||||
@Override
|
||||
public void execute(boolean is_pending) {
|
||||
System.out.println("Executing job id:" + id);
|
||||
hub.delJob(this.id);
|
||||
System.out.println("Executing job is_pending:" + is_pending);
|
||||
}
|
||||
|
||||
protected void finalize() {
|
||||
System.out.println("Job deleted");
|
||||
}
|
||||
|
||||
public MyJob(MyJobHub inHub) {
|
||||
super(false);
|
||||
hub = inHub;
|
||||
id = ThreadLocalRandom.current().nextInt(1, 100000 + 1);
|
||||
}
|
||||
}
|
||||
|
||||
class MyJobHub
|
||||
{
|
||||
Endpoint ep;
|
||||
HashMap<Integer, MyJob> jobMap;
|
||||
public MyJobHub(Endpoint inEp) {
|
||||
ep = inEp;
|
||||
jobMap = new HashMap();
|
||||
}
|
||||
|
||||
public void setNewJob() {
|
||||
MyJob job = new MyJob(this);
|
||||
jobMap.put(job.id, job);
|
||||
MyJob job = new MyJob();
|
||||
ep.utilAddPendingJob(job);
|
||||
}
|
||||
|
||||
public void delJob(int id) {
|
||||
jobMap.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
class MyShutdownHook extends Thread {
|
||||
|
@ -205,6 +188,7 @@ public class sample {
|
|||
} catch (Exception e) {}
|
||||
|
||||
jobHub.setNewJob();
|
||||
System.gc();
|
||||
|
||||
while (!Thread.currentThread().isInterrupted()) {
|
||||
// Handle events
|
||||
|
|
|
@ -185,6 +185,9 @@ using namespace pj;
|
|||
%template(RtcpFbCapVector) std::vector<pj::RtcpFbCap>;
|
||||
%template(SslCertNameVector) std::vector<pj::SslCertName>;
|
||||
|
||||
%refobject pj::RefCountObj "$this->addRef();"
|
||||
%unrefobject pj::RefCountObj "$this->delRef();"
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
%ignore pj::WindowHandle::display;
|
||||
%ignore pj::WindowHandle::window;
|
||||
|
|
|
@ -4,6 +4,7 @@ import time
|
|||
from collections import deque
|
||||
from random import randint
|
||||
import struct
|
||||
import gc
|
||||
|
||||
write=sys.stdout.write
|
||||
|
||||
|
@ -227,14 +228,19 @@ class TestJob(pj.PendingJob):
|
|||
def __del__(self):
|
||||
print("Job deleted")
|
||||
|
||||
class JobHub() :
|
||||
class MyJob(pj.PendingJob):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def execute(self, is_pending):
|
||||
print("Executing job, is_pending: ", is_pending)
|
||||
|
||||
class MyJobHub() :
|
||||
def __init__(self, ep):
|
||||
self.__jobList__ = {}
|
||||
self.__ep__ = ep
|
||||
|
||||
def setNewJob(self):
|
||||
job = TestJob(self)
|
||||
self.__jobList__[job.getId()] = job
|
||||
job = MyJob()
|
||||
self.__ep__.utilAddPendingJob(job)
|
||||
|
||||
def delJob(self, id):
|
||||
|
@ -250,8 +256,10 @@ def ua_pending_job_test():
|
|||
ep.libInit(ep_cfg)
|
||||
ep.libStart()
|
||||
|
||||
hub = JobHub(ep)
|
||||
hub = MyJobHub(ep)
|
||||
hub.setNewJob()
|
||||
gc.collect()
|
||||
|
||||
ep.libDestroy()
|
||||
|
||||
#
|
||||
|
|
|
@ -1159,27 +1159,41 @@ struct EpConfig : public PersistentObject
|
|||
|
||||
};
|
||||
|
||||
/* This will add reference counting capability. It is useful to enable
|
||||
* object destruction based on reference counting.
|
||||
*/
|
||||
struct RefCountObj {
|
||||
/** Return the current reference count. */
|
||||
int refCount() const { return count; }
|
||||
|
||||
/** Add the reference count. */
|
||||
int addRef() const { return add_ref(); }
|
||||
|
||||
/**
|
||||
* Remove or delete reference count. This might delete the object if
|
||||
* the reference count is 0.
|
||||
*/
|
||||
int delRef() const;
|
||||
|
||||
protected:
|
||||
virtual ~RefCountObj() = 0;
|
||||
|
||||
int add_ref() const { return ++count; }
|
||||
|
||||
int del_ref() const { return --count; }
|
||||
|
||||
private:
|
||||
mutable int count;
|
||||
};
|
||||
|
||||
/* This represents posted job */
|
||||
struct PendingJob
|
||||
struct PendingJob : public RefCountObj
|
||||
{
|
||||
PendingJob():autoDelete(true){};
|
||||
|
||||
PendingJob(bool autoDel):autoDelete(autoDel) {};
|
||||
|
||||
/** Perform the job */
|
||||
virtual void execute(bool is_pending) = 0;
|
||||
|
||||
bool getAutoDelete() { return autoDelete; };
|
||||
|
||||
/** Virtual destructor */
|
||||
virtual ~PendingJob() {}
|
||||
|
||||
private:
|
||||
/**
|
||||
* If this is set to true, the job will be automatically be deleted
|
||||
* after the job is executed.
|
||||
*/
|
||||
bool autoDelete;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -579,6 +579,17 @@ struct PendingLog : public PendingJob
|
|||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
int RefCountObj::delRef() const
|
||||
{
|
||||
if (refCount() == 0 || del_ref() == 0 ) {
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return refCount();
|
||||
}
|
||||
|
||||
RefCountObj::~RefCountObj() {}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* Endpoint instance
|
||||
|
@ -611,12 +622,8 @@ Endpoint& Endpoint::instance() PJSUA2_THROW(Error)
|
|||
Endpoint::~Endpoint()
|
||||
{
|
||||
while (!pendingJobs.empty()) {
|
||||
PendingJob *job = NULL;
|
||||
bool autoDel = job->getAutoDelete();
|
||||
job = pendingJobs.front();
|
||||
if (autoDel)
|
||||
delete job;
|
||||
|
||||
PendingJob *job = pendingJobs.front();
|
||||
job->delRef();
|
||||
pendingJobs.pop_front();
|
||||
}
|
||||
|
||||
|
@ -643,17 +650,11 @@ void Endpoint::utilAddPendingJob(PendingJob *job)
|
|||
enum {
|
||||
MAX_PENDING_JOBS = 1024
|
||||
};
|
||||
|
||||
job->addRef();
|
||||
/* See if we can execute immediately */
|
||||
if (!mainThreadOnly || pj_thread_this()==mainThread) {
|
||||
bool autoDel = job->getAutoDelete();
|
||||
job->execute(false);
|
||||
if (autoDel){
|
||||
utilLogWrite(1, THIS_FILE,
|
||||
"Deleting job");
|
||||
delete job;
|
||||
}
|
||||
|
||||
job->delRef();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -662,11 +663,8 @@ void Endpoint::utilAddPendingJob(PendingJob *job)
|
|||
|
||||
pj_enter_critical_section();
|
||||
for (unsigned i=0; i<NUMBER_TO_DISCARD; ++i) {
|
||||
PendingJob *tmp_job = NULL;
|
||||
tmp_job = pendingJobs.back();
|
||||
if (tmp_job->getAutoDelete())
|
||||
delete tmp_job;
|
||||
|
||||
PendingJob *job = pendingJobs.back();
|
||||
job->delRef();
|
||||
pendingJobs.pop_back();
|
||||
}
|
||||
|
||||
|
@ -724,10 +722,8 @@ void Endpoint::performPendingJobs()
|
|||
pj_leave_critical_section();
|
||||
|
||||
if (job) {
|
||||
bool autoDel = job->getAutoDelete();
|
||||
job->execute(true);
|
||||
if (autoDel)
|
||||
delete job;
|
||||
job->delRef();
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue