ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/IO-AIO/AIO.xs
(Generate patch)

Comparing IO-AIO/AIO.xs (file contents):
Revision 1.239 by root, Tue Feb 23 19:42:43 2016 UTC vs.
Revision 1.253 by root, Tue Feb 20 04:32:59 2018 UTC

21# include <sys/mman.h> 21# include <sys/mman.h>
22#endif 22#endif
23 23
24/* the incompetent fool that created musl keeps __linux__, refuses 24/* the incompetent fool that created musl keeps __linux__, refuses
25 * to implement any linux standard apis, and also has no way to test 25 * to implement any linux standard apis, and also has no way to test
26 * for his broken iplementation. on't complain if this fails for you. 26 * for his broken iplementation. don't complain to me if this fails
27 * for you.
27 */ 28 */
28#if __linux__ && (defined __GLIBC__ || defined __UCLIBC__) 29#if __linux__ && (defined __GLIBC__ || defined __UCLIBC__)
29# include <linux/fs.h> 30# include <linux/fs.h>
30# ifdef FS_IOC_FIEMAP 31# ifdef FS_IOC_FIEMAP
31# include <linux/types.h> 32# include <linux/types.h>
103#define expect_false(expr) expect ((expr) != 0, 0) 104#define expect_false(expr) expect ((expr) != 0, 0)
104#define expect_true(expr) expect ((expr) != 0, 1) 105#define expect_true(expr) expect ((expr) != 0, 1)
105 106
106/*****************************************************************************/ 107/*****************************************************************************/
107 108
109#include "libeio/config.h"
110
111#if HAVE_EVENTFD
112# include <sys/eventfd.h>
113#endif
114
115#if HAVE_RLIMITS
116 #include <sys/time.h>
117 #include <sys/resource.h>
118#endif
119
108typedef SV SV8; /* byte-sv, used for argument-checking */ 120typedef SV SV8; /* byte-sv, used for argument-checking */
109typedef int aio_rfd; /* read file desriptor */ 121typedef int aio_rfd; /* read file desriptor */
110typedef int aio_wfd; /* write file descriptor */ 122typedef int aio_wfd; /* write file descriptor */
111 123
112static HV *aio_stash, *aio_req_stash, *aio_grp_stash, *aio_wd_stash; 124static HV *aio_stash, *aio_req_stash, *aio_grp_stash, *aio_wd_stash;
118 STRLEN stroffset; \ 130 STRLEN stroffset; \
119 SV *self; 131 SV *self;
120 132
121#define EIO_NO_WRAPPERS 1 133#define EIO_NO_WRAPPERS 1
122 134
123#include "libeio/config.h"
124#include "libeio/eio.h" 135#include "libeio/eio.h"
125 136
126static int req_invoke (eio_req *req); 137static int req_invoke (eio_req *req);
127#define EIO_FINISH(req) req_invoke (req) 138#define EIO_FINISH(req) req_invoke (req)
128static void req_destroy (eio_req *grp); 139static void req_destroy (eio_req *grp);
161#endif 172#endif
162 173
163#if PAGESIZE <= 0 174#if PAGESIZE <= 0
164# define PAGESIZE sysconf (_SC_PAGESIZE) 175# define PAGESIZE sysconf (_SC_PAGESIZE)
165#endif 176#endif
177
178/*****************************************************************************/
179
180#if !_POSIX_MAPPED_FILES
181# define mmap(addr,length,prot,flags,fd,offs) EIO_ENOSYS ()
182# define munmap(addr,length) EIO_ENOSYS ()
183#endif
184
185#if !_POSIX_MEMORY_PROTECTION
186# define mprotect(addr,len,prot) EIO_ENOSYS ()
187#endif
188
189#define FOREIGN_MAGIC PERL_MAGIC_ext
190
191static int ecb_cold
192mmap_free (pTHX_ SV *sv, MAGIC *mg)
193{
194 int old_errno = errno;
195 munmap (mg->mg_ptr, (size_t)mg->mg_obj);
196 errno = old_errno;
197
198 mg->mg_obj = 0; /* just in case */
199
200 SvREADONLY_off (sv);
201
202 if (SvPVX (sv) != mg->mg_ptr)
203 croak ("ERROR: IO::AIO::mmap-mapped scalar changed location, detected");
204
205 SvCUR_set (sv, 0);
206 SvPVX (sv) = 0;
207 SvOK_off (sv);
208
209 return 0;
210}
211
212static MGVTBL mmap_vtbl = {
213 0, 0, 0, 0, mmap_free
214};
215
216static int ecb_cold
217sysfree_free (pTHX_ SV *sv, MAGIC *mg)
218{
219 free (mg->mg_ptr);
220 mg->mg_obj = 0; /* just in case */
221
222 SvREADONLY_off (sv);
223
224 if (SvPVX (sv) != mg->mg_ptr)
225 croak ("ERROR: IO::AIO mapped scalar changed location, detected");
226
227 SvCUR_set (sv, 0);
228 SvPVX (sv) = 0;
229 SvOK_off (sv);
230
231 return 0;
232}
233
234static MGVTBL sysfree_vtbl = {
235 0, 0, 0, 0, sysfree_free
236};
237
238/*****************************************************************************/
239
240/* helper: set scalar to foreign ptr with custom free */
241static void
242sv_set_foreign (SV *sv, const MGVTBL *const vtbl, void *addr, IV length)
243{
244 sv_force_normal (sv);
245
246 /* we store the length in mg_obj, as namlen is I32 :/ */
247 sv_magicext (sv, 0, FOREIGN_MAGIC, vtbl, (char *)addr, 0)
248 ->mg_obj = (SV *)length;
249
250 SvUPGRADE (sv, SVt_PV); /* nop... */
251
252 if (SvLEN (sv))
253 Safefree (SvPVX (sv));
254
255 SvPVX (sv) = (char *)addr;
256 SvCUR_set (sv, length);
257 SvLEN_set (sv, 0);
258 SvPOK_only (sv);
259}
260
261static void
262sv_clear_foreign (SV *sv)
263{
264 /* todo: iterate over magic and only free ours, but of course */
265 /* the perl5porters will call that (correct) behaviour buggy */
266 sv_unmagic (sv, FOREIGN_MAGIC);
267}
166 268
167/*****************************************************************************/ 269/*****************************************************************************/
168 270
169static void 271static void
170fiemap (eio_req *req) 272fiemap (eio_req *req)
590 SvSETMAGIC (req->sv2); 692 SvSETMAGIC (req->sv2);
591 PUSHs (sv_result); 693 PUSHs (sv_result);
592 } 694 }
593 break; 695 break;
594 696
697 case EIO_SLURP:
698 {
699 if (req->result >= 0)
700 {
701 /* if length was originally not known, we steal the malloc'ed memory */
702 if (req->flags & EIO_FLAG_PTR2_FREE)
703 {
704 req->flags &= ~EIO_FLAG_PTR2_FREE;
705 sv_set_foreign (req->sv2, &sysfree_vtbl, req->ptr2, req->result);
706 }
707 else
708 {
709 SvCUR_set (req->sv2, req->result);
710 *SvEND (req->sv2) = 0;
711 SvPOK_only (req->sv2);
712 }
713
714 SvSETMAGIC (req->sv2);
715 }
716
717 PUSHs (sv_result);
718 }
719 break;
720
595 case EIO_CUSTOM: 721 case EIO_CUSTOM:
596 if (req->feed == fiemap) 722 if (req->feed == fiemap)
597 { 723 {
598#if HAVE_FIEMAP 724#if HAVE_FIEMAP
599 if (!req->result) 725 if (!req->result)
742 create_respipe (); 868 create_respipe ();
743 869
744 if (eio_init (want_poll, done_poll) < 0) 870 if (eio_init (want_poll, done_poll) < 0)
745 croak ("IO::AIO: unable to initialise eio library"); 871 croak ("IO::AIO: unable to initialise eio library");
746} 872}
747
748/*****************************************************************************/
749
750#if !_POSIX_MAPPED_FILES
751# define mmap(addr,length,prot,flags,fd,offs) EIO_ENOSYS ()
752# define munmap(addr,length) EIO_ENOSYS ()
753#endif
754
755#if !_POSIX_MEMORY_PROTECTION
756# define mprotect(addr,len,prot) EIO_ENOSYS ()
757#endif
758
759#define MMAP_MAGIC PERL_MAGIC_ext
760
761static int ecb_cold
762mmap_free (pTHX_ SV *sv, MAGIC *mg)
763{
764 int old_errno = errno;
765 munmap (mg->mg_ptr, (size_t)mg->mg_obj);
766 errno = old_errno;
767
768 mg->mg_obj = 0; /* just in case */
769
770 SvREADONLY_off (sv);
771
772 if (SvPVX (sv) != mg->mg_ptr)
773 croak ("ERROR: IO::AIO::mmap-mapped scalar changed location, detected");
774
775 SvCUR_set (sv, 0);
776 SvPVX (sv) = 0;
777 SvOK_off (sv);
778
779 return 0;
780}
781
782static MGVTBL mmap_vtbl = {
783 0, 0, 0, 0, mmap_free
784};
785 873
786/*****************************************************************************/ 874/*****************************************************************************/
787 875
788static SV * 876static SV *
789get_cb (SV *cb_sv) 877get_cb (SV *cb_sv)
994 const_iv (MAP_GROWSDOWN) 1082 const_iv (MAP_GROWSDOWN)
995 const_iv (MAP_32BIT) 1083 const_iv (MAP_32BIT)
996 const_iv (MAP_HUGETLB) 1084 const_iv (MAP_HUGETLB)
997 const_iv (MAP_STACK) 1085 const_iv (MAP_STACK)
998 1086
1087 const_iv (F_DUPFD_CLOEXEC)
1088
1089 const_iv (F_OFD_GETLK)
1090 const_iv (F_OFD_SETLK)
1091 const_iv (F_OFD_GETLKW)
1092
1093 const_iv (FIFREEZE)
1094 const_iv (FITHAW)
1095 const_iv (FITRIM)
1096 const_iv (FICLONE)
1097 const_iv (FICLONERANGE)
1098 const_iv (FIDEDUPERANGE)
1099
1100 const_iv (FS_IOC_GETFLAGS)
1101 const_iv (FS_IOC_SETFLAGS)
1102 const_iv (FS_IOC_GETVERSION)
1103 const_iv (FS_IOC_SETVERSION)
1104 const_iv (FS_IOC_FIEMAP)
1105 const_iv (FS_IOC_FSGETXATTR)
1106 const_iv (FS_IOC_FSSETXATTR)
1107 const_iv (FS_IOC_SET_ENCRYPTION_POLICY)
1108 const_iv (FS_IOC_GET_ENCRYPTION_PWSALT)
1109 const_iv (FS_IOC_GET_ENCRYPTION_POLICY)
1110
1111 const_iv (FS_KEY_DESCRIPTOR_SIZE)
1112
1113 const_iv (FS_SECRM_FL)
1114 const_iv (FS_UNRM_FL)
1115 const_iv (FS_COMPR_FL)
1116 const_iv (FS_SYNC_FL)
1117 const_iv (FS_IMMUTABLE_FL)
1118 const_iv (FS_APPEND_FL)
1119 const_iv (FS_NODUMP_FL)
1120 const_iv (FS_NOATIME_FL)
1121 const_iv (FS_DIRTY_FL)
1122 const_iv (FS_COMPRBLK_FL)
1123 const_iv (FS_NOCOMP_FL)
1124 const_iv (FS_ENCRYPT_FL)
1125 const_iv (FS_BTREE_FL)
1126 const_iv (FS_INDEX_FL)
1127 const_iv (FS_JOURNAL_DATA_FL)
1128 const_iv (FS_NOTAIL_FL)
1129 const_iv (FS_DIRSYNC_FL)
1130 const_iv (FS_TOPDIR_FL)
1131 const_iv (FS_FL_USER_MODIFIABLE)
1132
1133 const_iv (FS_XFLAG_REALTIME)
1134 const_iv (FS_XFLAG_PREALLOC)
1135 const_iv (FS_XFLAG_IMMUTABLE)
1136 const_iv (FS_XFLAG_APPEND)
1137 const_iv (FS_XFLAG_SYNC)
1138 const_iv (FS_XFLAG_NOATIME)
1139 const_iv (FS_XFLAG_NODUMP)
1140 const_iv (FS_XFLAG_RTINHERIT)
1141 const_iv (FS_XFLAG_PROJINHERIT)
1142 const_iv (FS_XFLAG_NOSYMLINKS)
1143 const_iv (FS_XFLAG_EXTSIZE)
1144 const_iv (FS_XFLAG_EXTSZINHERIT)
1145 const_iv (FS_XFLAG_NODEFRAG)
1146 const_iv (FS_XFLAG_FILESTREAM)
1147 const_iv (FS_XFLAG_DAX)
1148 const_iv (FS_XFLAG_HASATTR)
1149
999 const_iv (FIEMAP_FLAG_SYNC) 1150 const_iv (FIEMAP_FLAG_SYNC)
1000 const_iv (FIEMAP_FLAG_XATTR) 1151 const_iv (FIEMAP_FLAG_XATTR)
1001 const_iv (FIEMAP_FLAGS_COMPAT) 1152 const_iv (FIEMAP_FLAGS_COMPAT)
1002 const_iv (FIEMAP_EXTENT_LAST) 1153 const_iv (FIEMAP_EXTENT_LAST)
1003 const_iv (FIEMAP_EXTENT_UNKNOWN) 1154 const_iv (FIEMAP_EXTENT_UNKNOWN)
1014 const_iv (SPLICE_F_MOVE) 1165 const_iv (SPLICE_F_MOVE)
1015 const_iv (SPLICE_F_NONBLOCK) 1166 const_iv (SPLICE_F_NONBLOCK)
1016 const_iv (SPLICE_F_MORE) 1167 const_iv (SPLICE_F_MORE)
1017 const_iv (SPLICE_F_GIFT) 1168 const_iv (SPLICE_F_GIFT)
1018 1169
1170 const_iv (EFD_CLOEXEC)
1171 const_iv (EFD_NONBLOCK)
1172 const_iv (EFD_SEMAPHORE)
1173
1019 /* these are libeio constants, and are independent of gendef0 */ 1174 /* these are libeio constants, and are independent of gendef0 */
1020 const_eio (SEEK_SET) 1175 const_eio (SEEK_SET)
1021 const_eio (SEEK_CUR) 1176 const_eio (SEEK_CUR)
1022 const_eio (SEEK_END) 1177 const_eio (SEEK_END)
1023 1178
1036 1191
1037 const_eio (FALLOC_FL_KEEP_SIZE) 1192 const_eio (FALLOC_FL_KEEP_SIZE)
1038 const_eio (FALLOC_FL_PUNCH_HOLE) 1193 const_eio (FALLOC_FL_PUNCH_HOLE)
1039 const_eio (FALLOC_FL_COLLAPSE_RANGE) 1194 const_eio (FALLOC_FL_COLLAPSE_RANGE)
1040 const_eio (FALLOC_FL_ZERO_RANGE) 1195 const_eio (FALLOC_FL_ZERO_RANGE)
1196 const_eio (FALLOC_FL_INSERT_RANGE)
1197 const_eio (FALLOC_FL_UNSHARE_RANGE)
1198
1199 const_eio (RENAME_NOREPLACE)
1200 const_eio (RENAME_EXCHANGE)
1201 const_eio (RENAME_WHITEOUT)
1041 1202
1042 const_eio (READDIR_DENTS) 1203 const_eio (READDIR_DENTS)
1043 const_eio (READDIR_DIRS_FIRST) 1204 const_eio (READDIR_DIRS_FIRST)
1044 const_eio (READDIR_STAT_ORDER) 1205 const_eio (READDIR_STAT_ORDER)
1045 const_eio (READDIR_FOUND_UNKNOWN) 1206 const_eio (READDIR_FOUND_UNKNOWN)
1316#else 1477#else
1317 STRLEN need = 256; 1478 STRLEN need = 256;
1318#endif 1479#endif
1319 1480
1320 if (svlen < need) 1481 if (svlen < need)
1321 svptr = SvGROW (arg, need + 1); 1482 svptr = SvGROW (arg, need);
1322 } 1483 }
1323 else 1484 else
1324 svptr = (char *)SvIV (arg); 1485 svptr = (char *)SvIV (arg);
1325 1486
1326 { 1487 {
1405UV 1566UV
1406major (UV dev) 1567major (UV dev)
1407 ALIAS: 1568 ALIAS:
1408 minor = 1 1569 minor = 1
1409 CODE: 1570 CODE:
1410 RETVAL = ix ? major (dev) : minor (dev); 1571 RETVAL = ix ? minor (dev) : major (dev);
1411 OUTPUT: 1572 OUTPUT:
1412 RETVAL 1573 RETVAL
1413 1574
1414UV 1575UV
1415makedev (UV maj, UV min) 1576makedev (UV maj, UV min)
1532 1693
1533 REQ_SEND; 1694 REQ_SEND;
1534} 1695}
1535 1696
1536void 1697void
1698aio_rename2 (SV8 *oldpath, SV8 *newpath, int flags = 0, SV *callback = &PL_sv_undef)
1699 PPCODE:
1700{
1701 eio_wd wd2 = 0;
1702 dREQ;
1703
1704 req->type = EIO_RENAME;
1705 req_set_path1 (req, oldpath);
1706 req_set_path (req, newpath, &req->sv2, &req->sv4, &wd2, &req->ptr2);
1707 req->int2 = flags;
1708 req->int3 = (long)wd2;
1709
1710 REQ_SEND;
1711}
1712
1713void
1537aio_mknod (SV8 *pathname, int mode, UV dev, SV *callback = &PL_sv_undef) 1714aio_mknod (SV8 *pathname, int mode, UV dev, SV *callback = &PL_sv_undef)
1538 PPCODE: 1715 PPCODE:
1539{ 1716{
1540 dREQ; 1717 dREQ;
1541 1718
1546 1723
1547 REQ_SEND; 1724 REQ_SEND;
1548} 1725}
1549 1726
1550void 1727void
1551aio_mtouch (SV8 *data, IV offset = 0, SV *length = &PL_sv_undef, int flags = 0, SV *callback = &PL_sv_undef) 1728aio_mtouch (SV8 *data, IV offset = 0, SV *length = &PL_sv_undef, int flags = -1, SV *callback = &PL_sv_undef)
1552 ALIAS: 1729 ALIAS:
1553 aio_mtouch = EIO_MTOUCH 1730 aio_mtouch = EIO_MTOUCH
1554 aio_msync = EIO_MSYNC 1731 aio_msync = EIO_MSYNC
1555 PPCODE: 1732 PPCODE:
1556{ 1733{
1557 STRLEN svlen; 1734 STRLEN svlen;
1558 char *svptr = SvPVbyte (data, svlen); 1735 char *svptr = SvPVbyte (data, svlen);
1559 UV len = SvUV (length); 1736 UV len = SvUV (length);
1737
1738 if (flags < 0)
1739 flags = ix == EIO_MSYNC ? EIO_MS_SYNC : 0;
1560 1740
1561 if (offset < 0) 1741 if (offset < 0)
1562 offset += svlen; 1742 offset += svlen;
1563 1743
1564 if (offset < 0 || offset > svlen) 1744 if (offset < 0 || offset > svlen)
1640 req->int2 = flags; 1820 req->int2 = flags;
1641 req->int3 = SvOK (count) ? SvIV (count) : -1; 1821 req->int3 = SvOK (count) ? SvIV (count) : -1;
1642#endif 1822#endif
1643 1823
1644 REQ_SEND; 1824 REQ_SEND;
1825}
1826
1827void
1828aio_slurp (SV *pathname, off_t offset, UV length, SV8 *data, SV *callback = &PL_sv_undef)
1829 PPCODE:
1830{
1831 char *svptr = 0;
1832
1833 sv_clear_foreign (data);
1834
1835 if (length) /* known length, directly read into scalar */
1836 {
1837 if (!SvPOK (data) || SvLEN (data) >= SvCUR (data))
1838 svptr = sv_grow (data, length + 1);
1839 else if (SvCUR (data) < length)
1840 croak ("length outside of scalar, and cannot grow");
1841 else
1842 svptr = SvPVbyte_nolen (data);
1843 }
1844
1845 {
1846 dREQ;
1847
1848 req->type = EIO_SLURP;
1849 req_set_path1 (req, pathname);
1850 req->offs = offset;
1851 req->size = length;
1852 req->sv2 = SvREFCNT_inc (data);
1853 req->ptr2 = svptr;
1854
1855 if (!SvREADONLY (data))
1856 {
1857 SvREADONLY_on (data);
1858 req->flags |= FLAG_SV2_RO_OFF;
1859 }
1860
1861 REQ_SEND;
1862 }
1645} 1863}
1646 1864
1647void 1865void
1648aio_busy (double delay, SV *callback = &PL_sv_undef) 1866aio_busy (double delay, SV *callback = &PL_sv_undef)
1649 PPCODE: 1867 PPCODE:
1786 RETVAL 2004 RETVAL
1787 2005
1788void 2006void
1789mmap (SV *scalar, STRLEN length, int prot, int flags, SV *fh = &PL_sv_undef, off_t offset = 0) 2007mmap (SV *scalar, STRLEN length, int prot, int flags, SV *fh = &PL_sv_undef, off_t offset = 0)
1790 PPCODE: 2008 PPCODE:
1791 sv_unmagic (scalar, MMAP_MAGIC); 2009 sv_clear_foreign (scalar);
1792{ 2010{
1793 int fd = SvOK (fh) ? s_fileno_croak (fh, flags & PROT_WRITE) : -1; 2011 int fd = SvOK (fh) ? s_fileno_croak (fh, flags & PROT_WRITE) : -1;
1794 void *addr = (void *)mmap (0, length, prot, flags, fd, offset); 2012 void *addr = (void *)mmap (0, length, prot, flags, fd, offset);
1795 if (addr == (void *)-1) 2013 if (addr == (void *)-1)
1796 XSRETURN_NO; 2014 XSRETURN_NO;
1797 2015
1798 sv_force_normal (scalar); 2016 sv_set_foreign (scalar, &mmap_vtbl, addr, length);
1799
1800 /* we store the length in mg_obj, as namlen is I32 :/ */
1801 sv_magicext (scalar, 0, MMAP_MAGIC, &mmap_vtbl, (char *)addr, 0)
1802 ->mg_obj = (SV *)length;
1803
1804 SvUPGRADE (scalar, SVt_PV); /* nop... */
1805 2017
1806 if (!(prot & PROT_WRITE)) 2018 if (!(prot & PROT_WRITE))
1807 SvREADONLY_on (scalar); 2019 SvREADONLY_on (scalar);
1808 2020
1809 if (SvLEN (scalar))
1810 Safefree (SvPVX (scalar));
1811
1812 SvPVX (scalar) = (char *)addr;
1813 SvCUR_set (scalar, length);
1814 SvLEN_set (scalar, 0);
1815 SvPOK_only (scalar);
1816
1817 XSRETURN_YES; 2021 XSRETURN_YES;
1818} 2022}
1819 2023
1820void 2024void
1821munmap (SV *scalar) 2025munmap (SV *scalar)
1822 CODE: 2026 CODE:
1823 sv_unmagic (scalar, MMAP_MAGIC); 2027 sv_clear_foreign (scalar);
1824 2028
1825int 2029int
1826madvise (SV *scalar, STRLEN offset = 0, SV *length = &PL_sv_undef, IV advice_or_prot) 2030madvise (SV *scalar, STRLEN offset = 0, SV *length = &PL_sv_undef, IV advice_or_prot)
1827 ALIAS: 2031 ALIAS:
1828 mprotect = 1 2032 mprotect = 1
1958 { 2162 {
1959 EXTEND (SP, 2); 2163 EXTEND (SP, 2);
1960 PUSHs (newmortalFH (fd[0], O_RDONLY)); 2164 PUSHs (newmortalFH (fd[0], O_RDONLY));
1961 PUSHs (newmortalFH (fd[1], O_WRONLY)); 2165 PUSHs (newmortalFH (fd[1], O_WRONLY));
1962 } 2166 }
2167}
2168
2169void
2170eventfd (unsigned int initval = 0, int flags = 0)
2171 PPCODE:
2172{
2173 int fd;
2174#if HAVE_EVENTFD
2175 fd = eventfd (initval, flags);
2176#else
2177 fd = (errno = ENOSYS, -1);
2178#endif
2179
2180 XPUSHs (newmortalFH (fd, O_RDWR));
2181}
2182
2183UV
2184get_fdlimit ()
2185 CODE:
2186#if HAVE_RLIMITS
2187 struct rlimit rl;
2188 if (0 == getrlimit (RLIMIT_NOFILE, &rl))
2189 XSRETURN_UV (rl.rlim_cur == RLIM_INFINITY ? (UV)-1 : rl.rlim_cur);
2190#endif
2191 XSRETURN_UNDEF;
2192 OUTPUT:
2193 RETVAL
2194
2195void
2196min_fdlimit (UV limit = 0x7fffffffU)
2197 CODE:
2198{
2199#if HAVE_RLIMITS
2200 struct rlimit rl;
2201 rlim_t orig_rlim_max;
2202 UV bit;
2203
2204 if (0 != getrlimit (RLIMIT_NOFILE, &rl))
2205 goto fail;
2206
2207 if (rl.rlim_cur == RLIM_INFINITY)
2208 XSRETURN_YES;
2209
2210 orig_rlim_max = rl.rlim_max == RLIM_INFINITY ? ((rlim_t)0)-1 : rl.rlim_max;
2211
2212 if (rl.rlim_cur < limit)
2213 {
2214 rl.rlim_cur = limit;
2215
2216 if (rl.rlim_max < rl.rlim_cur && rl.rlim_max != RLIM_INFINITY)
2217 rl.rlim_max = rl.rlim_cur;
2218 }
2219
2220 if (0 == setrlimit (RLIMIT_NOFILE, &rl))
2221 XSRETURN_YES;
2222
2223 if (errno == EPERM)
2224 {
2225 /* setlimit failed with EPERM - maybe we can't raise the hardlimit, or maybe */
2226 /* our limit overflows a system-wide limit */
2227 /* try an adaptive algorithm, but do not lower the hardlimit */
2228 rl.rlim_max = 0;
2229 for (bit = 0x40000000U; bit; bit >>= 1)
2230 {
2231 rl.rlim_max |= bit;
2232 rl.rlim_cur = rl.rlim_max;
2233
2234 /* nevr decrease the hard limit */
2235 if (rl.rlim_max < orig_rlim_max)
2236 break;
2237
2238 if (0 != setrlimit (RLIMIT_NOFILE, &rl))
2239 rl.rlim_max &= ~bit; /* too high, remove bit again */
2240 }
2241
2242 /* now, raise the soft limit to the max permitted */
2243 if (0 == getrlimit (RLIMIT_NOFILE, &rl))
2244 {
2245 rl.rlim_cur = rl.rlim_max;
2246 if (0 == setrlimit (RLIMIT_NOFILE, &rl))
2247 errno = EPERM;
2248 }
2249 }
2250#endif
2251 fail:
2252 XSRETURN_UNDEF;
1963} 2253}
1964 2254
1965void _on_next_submit (SV *cb) 2255void _on_next_submit (SV *cb)
1966 CODE: 2256 CODE:
1967 SvREFCNT_dec (on_next_submit); 2257 SvREFCNT_dec (on_next_submit);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines