-
Notifications
You must be signed in to change notification settings - Fork 161
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Connection: Add a new object to handle the iio_context and CommandQueue.
The open() and close() calls are done through a singleton ConnectionProvider while the reference count is handled inside the Connection object. This should replace the existing ContextProvider. Signed-off-by: AlexandraTrifan <[email protected]>
- Loading branch information
1 parent
16b4aec
commit 045f606
Showing
6 changed files
with
471 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#ifndef CONNECTION_H | ||
#define CONNECTION_H | ||
#include "scopy-iioutil_export.h" | ||
#include "commandqueue.h" | ||
#include <iio.h> | ||
#include <QObject> | ||
|
||
namespace scopy { | ||
class SCOPY_IIOUTIL_EXPORT Connection : public QObject | ||
{ | ||
Q_OBJECT | ||
public: | ||
Connection(QString uri); | ||
|
||
const QString &uri() const; | ||
CommandQueue *commandQueue() const; | ||
struct iio_context *context() const; | ||
int refCount() const; | ||
|
||
protected: | ||
~Connection(); | ||
|
||
/** | ||
* @brief open | ||
* Initialize the connection if not previously opened. | ||
* If previously opened, increase the internal refCount. | ||
*/ | ||
void open(); | ||
|
||
/** | ||
* @brief close | ||
* Decrement the internal refCount. | ||
* Emit the aboutToBeDestroyed() signal if refCount is zero. | ||
*/ | ||
void close(); | ||
|
||
/** | ||
* @brief closeAll | ||
* Reset the internal refCount to zero. | ||
* Force close the Connection. | ||
* Emit the aboutToBeDestroyed() signal. | ||
*/ | ||
void closeAll(); | ||
|
||
Q_SIGNALS: | ||
/** | ||
* @brief aboutToBeDestroyed | ||
* Connection clients should handle deinitialization | ||
* of their iio_context/CommandQueue related operations | ||
* in a slot connected to this signal. | ||
* After the signal is emitted, the Connection object | ||
* will no longer be valid. | ||
*/ | ||
void aboutToBeDestroyed(); | ||
|
||
private: | ||
friend class ConnectionProvider; | ||
QString m_uri; | ||
CommandQueue *m_commandQueue; | ||
struct iio_context *m_context; | ||
int m_refCount = 0; | ||
}; | ||
} // namespace scopy | ||
|
||
#endif // CONNECTION_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#ifndef CONNECTIONPROVIDER_H | ||
#define CONNECTIONPROVIDER_H | ||
|
||
#include "scopy-iioutil_export.h" | ||
#include "connection.h" | ||
|
||
#include <QObject> | ||
#include <QMap> | ||
#include <mutex> | ||
|
||
namespace scopy { | ||
class SCOPY_IIOUTIL_EXPORT ConnectionProvider : public QObject | ||
{ | ||
Q_OBJECT | ||
protected: | ||
ConnectionProvider(QObject *parent = nullptr); | ||
~ConnectionProvider(); | ||
|
||
public: | ||
ConnectionProvider(ConnectionProvider &other) = delete; | ||
void operator=(const ConnectionProvider &) = delete; | ||
|
||
static ConnectionProvider *GetInstance(); | ||
static Connection *open(QString uri); | ||
static void close(QString uri); | ||
static void closeAll(QString uri); | ||
|
||
private: | ||
Connection *_open(QString uri); | ||
void _close(QString uri); | ||
void _closeAll(QString uri); | ||
void _closeAndRemove(QString uri); | ||
static ConnectionProvider *pinstance_; | ||
static std::mutex mutex_; | ||
QMap<QString, Connection *> map; | ||
}; | ||
} // namespace scopy | ||
|
||
#endif // CONNECTIONPROVIDER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
#include "connection.h" | ||
|
||
using namespace scopy; | ||
|
||
Connection::Connection(QString uri) | ||
{ | ||
this->m_uri = uri; | ||
this->m_context = nullptr; | ||
this->m_commandQueue = nullptr; | ||
this->m_refCount = 0; | ||
} | ||
|
||
Connection::~Connection() | ||
{ | ||
if(this->m_commandQueue) { | ||
delete this->m_commandQueue; | ||
this->m_commandQueue = nullptr; | ||
} | ||
if(this->m_context) { | ||
iio_context_destroy(this->m_context); | ||
this->m_context = nullptr; | ||
} | ||
} | ||
|
||
const QString &Connection::uri() const { return m_uri; } | ||
|
||
CommandQueue *Connection::commandQueue() const { return m_commandQueue; } | ||
|
||
iio_context *Connection::context() const { return m_context; } | ||
|
||
int Connection::refCount() const { return m_refCount; } | ||
|
||
void Connection::open() | ||
{ | ||
if(!this->m_context) { | ||
this->m_context = iio_create_context_from_uri(this->m_uri.toStdString().c_str()); | ||
if(this->m_context) { | ||
this->m_commandQueue = new CommandQueue(); | ||
this->m_refCount++; | ||
} | ||
} else { | ||
this->m_refCount++; | ||
} | ||
} | ||
|
||
void Connection::closeAll() | ||
{ | ||
this->m_refCount = 0; | ||
close(); | ||
} | ||
|
||
void Connection::close() | ||
{ | ||
this->m_refCount--; | ||
if(this->m_refCount <= 0) { | ||
/* If the open() and close() number of calls done by a client | ||
* is mismatched, all the remaining clients should be notified of the | ||
* destruction. */ | ||
this->m_refCount = 0; | ||
Q_EMIT aboutToBeDestroyed(); | ||
} | ||
} | ||
|
||
#include "moc_connection.cpp" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
#include "connectionprovider.h" | ||
#include <QLoggingCategory> | ||
#include <QApplication> | ||
|
||
Q_LOGGING_CATEGORY(CAT_CONNECTIONMGR, "ConnectionProvider") | ||
|
||
using namespace scopy; | ||
|
||
ConnectionProvider *ConnectionProvider::pinstance_{nullptr}; | ||
std::mutex ConnectionProvider::mutex_; | ||
|
||
scopy::ConnectionProvider::ConnectionProvider(QObject *parent) | ||
: QObject(parent) | ||
{ | ||
qDebug(CAT_CONNECTIONMGR) << "ConnectionProvider object ctor"; | ||
} | ||
|
||
scopy::ConnectionProvider::~ConnectionProvider() { qDebug(CAT_CONNECTIONMGR) << "ConnectionProvider object dtor"; } | ||
|
||
ConnectionProvider *ConnectionProvider::GetInstance() | ||
{ | ||
std::lock_guard<std::mutex> lock(mutex_); | ||
if(pinstance_ == nullptr) { | ||
pinstance_ = new ConnectionProvider(QApplication::instance()); // singleton has the app as parent | ||
} else { | ||
qDebug(CAT_CONNECTIONMGR) << "ConnectionProvider: Got instance from singleton"; | ||
} | ||
return pinstance_; | ||
} | ||
|
||
Connection *ConnectionProvider::open(QString uri) { return ConnectionProvider::GetInstance()->_open(uri); } | ||
|
||
Connection *ConnectionProvider::_open(QString uri) | ||
{ | ||
std::lock_guard<std::mutex> lock(mutex_); | ||
Connection *connectionObject = nullptr; | ||
if(!map.contains(uri)) { | ||
connectionObject = new Connection(uri); | ||
map.insert(uri, connectionObject); | ||
qDebug(CAT_CONNECTIONMGR) << uri << " created in map "; | ||
} else { | ||
connectionObject = map.value(uri); | ||
qDebug(CAT_CONNECTIONMGR) << uri << " found in map "; | ||
} | ||
connectionObject->open(); | ||
if(connectionObject->refCount() == 0) { | ||
qDebug(CAT_CONNECTIONMGR) << uri << " Connection: failed to open, removed from map."; | ||
map.remove(uri); | ||
delete connectionObject; | ||
return nullptr; | ||
} | ||
qDebug(CAT_CONNECTIONMGR) << uri << " Connection: open, refcount++ = " << connectionObject->refCount(); | ||
return connectionObject; | ||
} | ||
|
||
void ConnectionProvider::closeAll(QString uri) { return ConnectionProvider::GetInstance()->_closeAll(uri); } | ||
|
||
void ConnectionProvider::close(QString uri) { return ConnectionProvider::GetInstance()->_close(uri); } | ||
|
||
void ConnectionProvider::_closeAll(QString uri) | ||
{ | ||
std::lock_guard<std::mutex> lock(mutex_); | ||
if(map.contains(uri)) { | ||
map.value(uri)->closeAll(); | ||
} | ||
_closeAndRemove(uri); | ||
} | ||
|
||
void ConnectionProvider::_close(QString uri) | ||
{ | ||
std::lock_guard<std::mutex> lock(mutex_); | ||
if(map.contains(uri)) { | ||
map.value(uri)->close(); | ||
} | ||
_closeAndRemove(uri); | ||
} | ||
|
||
void ConnectionProvider::_closeAndRemove(QString uri) | ||
{ | ||
if(map.contains(uri)) { | ||
qDebug(CAT_CONNECTIONMGR) | ||
<< uri << " Connection: closing - found in map - refcnt-- = " << map.value(uri)->refCount(); | ||
if(map.value(uri)->refCount() == 0) { | ||
delete map[uri]; | ||
map.remove(uri); | ||
qDebug(CAT_CONNECTIONMGR) << uri << " Connection: destroyed, removed from map"; | ||
} | ||
} else { | ||
qInfo(CAT_CONNECTIONMGR) << uri << " Connection: not found in map. nop"; | ||
} | ||
} | ||
|
||
#include "moc_connectionprovider.cpp" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.