app.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <l4/sys/types.h>
00015 #include <l4/sys/consts.h>
00016 #include <l4/env/errno.h>
00017 #include <l4/util/atomic.h>
00018 #include <l4/util/macros.h>
00019
00020
00021 #include <l4/dsi/dsi.h>
00022 #include "__event.h"
00023 #include "__stream.h"
00024 #include "__config.h"
00025 #include "__debug.h"
00026 #include "__app.h"
00027
00028
00029
00030
00031
00032
00033 static dsi_stream_t streams[DSI_MAX_STREAMS];
00034
00035
00036 static int next_stream;
00037
00038
00039
00040
00041 void
00042 dsi_init_streams(void)
00043 {
00044 int i;
00045
00046 for (i = 0; i < DSI_MAX_STREAMS; i++)
00047 streams[i].flags = DSI_STREAM_UNUSED;
00048 }
00049
00050
00051
00052
00053
00054
00055 static dsi_stream_t *
00056 __allocate_stream(void)
00057 {
00058 int i = next_stream;
00059
00060
00061 do
00062 {
00063 if (l4util_cmpxchg32(&streams[i].flags,
00064 DSI_STREAM_UNUSED,DSI_STREAM_USED))
00065 {
00066
00067 next_stream = (i + 1) % DSI_MAX_STREAMS;
00068 break;
00069 }
00070
00071 i = (i + 1) % DSI_MAX_STREAMS;
00072 }
00073 while (i != next_stream);
00074
00075 if (i == next_stream)
00076 return NULL;
00077 else
00078 return &streams[i];
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088 int
00089 dsi_is_valid_stream(dsi_stream_t * stream)
00090 {
00091 if (stream == NULL)
00092 return 0;
00093
00094 return ((stream >= streams) &&
00095 (stream < &streams[DSI_MAX_STREAMS]) &&
00096 (stream->flags != DSI_STREAM_UNUSED));
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106 static int
00107 dsi_is_valid_component(dsi_component_t * component)
00108 {
00109 if (component == NULL)
00110 return 0;
00111
00112 return ((!l4_is_invalid_id(component->socketref.work_th)) &&
00113 (!l4_is_invalid_id(component->socketref.sync_th)) &&
00114 (component->connect != NULL));
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 int
00132 dsi_stream_create(dsi_component_t * sender, dsi_component_t * receiver,
00133 l4dm_dataspace_t ctrl, l4dm_dataspace_t data,
00134 dsi_stream_t ** stream)
00135 {
00136 int ret;
00137 dsi_stream_t * s;
00138
00139 *stream = NULL;
00140
00141
00142 if (!dsi_is_valid_component(sender))
00143 {
00144 LOG_Error("DSI: invalid send component");
00145 return -L4_EINVAL;
00146 }
00147
00148 if (!dsi_is_valid_component(receiver))
00149 {
00150 LOG_Error("DSI: invalid receive component");
00151 return -L4_EINVAL;
00152 }
00153
00154 if (l4dm_is_invalid_ds(ctrl))
00155 {
00156 LOG_Error("DSI: invalid control area");
00157 return -L4_EINVAL;
00158 }
00159
00160 if (l4dm_is_invalid_ds(data))
00161 {
00162 LOG_Error("DSI: invalid data area");
00163 return -L4_EINVAL;
00164 }
00165
00166
00167 s = __allocate_stream();
00168 if (s == NULL)
00169 {
00170
00171 LOG_Error("DSI: no stream descriptor available!");
00172 return -DSI_ENOSTREAM;
00173 }
00174
00175
00176 ret = sender->connect(sender,&receiver->socketref);
00177 if (ret)
00178 {
00179 LOG_Error("DSI: connect sender failed: %s (%d)",
00180 l4env_errstr(ret),ret);
00181 s->flags = DSI_STREAM_UNUSED;
00182 return -DSI_ECONNECT;
00183 }
00184
00185 ret = receiver->connect(receiver,&sender->socketref);
00186 if (ret)
00187 {
00188 LOG_Error("DSI: connect receiver failed: %s (%d)",
00189 l4env_errstr(ret),ret);
00190 s->flags = DSI_STREAM_UNUSED;
00191 return -DSI_ECONNECT;
00192 }
00193
00194
00195 s->sender = *sender;
00196 s->receiver = *receiver;
00197 s->ctrl = ctrl;
00198 s->data = data;
00199 s->__private = NULL;
00200
00201 *stream = s;
00202
00203
00204 return 0;
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 int
00224 dsi_stream_start(dsi_stream_t * stream)
00225 {
00226 int ret;
00227
00228
00229 if (!dsi_is_valid_stream(stream))
00230 return -L4_EINVAL;
00231
00232
00233 if (stream->receiver.start != NULL)
00234 {
00235 ret = stream->receiver.start(&stream->receiver);
00236 if (ret)
00237 {
00238 LOG_Error("DSI: start receiver failed: %s (%d)",
00239 l4env_errstr(ret),ret);
00240 return ret;
00241 }
00242 }
00243
00244
00245 if (stream->sender.start != NULL)
00246 {
00247 ret = stream->sender.start(&stream->sender);
00248 if (ret)
00249 {
00250 LOG_Error("DSI: start sender failed: %s (%d)",
00251 l4env_errstr(ret),ret);
00252 return ret;
00253 }
00254 }
00255
00256
00257 return 0;
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 int
00274 dsi_stream_stop(dsi_stream_t * stream)
00275 {
00276 int ret;
00277
00278
00279 if (!dsi_is_valid_stream(stream))
00280 return -L4_EINVAL;
00281
00282
00283 LOGdL(DEBUG_STREAM,"calling sender (%x) to stop...",
00284 stream->sender.socketref.work_th.id.task);
00285
00286 if (stream->sender.stop != NULL){
00287 ret = stream->sender.stop(&stream->sender);
00288 if (ret)
00289 {
00290 LOG_Error("DSI: stop sender failed: %s (%d)",
00291 l4env_errstr(ret),ret);
00292 return ret;
00293 }
00294 }
00295
00296
00297 LOGdL(DEBUG_STREAM,"calling receiver (%x) to stop...",
00298 stream->receiver.socketref.work_th.id.task);
00299
00300 if (stream->receiver.stop != NULL){
00301 ret = stream->receiver.stop(&stream->receiver);
00302 if (ret)
00303 {
00304 LOG_Error("DSI: stop receiver failed: %s (%d)",
00305 l4env_errstr(ret),ret);
00306 return ret;
00307 }
00308 }
00309
00310
00311 return 0;
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 int
00335 dsi_stream_close(dsi_stream_t * stream)
00336 {
00337 int ret;
00338 int error = 0;
00339
00340
00341 if (!dsi_is_valid_stream(stream))
00342 return -L4_EINVAL;
00343
00344
00345 if (stream->sender.close == NULL)
00346 {
00347 LOG_Error("DSI: missing send components close function");
00348 return -L4_EINVAL;
00349 }
00350 if (stream->receiver.close == NULL)
00351 {
00352 LOG_Error("DSI: missing receive components close function");
00353 return -L4_EINVAL;
00354 }
00355
00356
00357 if (stream->sender.stop != NULL)
00358 {
00359 LOGdL(DEBUG_STREAM,"calling sender (%x) to stop...",
00360 stream->sender.socketref.work_th.id.task);
00361
00362 ret = stream->sender.stop(&stream->sender);
00363 if (ret)
00364 {
00365 LOG_Error("DSI: stop sender's failed: %s (%d)",
00366 l4env_errstr(ret),ret);
00367 error = -DSI_ECOMPONENT;
00368 }
00369 LOGdL(DEBUG_STREAM,"sender stop returned");
00370 }
00371
00372
00373 if (stream->receiver.stop != NULL)
00374 {
00375 LOGdL(DEBUG_STREAM,"calling receiver (%x) to stop...",
00376 stream->receiver.socketref.work_th.id.task);
00377
00378 ret = stream->receiver.stop(&stream->receiver);
00379 if (ret)
00380 {
00381 LOG_Error("DSI: stop receiver's failed: %s (%d)",
00382 l4env_errstr(ret),ret);
00383 error = -DSI_ECOMPONENT;
00384 }
00385 LOGdL(DEBUG_STREAM,"receiver stop returned");
00386 }
00387
00388
00389 LOGdL(DEBUG_STREAM,"calling sender (%x) to close...",
00390 stream->sender.socketref.work_th.id.task);
00391
00392 ret = stream->sender.close(&stream->sender);
00393 if (ret)
00394 {
00395 LOG_Error("DSI: close sender's socket failed: %s (%d)",
00396 l4env_errstr(ret),ret);
00397 error = -DSI_ECOMPONENT;
00398 }
00399 LOGdL(DEBUG_STREAM,"sender close returned");
00400
00401
00402 LOGdL(DEBUG_STREAM,"calling receiver (%x) to close...",
00403 stream->receiver.socketref.work_th.id.task);
00404
00405 ret = stream->receiver.close(&stream->receiver);
00406 if (ret)
00407 {
00408 LOG_Error("DSI: close receiver's socket failed: %s (%d)",
00409 l4env_errstr(ret),ret);
00410 error = -DSI_ECOMPONENT;
00411 }
00412 LOGdL(DEBUG_STREAM,"receiver close returned");
00413
00414
00415 stream->flags = DSI_STREAM_UNUSED;
00416
00417
00418 return error;
00419 }