]> rtime.felk.cvut.cz Git - frescor/frsh.git/blob - fres/resmng/frm_generic.c
Added some error messages
[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 *reserved;
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         bool schedulable;
26         int i;
27
28         ul_logmsg("reserve_contracts\n");
29         
30         prospective = fres_sa_scenario_duplicate(frm->reserved);
31         if (!prospective) goto err;
32         for (i=0; i<contracts->_length; i++) {
33                 struct fres_sa_contract *c;
34                 c = fres_sa_contract_new();
35                 if (!c) goto err;
36                 c->status = FRES_SA_CONTRACT_NEW;
37                 c->contract = fres_contract_duplicate(contracts->_buffer[i]);
38                 if (!c->contract) goto err;
39                 fres_sa_scenario_add_contract(prospective, c);
40         }
41
42         schedulable = frm->admission_test(prospective, frm->priv);
43
44         if (schedulable) {
45                 struct fres_sa_contract *c;
46                 fres_sa_scenario_for_each_contract(prospective, c) {
47                         if (c->status == FRES_SA_CONTRACT_NEW) {
48                                 c->status = FRES_SA_CONTRACT_RESERVED;
49                         }
50                 }
51                 fres_sa_scenario_destroy(frm->reserved);
52                 frm->reserved = prospective;
53         } else {
54                 fres_sa_scenario_destroy(prospective);
55         }
56         return schedulable ? 0 : 1;
57 err:
58         fres_sa_scenario_destroy(prospective);
59         return -1;
60 }
61
62 static void commit_contracts(fres_resource_manager obj,
63                       const fres_contract_id_seq* ids,
64                       fres_contract_ptr_seq** contracts_with_scheduling_data,
65                       CORBA_Environment *ev)
66 {
67         struct frm_data *frm = object_to_frm(obj);
68         int i, num;
69         struct fres_sa_contract *c;
70         fres_contract_ptr_seq *contracts;
71
72         ul_logmsg("commit_contracts\n");
73
74         contracts = forb_malloc(sizeof(*contracts));
75         if (!contracts) {
76                 ev->major = FORB_EX_NO_MEMORY;
77                 goto err;
78         }
79         num = ids->_length;
80         contracts->_buffer = CORBA_sequence_fres_contract_ptr_allocbuf(num);
81         CORBA_sequence_set_release(contracts, CORBA_TRUE);
82         contracts->_maximum = contracts->_length = num;
83         
84         for (i=0; i < num; i++) {
85                 c = fres_sa_scenario_find_contract(frm->reserved, &ids->_buffer[i]);
86                 c->status = FRES_SA_CONTRACT_COMMITED;
87                 contracts->_buffer[i] = c->contract;
88         }
89         
90         *contracts_with_scheduling_data = contracts;
91 err:;
92 }
93
94 static void cancel_contracts(fres_resource_manager obj,
95                       const fres_contract_id_seq* ids,
96                       CORBA_Environment *ev)
97 {
98         int i;
99         struct frm_data *frm = object_to_frm(obj);
100
101         ul_logmsg("cancel_contracts\n");
102
103         for (i=0; i<ids->_length; i++) {
104                 struct fres_sa_contract *c;
105                 c = fres_sa_scenario_find_contract(frm->reserved, &ids->_buffer[i]);
106
107                 if (c) {
108                         fres_sa_scenario_del_contract(frm->reserved, c);
109                 }
110         }
111 }
112
113
114 static const struct forb_fres_resource_manager_impl frm_impl = {
115         .reserve_contracts = reserve_contracts,
116         .commit_contracts  = commit_contracts,
117         .cancel_contracts  = cancel_contracts,
118 };
119
120 /** 
121  * Initializes and runs a generic resource manager. The only thing a
122  * caller has to supply is admission test function, which is passed in
123  * @a frm_data->admission_test.
124  * 
125  * @param orb FORB object used to communicate with other components.
126  * @param admission_test Admission test function.
127  * @param priv Pointer to passed as priv parameter to frm_adm_test_fnc_t.
128  * 
129  * @return 
130  */
131 int frm_register_and_run(forb_orb orb, const struct fres_res_manager *res_manager)
132 {
133         fres_contract_broker fcb;
134         fres_resource_manager frm;
135         struct forb_env env;
136         struct frm_data frm_data;
137         forb_executor_t executor;
138         int ret;
139
140         memset(&frm_data, 0, sizeof(frm_data));
141         frm_data.admission_test = res_manager->admission_test;
142         frm_data.priv = res_manager->priv;
143         frm_data.reserved = fres_sa_scenario_new();
144         if (!frm_data.reserved) {
145                 save_errno(ul_logerr("fres_sa_scenario_new failed\n"));
146                 goto err;
147         }
148
149         fcb = forb_resolve_reference(orb, fres_contract_broker_reg_name);
150         if (!fcb) {
151                 save_errno(ul_logerr("Could not find contract broker"));
152                 goto err;
153         }
154
155         frm = forb_fres_resource_manager_new(orb, &frm_impl, &frm_data);
156         if (!frm) {
157                 save_errno(ul_logerr("forb_fres_resource_manager_new error"));
158                 goto err_release_fcb;
159         }
160
161         /* Prepare executor before we register the resource manager
162          * with contract broker */
163         ret = forb_executor_init(&executor);
164         if (ret) {
165                 save_errno(ul_logerr("forb_executor_init failed"));
166                 goto err_release_frm;
167         }
168                 
169         ret = forb_executor_register_object(&executor, frm);
170         if (ret) {
171                 save_errno(ul_logerr("forb_executor_register_object failed"));
172                 goto err_executor;
173         }
174
175         /* Register resource manager */
176         ret = fres_contract_broker_register_manager(fcb,
177                                                     res_manager->res_type,
178                                                     res_manager->res_id,
179                                                     frm, &env);
180         if (forb_exception_occured(&env) || ret != 0) {
181                 save_errno(ul_logerr("fres_contract_broker_register_manager exception\n"));
182                 goto err_executor;
183         }
184
185         /* Start request processing */
186         ul_logmsg("Waiting for requests\n");
187         ret = forb_executor_run(&executor);
188         if (ret) goto err_executor;
189         
190         return 0;
191 err_executor:
192         forb_executor_destroy(&executor);
193 err_release_frm:        
194         forb_object_release(frm);
195 err_release_fcb:        
196         forb_object_release(fcb);
197 err:
198         return -1;
199 }