session: Make event source injection API private

Also remove the corresponding functionality from the bindings.
This commit is contained in:
Daniel Elstner 2015-10-09 19:46:14 +02:00
parent f91cf612df
commit ee9953ef12
8 changed files with 34 additions and 375 deletions

View File

@ -872,55 +872,6 @@ void DatafeedCallbackData::run(const struct sr_dev_inst *sdi,
_callback(device, packet);
}
SourceCallbackData::SourceCallbackData(shared_ptr<EventSource> source) :
_source(source)
{
}
bool SourceCallbackData::run(int revents)
{
return _source->_callback((Glib::IOCondition) revents);
}
shared_ptr<EventSource> EventSource::create(int fd, Glib::IOCondition events,
int timeout, SourceCallbackFunction callback)
{
auto result = new EventSource(timeout, callback);
result->_type = EventSource::SOURCE_FD;
result->_fd = fd;
result->_events = events;
return shared_ptr<EventSource>(result, EventSource::Deleter());
}
shared_ptr<EventSource> EventSource::create(Glib::PollFD pollfd, int timeout,
SourceCallbackFunction callback)
{
auto result = new EventSource(timeout, callback);
result->_type = EventSource::SOURCE_POLLFD;
result->_pollfd = pollfd;
return shared_ptr<EventSource>(result, EventSource::Deleter());
}
shared_ptr<EventSource> EventSource::create(Glib::RefPtr<Glib::IOChannel> channel,
Glib::IOCondition events, int timeout, SourceCallbackFunction callback)
{
auto result = new EventSource(timeout, callback);
result->_type = EventSource::SOURCE_IOCHANNEL;
result->_channel = channel;
result->_events = events;
return shared_ptr<EventSource>(result, EventSource::Deleter());
}
EventSource::EventSource(int timeout, SourceCallbackFunction callback) :
_timeout(timeout),
_callback(callback)
{
}
EventSource::~EventSource()
{
}
SessionDevice::SessionDevice(struct sr_dev_inst *structure) :
ParentOwned(structure),
Device(structure)
@ -967,9 +918,6 @@ Session::~Session()
for (auto callback : _datafeed_callbacks)
delete callback;
for (auto entry : _source_callbacks)
delete entry.second;
for (auto entry : _owned_devices)
delete entry.second;
}
@ -1073,66 +1021,6 @@ void Session::remove_datafeed_callbacks(void)
_datafeed_callbacks.clear();
}
static int source_callback(int fd, int revents, void *cb_data)
{
(void) fd;
auto callback = (SourceCallbackData *) cb_data;
return callback->run(revents);
}
void Session::add_source(shared_ptr<EventSource> source)
{
if (_source_callbacks.count(source) == 1)
throw Error(SR_ERR_ARG);
auto cb_data = new SourceCallbackData(source);
switch (source->_type)
{
case EventSource::SOURCE_FD:
check(sr_session_source_add(_structure, source->_fd, source->_events,
source->_timeout, source_callback, cb_data));
break;
case EventSource::SOURCE_POLLFD:
check(sr_session_source_add_pollfd(_structure,
source->_pollfd.gobj(), source->_timeout, source_callback,
cb_data));
break;
case EventSource::SOURCE_IOCHANNEL:
check(sr_session_source_add_channel(_structure,
source->_channel->gobj(), source->_events, source->_timeout,
source_callback, cb_data));
break;
}
_source_callbacks[source] = cb_data;
}
void Session::remove_source(shared_ptr<EventSource> source)
{
if (_source_callbacks.count(source) == 0)
throw Error(SR_ERR_ARG);
switch (source->_type)
{
case EventSource::SOURCE_FD:
check(sr_session_source_remove(_structure, source->_fd));
break;
case EventSource::SOURCE_POLLFD:
check(sr_session_source_remove_pollfd(_structure,
source->_pollfd.gobj()));
break;
case EventSource::SOURCE_IOCHANNEL:
check(sr_session_source_remove_channel(_structure,
source->_channel->gobj()));
break;
}
delete _source_callbacks[source];
_source_callbacks.erase(source);
}
shared_ptr<Trigger> Session::trigger()
{
return _trigger;

View File

@ -91,7 +91,6 @@ class SR_API Driver;
class SR_API Device;
class SR_API HardwareDevice;
class SR_API Channel;
class SR_API EventSource;
class SR_API Session;
class SR_API ConfigKey;
class SR_API InputFormat;
@ -610,71 +609,6 @@ protected:
friend class Session;
};
/** Type of source callback */
typedef function<bool(Glib::IOCondition)>
SourceCallbackFunction;
/* Data required for C callback function to call a C++ source callback */
class SR_PRIV SourceCallbackData
{
public:
bool run(int revents);
protected:
SourceCallbackData(shared_ptr<EventSource> source);
shared_ptr<EventSource> _source;
friend class Session;
};
/** An I/O event source */
class SR_API EventSource
{
public:
/** Create an event source from a file descriptor.
* @param fd File descriptor.
* @param events GLib IOCondition event mask.
* @param timeout Timeout in milliseconds.
* @param callback Callback of the form callback(events) */
static shared_ptr<EventSource> create(int fd, Glib::IOCondition events,
int timeout, SourceCallbackFunction callback);
/** Create an event source from a GLib PollFD
* @param pollfd GLib PollFD
* @param timeout Timeout in milliseconds.
* @param callback Callback of the form callback(events) */
static shared_ptr<EventSource> create(Glib::PollFD pollfd, int timeout,
SourceCallbackFunction callback);
/** Create an event source from a GLib IOChannel
* @param channel GLib IOChannel.
* @param events GLib IOCondition event mask.
* @param timeout Timeout in milliseconds.
* @param callback Callback of the form callback(events) */
static shared_ptr<EventSource> create(
Glib::RefPtr<Glib::IOChannel> channel, Glib::IOCondition events,
int timeout, SourceCallbackFunction callback);
protected:
EventSource(int timeout, SourceCallbackFunction callback);
~EventSource();
enum source_type {
SOURCE_FD,
SOURCE_POLLFD,
SOURCE_IOCHANNEL
} _type;
int _fd;
Glib::PollFD _pollfd;
Glib::RefPtr<Glib::IOChannel> _channel;
Glib::IOCondition _events;
int _timeout;
SourceCallbackFunction _callback;
/** Deleter needed to allow shared_ptr use with protected destructor. */
class Deleter
{
public:
void operator()(EventSource *source) { delete source; }
};
friend class Deleter;
friend class Session;
friend class SourceCallbackData;
};
/** A virtual device associated with a stored session */
class SR_API SessionDevice :
public ParentOwned<SessionDevice, Session, struct sr_dev_inst>,
@ -710,12 +644,6 @@ public:
void add_datafeed_callback(DatafeedCallbackFunction callback);
/** Remove all datafeed callbacks from this session. */
void remove_datafeed_callbacks();
/** Add an I/O event source.
* @param source EventSource to add. */
void add_source(shared_ptr<EventSource> source);
/** Remove an event source.
* @param source EventSource to remove. */
void remove_source(shared_ptr<EventSource> source);
/** Start the session. */
void start();
/** Run the session event loop. */
@ -745,7 +673,6 @@ protected:
map<const struct sr_dev_inst *, shared_ptr<Device> > _other_devices;
vector<DatafeedCallbackData *> _datafeed_callbacks;
SessionStoppedCallback _stopped_callback;
map<shared_ptr<EventSource>, SourceCallbackData *> _source_callbacks;
string _filename;
shared_ptr<Trigger> _trigger;
friend class Deleter;

View File

@ -36,21 +36,8 @@
import org.sigrok.core.interfaces.LogCallback;
import org.sigrok.core.interfaces.DatafeedCallback;
import org.sigrok.core.interfaces.SourceCallback;
%}
/* Map Java FileDescriptor objects to int fds */
%typemap(jni) int fd "jobject"
%typemap(jtype) int fd "java.io.FileDescriptor"
%typemap(jstype) int fd "java.io.FileDescriptor"
%typemap(javain) int fd "$javainput"
%typemap(in) int fd {
jclass FileDescriptor = jenv->FindClass("java/io/FileDescriptor");
jfieldID fd = jenv->GetFieldID(FileDescriptor, "fd", "I");
$1 = jenv->GetIntField($input, fd);
}
/* Map Glib::VariantBase to a Variant class in Java */
%rename(Variant) VariantBase;
namespace Glib {
@ -346,41 +333,6 @@ typedef jobject jdatafeedcallback;
}
}
/* Support Java event source callbacks. */
%typemap(javaimports) sigrok::EventSource
"import org.sigrok.core.interfaces.SourceCallback;"
%inline {
typedef jobject jsourcecallback;
}
%typemap(jni) jsourcecallback "jsourcecallback"
%typemap(jtype) jsourcecallback "SourceCallback"
%typemap(jstype) jsourcecallback "SourceCallback"
%typemap(javain) jsourcecallback "$javainput"
%extend sigrok::EventSource
{
std::shared_ptr<sigrok::EventSource> create(
int fd, Glib::IOCondition events, int timeout,
JNIEnv *env, jsourcecallback obj)
{
(void) $self;
jclass obj_class = env->GetObjectClass(obj);
jmethodID method = env->GetMethodID(obj_class, "run", "(I)V");
jobject obj_ref = env->NewGlobalRef(obj);
return sigrok::EventSource::create(fd, events, timeout, [=] (int revents)
{
bool result = env->CallBooleanMethod(obj_ref, method, revents);
if (env->ExceptionCheck())
throw sigrok::Error(SR_ERR);
return result;
});
}
}
%include "doc.i"
%define %attributevector(Class, Type, Name, Get)

View File

@ -51,8 +51,6 @@ which provides access to the error code and description."
PyObject *PyGObject_lib;
PyObject *GLib;
PyTypeObject *IOChannel;
PyTypeObject *PollFD;
#include "config.h"
@ -81,8 +79,6 @@ typedef guint pyg_flags_type;
return;
#endif
}
IOChannel = (PyTypeObject *) PyObject_GetAttrString(GLib, "IOChannel");
PollFD = (PyTypeObject *) PyObject_GetAttrString(GLib, "PollFD");
import_array();
%}
@ -91,15 +87,6 @@ typedef guint pyg_flags_type;
$1 = (PyObject_AsFileDescriptor($input) != -1);
}
%typemap(in) int fd {
int fd = PyObject_AsFileDescriptor($input);
if (fd == -1)
SWIG_exception(SWIG_TypeError,
"Expected file object or integer file descriptor");
else
$1 = fd;
}
/* Map from Glib::Variant to native Python types. */
%typemap(out) Glib::VariantBase {
GValue *value = g_new0(GValue, 1);
@ -113,113 +100,6 @@ typedef guint pyg_flags_type;
g_free(value);
}
/* Map from Glib::IOCondition to GLib.IOCondition. */
%typecheck(SWIG_TYPECHECK_POINTER) Glib::IOCondition {
pyg_flags_type flags;
$1 = pygobject_check($input, &PyGFlags_Type) &&
(pyg_flags_get_value(G_TYPE_IO_CONDITION, $input, &flags) != -1);
}
%typemap(in) Glib::IOCondition {
if (!pygobject_check($input, &PyGFlags_Type))
SWIG_exception(SWIG_TypeError, "Expected GLib.IOCondition value");
pyg_flags_type flags;
if (pyg_flags_get_value(G_TYPE_IO_CONDITION, $input, &flags) == -1)
SWIG_exception(SWIG_TypeError, "Not a valid Glib.IOCondition value");
$1 = (Glib::IOCondition) flags;
}
/* And back */
%typemap(out) Glib::IOCondition {
GValue *value = g_new0(GValue, 1);
g_value_init(value, G_TYPE_IO_CONDITION);
g_value_set_flags(value, &$1);
$result = pyg_value_as_pyobject(value, true);
g_free(value);
}
/* Map from GLib.PollFD to Glib::PollFD *. */
%typecheck(SWIG_TYPECHECK_POINTER) Glib::PollFD {
$1 = pygobject_check($input, PollFD);
}
%typemap(in) Glib::PollFD {
if (!pygobject_check($input, PollFD))
SWIG_exception(SWIG_TypeError, "Expected GLib.PollFD");
PyObject *fd_obj = PyObject_GetAttrString($input, "fd");
PyObject *events_obj = PyObject_GetAttrString($input, "events");
pyg_flags_type flags;
pyg_flags_get_value(G_TYPE_IO_CONDITION, events_obj, &flags);
int fd = PyInt_AsLong(fd_obj);
Glib::IOCondition events = (Glib::IOCondition) flags;
$1 = Glib::PollFD(fd, events);
}
/* Map from GLib.IOChannel to Glib::IOChannel *. */
%typecheck(SWIG_TYPECHECK_POINTER) Glib::RefPtr<Glib::IOChannel> {
$1 = pygobject_check($input, IOChannel);
}
%typemap(in) Glib::RefPtr<Glib::IOChannel> {
if (!pygobject_check($input, IOChannel))
SWIG_exception(SWIG_TypeError, "Expected GLib.IOChannel");
$1 = Glib::wrap((GIOChannel *) PyObject_Hash($input), true);
}
/* Map from callable PyObject to SourceCallbackFunction. */
%typecheck(SWIG_TYPECHECK_POINTER) sigrok::SourceCallbackFunction {
$1 = PyCallable_Check($input);
}
%typemap(in) sigrok::SourceCallbackFunction {
if (!PyCallable_Check($input))
SWIG_exception(SWIG_TypeError, "Expected a callable Python object");
$1 = [=] (Glib::IOCondition revents) {
auto gstate = PyGILState_Ensure();
GValue *value = g_new0(GValue, 1);
g_value_init(value, G_TYPE_IO_CONDITION);
g_value_set_flags(value, revents);
auto revents_obj = pyg_value_as_pyobject(value, true);
g_free(value);
auto arglist = Py_BuildValue("(O)", revents_obj);
auto result = PyEval_CallObject($input, arglist);
Py_XDECREF(arglist);
Py_XDECREF(revents_obj);
bool completed = !PyErr_Occurred();
if (!completed)
PyErr_Print();
bool valid_result = (completed && PyBool_Check(result));
if (completed && !valid_result)
{
PyErr_SetString(PyExc_TypeError,
"EventSource callback did not return a boolean");
PyErr_Print();
}
bool retval = (valid_result && result == Py_True);
Py_XDECREF(result);
PyGILState_Release(gstate);
if (!valid_result)
throw sigrok::Error(SR_ERR);
return retval;
};
Py_XINCREF($input);
}
/* Map from callable PyObject to LogCallbackFunction */
%typecheck(SWIG_TYPECHECK_POINTER) sigrok::LogCallbackFunction {
$1 = PyCallable_Check($input);

View File

@ -66,7 +66,6 @@ template< class T > class enable_shared_from_this;
%shared_ptr(sigrok::HardwareDevice);
%shared_ptr(sigrok::Channel);
%shared_ptr(sigrok::ChannelGroup);
%shared_ptr(sigrok::EventSource);
%shared_ptr(sigrok::Session);
%shared_ptr(sigrok::SessionDevice);
%shared_ptr(sigrok::Packet);
@ -138,7 +137,6 @@ template< class T > class enable_shared_from_this;
#define SR_PRIV
%ignore sigrok::DatafeedCallbackData;
%ignore sigrok::SourceCallbackData;
#define SWIG_ATTRIBUTE_TEMPLATE

View File

@ -128,20 +128,6 @@ SR_API int sr_session_is_running(struct sr_session *session);
SR_API int sr_session_stopped_callback_set(struct sr_session *session,
sr_session_stopped_callback cb, void *cb_data);
SR_API int sr_session_source_add(struct sr_session *session, int fd,
int events, int timeout, sr_receive_data_callback cb, void *cb_data);
SR_API int sr_session_source_add_pollfd(struct sr_session *session,
GPollFD *pollfd, int timeout, sr_receive_data_callback cb,
void *cb_data);
SR_API int sr_session_source_add_channel(struct sr_session *session,
GIOChannel *channel, int events, int timeout,
sr_receive_data_callback cb, void *cb_data);
SR_API int sr_session_source_remove(struct sr_session *session, int fd);
SR_API int sr_session_source_remove_pollfd(struct sr_session *session,
GPollFD *pollfd);
SR_API int sr_session_source_remove_channel(struct sr_session *session,
GIOChannel *channel);
/*--- input/input.c ---------------------------------------------------------*/
SR_API const struct sr_input_module **sr_input_list(void);

View File

@ -730,6 +730,21 @@ SR_PRIV int sr_session_source_destroyed(struct sr_session *session,
SR_PRIV int sr_session_fd_source_add(struct sr_session *session,
void *key, gintptr fd, int events, int timeout,
sr_receive_data_callback cb, void *cb_data);
SR_PRIV int sr_session_source_add(struct sr_session *session, int fd,
int events, int timeout, sr_receive_data_callback cb, void *cb_data);
SR_PRIV int sr_session_source_add_pollfd(struct sr_session *session,
GPollFD *pollfd, int timeout, sr_receive_data_callback cb,
void *cb_data);
SR_PRIV int sr_session_source_add_channel(struct sr_session *session,
GIOChannel *channel, int events, int timeout,
sr_receive_data_callback cb, void *cb_data);
SR_PRIV int sr_session_source_remove(struct sr_session *session, int fd);
SR_PRIV int sr_session_source_remove_pollfd(struct sr_session *session,
GPollFD *pollfd);
SR_PRIV int sr_session_source_remove_channel(struct sr_session *session,
GIOChannel *channel);
SR_PRIV int sr_session_send(const struct sr_dev_inst *sdi,
const struct sr_datafeed_packet *packet);
SR_PRIV int sr_sessionfile_check(const char *filename);

View File

@ -1132,10 +1132,13 @@ SR_PRIV int sr_session_send(const struct sr_dev_inst *sdi,
* @param session The session to use. Must not be NULL.
* @param key The key which identifies the event source.
* @param source An event source object. Must not be NULL.
*
* @retval SR_OK Success.
* @retval SR_ERR_ARG Invalid argument.
* @retval SR_ERR_BUG Event source with @a key already installed.
* @retval SR_ERR Other error.
*
* @private
*/
SR_PRIV int sr_session_source_add_internal(struct sr_session *session,
void *key, GSource *source)
@ -1192,8 +1195,9 @@ SR_PRIV int sr_session_fd_source_add(struct sr_session *session,
* @retval SR_ERR_ARG Invalid argument.
*
* @since 0.3.0
* @private
*/
SR_API int sr_session_source_add(struct sr_session *session, int fd,
SR_PRIV int sr_session_source_add(struct sr_session *session, int fd,
int events, int timeout, sr_receive_data_callback cb, void *cb_data)
{
if (fd < 0 && timeout < 0) {
@ -1218,8 +1222,9 @@ SR_API int sr_session_source_add(struct sr_session *session, int fd,
* @retval SR_ERR_ARG Invalid argument.
*
* @since 0.3.0
* @private
*/
SR_API int sr_session_source_add_pollfd(struct sr_session *session,
SR_PRIV int sr_session_source_add_pollfd(struct sr_session *session,
GPollFD *pollfd, int timeout, sr_receive_data_callback cb,
void *cb_data)
{
@ -1246,8 +1251,9 @@ SR_API int sr_session_source_add_pollfd(struct sr_session *session,
* @retval SR_ERR_ARG Invalid argument.
*
* @since 0.3.0
* @private
*/
SR_API int sr_session_source_add_channel(struct sr_session *session,
SR_PRIV int sr_session_source_add_channel(struct sr_session *session,
GIOChannel *channel, int events, int timeout,
sr_receive_data_callback cb, void *cb_data)
{
@ -1278,6 +1284,8 @@ SR_API int sr_session_source_add_channel(struct sr_session *session,
*
* @retval SR_OK Success
* @retval SR_ERR_BUG No event source for poll_object found.
*
* @private
*/
SR_PRIV int sr_session_source_remove_internal(struct sr_session *session,
void *key)
@ -1309,8 +1317,9 @@ SR_PRIV int sr_session_source_remove_internal(struct sr_session *session,
* @retval SR_ERR_BUG Internal error.
*
* @since 0.3.0
* @private
*/
SR_API int sr_session_source_remove(struct sr_session *session, int fd)
SR_PRIV int sr_session_source_remove(struct sr_session *session, int fd)
{
return sr_session_source_remove_internal(session, GINT_TO_POINTER(fd));
}
@ -1326,8 +1335,9 @@ SR_API int sr_session_source_remove(struct sr_session *session, int fd)
* internal errors.
*
* @since 0.2.0
* @private
*/
SR_API int sr_session_source_remove_pollfd(struct sr_session *session,
SR_PRIV int sr_session_source_remove_pollfd(struct sr_session *session,
GPollFD *pollfd)
{
if (!pollfd) {
@ -1348,8 +1358,9 @@ SR_API int sr_session_source_remove_pollfd(struct sr_session *session,
* @return SR_ERR_BUG Internal error.
*
* @since 0.2.0
* @private
*/
SR_API int sr_session_source_remove_channel(struct sr_session *session,
SR_PRIV int sr_session_source_remove_channel(struct sr_session *session,
GIOChannel *channel)
{
if (!channel) {
@ -1370,6 +1381,8 @@ SR_API int sr_session_source_remove_channel(struct sr_session *session,
* @retval SR_OK Success.
* @retval SR_ERR_BUG Event source for @a key does not match @a source.
* @retval SR_ERR Other error.
*
* @private
*/
SR_PRIV int sr_session_source_destroyed(struct sr_session *session,
void *key, GSource *source)