select.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <l4/sys/types.h>
00014 #include <l4/env/errno.h>
00015 #include <l4/util/macros.h>
00016 #include <l4/thread/thread.h>
00017 #include <l4/semaphore/semaphore.h>
00018
00019
00020 #include <l4/dsi/dsi.h>
00021 #include "__event.h"
00022 #include "__stream.h"
00023 #include "__thread.h"
00024 #include "__debug.h"
00025
00026
00027
00028
00029
00030
00031
00032
00033 typedef struct dsi_select_thread_arg
00034 {
00035
00036 l4_uint32_t events;
00037 dsi_socket_ref_t * socket;
00038 l4semaphore_t * sem;
00039
00040
00041 l4_uint32_t mask;
00042 int error;
00043 } dsi_select_thread_arg_t;
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 static void
00054 __select_thread(void * data)
00055 {
00056 dsi_select_thread_arg_t * args = (dsi_select_thread_arg_t *)data;
00057 l4_int32_t mask;
00058
00059 LOGdL(DEBUG_SELECT,"signalling thread "l4util_idfmt,
00060 l4util_idstr(args->socket->event_th));
00061 LOGdL(DEBUG_SELECT,"socket %d, events 0x%08x",
00062 args->socket->socket,args->events);
00063
00064
00065 mask = dsi_event_wait(args->socket->event_th,args->socket->socket,
00066 args->events);
00067
00068 LOGdL(DEBUG_SELECT,"mask = 0x%08x",mask);
00069
00070 if (mask < 0)
00071 args->error = mask;
00072 else
00073 {
00074 args->mask = mask;
00075 args->error = 0;
00076 }
00077
00078
00079 l4semaphore_up(args->sem);
00080
00081
00082
00083
00084
00085
00086 l4thread_sleep(300000);
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 int
00126 dsi_stream_select(dsi_select_socket_t *sockets, const int num_sockets,
00127 dsi_select_socket_t *events, int * num_events)
00128 {
00129 dsi_select_thread_arg_t args[num_sockets];
00130 l4thread_t threads[num_sockets];
00131 l4semaphore_t sem = L4SEMAPHORE_LOCKED;
00132 int i,j,error,ret;
00133 l4thread_t me = l4thread_myself();
00134
00135
00136 for (i = 0; i < num_sockets; i++)
00137 {
00138 if (!dsi_is_valid_stream(sockets[i].stream))
00139 return -L4_EINVAL;
00140
00141 args[i].events = sockets[i].events;
00142 if (sockets[i].component & DSI_SEND_COMPONENT)
00143 args[i].socket = &sockets[i].stream->sender.socketref;
00144 else
00145 args[i].socket = &sockets[i].stream->receiver.socketref;
00146 args[i].sem = &sem;
00147 args[i].mask = 0;
00148 args[i].error = 0;
00149 }
00150
00151
00152 for (i = 0; i < num_sockets; i++)
00153 {
00154 threads[i] = dsi_create_select_thread(__select_thread, &args[i],
00155 me ,i);
00156 if (threads[i] == L4THREAD_INVALID_ID)
00157 {
00158
00159 for (j = 0; j < i; j++)
00160 dsi_shutdown_select_thread(threads[j]);
00161 return -L4_ENOTHREAD;
00162 }
00163 }
00164
00165
00166 l4semaphore_down(&sem);
00167
00168
00169 error = 0;
00170 for (i = 0; i < num_sockets; i++)
00171 {
00172
00173 dsi_shutdown_select_thread(threads[i]);
00174
00175
00176 error = args[i].error;
00177 }
00178
00179 if (error)
00180 {
00181 LOG_Error("DSI: select error %d",error);
00182 return error;
00183 }
00184
00185
00186 j = 0;
00187 for (i = 0; i < num_sockets; i++)
00188 {
00189 LOGdL(DEBUG_SELECT,"%d, mask=0x%08x, error = %d",
00190 i, args[i].mask, args[i].error);
00191
00192 if (args[i].mask)
00193 {
00194
00195 events[j].stream = sockets[i].stream;
00196 events[j].component = sockets[i].component;
00197 events[j].events = args[i].mask;
00198
00199 LOGdL(DEBUG_SELECT,"events %08x <= %08x", events[j].events, args[i].mask);
00200 LOGdL(DEBUG_SELECT,"reset 0x%08x at "l4util_idfmt,
00201 args[i].mask, l4util_idstr(args[i].socket->event_th));
00202
00203
00204 ret = dsi_event_reset(args[i].socket->event_th,
00205 args[i].socket->socket,args[i].mask);
00206 if (ret)
00207 {
00208 LOG_Error("DSI: reset events failed: %s (%d)",
00209 l4env_errstr(ret),ret);
00210 }
00211 j++;
00212 }
00213 }
00214
00215 *num_events = j;
00216
00217
00218 return error;
00219 }