Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
641cecdbd7907823746d26d84c8f43c9818cd207
[simgrid.git] / doc / gtut-tour-5-globals.doc
1 /**
2 @page GRAS_tut_tour_globals Lesson 5: Using globals in processes
3
4 Callbacks are great to express your processes as state machines, but they
5 pose another problem: callbacks don't have acces to the variable declared
6 within the scope of the process' main function (of course). You should
7 however resist to the temptation to declare globals outside of the scope of
8 the functions, or you won't be able to use more than one process of each
9 type in the simulation. Remember, all gras processes run as thread
10 within the same naming space in SG so your globals will be shared between
11 the several instances of your process, leading to bad problems.
12
13 Instead, you you have to put all globals in a structure, and let GRAS handle
14 it with the gras_userdata_* functions (there is only 3 of them ;). 
15
16 We will now modify the example to add a "kill" message, and let the server
17 loop on incoming messages until it gets such a message. We only need a
18 boolean, so the structure is quite simple: 
19 \dontinclude 5-globals.c
20 \skip struct
21 \until server_data
22  
23 Then, we need to create this structure in the process main function. We
24 could use either gras_userdata_new() or gras_userdata_set(). The former is an
25 helper macro mallocing the space needed by the structure and passing it to
26 gras using the latter function. If you go for gras_userdata_set(), you
27 should pass it a pointer to your data you want to retrieve afterward.
28
29 \dontinclude 5-globals.c
30 \skip userdata_new
31 \until userdata_new
32
33 Once you declared a global that way, retriving this (for example in a
34 callback) is really easy:
35 \dontinclude 5-globals.c
36 \skip userdata_get
37 \until userdata_get
38
39 We can now write the callback, which simply retrive the globals and change
40 the value of the <tt>kileld</tt> field.
41 \dontinclude 5-globals.c
42 \skip kill_cb
43 \until end_of_kill_callback
44
45 And we replace the single gras_msg_handle() of the server main function by a
46 loop:
47 \skip while
48 \until }
49
50 \section GRAS_tut_tour_callback_pitfall Common pitfall of globals
51
52 There is an error that I do myself every other day using globals in GRAS.
53 This is to write something like:
54 \verbatim int server(int argc, char *argv[]) {
55   server_data_t globals=gras_user_new(server_data_t);
56   /* other variable definition */
57   
58   gras_init(&argc, argv);
59   
60   /* rest of the code */
61 }\endverbatim
62
63 The problem is that you call gras_userdata_new() before gras_init(). Doing so,
64 embarass GRAS since it does not have its internal buffer initialized yet,
65 and cannot store your data anywhere. That is why doing so triggers an error
66 at run time.
67
68 \section GRAS_tut_tour_callback_recap Recaping everything together
69
70 The whole program now reads:
71 \include 5-globals.c
72
73 And here is the output (unchanged wrt previous version):
74 \include 5-globals.output
75
76 That's it, we're done. We have a server able to handle any number of
77 messages, which the client can stop remotely properly. That's already
78 something, hu?
79
80 \ref GRAS_tut_tour_timer
81
82 */