]> rtime.felk.cvut.cz Git - frescor/frsh.git/blob - fres/resmng/frm_generic.c
Executor is initialized before the object is registered
[frescor/frsh.git] / fres / resmng / frm_generic.c
1 #include <frm_generic.h>
2 #include <forb.h>
3 #include <ul_log.h>
4 #include <fres_sa_scenario.h>
5 #include <fcb.h>
6
7 UL_LOG_CUST(ulogd_frm);
8 ul_log_domain_t ulogd_frm = {UL_LOGL_MSG, "frm"};
9
10 struct frm_data {
11         struct fres_sa_scenario *running;
12         frm_adm_test_fnc_t admission_test;
13         void *priv;
14 };
15
16 #define object_to_frm(o) (struct frm_data*)forb_instance_data(o)
17 #define save_errno(cmd) do { int _e = errno; cmd; errno = _e; } while(0)
18
19 static CORBA_long reserve_contracts(fres_resource_manager obj,
20                              const fres_contract_ptr_seq* contracts,
21                              CORBA_Environment *ev)
22 {
23         struct frm_data *frm = object_to_frm(obj);
24         struct fres_sa_scenario *prospective;
25         struct fres_contract *c;
26         bool schedulable;
27         int i;
28
29         ul_logdeb("reserve_contracts\n");
30         
31         prospective = fres_sa_scenario_duplicate(frm->running);
32         for (i=0; i<contracts->_length; i++) {
33                 c = fres_contract_duplicate(contracts->_buffer[i]);
34                 fres_sa_scenario_add_contract(prospective, c);
35         }
36
37         schedulable = frm->admission_test(prospective, frm->priv);
38
39         if (schedulable) {
40                 fres_sa_scenario_destroy(frm->running);
41                 frm->running = prospective;
42         } else {
43                 fres_sa_scenario_destroy(prospective);
44         }
45         return schedulable ? 0 : 1;
46 }
47
48 static void commit_contracts(fres_resource_manager obj,
49                       const fres_contract_id_seq* ids,
50                       fres_contract_ptr_seq** contract_with_scheduler_data,
51                       CORBA_Environment *ev)
52 {
53         struct frm_data *frm = object_to_frm(obj);
54         int i, num;
55         struct fres_sa_contract *c;
56         fres_contract_ptr_seq *contracts;
57
58         ul_logdeb("commit_contracts\n");
59
60         contracts = forb_malloc(sizeof(*contracts));
61         if (!contracts) {
62                 ev->major = FORB_EX_NO_MEMORY;
63                 goto err;
64         }
65         num = ids->_length;
66         contracts->_buffer = CORBA_sequence_fres_contract_ptr_allocbuf(num);
67         contracts->_maximum = contracts->_length = num;
68         
69         for (i=0; i < num; i++) {
70                 c = fres_sa_scenario_find_contract(frm->running, &ids->_buffer[i]);
71         }
72         
73         *contract_with_scheduler_data = contracts;
74 err:;
75 }
76
77 static void cancel_contracts(fres_resource_manager obj,
78                       const fres_contract_id_seq* ids,
79                       CORBA_Environment *ev)
80 {
81         int i;
82         struct frm_data *frm = object_to_frm(obj);
83
84         ul_logdeb("cancel_contracts\n");
85
86         for (i=0; i<ids->_length; i++) {
87                 struct fres_sa_contract *c;
88                 c = fres_sa_scenario_find_contract(frm->running, &ids->_buffer[i]);
89
90                 if (c) {
91                         fres_sa_scenario_del_contract(frm->running, c);
92                 }
93         }
94 }
95
96
97 static const struct forb_fres_resource_manager_impl frm_impl = {
98         .reserve_contracts = reserve_contracts,
99         .commit_contracts  = commit_contracts,
100         .cancel_contracts  = cancel_contracts,
101 };
102
103 /** 
104  * Initializes and runs a generic resource manager. The only thing a
105  * caller has to supply is admission test function, which is passed in
106  * @a frm_data->admission_test.
107  * 
108  * @param orb FORB object used to communicate with other components.
109  * @param admission_test Admission test function.
110  * @param priv Pointer to passed as priv parameter to frm_adm_test_fnc_t.
111  * 
112  * @return 
113  */
114 int frm_generic_run(forb_orb orb, frm_adm_test_fnc_t admission_test, void *priv)
115 {
116         fres_contract_broker fcb;
117         fres_resource_manager frm;
118         struct forb_env env;
119         struct frm_data frm_data;
120         forb_executor_t executor;
121         int ret;
122
123         memset(&frm_data, 0, sizeof(frm_data));
124         frm_data.admission_test = admission_test;
125         frm_data.priv = priv;
126
127         fcb = forb_resolve_reference(orb, fres_contract_broker_reg_name);
128         if (!fcb) {
129                 save_errno(ul_logerr("Could not find contract broker"));
130                 goto err;
131         }
132
133         frm = forb_fres_resource_manager_new(orb, &frm_impl, &frm_data);
134         if (!frm) {
135                 save_errno(ul_logerr("forb_fres_resource_manager_new error"));
136                 goto err_release_fcb;
137         }
138
139         /* Prepare executor before we register the resource manager
140          * with contract broker */
141         ret = forb_executor_init(&executor);
142         if (ret) goto err_release_frm;
143                 
144         ret = forb_executor_register_object(&executor, frm);
145         if (ret) goto err_executor;
146
147         /* Register resource manager */
148         fres_contract_broker_register_manager(fcb, FRSH_RT_PROCESSOR, 0,
149                                               frm, &env);
150         if (forb_exception_occured(&env)) {
151                 goto err_executor;
152         }
153
154         /* Start request processing */
155         ret = forb_executor_run(&executor);
156         if (ret) goto err_executor;
157         
158         return 0;
159 err_executor:
160         forb_executor_destroy(&executor);
161 err_release_frm:        
162         forb_object_release(frm);
163 err_release_fcb:        
164         forb_object_release(fcb);
165 err:
166         return -1;
167 }