Socket Linux dengan SO_RCVLOWAT di atas satu byte dapat memiliki data dalam antrean sementara poll(), select(), atau epoll belum melaporkan readiness baca normal. Sejak Linux 2.6.28, antarmuka readiness tersebut menghormati receive low-water mark yang dikonfigurasi.
Opsi ini mengubah ambang yang terkait dengan readiness penerimaan normal. Opsi ini tidak menetapkan batas pesan, tidak mencadangkan ruang receive buffer, dan tidak menjamin operasi penerimaan berikutnya mengembalikan tepat sejumlah byte sesuai nilai konfigurasi.
Readability dapat memerlukan lebih dari satu byte dalam antrean
Readiness penerimaan socket biasanya diamati dengan low-water mark bawaan sebesar satu byte. Pada kondisi ini, data biasa yang sudah masuk antrean cukup untuk memenuhi bagian volume data dari kondisi readable.
SO_RCVLOWAT menaikkan ambang byte tersebut. Nilai 4096 berarti readiness penerimaan normal dapat tetap false saat data yang tersedia kurang dari 4096 byte, lalu menjadi true ketika antrean mencapai ambang itu.
int lowat = 4096;
if (setsockopt(fd, SOL_SOCKET, SO_RCVLOWAT,
&lowat, sizeof(lowat)) == -1) {
/* handle error */
}Linux mengizinkan perubahan SO_RCVLOWAT; nilai bawaannya adalah 1. Opsi terkait, SO_SNDLOWAT, tidak dapat diubah di Linux.
Ambang memengaruhi readiness dan penerimaan blocking
Low-water mark berperan pada dua batas yang saling terkait. Operasi penerimaan blocking dapat menunggu kondisi penerimaan yang terkait dengan ambang tersebut, dan antarmuka readiness Linux modern memakai pengaturan yang sama saat menentukan apakah data normal membuat socket berstatus readable.
Keterkaitan itu mencegah ketidakselarasan umum: penantian readiness selesai karena satu byte masuk antrean, lalu operasi penerimaan blocking masih menunggu ambang low-water yang lebih besar. Kernel Linux sebelum 2.6.28 memiliki ketidakselarasan tersebut karena select(), poll(), dan epoll belum menghormati SO_RCVLOWAT.
Pada socket nonblocking, operasi penerimaan tetap mempertahankan semantik nonblocking. Jika operasi tidak dapat dilanjutkan, panggilan mengembalikan error seperti EAGAIN atau EWOULDBLOCK alih-alih tidur. Readiness tetap merupakan indikasi keadaan, bukan reservasi byte untuk thread tertentu.
Readiness tidak mempertahankan alokasi byte
Event readiness menyatakan bahwa socket memenuhi suatu kondisi readiness saat kernel mengevaluasinya. Event itu tidak menetapkan byte dalam antrean kepada waiter tertentu.
Thread atau proses lain yang berbagi socket dapat mengonsumsi data sebelum waiter awal memanggil recv(). Keadaan protokol juga dapat menghasilkan kondisi readable lain, termasuk orderly shutdown atau error yang tertunda. Karena itu, kode yang memakai socket bersama tidak dapat memperlakukan event sebagai kepemilikan atas sejumlah byte sebesar SO_RCVLOWAT.
Perbedaan ini penting pada event loop. Low-water mark dapat menekan wakeup akibat kedatangan data kecil, tetapi bukan batas transaksi untuk receive queue.
TCP tetap berupa byte stream
Pada socket TCP, SO_RCVLOWAT = 4096 tidak membentuk record berukuran 4096 byte. TCP tetap menyediakan ordered byte stream, dan batas write pada pengirim tetap terpisah dari batas read pada penerima.
Setelah operasi penerimaan berjalan, hasilnya bergantung pada panjang yang diminta, data yang tersedia, flag, mode socket, keadaan protokol, dan semantik penerimaan yang berlaku. Nilai low-water bukan field framing yang dibawa TCP dan tidak terlihat oleh peer sebagai ukuran record aplikasi.
Protokol yang memerlukan record aplikasi lengkap tetap membutuhkan framing eksplisit, misalnya header berukuran tetap yang memuat panjang payload. SO_RCVLOWAT dapat mengubah perilaku wakeup di sekitar byte yang sudah masuk antrean, tetapi tidak menggantikan framing tersebut.
Ambang lebih besar menukar wakeup cepat dengan batching
Menaikkan receive low-water mark dapat mengurangi notifikasi readable normal yang dipicu oleh kedatangan data kecil secara bertahap. Efek ini cocok dengan aplikasi yang secara alami memproses data dalam batch lebih besar dan dapat menoleransi waktu tunggu sampai antrean bertambah.
Mekanisme yang sama dapat menambah latensi saat trafik datang perlahan. Request atau response parsial dapat tetap berada di receive queue tanpa menghasilkan readiness data normal sampai byte tambahan tiba atau kondisi socket lain mengubah hasil evaluasi.
Karena itu, ambang ini merupakan bagian dari kebijakan penjadwalan penerimaan, bukan framing transport. Dampaknya bergantung pada bentuk trafik, buffering aplikasi, konkurensi, dan model event loop.
Versi kernel menjadi batas perilaku
Linux mengizinkan SO_RCVLOWAT diubah sejak Linux 2.4. Perilaku readiness berubah pada Linux 2.6.28: mulai rilis tersebut, select(), poll(), dan epoll melaporkan readiness baca normal hanya ketika setidaknya sejumlah data sesuai low-water mark tersedia.
Batas versi itu relevan bagi perangkat lunak yang menargetkan kernel lama atau lingkungan kompatibilitas yang mereproduksi perilaku lama. Pada sistem Linux saat ini, receive low-water mark merupakan bagian dari keputusan readiness itu sendiri, bukan sekadar parameter yang diperiksa setelah operasi penerimaan dimulai.