bbslib - safe_rw and lockfile

作者: 遊手好閒的石頭成 <shirock@mail.educities.edu.tw>
日期: 2001年4月17日

Header files

#include <bbslib/safe_filerw.h>

or

#include <bbslib/safe_rw.h>
#include <bbslib/lockfile.h> 

也可以直接引入 <bbslib.h> , bbslib.h 會將引入所有 bbslib 的 header files 。

Functions

safe_rw

lockfile

safe_rw

safewrite()

ssize_t safewrite(int fd, const void*buf, size_t size);

比 write() 安全一點的資料寫入函數,目的在防止被 signal 中斷,而導致寫入不完全。

依 POSIX 的說明,當被 signal 中斷時,系統可能採取的方式有:

  1. write() 傳回 -1 ,且 errno 被設為 EINTR , safewrite() 會檢查 errno 是否為 EINTR ,若是,則會重新 write() 。
    按照文件的說明( Freebsd, Linux ),當 write() 被 signal 中斷後, 會傳回 -1 ,且 errno 設為 EINTR 。 此時, write 動作將會失敗, 沒有資料被寫入,同時檔案讀寫指標(file position)不會改變,所以只 要繼續呼叫原本的 write() 即可,不必改變任何參數或做 seek 動作。
  2. write() 傳回已寫入的 bytes ,此值將小於 write() 所指定的 nbytes 。 safewrite() 會檢查 write() 是否成功寫入所有的資料數, 若尚未全部寫入,則繼續呼叫 write() 寫入剩下的資料。 少於指定的 bytes 數,此時必須將 write() 的傳回值(已寫入 bytes)記起來, 變動參數及寫入位元數,再繼續嘗試 write() ,直到已完全寫入。

RC: 成功(寫入的byte數,等於size)、失敗(-1)

See also: write(2), saferead()

saferead()

ssize_t saferead(int fd, void*buf, size_t size);

比 read() 安全一點的資料讀取函數,目的在防止被 signal 中斷,而導致讀取不完全。 其他說明同 safewrite() 。

RC: 成功(讀取的byte數,等於size)、失敗(-1), If EOF, return zero.

See also: read(2), safewrite()

pread/pwrite

ssize_t pread(int fd, void *buf, size_t count, off_t offset);

ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);

當系統不提供 pread() 及 pwrite() 時, safe_rw 中所提供的實作函數。 和 read()/write() 的不同之處在於, pread()/pwrite() 需要提供 offset 以指示讀寫的 position ,且執行後,不會改變 position 。

CONFORMING TO: X/Open, Unix98. It's for thread.

lockfile

lock_file()

int lock_file(int fd, int op);

若被 signal 中斷時, lock_file() 會自動恢復等待取得鎖定的狀態,因此使用 lock_file() 時,不需要檢查 EINTR 的情形。 當以 LOCK_NB 操作時,則不會被擱置,函數傳回-1, errno 設為 EAGAIN 。

  fd: 檔案代碼
  op: 
    LOCK_SH (共享鎖定 - 其他程序可讀不可寫)
    LOCK_EX (互斥鎖定 - 其他程序不可讀寫)
    LOCK_NB (不攔置,與LOCK_SH、LOCK_EX配合使用)
    LOCK_UN (解除鎖定)

RC: 成功(0)、失敗(-1, if op is LOCK_NB also sets error to EAGAIN)

See also: fcntl(2), _lock_file(), lock_record()

lock_record()/lock_record2()

int lock_record(int fd, int op, size_t size, int id);

int lock_record2(int fd, int op, size_t size, int id, int nrec);

lock_record() 鎖定單一記錄, lock_record2() 鎖定連續多筆記錄。

lock_file() 是鎖定整個檔案,但有時並不需要鎖定整個檔案,例如修改某個記錄,故增加了 lock_record() 鎖定單一記錄。 lock_record() 增加了表示記錄大小及記錄編號的兩個參數,其他部份則跟 lock_file() 一樣。

PS. 因為 lock_file() 會在檔案為其他行程鎖定時被擱置,若同時有數個程序同時修改互不相同的記錄時,將會造成 delay 。

id為記錄在資料檔中的編號(記錄編號、分錄碼),從 1 開始。 size表示記錄的 bytes 數。 lock_record2() 多了表示要鎖定記錄數的 nrecords (最少為 1 )。

RC: 成功(0)、失敗(-1)

See also: fcntl(2), _lock_file(), lock_file(), lock_record2()


The TIP Project

Short URL: http://fbtip.tsx.org/
Group: http://groups.yahoo.com/list/firebird-tip
Mailing list: firebird-tip@yahoogroups.com