Subversion Repositories HelenOS

Rev

Rev 3474 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3438 svoboda 1
/*
2
 * Copyright (c) 2008 Jiri Svoboda
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
/** @addtogroup trace
30
 * @{
31
 */
32
/** @file
33
 */
34
 
35
#include <stdio.h>
36
#include <stdlib.h>
37
#include <ipc/ipc.h>
4691 svoboda 38
#include <adt/hash_table.h>
3438 svoboda 39
 
3474 svoboda 40
#include "trace.h"
3438 svoboda 41
#include "proto.h"
42
 
43
#define SRV_PROTO_TABLE_CHAINS 32
44
#define METHOD_OPER_TABLE_CHAINS 32
45
 
46
hash_table_t srv_proto;
47
 
48
typedef struct {
4691 svoboda 49
    unsigned srv;
3438 svoboda 50
    proto_t *proto;
51
    link_t link;
52
} srv_proto_t;
53
 
54
typedef struct {
55
    ipcarg_t method;
56
    oper_t *oper;
57
    link_t link;
58
} method_oper_t;
59
 
60
static hash_index_t srv_proto_hash(unsigned long key[]);
61
static int srv_proto_compare(unsigned long key[], hash_count_t keys,
62
    link_t *item);
63
static void srv_proto_remove_callback(link_t *item);
64
 
65
hash_table_operations_t srv_proto_ops = {
66
    .hash = srv_proto_hash,
67
    .compare = srv_proto_compare,
68
    .remove_callback = srv_proto_remove_callback
69
};
70
 
71
static hash_index_t method_oper_hash(unsigned long key[]);
72
static int method_oper_compare(unsigned long key[], hash_count_t keys,
73
    link_t *item);
74
static void method_oper_remove_callback(link_t *item);
75
 
76
hash_table_operations_t method_oper_ops = {
77
    .hash = method_oper_hash,
78
    .compare = method_oper_compare,
79
    .remove_callback = method_oper_remove_callback
80
};
81
 
82
static hash_index_t srv_proto_hash(unsigned long key[])
83
{
84
    return key[0] % SRV_PROTO_TABLE_CHAINS;
85
}
86
 
87
static int srv_proto_compare(unsigned long key[], hash_count_t keys,
88
    link_t *item)
89
{
90
    srv_proto_t *sp;
91
 
92
    sp = hash_table_get_instance(item, srv_proto_t, link);
93
 
94
    return key[0] == sp->srv;
95
}
96
 
97
static void srv_proto_remove_callback(link_t *item)
98
{
99
}
100
 
101
static hash_index_t method_oper_hash(unsigned long key[])
102
{
103
    return key[0] % METHOD_OPER_TABLE_CHAINS;
104
}
105
 
106
static int method_oper_compare(unsigned long key[], hash_count_t keys,
107
    link_t *item)
108
{
109
    method_oper_t *mo;
110
 
111
    mo = hash_table_get_instance(item, method_oper_t, link);
112
 
113
    return key[0] == mo->method;
114
}
115
 
116
static void method_oper_remove_callback(link_t *item)
117
{
118
}
119
 
120
 
121
void proto_init(void)
122
{
123
    hash_table_create(&srv_proto, SRV_PROTO_TABLE_CHAINS, 1,
124
        &srv_proto_ops);
125
}
126
 
127
void proto_cleanup(void)
128
{
129
    hash_table_destroy(&srv_proto);
130
}
131
 
132
void proto_register(int srv, proto_t *proto)
133
{
134
    srv_proto_t *sp;
135
    unsigned long key;
136
 
137
    sp = malloc(sizeof(srv_proto_t));
138
    sp->srv = srv;
139
    sp->proto = proto;
140
    key = srv;
141
 
142
    hash_table_insert(&srv_proto, &key, &sp->link);
143
}
144
 
145
proto_t *proto_get_by_srv(int srv)
146
{
147
    unsigned long key;
148
    link_t *item;
149
    srv_proto_t *sp;
150
 
151
    key = srv;
152
    item = hash_table_find(&srv_proto, &key);
153
    if (item == NULL) return NULL;
154
 
155
    sp = hash_table_get_instance(item, srv_proto_t, link);
156
    return sp->proto;
157
}
158
 
159
static void proto_struct_init(proto_t *proto, char *name)
160
{
161
    proto->name = name;
162
    hash_table_create(&proto->method_oper, SRV_PROTO_TABLE_CHAINS, 1,
163
        &method_oper_ops);
164
}
165
 
166
proto_t *proto_new(char *name)
167
{
168
    proto_t *p;
169
 
170
    p = malloc(sizeof(proto_t));
171
    proto_struct_init(p, name);
172
 
173
    return p;
174
}
175
 
3443 svoboda 176
void proto_delete(proto_t *proto)
177
{
178
    free(proto);
179
}
180
 
3438 svoboda 181
void proto_add_oper(proto_t *proto, int method, oper_t *oper)
182
{
183
    method_oper_t *mo;
184
    unsigned long key;
185
 
186
    mo = malloc(sizeof(method_oper_t));
187
    mo->method = method;
188
    mo->oper = oper;
189
    key = method;
190
 
191
    hash_table_insert(&proto->method_oper, &key, &mo->link);   
192
}
193
 
194
oper_t *proto_get_oper(proto_t *proto, int method)
195
{
196
    unsigned long key;
197
    link_t *item;
198
    method_oper_t *mo;
199
 
200
    key = method;
201
    item = hash_table_find(&proto->method_oper, &key);
202
    if (item == NULL) return NULL;
203
 
204
    mo = hash_table_get_instance(item, method_oper_t, link);
205
    return mo->oper;
206
}
207
 
208
static void oper_struct_init(oper_t *oper, char *name)
209
{
210
    oper->name = name;
211
}
212
 
3474 svoboda 213
oper_t *oper_new(char *name, int argc, val_type_t *arg_types,
214
    val_type_t rv_type, int respc, val_type_t *resp_types)
3438 svoboda 215
{
216
    oper_t *o;
3474 svoboda 217
    int i;
3438 svoboda 218
 
219
    o = malloc(sizeof(oper_t));
220
    oper_struct_init(o, name);
221
 
3474 svoboda 222
    o->argc = argc;
223
    for (i = 0; i < argc; i++)
224
        o->arg_type[i] = arg_types[i];
225
 
226
    o->rv_type = rv_type;
227
 
228
    o->respc = respc;
229
    for (i = 0; i < respc; i++)
230
        o->resp_type[i] = resp_types[i];
231
 
3438 svoboda 232
    return o;
233
}
234
 
235
/** @}
236
 */