I have a situation where I have a single ObServer object and a set of Clients.
ObServer and clients connected through D-BUS (IPC). ObServer has generic interface for all clients. But, time to time ObServer needs to notify clients about some events. Clients listen for a ObServer Generic interface signal OnNotify().
Question:
How to emit D-BUS signal (OnNotify()) from ObServer to specified client (instead of broadcast to all) ?
p.s
Qt D-BUS used for wrapping but any approach are welcome.
You can't. Signals are received by all clients that have registered for that signal on a DBus interface.
You can either add a parameter to the OnNotify signal, and handle it in the client, or create separate signals for each client. However, if you want this component to be dynamic (add clients at runtime), you have to go with the first approach (parameter to OnNotify).
EDIT: more information on signals
A signal is defined as follows:
A signal in DBus consists of a single message, sent by one process to any number of other processes. That is, a signal is a unidirectional broadcast. The signal may contain arguments (a data payload), but because it is a broadcast, it never has a "return value." Contrast this with a method call (see the section called “Calling a Method - Behind the Scenes”) where the method call message has a matching method reply message.
The emitter (aka sender) of a signal has no knowledge of the signal recipients. Recipients register with the bus daemon to receive signals based on "match rules" - these rules would typically include the sender and the signal name. The bus daemon sends each signal only to recipients who have expressed interest in that signal.
Original source.
EDIT: updated answer in light of Dmitry's comments.
Filtering dbus signals will not work with any of the current available bindings (didn't check all of them, only 2 (dbus-cpp and qt), so anyone can follow up on this).
However it is possible to set the DESTINATION field in the header of the dbus message, using a function that is available in the dbus interface (dbus-message.h):
dbus_bool_t dbus_message_set_destination (DBusMessage *message, const char *destination)
In case of QT bindings, you have to modify the bindings as follows: in qdbusmessage.cpp in the method
DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDBusError *error)
on the case branch DBUS_MESSAGE_TYPE_SIGNAL you need to make a call to q_dbus_message_set_destination.
Also the destination must be available from the upper layers. Easiest way would be to extend the QDBusMessage class in order to retain the destination, and then pass it below to the dbus layer.
If you are able to modify the QT bindings in your project, then you might do such a maneuver :).
Related
I know how a process can respond to signals that were sent to it specifically (e.g. SIGINT, SIGTERM, SIGUSR2, etc.). But can a process be notified of signals that were sent to a different process?
Not in standard Unix or POSIX, you cannot be notified for signals sent to another process. See signal(7) and signal-safety(7).
However, waitpid(2) and friends can tell you if a child process has terminated with a signal. And killpg(2) sends a signal to a process group (and kill(2) does also that with a negative target pid). And getrusage(2) can count signals (recieved by some other process). You could also use proc(5) to query information about other processes. And you might use signalfd(2) or ptrace(2) etc....
Signals are a very limited and poor form of inter-process communication. There are better ways.
BTW, sigaction(2) can be used with SA_SIGINFO and then your handler gets a pointer to siginfo_t and another to ucontext_t so you get a lot of information.
Notice that process groups and sessions are related. See also setpgid(2), setsid(2), credentials(7) and also related to terminals and pseudo-ttys (read the tty demystified and about job control).
I guess that your other question is about these. But you don't mention any of them there.
If I press a button, a network server should get started. But it seems the compiler does not know the right accept-function. This line:
sockConnection = accept(hSocket, &remoteAddr, &iRemoteAddrLen);
gets this error:
no matching function for call to 'NetConf::accept(SOCKET&, sockaddr_in*, socklen_t*)'
It appears that the accept-function is part of a Qt Object and not the socket one I would like to use. I read about including "socket.h" but cant find it on my system (Windows 7 - 64 bit, Qt library 4.8.6). Any suggestions?
Qt is a framework that abstracts away the requirement for calling low level functions such as accept.
If you want a TCP-based network server, start with a QTcpServer class object and call its listen function
If you've connected a QObject's slot to the QTcpServer's newConnection signal, you'll be notified when a connection is made.
Once notified of a new connection, you then call nextPendingConnection which returns a QTcpSocket, which you can use to communicate with the client by using its available functions as described in the Qt docs for this class.
I have a process which is already in signal handler , and called a process blocking call. What will happen if one more signal arrives for this process ?
By default signals don't block each other. A signal only blocks itself during its own delivery. So, in general, an handling code can be interrupted by another signal delivery.
You can control this behavior by setting the process signal mask relatively to each signal delivery. This means that you can block (or serialize) signal delivery. For instance you can declare that you accept to be interrupted with signal S1 while handling signal S2, but not the converse...
Remember that signal delivery introduces some concurrency into your code, so controlling the blocking is needed.
I'm pretty sure signals are blocked while a handler is being executed, but I'm having a hard time finding something that says that definitively.
Also, you may wish to see this question - some of the answers talk about what functions you should and shouldn't call from a signal handler.
In general, you should consider a signal handler like an interrupt handler - do the very least you can in the handler, and return quickly.
One thread do an emit signal1();
A second thread do an emit signal2(); after that first thread has sent its signal ( there is the same mutex locked before emit call on both thread and I logged it, I can see in my log that first thread acquire lock before second thread)
first thread and second thread or not the GUI thread.
Is there any guarentees that signal1's slot will be call before signal2's slot ?
As the emitter and the receiver objects are running in different threads, the slots will not be executed synchronously: Qt is using a queued connection by default instead of a direct connection. You can however force a synchronous execution by using a blocking queued connection (see also http://qt-project.org/doc/qt-4.8/qt.html#ConnectionType-enum for the description of the different connection types) when connecting signals and slots.
But a blocking queue connection has a cost: the emitter thread is blocked until all the connected slots are executed, which is not necessarily a good idea. If you want to use a non-blocking connection, however, the order of execution depends on the objects were the slots are executed.
The important thing to consider is that each QThread has its own event queue. It means that the order of execution is only guaranteed for the slots of a given thread. This means that you have to consider the following cases:
signal1's slot and signal2's slot are defined in QObject's living in the same thread: in that case, you can be sure that the slots are executed in the expected order because they are triggered by the same event queue
both slots are running in different threads: here you have no control over the order of execution as the signals are posted to 2 independent event queues. If this is the case, you have to use mutexes or wait conditions (or use a blocking connection).
emit is just syntactic sugar, look at the .cpp generated by the Meta Object Compiler (moc).
So, emit signal1(); is compiled as signal1();, and the answer to your question is YES, but of course you have no guarentees that signal1() execution ends before signal2() invocation.
I am not sure if I understand you correctly, but this might help you:
When a signal is emitted, the slots connected to it are usually executed immediately, just like a normal function call.
from http://doc.qt.io/qt-5/signalsandslots.html
So think of calling emit() as calling any other function.
Netty channels have multiple states but I am unable to find any
documentation on the actual state transitions. The closest to any
documentation on this that I could find for Netty 3.2.x system is
here.
I was able to locate the possible states that a channel can be in
here.
However there is nothing that describes the normal transitions that a
channel can make from one state to another. It appears that not all
channels make all possible state transitions.
Different Netty channels do indeed have different state transitions.
In general the possible state transitions for TCP based server
channels are:
OPEN -> ( BOUND -> UNBOUND )* -> CLOSE
If you are using a SimpleChannelHandler subclass in your pipeline
the equivalent methods for handling the upstream events when one of
these state changes occur are:
channelOpen
channelBound
channelUnbound
channelClose
Server channels never move into the CONNECTED state.
Server channels rarely move back into the BOUND state once they
move into the UNBOUND state, however this appears to be dependent
on the application so YMMV.
Note that server channels can fire events when a child channel is
opened or closed. These events can occur only after the server
channel is in the BOUND state. When these events are sent
upstream on behalf of the server channel then the following methods on
your SimpleChannelHandler subclass are called:
childChannelOpen
childChannelClosed
The possible state transitions for TCP based child and client channels
are:
OPEN -> ( BOUND -> ( CONNECTED -> DISCONNECTED )* -> UNBOUND )* -> CLOSE
It appears that moving into the CONNECTED state first is not
enforced within the channel code; however this state is invariably
fired first for both child and client channels within the Netty
framework before the channel is moved into the CONNECTED state.
If you are using SimpleChannelHandler or a subclass thereof in
your pipeline the equivalent methods are:
channelOpen
channelBound
channelConnected
channelDisconnected
channelUnbound
channelClose
A TCP based channel must be in the CONNECTED state before anything
can be read or written to the channel. This includes server channels,
which can never be read from or written to, which is not much of a
surprise as server channels are invariably used only for managing the
connect operation on behalf of the server.
Datagram sockets operate differently than TCP based sockets in that
they can be used to read and write data without actually being
connected (though connecting a datagram socket can be faster as you
avoid security checks). Datagram sockets can be effectively used
using both of the state transitions listed for TCP based child and
server channels described above.