|
Shinya Kitaoka |
810553 |
#pragma once
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifndef TIPC_H
|
|
Toshihiro Shimizu |
890ddd |
#define TIPC_H
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Qt includes
|
|
Toshihiro Shimizu |
890ddd |
#include <qdatastream></qdatastream>
|
|
Toshihiro Shimizu |
890ddd |
#include <qbytearray></qbytearray>
|
|
Toshihiro Shimizu |
890ddd |
#include <qlocalsocket></qlocalsocket>
|
|
Toshihiro Shimizu |
890ddd |
#include <qeventloop></qeventloop>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// STL includes
|
|
Toshihiro Shimizu |
890ddd |
#include <limits></limits>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Toonz includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tcommon.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#undef DVAPI
|
|
Toshihiro Shimizu |
890ddd |
#undef DVVAR
|
|
Toshihiro Shimizu |
890ddd |
#ifdef TNZCORE_EXPORTS
|
|
Toshihiro Shimizu |
890ddd |
#define DVAPI DV_EXPORT_API
|
|
Toshihiro Shimizu |
890ddd |
#define DVVAR DV_EXPORT_VAR
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
#define DVAPI DV_IMPORT_API
|
|
Toshihiro Shimizu |
890ddd |
#define DVVAR DV_IMPORT_VAR
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Forward declarations
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class QSharedMemory;
|
|
Toshihiro Shimizu |
890ddd |
class QProcess;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Toonz Inter-Process Communication namespace
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*! \namespace tipc
|
|
Toshihiro Shimizu |
890ddd |
The tipc namespace provides facilities to deal with
|
|
Toshihiro Shimizu |
890ddd |
inter-process communication tasks.
|
|
Toshihiro Shimizu |
890ddd |
The tipc inner workings make use of Qt's
|
|
Toshihiro Shimizu |
890ddd |
QLocalServer/QLocalSocket standard ipc framework;
|
|
Toshihiro Shimizu |
890ddd |
but moreover, it helps the user hiding some of the
|
|
Toshihiro Shimizu |
890ddd |
intricacies of ipc management.
|
|
Toshihiro Shimizu |
890ddd |
\m \m
|
|
Toshihiro Shimizu |
890ddd |
The tipc model assumes there is a server process
|
|
Toshihiro Shimizu |
890ddd |
running to which several processes can connect to in order
|
|
Toshihiro Shimizu |
890ddd |
to require services through appropriate server-supported
|
|
Toshihiro Shimizu |
890ddd |
commands. Communication happens by sending tipc::Message
|
|
Toshihiro Shimizu |
890ddd |
instances through a tipc::Stream constructed on a
|
|
Toshihiro Shimizu |
890ddd |
QLocalSocket device connected to the server in a Qt-like
|
|
Toshihiro Shimizu |
890ddd |
manner.
|
|
Toshihiro Shimizu |
890ddd |
\n\n
|
|
Toshihiro Shimizu |
890ddd |
Messages encapsulate an atomic communication that must be
|
|
Toshihiro Shimizu |
890ddd |
received in its entirety to be understood by the receiver.
|
|
Toshihiro Shimizu |
890ddd |
Any message sent by a client must provide a QString header
|
|
Toshihiro Shimizu |
890ddd |
to identify the message type, which must be recognizable
|
|
Toshihiro Shimizu |
890ddd |
by the server side to be appropriately parsed.
|
|
Toshihiro Shimizu |
890ddd |
Each message understood by the server process will be replied
|
|
Toshihiro Shimizu |
890ddd |
with a message to ensure the client that the parsing has
|
|
Toshihiro Shimizu |
890ddd |
been completed.
|
|
Toshihiro Shimizu |
890ddd |
\n\n
|
|
Toshihiro Shimizu |
890ddd |
A tipc::Server instance must be used on the server side to
|
|
Toshihiro Shimizu |
890ddd |
process supported messages. Message parsing is responsibility
|
|
Toshihiro Shimizu |
890ddd |
of specific subclasses of the tipc::MessageParser base class,
|
|
Toshihiro Shimizu |
890ddd |
which must be implemented and added to the server.
|
|
Toshihiro Shimizu |
890ddd |
\n \n
|
|
Toshihiro Shimizu |
890ddd |
Tipc standard messages include requests for temporary files
|
|
Toshihiro Shimizu |
890ddd |
or shared memory segments, which must be released after use.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace tipc {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************
|
|
Toshihiro Shimizu |
890ddd |
// tipc Fundamental Classes
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
The tipc::Message class encapsulates several data into one single byte array
|
|
Toshihiro Shimizu |
890ddd |
in order to make data transfer among sockets an atomic operation.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
class Message {
|
|
Shinya Kitaoka |
120a6e |
QByteArray m_ba;
|
|
Shinya Kitaoka |
120a6e |
QDataStream m_ds;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
Message() : m_ba(), m_ds(&m_ba, QIODevice::ReadWrite) {}
|
|
Shinya Kitaoka |
120a6e |
~Message() {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const QByteArray &ba() const { return m_ba; }
|
|
Shinya Kitaoka |
120a6e |
QByteArray &ba() { return m_ba; }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const QDataStream &ds() const { return m_ds; }
|
|
Shinya Kitaoka |
120a6e |
QDataStream &ds() { return m_ds; }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
template <typename type=""></typename>
|
|
Shinya Kitaoka |
120a6e |
Message &operator<<(const Type &data) {
|
|
Shinya Kitaoka |
120a6e |
m_ds << data;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
template <typename type=""></typename>
|
|
Shinya Kitaoka |
120a6e |
Message &operator>>(Type &data) {
|
|
Shinya Kitaoka |
120a6e |
m_ds >> data;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Message &operator<<(const char *str) { return operator<<(QString(str)); }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void clear() {
|
|
Shinya Kitaoka |
120a6e |
m_ba.clear();
|
|
Shinya Kitaoka |
120a6e |
m_ds.device()->seek(0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
A tipc::Stream is a specialized QDataStream designed to work with a tipc-based
|
|
Toshihiro Shimizu |
890ddd |
QLocalSocket instance.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
d1f6c4 |
class DVAPI Stream final : public QDataStream {
|
|
Shinya Kitaoka |
120a6e |
QLocalSocket *m_socket;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
Stream(QLocalSocket *socket) : QDataStream(socket), m_socket(socket) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QLocalSocket *socket() { return m_socket; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int readSize();
|
|
Shinya Kitaoka |
120a6e |
bool messageReady();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool readData(char *data, qint64 dataSize, int msecs = -1);
|
|
Shinya Kitaoka |
120a6e |
bool readMessage(Message &msg, int msecs = -1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool readDataNB(char *data, qint64 dataSize, int msecs = -1,
|
|
Shinya Kitaoka |
120a6e |
QEventLoop::ProcessEventsFlag flag = QEventLoop::AllEvents);
|
|
Shinya Kitaoka |
120a6e |
bool readMessageNB(
|
|
Shinya Kitaoka |
120a6e |
Message &msg, int msecs = -1,
|
|
Shinya Kitaoka |
120a6e |
QEventLoop::ProcessEventsFlag flag = QEventLoop::AllEvents);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool flush(int msecs = -1);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace tipc
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************
|
|
Toshihiro Shimizu |
890ddd |
// tipc Stream Operators
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
DVAPI tipc::Stream &operator>>(tipc::Stream &stream, tipc::Message &msg);
|
|
Toshihiro Shimizu |
890ddd |
DVAPI tipc::Stream &operator<<(tipc::Stream &stream, tipc::Message &msg);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline tipc::Message &operator<<(tipc::Message &msg,
|
|
Shinya Kitaoka |
120a6e |
tipc::Message &(*func)(tipc::Message &)) {
|
|
Shinya Kitaoka |
120a6e |
return func(msg);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline tipc::Message &operator>>(tipc::Message &msg,
|
|
Shinya Kitaoka |
120a6e |
tipc::Message &(*func)(tipc::Message &)) {
|
|
Shinya Kitaoka |
120a6e |
return func(msg);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************
|
|
Toshihiro Shimizu |
890ddd |
// tipc Stream Manipulator Functions
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace tipc {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline Message &clr(Message &msg) {
|
|
Shinya Kitaoka |
120a6e |
msg.clear();
|
|
Shinya Kitaoka |
120a6e |
return msg;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline Message &reset(Message &msg) {
|
|
Shinya Kitaoka |
120a6e |
msg.ds().device()->seek(0);
|
|
Shinya Kitaoka |
120a6e |
return msg;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace tipc
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************
|
|
Toshihiro Shimizu |
890ddd |
// tipc Utility Functions
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace tipc {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------- Connection-message utilities ----------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
DVAPI bool startBackgroundProcess(QString cmdline);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
DVAPI QString applicationSpecificServerName(QString srvName);
|
|
Shinya Kitaoka |
120a6e |
DVAPI bool startSlaveConnection(QLocalSocket *socket, QString srvName,
|
|
Shinya Kitaoka |
120a6e |
int msecs = -1, QString cmdline = QString(),
|
|
Shinya Kitaoka |
120a6e |
QString threadName = QString());
|
|
Toshihiro Shimizu |
890ddd |
DVAPI bool startSlaveServer(QString srvName, QString cmdline);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
DVAPI QString readMessage(Stream &stream, Message &msg, int msecs = -1);
|
|
Shinya Kitaoka |
120a6e |
DVAPI QString
|
|
Shinya Kitaoka |
120a6e |
readMessageNB(Stream &stream, Message &msg, int msecs = -1,
|
|
Shinya Kitaoka |
120a6e |
QEventLoop::ProcessEventsFlag flag = QEventLoop::AllEvents);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------- Shared Memory utilities ----------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
DVAPI int shm_maxSegmentSize();
|
|
Toshihiro Shimizu |
890ddd |
DVAPI int shm_maxSegmentCount();
|
|
Toshihiro Shimizu |
890ddd |
DVAPI int shm_maxSharedPages();
|
|
Toshihiro Shimizu |
890ddd |
DVAPI int shm_maxSharedCount();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
DVAPI void shm_set(int maxSegmentSize, int maxSegmentCount, int maxSharedSize,
|
|
Shinya Kitaoka |
120a6e |
int maxSharedCount);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
DVAPI QString uniqueId();
|
|
Toshihiro Shimizu |
890ddd |
DVAPI int create(QSharedMemory &shmem, int size, bool strictSize = false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class ShMemReader {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
virtual int read(const char *srcBuf, int len) = 0;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Shinya Kitaoka |
120a6e |
class ShMemWriter {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
virtual int write(char *dstBuf, int len) = 0;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
DVAPI bool readShMemBuffer(Stream &stream, Message &msg,
|
|
Shinya Kitaoka |
120a6e |
ShMemReader *dataReader);
|
|
Shinya Kitaoka |
120a6e |
DVAPI bool writeShMemBuffer(Stream &stream, Message &msg, int bufSize,
|
|
Shinya Kitaoka |
120a6e |
ShMemWriter *dataWriter);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace tipc
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************
|
|
Toshihiro Shimizu |
890ddd |
// STL compatibility Stream operators
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename t=""></typename>
|
|
Shinya Kitaoka |
120a6e |
QDataStream &operator<<(QDataStream &ds, const std::vector<t> &vec) {</t>
|
|
Shinya Kitaoka |
120a6e |
unsigned int i, size = vec.size();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ds << size;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < size; ++i) ds << vec[i];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return ds;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename t=""></typename>
|
|
Shinya Kitaoka |
120a6e |
QDataStream &operator>>(QDataStream &ds, T &vec) {
|
|
Shinya Kitaoka |
120a6e |
return ds >> vec;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename t=""></typename>
|
|
Shinya Kitaoka |
120a6e |
QDataStream &operator>>(QDataStream &ds, std::vector<t> &vec) {</t>
|
|
Shinya Kitaoka |
120a6e |
unsigned int i, size;
|
|
Shinya Kitaoka |
120a6e |
T val;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ds >> size;
|
|
Shinya Kitaoka |
120a6e |
vec.reserve(size);
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < size; ++i) {
|
|
Shinya Kitaoka |
120a6e |
ds >> val;
|
|
Shinya Kitaoka |
120a6e |
vec.push_back(val);
|
|
Shinya Kitaoka |
120a6e |
if (ds.atEnd()) break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return ds;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline QDataStream &operator<<(QDataStream &ds, const std::string &str) {
|
|
Shinya Kitaoka |
120a6e |
ds << QString::fromStdString(str);
|
|
Shinya Kitaoka |
120a6e |
return ds;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
inline QDataStream &operator>>(QDataStream &ds, std::string &str) {
|
|
Shinya Kitaoka |
120a6e |
QString qstr;
|
|
Shinya Kitaoka |
120a6e |
ds >> qstr;
|
|
Shinya Kitaoka |
120a6e |
str = qstr.toStdString();
|
|
Shinya Kitaoka |
120a6e |
return ds;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline QDataStream &operator<<(QDataStream &ds, const std::wstring &str) {
|
|
Shinya Kitaoka |
120a6e |
ds << QString::fromStdWString(str);
|
|
Shinya Kitaoka |
120a6e |
return ds;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
inline QDataStream &operator>>(QDataStream &ds, std::wstring &str) {
|
|
Shinya Kitaoka |
120a6e |
QString qstr;
|
|
Shinya Kitaoka |
120a6e |
ds >> qstr;
|
|
Shinya Kitaoka |
120a6e |
str = qstr.toStdWString();
|
|
Shinya Kitaoka |
120a6e |
return ds;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline QDataStream &operator<<(QDataStream &ds, const wchar_t &ch) {
|
|
Shinya Kitaoka |
120a6e |
ds.writeRawData((const char *)&ch, sizeof(wchar_t));
|
|
Shinya Kitaoka |
120a6e |
return ds;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
inline QDataStream &operator>>(QDataStream &ds, wchar_t &ch) {
|
|
Shinya Kitaoka |
120a6e |
ds.readRawData((char *)&ch, sizeof(wchar_t));
|
|
Shinya Kitaoka |
120a6e |
return ds;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
#endif // TIPC_H
|