source: mainline/uspace/srv/sysman/configuration.c@ 4224ef7

Last change on this file since 4224ef7 was dda2602, checked in by Matthieu Riolo <matthieu.riolo@…>, 6 years ago

sysman: Create units to start up to compositor

  • add necessary units to support basic GUI (barber, vterm)
  • lacking autostart is compensated with explicit dependencies
  • IPC_FLAG_AUTOSTART in compositor and locsrv fix
  • paths to v* binaries
  • refactored job closure creation

Conflicts:

boot/Makefile.common
uspace/app/vlaunch/vlaunch.c
uspace/srv/hid/compositor/compositor.c
uspace/srv/locsrv/locsrv.c

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/*
2 * Copyright (c) 2015 Michal Koutny
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <adt/hash.h>
30#include <adt/hash_table.h>
31#include <adt/list.h>
32#include <assert.h>
33#include <errno.h>
34#include <fibril_synch.h>
35
36#include "configuration.h"
37#include "dep.h"
38#include "log.h"
39
40LIST_INITIALIZE(units);
41
42static hash_table_t units_by_name;
43
44/* Hash table functions */
45static size_t units_by_name_ht_hash(const ht_link_t *item)
46{
47 unit_t *unit =
48 hash_table_get_inst(item, unit_t, units_by_name);
49 return hash_string(unit->name);
50}
51
52static size_t units_by_name_ht_key_hash(void *key)
53{
54 return hash_string((const char *)key);
55}
56
57static bool units_by_name_ht_equal(const ht_link_t *item1, const ht_link_t *item2)
58{
59 return str_cmp(
60 hash_table_get_inst(item1, unit_t, units_by_name)->name,
61 hash_table_get_inst(item2, unit_t, units_by_name)->name) == 0;
62}
63
64static bool units_by_name_ht_key_equal(void *key, const ht_link_t *item)
65{
66 return str_cmp((const char *)key,
67 hash_table_get_inst(item, unit_t, units_by_name)->name) == 0;
68}
69
70
71static hash_table_ops_t units_by_name_ht_ops = {
72 .hash = &units_by_name_ht_hash,
73 .key_hash = &units_by_name_ht_key_hash,
74 .equal = &units_by_name_ht_equal,
75 .key_equal = &units_by_name_ht_key_equal,
76 .remove_callback = NULL // TODO realy unneeded?
77};
78
79/* Configuration functions */
80
81void configuration_init(void)
82{
83 hash_table_create(&units_by_name, 0, 0, &units_by_name_ht_ops);
84}
85
86int configuration_add_unit(unit_t *unit)
87{
88 assert(unit);
89 assert(unit->state == STATE_EMBRYO);
90 assert(unit->name != NULL);
91 sysman_log(LVL_DEBUG2, "%s('%s')", __func__, unit_name(unit));
92
93 if (hash_table_insert_unique(&units_by_name, &unit->units_by_name)) {
94 list_append(&unit->units, &units);
95 return EOK;
96 } else {
97 return EEXISTS;
98 }
99}
100
101void configuration_start_update(void) {
102 sysman_log(LVL_DEBUG2, "%s", __func__);
103}
104
105static bool configuration_commit_unit(ht_link_t *ht_link, void *arg)
106{
107 unit_t *unit = hash_table_get_inst(ht_link, unit_t, units_by_name);
108 // TODO state locking?
109 if (unit->state == STATE_EMBRYO) {
110 unit->state = STATE_STOPPED;
111 }
112
113 list_foreach(unit->dependencies, dependencies, unit_dependency_t, dep) {
114 if (dep->state == DEP_EMBRYO) {
115 dep->state = DEP_VALID;
116 }
117 }
118 return true;
119}
120
121/** Marks newly added units_by_name as usable (via state change) */
122void configuration_commit(void)
123{
124 sysman_log(LVL_DEBUG2, "%s", __func__);
125
126 /*
127 * Apply commit to all units_by_name, each commited unit commits its outgoing
128 * deps, thus eventually commiting all embryo deps as well.
129 */
130 hash_table_apply(&units_by_name, &configuration_commit_unit, NULL);
131}
132
133static bool configuration_rollback_unit(ht_link_t *ht_link, void *arg)
134{
135 unit_t *unit = hash_table_get_inst(ht_link, unit_t, units_by_name);
136
137 list_foreach_safe(unit->dependencies, cur_link, next_link) {
138 unit_dependency_t *dep =
139 list_get_instance(cur_link, unit_dependency_t, dependencies);
140 if (dep->state == DEP_EMBRYO) {
141 dep_remove_dependency(&dep);
142 }
143 }
144
145 if (unit->state == STATE_EMBRYO) {
146 hash_table_remove_item(&units_by_name, ht_link);
147 list_remove(&unit->units);
148 unit_destroy(&unit);
149 }
150
151 return true;
152}
153
154/** Remove all uncommited units_by_name and edges from configuratio
155 *
156 * Memory used by removed object is released.
157 */
158void configuration_rollback(void)
159{
160 sysman_log(LVL_DEBUG2, "%s", __func__);
161
162 hash_table_apply(&units_by_name, &configuration_rollback_unit, NULL);
163}
164
165static bool configuration_resolve_unit(ht_link_t *ht_link, void *arg)
166{
167 bool *has_error_ptr = arg;
168 unit_t *unit = hash_table_get_inst(ht_link, unit_t, units_by_name);
169
170 list_foreach(unit->dependencies, dependencies, unit_dependency_t, dep) {
171 assert(dep->dependant == unit);
172 assert((dep->dependency != NULL) != (dep->dependency_name != NULL));
173 if (dep->dependency) {
174 continue;
175 }
176
177 unit_t *dependency =
178 configuration_find_unit_by_name(dep->dependency_name);
179 if (dependency == NULL) {
180 sysman_log(LVL_ERROR,
181 "Cannot resolve dependency of '%s' to unit '%s'",
182 unit_name(unit), dep->dependency_name);
183 *has_error_ptr = true;
184 // TODO should we just leave the sprout untouched?
185 } else {
186 dep_resolve_dependency(dep, dependency);
187 }
188 }
189
190 return true;
191}
192
193/** Resolve unresolved dependencies between any pair of units_by_name
194 *
195 * @return EOK on success
196 * @return ENOENT when one or more resolution fails, information is logged
197 */
198int configuration_resolve_dependecies(void)
199{
200 sysman_log(LVL_DEBUG2, "%s", __func__);
201
202 bool has_error = false;
203 hash_table_apply(&units_by_name, &configuration_resolve_unit, &has_error);
204
205 return has_error ? ENOENT : EOK;
206}
207
208unit_t *configuration_find_unit_by_name(const char *name)
209{
210 ht_link_t *ht_link = hash_table_find(&units_by_name, (void *)name);
211 if (ht_link != NULL) {
212 return hash_table_get_inst(ht_link, unit_t, units_by_name);
213 } else {
214 return NULL;
215 }
216}
217
Note: See TracBrowser for help on using the repository browser.