ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libeio/eio.c
(Generate patch)

Comparing libeio/eio.c (file contents):
Revision 1.66 by root, Sun Jun 5 19:58:37 2011 UTC vs.
Revision 1.69 by root, Fri Jun 10 06:50:42 2011 UTC

942 942
943/* sendfile always needs emulation */ 943/* sendfile always needs emulation */
944static ssize_t 944static ssize_t
945eio__sendfile (int ofd, int ifd, off_t offset, size_t count, etp_worker *self) 945eio__sendfile (int ofd, int ifd, off_t offset, size_t count, etp_worker *self)
946{ 946{
947 ssize_t written = 0;
947 ssize_t res; 948 ssize_t res;
948 949
949 if (!count) 950 if (!count)
950 return 0; 951 return 0;
951 952
953 for (;;)
954 {
952#if HAVE_SENDFILE 955#if HAVE_SENDFILE
953# if __linux 956# if __linux
957 off_t soffset = offset;
954 res = sendfile (ofd, ifd, &offset, count); 958 res = sendfile (ofd, ifd, &soffset, count);
955 959
956# elif __FreeBSD__ 960# elif __FreeBSD__
957 /* 961 /*
958 * Of course, the freebsd sendfile is a dire hack with no thoughts 962 * Of course, the freebsd sendfile is a dire hack with no thoughts
959 * wasted on making it similar to other I/O functions. 963 * wasted on making it similar to other I/O functions.
960 */ 964 */
961 {
962 off_t sbytes; 965 off_t sbytes;
963 res = sendfile (ifd, ofd, offset, count, 0, &sbytes, 0); 966 res = sendfile (ifd, ofd, offset, count, 0, &sbytes, 0);
964 967
965 #if 0 /* according to the manpage, this is correct, but broken behaviour */ 968 #if 0 /* according to the manpage, this is correct, but broken behaviour */
966 /* freebsd' sendfile will return 0 on success */ 969 /* freebsd' sendfile will return 0 on success */
967 /* freebsd 8 documents it as only setting *sbytes on EINTR and EAGAIN, but */ 970 /* freebsd 8 documents it as only setting *sbytes on EINTR and EAGAIN, but */
968 /* not on e.g. EIO or EPIPE - sounds broken */ 971 /* not on e.g. EIO or EPIPE - sounds broken */
969 if ((res < 0 && (errno == EAGAIN || errno == EINTR) && sbytes) || res == 0) 972 if ((res < 0 && (errno == EAGAIN || errno == EINTR) && sbytes) || res == 0)
970 res = sbytes; 973 res = sbytes;
971 #endif 974 #endif
972 975
973 /* according to source inspection, this is correct, and useful behaviour */ 976 /* according to source inspection, this is correct, and useful behaviour */
974 if (sbytes) 977 if (sbytes)
975 res = sbytes; 978 res = sbytes;
976 }
977 979
978# elif defined (__APPLE__) 980# elif defined (__APPLE__)
979
980 {
981 off_t sbytes = count; 981 off_t sbytes = count;
982 res = sendfile (ifd, ofd, offset, &sbytes, 0, 0); 982 res = sendfile (ifd, ofd, offset, &sbytes, 0, 0);
983 983
984 /* according to the manpage, sbytes is always valid */ 984 /* according to the manpage, sbytes is always valid */
985 if (sbytes) 985 if (sbytes)
986 res = sbytes; 986 res = sbytes;
987 }
988 987
989# elif __hpux 988# elif __hpux
990 res = sendfile (ofd, ifd, offset, count, 0, 0); 989 res = sendfile (ofd, ifd, offset, count, 0, 0);
991 990
992# elif __solaris 991# elif __solaris
993 {
994 struct sendfilevec vec; 992 struct sendfilevec vec;
995 size_t sbytes; 993 size_t sbytes;
996 994
997 vec.sfv_fd = ifd; 995 vec.sfv_fd = ifd;
998 vec.sfv_flag = 0; 996 vec.sfv_flag = 0;
999 vec.sfv_off = offset; 997 vec.sfv_off = offset;
1000 vec.sfv_len = count; 998 vec.sfv_len = count;
1001 999
1002 res = sendfilev (ofd, &vec, 1, &sbytes); 1000 res = sendfilev (ofd, &vec, 1, &sbytes);
1003 1001
1004 if (res < 0 && sbytes) 1002 if (res < 0 && sbytes)
1005 res = sbytes; 1003 res = sbytes;
1006 }
1007 1004
1008# endif 1005# endif
1009 1006
1010#elif defined (_WIN32) 1007#elif defined (_WIN32)
1011
1012 /* does not work, just for documentation of what would need to be done */ 1008 /* does not work, just for documentation of what would need to be done */
1013 {
1014 HANDLE h = TO_SOCKET (ifd); 1009 HANDLE h = TO_SOCKET (ifd);
1015 SetFilePointer (h, offset, 0, FILE_BEGIN); 1010 SetFilePointer (h, offset, 0, FILE_BEGIN);
1016 res = TransmitFile (TO_SOCKET (ofd), h, count, 0, 0, 0, 0); 1011 res = TransmitFile (TO_SOCKET (ofd), h, count, 0, 0, 0, 0);
1017 }
1018 1012
1019#else 1013#else
1020 res = -1; 1014 res = -1;
1021 errno = ENOSYS; 1015 errno = ENOSYS;
1022#endif 1016#endif
1023 1017
1018 /* we assume sendfile can copy at least 128mb in one go */
1019 if (res <= 128 * 1024 * 1024)
1020 {
1021 if (res > 0)
1022 written += res;
1023
1024 if (written)
1025 return written;
1026
1027 break;
1028 }
1029 else
1030 {
1031 /* if we requested more, then probably the kernel was lazy */
1032 written += res;
1033 offset += res;
1034 count -= res;
1035
1036 if (!count)
1037 return written;
1038 }
1039 }
1040
1024 if (res < 0 1041 if (res < 0
1025 && (errno == ENOSYS || errno == EINVAL || errno == ENOTSOCK 1042 && (errno == ENOSYS || errno == EINVAL || errno == ENOTSOCK
1026 /* BSDs */ 1043 /* BSDs */
1027#ifdef ENOTSUP /* sigh, if the steenking pile called openbsd would only try to at least compile posix code... */ 1044#ifdef ENOTSUP /* sigh, if the steenking pile called openbsd would only try to at least compile posix code... */
1028 || errno == ENOTSUP 1045 || errno == ENOTSUP
1029#endif 1046#endif
1523} 1540}
1524 1541
1525#endif 1542#endif
1526 1543
1527int 1544int
1528eio__mtouch (void *mem, size_t len, int flags) 1545eio__mtouch (eio_req *req)
1529{ 1546{
1547 void *mem = req->ptr2;
1548 size_t len = req->size;
1549 int flags = req->int1;
1550
1530 eio_page_align (&mem, &len); 1551 eio_page_align (&mem, &len);
1531 1552
1532 { 1553 {
1533 intptr_t addr = (intptr_t)mem; 1554 intptr_t addr = (intptr_t)mem;
1534 intptr_t end = addr + len; 1555 intptr_t end = addr + len;
1535 intptr_t page = eio_pagesize (); 1556 intptr_t page = eio_pagesize ();
1536 1557
1537 if (addr < end) 1558 if (addr < end)
1538 if (flags & EIO_MT_MODIFY) /* modify */ 1559 if (flags & EIO_MT_MODIFY) /* modify */
1539 do { *((volatile sig_atomic_t *)addr) |= 0; } while ((addr += page) < len); 1560 do { *((volatile sig_atomic_t *)addr) |= 0; } while ((addr += page) < len && !EIO_CANCELLED (req));
1540 else 1561 else
1541 do { *((volatile sig_atomic_t *)addr) ; } while ((addr += page) < len); 1562 do { *((volatile sig_atomic_t *)addr) ; } while ((addr += page) < len && !EIO_CANCELLED (req));
1542 } 1563 }
1543 1564
1544 return 0; 1565 return 0;
1545} 1566}
1546 1567
1720 1741
1721 case EIO_SYNC: req->result = 0; sync (); break; 1742 case EIO_SYNC: req->result = 0; sync (); break;
1722 case EIO_FSYNC: req->result = fsync (req->int1); break; 1743 case EIO_FSYNC: req->result = fsync (req->int1); break;
1723 case EIO_FDATASYNC: req->result = fdatasync (req->int1); break; 1744 case EIO_FDATASYNC: req->result = fdatasync (req->int1); break;
1724 case EIO_MSYNC: req->result = eio__msync (req->ptr2, req->size, req->int1); break; 1745 case EIO_MSYNC: req->result = eio__msync (req->ptr2, req->size, req->int1); break;
1725 case EIO_MTOUCH: req->result = eio__mtouch (req->ptr2, req->size, req->int1); break; 1746 case EIO_MTOUCH: req->result = eio__mtouch (req); break;
1726 case EIO_MLOCK: req->result = eio__mlock (req->ptr2, req->size); break; 1747 case EIO_MLOCK: req->result = eio__mlock (req->ptr2, req->size); break;
1727 case EIO_MLOCKALL: req->result = eio__mlockall (req->int1); break; 1748 case EIO_MLOCKALL: req->result = eio__mlockall (req->int1); break;
1728 case EIO_SYNC_FILE_RANGE: req->result = eio__sync_file_range (req->int1, req->offs, req->size, req->int2); break; 1749 case EIO_SYNC_FILE_RANGE: req->result = eio__sync_file_range (req->int1, req->offs, req->size, req->int2); break;
1729 1750
1730 case EIO_READDIR: eio__scandir (req, self); break; 1751 case EIO_READDIR: eio__scandir (req, self); break;
1774 case EIO_NOP: 1795 case EIO_NOP:
1775 req->result = 0; 1796 req->result = 0;
1776 break; 1797 break;
1777 1798
1778 case EIO_CUSTOM: 1799 case EIO_CUSTOM:
1779 ((void (*)(eio_req *))req->feed) (req); 1800 req->feed (req);
1780 break; 1801 break;
1781 1802
1782 default: 1803 default:
1783 errno = ENOSYS; 1804 errno = ENOSYS;
1784 req->result = -1; 1805 req->result = -1;
2005eio_req *eio_rename (const char *path, const char *new_path, int pri, eio_cb cb, void *data) 2026eio_req *eio_rename (const char *path, const char *new_path, int pri, eio_cb cb, void *data)
2006{ 2027{
2007 return eio__2path (EIO_RENAME, path, new_path, pri, cb, data); 2028 return eio__2path (EIO_RENAME, path, new_path, pri, cb, data);
2008} 2029}
2009 2030
2010eio_req *eio_custom (eio_cb execute, int pri, eio_cb cb, void *data) 2031eio_req *eio_custom (void (*)(eio_req *) execute, int pri, eio_cb cb, void *data);
2011{ 2032{
2012 REQ (EIO_CUSTOM); req->feed = (void (*)(eio_req *))execute; SEND; 2033 REQ (EIO_CUSTOM); req->feed = execute; SEND;
2013} 2034}
2014 2035
2015#endif 2036#endif
2016 2037
2017eio_req *eio_grp (eio_cb cb, void *data) 2038eio_req *eio_grp (eio_cb cb, void *data)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines