Line data Source code
1 : /*
2 : START OF LICENSE STUB
3 : DeDOS: Declarative Dispersion-Oriented Software
4 : Copyright (C) 2017 University of Pennsylvania, Georgetown University
5 :
6 : This program is free software: you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation, either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : END OF LICENSE STUB
19 : */
20 : /**
21 : * @file msu_type.c
22 : *
23 : * Registration and location of msu types
24 : */
25 :
26 : #include "dfg.h"
27 : #include "msu_type.h"
28 : #include "logging.h"
29 : #include "msu_type_list.h"
30 :
31 : /**
32 : * MOVEME: MAX_TYPE_ID
33 : * This is the maximum ID that can be assigned to an MSU type
34 : */
35 : #define MAX_TYPE_ID 1000
36 :
37 : /**
38 : * Every MSU type that can be used. Defined in `msu_type_list.h`,
39 : * or overridden from previous definition
40 : */
41 : static struct msu_type *DEFINED_MSU_TYPES[] = MSU_TYPE_LIST;
42 :
43 : /**
44 : * The number of available MSU types
45 : */
46 : #define N_MSU_TYPES (sizeof(DEFINED_MSU_TYPES) / sizeof(struct msu_type*))
47 :
48 : /**
49 : * Pointers to MSU Types, indexed by ID
50 : */
51 : static struct msu_type *msu_types[MAX_TYPE_ID];
52 :
53 : /**
54 : * Regsiters an MSU type so that it can be later referenced by its ID
55 : * @param type MSU Type to be registered
56 : * @return 0 on success, -1 on error
57 : */
58 10 : static int register_msu_type(struct msu_type *type) {
59 10 : if (type->id > MAX_TYPE_ID) {
60 0 : log_error("MSU type %s not registered. Type ID %d too high. Max: %d",
61 : type->name, type->id, MAX_TYPE_ID);
62 0 : return -1;
63 : }
64 10 : msu_types[type->id] = type;
65 10 : log(LOG_MSU_TYPE_INIT, "Registered MSU type %s", type->name);
66 10 : return 0;
67 : }
68 :
69 0 : void destroy_msu_types() {
70 0 : for (int i=0; i < N_MSU_TYPES; i++) {
71 0 : struct msu_type *type = DEFINED_MSU_TYPES[i];
72 0 : if (msu_types[type->id] != NULL) {
73 0 : if (msu_types[type->id]->destroy_type != NULL) {
74 0 : msu_types[type->id]->destroy_type(type);
75 : }
76 : }
77 : }
78 0 : }
79 :
80 4 : struct msu_type *get_msu_type(int id) {
81 4 : if (id > MAX_TYPE_ID) {
82 0 : log_error("MSU type %d cannot be found Type ID too high. Max: %d",
83 : id, MAX_TYPE_ID);
84 0 : return NULL;
85 : }
86 4 : return msu_types[id];
87 : }
88 :
89 : /**
90 : * Checks whether the msu type has the required fields to be used.
91 : * (At the moment, the only required field is `receive`)
92 : * @return true/false
93 : */
94 13 : static bool has_required_fields(struct msu_type *type) {
95 13 : if (type->receive == NULL) {
96 2 : log_error("MSU type %s does not register a recieve function",
97 : type->name);
98 2 : return false;
99 : }
100 11 : return true;
101 : }
102 :
103 : /**
104 : * Initializes a specific MSU type, calling its init function
105 : * and registering it for future calls
106 : * @param type The type of MSU to be registered
107 : * @return 0 on success, -1 on error
108 : */
109 10 : static int init_msu_type(struct msu_type *type) {
110 10 : if (!has_required_fields(type)) {
111 1 : log_error("Not registering MSU type %s due to missing fields",
112 : type->name);
113 1 : return -1;
114 : }
115 9 : if (type->init_type) {
116 2 : if (type->init_type(type) != 0) {
117 0 : log_error("MSU Type %s not initialized: failed custom constructor",
118 : type->name);
119 0 : return -1;
120 : } else {
121 2 : log(LOG_MSU_TYPE_INIT, "Initialized msu type %s", type->name);
122 : }
123 : }
124 9 : if (register_msu_type(type) != 0) {
125 0 : log_error("MSU type %s not registered", type->name);
126 0 : return -1;
127 : }
128 9 : return 0;
129 : }
130 :
131 :
132 9 : int init_msu_type_id(unsigned int type_id) {
133 9 : log(TEST, "Number of MSU types: %d", (int)N_MSU_TYPES);
134 16 : for (int i=0; i<N_MSU_TYPES; i++) {
135 15 : struct msu_type *type = DEFINED_MSU_TYPES[i];
136 15 : if (type->id == type_id) {
137 8 : return init_msu_type(type);
138 : }
139 : }
140 1 : log_error("MSU Type ID %u not found!", type_id);
141 1 : return -1;
142 : }
|