Use reference counting alternative

This commit is contained in:
Riza Sulistyo 2023-11-24 09:51:51 +07:00
parent b50fe8c207
commit f0af58927c
5 changed files with 65 additions and 60 deletions

View File

@ -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

View File

@ -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;

View File

@ -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()
#

View File

@ -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;
};
//////////////////////////////////////////////////////////////////////////////

View File

@ -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;
}