#include "spebase.h"
Go to the source code of this file.
typedef struct spe_context_event_priv * spe_context_event_priv_ptr_t |
typedef struct spe_context_event_priv spe_context_event_priv_t |
enum __spe_event_types |
__SPE_EVENT_OUT_INTR_MBOX | |
__SPE_EVENT_IN_MBOX | |
__SPE_EVENT_TAG_GROUP | |
__SPE_EVENT_SPE_STOPPED | |
__NUM_SPE_EVENT_TYPES |
Definition at line 28 of file speevent.h.
00028 { 00029 __SPE_EVENT_OUT_INTR_MBOX, __SPE_EVENT_IN_MBOX, 00030 __SPE_EVENT_TAG_GROUP, __SPE_EVENT_SPE_STOPPED, 00031 __NUM_SPE_EVENT_TYPES 00032 };
int _event_spe_context_finalize | ( | spe_context_ptr_t | spe | ) |
Definition at line 416 of file spe_event.c.
References __SPE_EVENT_CONTEXT_PRIV_GET, __SPE_EVENT_CONTEXT_PRIV_SET, spe_context_event_priv::lock, spe_context_event_priv::stop_event_pipe, and spe_context_event_priv::stop_event_read_lock.
00417 { 00418 spe_context_event_priv_ptr_t evctx; 00419 00420 if (!spe) { 00421 errno = ESRCH; 00422 return -1; 00423 } 00424 00425 evctx = __SPE_EVENT_CONTEXT_PRIV_GET(spe); 00426 __SPE_EVENT_CONTEXT_PRIV_SET(spe, NULL); 00427 00428 close(evctx->stop_event_pipe[0]); 00429 close(evctx->stop_event_pipe[1]); 00430 00431 pthread_mutex_destroy(&evctx->lock); 00432 pthread_mutex_destroy(&evctx->stop_event_read_lock); 00433 00434 free(evctx); 00435 00436 return 0; 00437 }
struct spe_context_event_priv* _event_spe_context_initialize | ( | spe_context_ptr_t | spe | ) | [read] |
Definition at line 439 of file spe_event.c.
References spe_context_event_priv::events, spe_context_event_priv::lock, spe_event_unit::spe, spe_context_event_priv::stop_event_pipe, and spe_context_event_priv::stop_event_read_lock.
00440 { 00441 spe_context_event_priv_ptr_t evctx; 00442 int rc; 00443 int i; 00444 00445 evctx = calloc(1, sizeof(*evctx)); 00446 if (!evctx) { 00447 return NULL; 00448 } 00449 00450 rc = pipe(evctx->stop_event_pipe); 00451 if (rc == -1) { 00452 free(evctx); 00453 return NULL; 00454 } 00455 rc = fcntl(evctx->stop_event_pipe[0], F_GETFL); 00456 if (rc != -1) { 00457 rc = fcntl(evctx->stop_event_pipe[0], F_SETFL, rc | O_NONBLOCK); 00458 } 00459 if (rc == -1) { 00460 close(evctx->stop_event_pipe[0]); 00461 close(evctx->stop_event_pipe[1]); 00462 free(evctx); 00463 errno = EIO; 00464 return NULL; 00465 } 00466 00467 for (i = 0; i < sizeof(evctx->events) / sizeof(evctx->events[0]); i++) { 00468 evctx->events[i].spe = spe; 00469 } 00470 00471 pthread_mutex_init(&evctx->lock, NULL); 00472 pthread_mutex_init(&evctx->stop_event_read_lock, NULL); 00473 00474 return evctx; 00475 }
void _event_spe_context_lock | ( | spe_context_ptr_t | spe | ) |
Definition at line 49 of file spe_event.c.
References __SPE_EVENT_CONTEXT_PRIV_GET.
Referenced by _event_spe_event_handler_deregister(), _event_spe_event_handler_register(), and _event_spe_event_wait().
00050 { 00051 pthread_mutex_lock(&__SPE_EVENT_CONTEXT_PRIV_GET(spe)->lock); 00052 }
int _event_spe_context_run | ( | spe_context_ptr_t | spe, | |
unsigned int * | entry, | |||
unsigned int | runflags, | |||
void * | argp, | |||
void * | envp, | |||
spe_stop_info_t * | stopinfo | |||
) |
Definition at line 477 of file spe_event.c.
References __SPE_EVENT_CONTEXT_PRIV_GET, _base_spe_context_run(), and spe_context_event_priv::stop_event_pipe.
00478 { 00479 spe_context_event_priv_ptr_t evctx; 00480 spe_stop_info_t stopinfo_buf; 00481 int rc; 00482 00483 if (!stopinfo) { 00484 stopinfo = &stopinfo_buf; 00485 } 00486 rc = _base_spe_context_run(spe, entry, runflags, argp, envp, stopinfo); 00487 00488 evctx = __SPE_EVENT_CONTEXT_PRIV_GET(spe); 00489 if (write(evctx->stop_event_pipe[1], stopinfo, sizeof(*stopinfo)) != sizeof(*stopinfo)) { 00490 /* error check. */ 00491 } 00492 00493 return rc; 00494 }
void _event_spe_context_unlock | ( | spe_context_ptr_t | spe | ) |
Definition at line 54 of file spe_event.c.
References __SPE_EVENT_CONTEXT_PRIV_GET.
Referenced by _event_spe_event_handler_deregister(), _event_spe_event_handler_register(), and _event_spe_event_wait().
00055 { 00056 pthread_mutex_unlock(&__SPE_EVENT_CONTEXT_PRIV_GET(spe)->lock); 00057 }
spe_event_handler_ptr_t _event_spe_event_handler_create | ( | void | ) |
Definition at line 110 of file spe_event.c.
References __SPE_EPOLL_FD_SET, and __SPE_EPOLL_SIZE.
00111 { 00112 int epfd; 00113 spe_event_handler_t *evhandler; 00114 00115 evhandler = calloc(1, sizeof(*evhandler)); 00116 if (!evhandler) { 00117 return NULL; 00118 } 00119 00120 epfd = epoll_create(__SPE_EPOLL_SIZE); 00121 if (epfd == -1) { 00122 free(evhandler); 00123 return NULL; 00124 } 00125 00126 __SPE_EPOLL_FD_SET(evhandler, epfd); 00127 00128 return evhandler; 00129 }
int _event_spe_event_handler_deregister | ( | spe_event_handler_ptr_t | evhandler, | |
spe_event_unit_t * | event | |||
) |
Definition at line 273 of file spe_event.c.
References __base_spe_event_source_acquire(), __SPE_EPOLL_FD_GET, __SPE_EVENT_ALL, __SPE_EVENT_CONTEXT_PRIV_GET, __SPE_EVENT_IN_MBOX, __SPE_EVENT_OUT_INTR_MBOX, __SPE_EVENT_SPE_STOPPED, __SPE_EVENT_TAG_GROUP, __SPE_EVENTS_ENABLED, _event_spe_context_lock(), _event_spe_context_unlock(), spe_context_event_priv::events, spe_event_unit::events, FD_IBOX, FD_MFC, FD_WBOX, spe_event_unit::spe, SPE_EVENT_IN_MBOX, SPE_EVENT_OUT_INTR_MBOX, SPE_EVENT_SPE_STOPPED, SPE_EVENT_TAG_GROUP, and spe_context_event_priv::stop_event_pipe.
00274 { 00275 int epfd; 00276 const int ep_op = EPOLL_CTL_DEL; 00277 spe_context_event_priv_ptr_t evctx; 00278 int fd; 00279 00280 if (!evhandler) { 00281 errno = ESRCH; 00282 return -1; 00283 } 00284 if (!event || !event->spe) { 00285 errno = EINVAL; 00286 return -1; 00287 } 00288 if (!__SPE_EVENTS_ENABLED(event->spe)) { 00289 errno = ENOTSUP; 00290 return -1; 00291 } 00292 00293 epfd = __SPE_EPOLL_FD_GET(evhandler); 00294 evctx = __SPE_EVENT_CONTEXT_PRIV_GET(event->spe); 00295 00296 if (event->events & ~__SPE_EVENT_ALL) { 00297 errno = ENOTSUP; 00298 return -1; 00299 } 00300 00301 _event_spe_context_lock(event->spe); /* for spe->event_private->events */ 00302 00303 if (event->events & SPE_EVENT_OUT_INTR_MBOX) { 00304 fd = __base_spe_event_source_acquire(event->spe, FD_IBOX); 00305 if (fd == -1) { 00306 _event_spe_context_unlock(event->spe); 00307 return -1; 00308 } 00309 if (epoll_ctl(epfd, ep_op, fd, NULL) == -1) { 00310 _event_spe_context_unlock(event->spe); 00311 return -1; 00312 } 00313 evctx->events[__SPE_EVENT_OUT_INTR_MBOX].events = 0; 00314 } 00315 00316 if (event->events & SPE_EVENT_IN_MBOX) { 00317 fd = __base_spe_event_source_acquire(event->spe, FD_WBOX); 00318 if (fd == -1) { 00319 _event_spe_context_unlock(event->spe); 00320 return -1; 00321 } 00322 if (epoll_ctl(epfd, ep_op, fd, NULL) == -1) { 00323 _event_spe_context_unlock(event->spe); 00324 return -1; 00325 } 00326 evctx->events[__SPE_EVENT_IN_MBOX].events = 0; 00327 } 00328 00329 if (event->events & SPE_EVENT_TAG_GROUP) { 00330 fd = __base_spe_event_source_acquire(event->spe, FD_MFC); 00331 if (fd == -1) { 00332 _event_spe_context_unlock(event->spe); 00333 return -1; 00334 } 00335 if (epoll_ctl(epfd, ep_op, fd, NULL) == -1) { 00336 _event_spe_context_unlock(event->spe); 00337 return -1; 00338 } 00339 evctx->events[__SPE_EVENT_TAG_GROUP].events = 0; 00340 } 00341 00342 if (event->events & SPE_EVENT_SPE_STOPPED) { 00343 fd = evctx->stop_event_pipe[0]; 00344 if (epoll_ctl(epfd, ep_op, fd, NULL) == -1) { 00345 _event_spe_context_unlock(event->spe); 00346 return -1; 00347 } 00348 evctx->events[__SPE_EVENT_SPE_STOPPED].events = 0; 00349 } 00350 00351 _event_spe_context_unlock(event->spe); 00352 00353 return 0; 00354 }
int _event_spe_event_handler_destroy | ( | spe_event_handler_ptr_t | evhandler | ) |
Definition at line 135 of file spe_event.c.
References __SPE_EPOLL_FD_GET.
00136 { 00137 int epfd; 00138 00139 if (!evhandler) { 00140 errno = ESRCH; 00141 return -1; 00142 } 00143 00144 epfd = __SPE_EPOLL_FD_GET(evhandler); 00145 close(epfd); 00146 00147 free(evhandler); 00148 return 0; 00149 }
int _event_spe_event_handler_register | ( | spe_event_handler_ptr_t | evhandler, | |
spe_event_unit_t * | event | |||
) |
Definition at line 155 of file spe_event.c.
References __base_spe_event_source_acquire(), __SPE_EPOLL_FD_GET, __SPE_EVENT_ALL, __SPE_EVENT_CONTEXT_PRIV_GET, __SPE_EVENT_IN_MBOX, __SPE_EVENT_OUT_INTR_MBOX, __SPE_EVENT_SPE_STOPPED, __SPE_EVENT_TAG_GROUP, __SPE_EVENTS_ENABLED, _event_spe_context_lock(), _event_spe_context_unlock(), spe_context::base_private, spe_event_unit::data, spe_context_event_priv::events, spe_event_unit::events, FD_IBOX, FD_MFC, FD_WBOX, spe_context_base_priv::flags, spe_event_data::ptr, spe_event_unit::spe, SPE_EVENT_IN_MBOX, SPE_EVENT_OUT_INTR_MBOX, SPE_EVENT_SPE_STOPPED, SPE_EVENT_TAG_GROUP, SPE_MAP_PS, and spe_context_event_priv::stop_event_pipe.
00156 { 00157 int epfd; 00158 const int ep_op = EPOLL_CTL_ADD; 00159 spe_context_event_priv_ptr_t evctx; 00160 spe_event_unit_t *ev_buf; 00161 struct epoll_event ep_event; 00162 int fd; 00163 00164 if (!evhandler) { 00165 errno = ESRCH; 00166 return -1; 00167 } 00168 if (!event || !event->spe) { 00169 errno = EINVAL; 00170 return -1; 00171 } 00172 if (!__SPE_EVENTS_ENABLED(event->spe)) { 00173 errno = ENOTSUP; 00174 return -1; 00175 } 00176 00177 epfd = __SPE_EPOLL_FD_GET(evhandler); 00178 evctx = __SPE_EVENT_CONTEXT_PRIV_GET(event->spe); 00179 00180 if (event->events & ~__SPE_EVENT_ALL) { 00181 errno = ENOTSUP; 00182 return -1; 00183 } 00184 00185 _event_spe_context_lock(event->spe); /* for spe->event_private->events */ 00186 00187 if (event->events & SPE_EVENT_OUT_INTR_MBOX) { 00188 fd = __base_spe_event_source_acquire(event->spe, FD_IBOX); 00189 if (fd == -1) { 00190 _event_spe_context_unlock(event->spe); 00191 return -1; 00192 } 00193 00194 ev_buf = &evctx->events[__SPE_EVENT_OUT_INTR_MBOX]; 00195 ev_buf->events = SPE_EVENT_OUT_INTR_MBOX; 00196 ev_buf->data = event->data; 00197 00198 ep_event.events = EPOLLIN; 00199 ep_event.data.ptr = ev_buf; 00200 if (epoll_ctl(epfd, ep_op, fd, &ep_event) == -1) { 00201 _event_spe_context_unlock(event->spe); 00202 return -1; 00203 } 00204 } 00205 00206 if (event->events & SPE_EVENT_IN_MBOX) { 00207 fd = __base_spe_event_source_acquire(event->spe, FD_WBOX); 00208 if (fd == -1) { 00209 _event_spe_context_unlock(event->spe); 00210 return -1; 00211 } 00212 00213 ev_buf = &evctx->events[__SPE_EVENT_IN_MBOX]; 00214 ev_buf->events = SPE_EVENT_IN_MBOX; 00215 ev_buf->data = event->data; 00216 00217 ep_event.events = EPOLLOUT; 00218 ep_event.data.ptr = ev_buf; 00219 if (epoll_ctl(epfd, ep_op, fd, &ep_event) == -1) { 00220 _event_spe_context_unlock(event->spe); 00221 return -1; 00222 } 00223 } 00224 00225 if (event->events & SPE_EVENT_TAG_GROUP) { 00226 fd = __base_spe_event_source_acquire(event->spe, FD_MFC); 00227 if (fd == -1) { 00228 _event_spe_context_unlock(event->spe); 00229 return -1; 00230 } 00231 00232 if (event->spe->base_private->flags & SPE_MAP_PS) { 00233 _event_spe_context_unlock(event->spe); 00234 errno = ENOTSUP; 00235 return -1; 00236 } 00237 00238 ev_buf = &evctx->events[__SPE_EVENT_TAG_GROUP]; 00239 ev_buf->events = SPE_EVENT_TAG_GROUP; 00240 ev_buf->data = event->data; 00241 00242 ep_event.events = EPOLLIN; 00243 ep_event.data.ptr = ev_buf; 00244 if (epoll_ctl(epfd, ep_op, fd, &ep_event) == -1) { 00245 _event_spe_context_unlock(event->spe); 00246 return -1; 00247 } 00248 } 00249 00250 if (event->events & SPE_EVENT_SPE_STOPPED) { 00251 fd = evctx->stop_event_pipe[0]; 00252 00253 ev_buf = &evctx->events[__SPE_EVENT_SPE_STOPPED]; 00254 ev_buf->events = SPE_EVENT_SPE_STOPPED; 00255 ev_buf->data = event->data; 00256 00257 ep_event.events = EPOLLIN; 00258 ep_event.data.ptr = ev_buf; 00259 if (epoll_ctl(epfd, ep_op, fd, &ep_event) == -1) { 00260 _event_spe_context_unlock(event->spe); 00261 return -1; 00262 } 00263 } 00264 00265 _event_spe_context_unlock(event->spe); 00266 00267 return 0; 00268 }
int _event_spe_event_wait | ( | spe_event_handler_ptr_t | evhandler, | |
spe_event_unit_t * | events, | |||
int | max_events, | |||
int | timeout | |||
) |
Definition at line 360 of file spe_event.c.
References __SPE_EPOLL_FD_GET, _event_spe_context_lock(), _event_spe_context_unlock(), and spe_event_unit::spe.
00361 { 00362 int epfd; 00363 struct epoll_event *ep_events; 00364 int rc; 00365 00366 if (!evhandler) { 00367 errno = ESRCH; 00368 return -1; 00369 } 00370 if (!events || max_events <= 0) { 00371 errno = EINVAL; 00372 return -1; 00373 } 00374 00375 epfd = __SPE_EPOLL_FD_GET(evhandler); 00376 00377 ep_events = malloc(sizeof(*ep_events) * max_events); 00378 if (!ep_events) { 00379 return -1; 00380 } 00381 00382 for ( ; ; ) { 00383 rc = epoll_wait(epfd, ep_events, max_events, timeout); 00384 if (rc == -1) { /* error */ 00385 if (errno == EINTR) { 00386 if (timeout >= 0) { /* behave as timeout */ 00387 rc = 0; 00388 break; 00389 } 00390 /* else retry */ 00391 } 00392 else { 00393 break; 00394 } 00395 } 00396 else if (rc > 0) { 00397 int i; 00398 for (i = 0; i < rc; i++) { 00399 spe_event_unit_t *ev = (spe_event_unit_t *)(ep_events[i].data.ptr); 00400 _event_spe_context_lock(ev->spe); /* lock ev itself */ 00401 events[i] = *ev; 00402 _event_spe_context_unlock(ev->spe); 00403 } 00404 break; 00405 } 00406 else { /* timeout */ 00407 break; 00408 } 00409 } 00410 00411 free(ep_events); 00412 00413 return rc; 00414 }
int _event_spe_stop_info_read | ( | spe_context_ptr_t | spe, | |
spe_stop_info_t * | stopinfo | |||
) |
Definition at line 59 of file spe_event.c.
References __SPE_EVENT_CONTEXT_PRIV_GET, spe_context_event_priv::stop_event_pipe, and spe_context_event_priv::stop_event_read_lock.
00060 { 00061 spe_context_event_priv_ptr_t evctx; 00062 int rc; 00063 int fd; 00064 size_t total; 00065 00066 evctx = __SPE_EVENT_CONTEXT_PRIV_GET(spe); 00067 fd = evctx->stop_event_pipe[0]; 00068 00069 pthread_mutex_lock(&evctx->stop_event_read_lock); /* for atomic read */ 00070 00071 rc = read(fd, stopinfo, sizeof(*stopinfo)); 00072 if (rc == -1) { 00073 pthread_mutex_unlock(&evctx->stop_event_read_lock); 00074 return -1; 00075 } 00076 00077 total = rc; 00078 while (total < sizeof(*stopinfo)) { /* this loop will be executed in few cases */ 00079 struct pollfd fds; 00080 fds.fd = fd; 00081 fds.events = POLLIN; 00082 rc = poll(&fds, 1, -1); 00083 if (rc == -1) { 00084 if (errno != EINTR) { 00085 break; 00086 } 00087 } 00088 else if (rc == 1) { 00089 rc = read(fd, (char *)stopinfo + total, sizeof(*stopinfo) - total); 00090 if (rc == -1) { 00091 if (errno != EAGAIN) { 00092 break; 00093 } 00094 } 00095 else { 00096 total += rc; 00097 } 00098 } 00099 } 00100 00101 pthread_mutex_unlock(&evctx->stop_event_read_lock); 00102 00103 return rc == -1 ? -1 : 0; 00104 }