os.read() must also be allocating the read buffer in addition to calling the system read() function. I just uploaded a new test script "test_fork_pipe_error.py" that iterates in increasing or decreasing order over initial pipe read sizes and accumulates failed size values. It iterates in multiples of 1024 (1024*1, 1024*2, 1024*3, ... 1024*1024 or in reverse) . It makes some interesting (possibly also red-herring) discoveries:
1. When iterating the initial read size in increasing order (1024, 2048, 3072, ...) the test doesn't trigger the EINVAL error.
2. When iterating the initial read size in decreasing order, the test triggers EINVAL every 4KB (1024*1024, 1024*1020, 1024*1016, etc.) all the way down to 1024*128. However, the test doesn't trigger any more EINVAL errors for initial read sizes of 127KB and lower (1024*127, 1024*126, 1024*125, ... 1024*1).
Failed initialReadSize multipliers of 1024: [1024, 1020, 1016, 1012, 1008, 1004, 1000, 996, 992, 988, 984, 980, 976, 972, 968, 964, 960, 956, 952, 948, 944, 940, 936, 932, 928, 924, 920, 916, 912, 908, 904, 900, 896, 892, 888, 884, 880, 876, 872, 868, 864, 860, 856, 852, 848, 844, 840, 836, 832, 828, 824, 820, 816, 812, 808, 804, 800, 796, 792, 788, 784, 780, 776, 772, 768, 764, 760, 756, 752, 748, 744, 740, 736, 732, 728, 724, 720, 716, 712, 708, 704, 700, 696, 692, 688, 684, 680, 676, 672, 668, 664, 660, 656, 652, 648, 644, 640, 636, 632, 628, 624, 620, 616, 612, 608, 604, 600, 596, 592, 588, 584, 580, 576, 572, 568, 564, 560, 556, 552, 548, 544, 540, 536, 532, 528, 524, 520, 516, 512, 508, 504, 500, 496, 492, 488, 484, 480, 476, 472, 468, 464, 460, 456, 452, 448, 444, 440, 436, 432, 428, 424, 420, 416, 412, 408, 404, 400, 396, 392, 388, 384, 380, 376, 372, 368, 364, 360, 356, 352, 348, 344, 340, 336, 332, 328, 324, 320, 316, 312, 308, 304, 300, 296, 292, 288, 284, 280, 276, 272, 268, 264, 260, 256, 252, 248, 244, 240, 236, 232, 228, 224, 220, 216, 212, 208, 204, 200, 196, 192, 188, 184, 180, 176, 172, 168, 164, 160, 156, 152, 148, 144, 140, 136, 132, 128]
The reason I said above that those might be red-herring discoveries is this: if I insert a short time.sleep(0.001) delay before the outer pipe-read loop, the EINVAL errors don't get triggered either.
Still, these remain a mystery:
1. Why doesn't the test encounter EINVAL in the range 127KB ... 1KB (when iterating initialReadSize in *decreasing* order). If the pre-read delay is significant, then does it take significantly more time to allocate a 127KB chunk of memory than it does a 128KB chunk?
2. Why doesn't the test encounter EINVAL at all when iterating initialReadSize in *increasing* order? |