_8-exceptions_client.c _8-exceptions_server.c _8-exceptions_simulator.c: 8-exceptions.c 3-args.xml
../../tools/gras/gras_stub_generator 8-exceptions 3-args.xml >/dev/null
+# Lesson 9: simple data exchange
+########################################
+9-simpledata: 9-simpledata.c
+ gcc -I$(GRAS_ROOT)/include -lgras -L$(GRAS_ROOT)/lib $^ -o $@
+
+
clean::
if [ -e 8-exceptions.mk ] ; then make -f 8-exceptions.mk clean; fi
rm -f _8-exceptions_client.c _8-exceptions_server.c _8-exceptions_simulator.c 8-exceptions.trace 8-exceptions.mk
since in RL, each of them will run on a different host. If you use some AMOK
modules, you have to initialize them in each process too.
-The source file then reads: \include 1-bones.c
+The source file then reads: \include 01-bones.c
That's it. You have a working GRAS application with two processes. They
don't do anything useful, but that's a beginning. Let's see how to bring
generated binaries, and that's it. To start the simulation, simply call:
\verbatim ./<project>_simulator platform.xml deployment.xml\endverbatim
-Here is an example of execution: \include 1-bones.output
+Here is an example of execution: \include 01-bones.output
That's it. You are done with this lesson and can now write, build and
execute GRAS applications as long as they don't do anything ;) Move
We won't convey any payload in this lesson, so we just have to give the name
of message to declare them:
-\dontinclude 2-simple.c
+\dontinclude 02-simple.c
\skip gras_msgtype_declare
\until gras_msgtype_declare
\ref gras_socket_client with the hostname and the port of the process you
want to contact as arguments. Our client should simply do:
-\dontinclude 2-simple.c
+\dontinclude 02-simple.c
\skip socket_client
\until socket_client
message. The simplest way to retrive a message type from its name is to use
\ref gras_msgtype_by_name. Since we don't have any payload, this becomes:
-\dontinclude 2-simple.c
+\dontinclude 02-simple.c
\skip msg_send
\until msg_send
Since our server is willing to wait up to 60 seconds for a message, the
following will do it:
-\dontinclude 2-simple.c
+\dontinclude 02-simple.c
\skip msg_wait
\until msg_wait
\ref gras_socket_my_port, \ref gras_socket_peer_name and \ref
gras_socket_peer_port to retrieve information about who you are connected to.
-\include 2-simple.c
+\include 02-simple.c
Here is the output of the simulator. Note that \ref gras_socket_peer_port
actually returns the port number of the <i>server</i> of the peer. This may
sound a bit strange to BSD experts, but it is actually really useful: you
can store this value, and contact your peer afterward passing this number to
\ref gras_socket_client .
-\include 2-simple.output
+\include 02-simple.output
Here we are, you now know how to exchange messages between peers. There is
still a large room for improvement, such as adding payload to messages. But
In RL, the situation is quite simple: we just have to use the command line
arguments as we would do in a usual C program. In the server, only change
concern the opennong of the master socket:
-\dontinclude 3-args.c
+\dontinclude 03-args.c
\skip gras_socket_server
\until gras_socket_server
At this point, the problem is to pass arguments to the processes in SG.
Fortunately, it is quite simple. You just have to edit your deployment file
-so that it reads: \include 3-args.xml
+so that it reads: \include 03-args.xml
The syntax should be self-explanatory at this point.
\section GRAS_tut_tour_args_recap Recaping everything together
The whole program now reads:
-\include 3-args.c
+\include 03-args.c
And here is the output:
-\include 3-args.output
+\include 03-args.output
Go to \ref GRAS_tut_tour_callbacks
That's historical, but I may change this in the future (no worry, I'll add
backward compatibility solutions). Here is the actual code of our callback:
-\dontinclude 4-callback.c
+\dontinclude 04-callback.c
\skip gras_msg_cb_ctx_t
\until end_of_callback
\section GRAS_tut_tour_callback_recap Recaping everything together
The whole program now reads:
-\include 4-callback.c
+\include 04-callback.c
And here is the output (unchanged wrt previous version):
-\include 4-callback.output
+\include 04-callback.output
Our little example turns slowly to a quite advanced GRAS program. It entails
most of the mecanism most program will use.
We will now modify the example to add a "kill" message, and let the server
loop on incoming messages until it gets such a message. We only need a
boolean, so the structure is quite simple:
-\dontinclude 5-globals.c
+\dontinclude 05-globals.c
\skip struct
\until server_data
gras using the latter function. If you go for gras_userdata_set(), you
should pass it a pointer to your data you want to retrieve afterward.
-\dontinclude 5-globals.c
+\dontinclude 05-globals.c
\skip userdata_new
\until userdata_new
Once you declared a global that way, retriving this (for example in a
callback) is really easy:
-\dontinclude 5-globals.c
+\dontinclude 05-globals.c
\skip userdata_get
\until userdata_get
We can now write the callback, which simply retrive the globals and change
the value of the <tt>kileld</tt> field.
-\dontinclude 5-globals.c
+\dontinclude 05-globals.c
\skip kill_cb
\until end_of_kill_callback
\section GRAS_tut_tour_callback_recap Recaping everything together
The whole program now reads:
-\include 5-globals.c
+\include 05-globals.c
And here is the output (unchanged wrt previous version):
-\include 5-globals.output
+\include 05-globals.output
That's it, we're done. We have a server able to handle any number of
messages, which the client can stop remotely properly. That's already
Let's have another look at the output of the program we came up with in
lesson 5:
-\include 5-globals.output
+\include 05-globals.output
It is a bit difficult to read, isn't it? Indeed, it is hard to identify
which process printed which line. It would be possible to add [server] in
What we want here is a root category (it does not belong to any existing
channel, for sure), and we want it to be the default one in our file (of
course, it's the only one).
-\dontinclude 6-logs.c
+\dontinclude 06-logs.c
\skip XBT_LOG
\until XBT_LOG
Once we changed any fprintf of our code to some of these macros, the program
may read:
-\include 6-logs.c
+\include 06-logs.c
And the output now looks better:
-\include 6-logs.output
+\include 06-logs.output
\section GRAS_tut_tour_logs_config The user side: configuring logs at run time
to choose at run time what we want to see. For example, if we want more
details about our code, we should do (note that a VERBOSE line appears on
client side):
-\include 6-logs.output.verbose
+\include 06-logs.output.verbose
On the contrary, if we want to reduce the amount of logging, we may want to
-do: \include 6-logs.output.error
+do: \include 06-logs.output.error
Again, you should refer to the \ref XBT_log section for more information on
how to configure the logs. Or you can proceed with the next lesson, of
onto the server (to send messages) and a boolean indicating whether we are
done or not, just like we did on the server side in \ref
GRAS_tut_tour_globals. Here is the resulting global structure:
-\dontinclude 7-timers.c
+\dontinclude 07-timers.c
\skip client_data
\until client_data_t
periodicity at which it was desinstalled (so that the same action can be
scheduled at different intervals, and each of them be desinstallable
separately).
-\dontinclude 7-timers.c
+\dontinclude 07-timers.c
\skip gras_timer_cancel_repeat
\until gras_timer_cancel_repeat
be self-explanatory at this point. It could be cancelled before its
expiration using gras_timer_cancel_delay(), which accepts exactly the same
kind of arguments than gras_timer_cancel_repeat().
-\dontinclude 7-timers.c
+\dontinclude 07-timers.c
\skip client_do_stop
\until end_of_client_do_stop
\section GRAS_tut_tour_timers_recap Recapping everything together
The program now reads:
-\include 7-timers.c
+\include 07-timers.c
Which produces the expected output:
-\include 7-timers.output
+\include 07-timers.output
Go to \ref GRAS_tut_tour_exceptions
kill message to each ports of the search range. If it manage to close the
socket after sending the message without being interrupted by an exception,
it can assume that it killed the server and stop searching.
-\dontinclude 8-exceptions.c
+\dontinclude 08-exceptions.c
\skip port=3000
\until end_of_loop
look like when it's not catched), we add a potential command line argument
to the server, asking it to cheat and to not open its port within the search
range but elsewhere:
-\dontinclude 8-exceptions.c
+\dontinclude 08-exceptions.c
\skip strcmp
\until gras_socket_my_port
\until }
no idea of how to retrieve the call stack of the current process under the
other operating systems. But help is always welcome in this area too ;)
-\include 8-exceptions.output
+\include 08-exceptions.output
The complete program reads:
-\include 8-exceptions.c
+\include 08-exceptions.c
Go to \ref GRAS_tut_tour_rpc
--- /dev/null
+/**
+@page GRAS_tut_tour_simpledata Lesson 9: Exchanging simple data (TODO)
+
+\section GRAS_tut_tour_simpledata_toc Table of Contents
+ - \ref GRAS_tut_tour_simpledata_intro
+ - \ref GRAS_tut_tour_simpledata_use
+ - \ref GRAS_tut_tour_simpledata_recap
+
+<hr>
+
+\section GRAS_tut_tour_simpledata_intro Introduction
+
+
+\section GRAS_tut_tour_simpledata_use Actually exchanging simple data in messages
+
+
+\section GRAS_tut_tour_simpledata_recap Recapping everything together
+
+The program now reads:
+\include 09-simpledata.c
+
+Which produces the expected output:
+\include 09-simpledata.output
+
+
+*/
/**
-@page GRAS_tut_tour_rpc Lesson 9: Remote Procedure Calling (RPCing) (TODO)
+@page GRAS_tut_tour_rpc Lesson 10: Remote Procedure Calling (RPCing) (TODO)
\section GRAS_tut_tour_rpc_toc Table of Contents
- \ref GRAS_tut_tour_rpc_intro
\section GRAS_tut_tour_rpc_recap Recapping everything together
The program now reads:
-\include 9-rpc.c
+\include 10-rpc.c
Which produces the expected output:
-\include 9-rpc.output
+\include 10-rpc.output
*/