… | |
… | |
302 | /* |
302 | /* |
303 | * make our pread/pwrite emulation safe against themselves, but not against |
303 | * make our pread/pwrite emulation safe against themselves, but not against |
304 | * normal read/write by using a mutex. slows down execution a lot, |
304 | * normal read/write by using a mutex. slows down execution a lot, |
305 | * but that's your problem, not mine. |
305 | * but that's your problem, not mine. |
306 | */ |
306 | */ |
307 | static xmutex_t preadwritelock = X_MUTEX_INIT; |
307 | static xmutex_t preadwritelock; |
308 | #endif |
308 | #endif |
309 | |
309 | |
310 | typedef struct etp_worker |
310 | typedef struct etp_worker |
311 | { |
311 | { |
312 | /* locked by wrklock */ |
312 | /* locked by wrklock */ |
… | |
… | |
318 | ETP_REQ *req; /* currently processed request */ |
318 | ETP_REQ *req; /* currently processed request */ |
319 | |
319 | |
320 | ETP_WORKER_COMMON |
320 | ETP_WORKER_COMMON |
321 | } etp_worker; |
321 | } etp_worker; |
322 | |
322 | |
323 | static etp_worker wrk_first = { &wrk_first, &wrk_first, 0 }; /* NOT etp */ |
323 | static etp_worker wrk_first; /* NOT etp */ |
324 | |
324 | |
325 | #define ETP_WORKER_LOCK(wrk) X_LOCK (wrklock) |
325 | #define ETP_WORKER_LOCK(wrk) X_LOCK (wrklock) |
326 | #define ETP_WORKER_UNLOCK(wrk) X_UNLOCK (wrklock) |
326 | #define ETP_WORKER_UNLOCK(wrk) X_UNLOCK (wrklock) |
327 | |
327 | |
328 | /* worker threads management */ |
328 | /* worker threads management */ |
… | |
… | |
453 | } |
453 | } |
454 | |
454 | |
455 | abort (); |
455 | abort (); |
456 | } |
456 | } |
457 | |
457 | |
458 | static void ecb_cold |
458 | static int ecb_cold |
459 | etp_thread_init (void) |
459 | etp_init (void (*want_poll)(void), void (*done_poll)(void)) |
460 | { |
460 | { |
461 | #if !HAVE_PREADWRITE |
|
|
462 | X_MUTEX_CREATE (preadwritelock); |
|
|
463 | #endif |
|
|
464 | X_MUTEX_CREATE (wrklock); |
461 | X_MUTEX_CREATE (wrklock); |
465 | X_MUTEX_CREATE (reslock); |
462 | X_MUTEX_CREATE (reslock); |
466 | X_MUTEX_CREATE (reqlock); |
463 | X_MUTEX_CREATE (reqlock); |
467 | X_COND_CREATE (reqwait); |
464 | X_COND_CREATE (reqwait); |
468 | } |
|
|
469 | |
465 | |
470 | static void ecb_cold |
|
|
471 | etp_atfork_child (void) |
|
|
472 | { |
|
|
473 | reqq_init (&req_queue); |
466 | reqq_init (&req_queue); |
474 | reqq_init (&res_queue); |
467 | reqq_init (&res_queue); |
475 | |
468 | |
476 | wrk_first.next = |
469 | wrk_first.next = |
477 | wrk_first.prev = &wrk_first; |
470 | wrk_first.prev = &wrk_first; |
… | |
… | |
479 | started = 0; |
472 | started = 0; |
480 | idle = 0; |
473 | idle = 0; |
481 | nreqs = 0; |
474 | nreqs = 0; |
482 | nready = 0; |
475 | nready = 0; |
483 | npending = 0; |
476 | npending = 0; |
484 | |
|
|
485 | etp_thread_init (); |
|
|
486 | } |
|
|
487 | |
|
|
488 | static void ecb_cold |
|
|
489 | etp_once_init (void) |
|
|
490 | { |
|
|
491 | etp_thread_init (); |
|
|
492 | X_THREAD_ATFORK (0, 0, etp_atfork_child); |
|
|
493 | } |
|
|
494 | |
|
|
495 | static int ecb_cold |
|
|
496 | etp_init (void (*want_poll)(void), void (*done_poll)(void)) |
|
|
497 | { |
|
|
498 | static pthread_once_t doinit = PTHREAD_ONCE_INIT; |
|
|
499 | |
|
|
500 | pthread_once (&doinit, etp_once_init); |
|
|
501 | |
477 | |
502 | want_poll_cb = want_poll; |
478 | want_poll_cb = want_poll; |
503 | done_poll_cb = done_poll; |
479 | done_poll_cb = done_poll; |
504 | |
480 | |
505 | return 0; |
481 | return 0; |
… | |
… | |
1651 | if (!(flags & EIO_READDIR_DENTS)) |
1627 | if (!(flags & EIO_READDIR_DENTS)) |
1652 | flags &= ~(EIO_READDIR_DIRS_FIRST | EIO_READDIR_STAT_ORDER); |
1628 | flags &= ~(EIO_READDIR_DIRS_FIRST | EIO_READDIR_STAT_ORDER); |
1653 | |
1629 | |
1654 | #ifdef _WIN32 |
1630 | #ifdef _WIN32 |
1655 | { |
1631 | { |
|
|
1632 | int len = strlen ((const char *)req->ptr1); |
1656 | char *path = malloc (MAX_PATH); |
1633 | char *path = malloc (MAX_PATH); |
|
|
1634 | const char *fmt; |
|
|
1635 | |
|
|
1636 | if (!len) |
|
|
1637 | fmt = "./*"; |
|
|
1638 | else if (((const char *)req->ptr1)[len - 1] == '/' || ((const char *)req->ptr1)[len - 1] == '\\') |
|
|
1639 | fmt = "%s*"; |
|
|
1640 | else |
|
|
1641 | fmt = "%s/*"; |
|
|
1642 | |
1657 | _snprintf (path, MAX_PATH, "%s/*", (const char *)req->ptr1); |
1643 | _snprintf (path, MAX_PATH, fmt, (const char *)req->ptr1); |
1658 | dirp = FindFirstFile (path, &entp); |
1644 | dirp = FindFirstFile (path, &entp); |
1659 | free (path); |
1645 | free (path); |
1660 | |
1646 | |
1661 | if (!dirp) |
1647 | if (dirp == INVALID_HANDLE_VALUE) |
1662 | { |
1648 | { |
|
|
1649 | dirp = 0; |
|
|
1650 | |
1663 | switch (GetLastError ()) |
1651 | switch (GetLastError ()) |
1664 | { |
1652 | { |
1665 | case ERROR_FILE_NOT_FOUND: |
1653 | case ERROR_FILE_NOT_FOUND: |
1666 | req->result = 0; |
1654 | req->result = 0; |
1667 | break; |
1655 | break; |
1668 | |
1656 | |
|
|
1657 | case ERROR_INVALID_NAME: |
1669 | case ERROR_PATH_NOT_FOUND: |
1658 | case ERROR_PATH_NOT_FOUND: |
1670 | case ERROR_NO_MORE_FILES: |
1659 | case ERROR_NO_MORE_FILES: |
1671 | errno = ENOENT; |
1660 | errno = ENOENT; |
1672 | break; |
1661 | break; |
1673 | |
1662 | |
… | |
… | |
1677 | |
1666 | |
1678 | default: |
1667 | default: |
1679 | errno = EINVAL; |
1668 | errno = EINVAL; |
1680 | break; |
1669 | break; |
1681 | } |
1670 | } |
1682 | |
|
|
1683 | } |
1671 | } |
1684 | } |
1672 | } |
1685 | #else |
1673 | #else |
1686 | dirp = opendir (req->ptr1); |
1674 | dirp = opendir (req->ptr1); |
1687 | #endif |
1675 | #endif |
1688 | |
1676 | |
… | |
… | |
1694 | req->ptr2 = names = malloc (namesalloc); |
1682 | req->ptr2 = names = malloc (namesalloc); |
1695 | |
1683 | |
1696 | if (dirp && names && (!flags || dents)) |
1684 | if (dirp && names && (!flags || dents)) |
1697 | for (;;) |
1685 | for (;;) |
1698 | { |
1686 | { |
1699 | int more; |
1687 | int done; |
1700 | |
1688 | |
1701 | #ifdef _WIN32 |
1689 | #ifdef _WIN32 |
1702 | more = dirp; |
1690 | done = !dirp; |
1703 | #else |
1691 | #else |
1704 | errno = 0; |
1692 | errno = 0; |
1705 | entp = readdir (dirp); |
1693 | entp = readdir (dirp); |
1706 | more = entp; |
1694 | done = !entp; |
1707 | #endif |
1695 | #endif |
1708 | |
1696 | |
1709 | if (!more) |
1697 | if (done) |
1710 | { |
1698 | { |
1711 | #ifndef _WIN32 |
1699 | #ifndef _WIN32 |
1712 | int old_errno = errno; |
1700 | int old_errno = errno; |
1713 | closedir (dirp); |
1701 | closedir (dirp); |
1714 | errno = old_errno; |
1702 | errno = old_errno; |
… | |
… | |
1979 | /*****************************************************************************/ |
1967 | /*****************************************************************************/ |
1980 | |
1968 | |
1981 | int ecb_cold |
1969 | int ecb_cold |
1982 | eio_init (void (*want_poll)(void), void (*done_poll)(void)) |
1970 | eio_init (void (*want_poll)(void), void (*done_poll)(void)) |
1983 | { |
1971 | { |
|
|
1972 | #if !HAVE_PREADWRITE |
|
|
1973 | X_MUTEX_CREATE (preadwritelock); |
|
|
1974 | #endif |
|
|
1975 | |
1984 | return etp_init (want_poll, done_poll); |
1976 | return etp_init (want_poll, done_poll); |
1985 | } |
1977 | } |
1986 | |
1978 | |
1987 | ecb_inline void |
1979 | ecb_inline void |
1988 | eio_api_destroy (eio_req *req) |
1980 | eio_api_destroy (eio_req *req) |