rtthread_io_methods.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. static int _rtthread_io_read(sqlite3_file *file_id, void *pbuf, int cnt, sqlite3_int64 offset)
  2. {
  3. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  4. sqlite3_int64 new_offset;
  5. int r_cnt;
  6. assert(file_id);
  7. assert(offset >= 0);
  8. assert(cnt > 0);
  9. new_offset = lseek(file->fd, offset, SEEK_SET);
  10. if (new_offset != offset)
  11. {
  12. return SQLITE_IOERR_READ;
  13. }
  14. do {
  15. r_cnt = read(file->fd, pbuf, cnt);
  16. if (r_cnt == cnt)
  17. {
  18. break;
  19. }
  20. if (r_cnt < 0)
  21. {
  22. if (errno != EINTR)
  23. {
  24. return SQLITE_IOERR_READ;
  25. }
  26. r_cnt = 1;
  27. continue;
  28. }
  29. else if (r_cnt > 0)
  30. {
  31. cnt -= r_cnt;
  32. pbuf = (void*)(r_cnt + (char*)pbuf);
  33. }
  34. } while (r_cnt > 0);
  35. if (r_cnt != cnt)
  36. {
  37. memset(&((char*)pbuf)[r_cnt], 0, cnt - r_cnt);
  38. return SQLITE_IOERR_SHORT_READ;
  39. }
  40. return SQLITE_OK;
  41. }
  42. static int _rtthread_io_write(sqlite3_file* file_id, const void *pbuf, int cnt, sqlite3_int64 offset)
  43. {
  44. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  45. sqlite3_int64 new_offset;
  46. int w_cnt;
  47. assert(file_id);
  48. assert(cnt > 0);
  49. new_offset = lseek(file->fd, offset, SEEK_SET);
  50. if (new_offset != offset)
  51. {
  52. return SQLITE_IOERR_WRITE;
  53. }
  54. do {
  55. w_cnt = write(file->fd, pbuf, cnt);
  56. if (w_cnt == cnt)
  57. {
  58. break;
  59. }
  60. if (w_cnt < 0)
  61. {
  62. if (errno != EINTR)
  63. {
  64. return SQLITE_IOERR_WRITE;
  65. }
  66. w_cnt = 1;
  67. continue;
  68. }
  69. else if (w_cnt > 0)
  70. {
  71. cnt -= w_cnt;
  72. pbuf = (void*)(w_cnt + (char*)pbuf);
  73. }
  74. } while (w_cnt > 0);
  75. if (w_cnt != cnt)
  76. {
  77. return SQLITE_FULL;
  78. }
  79. return SQLITE_OK;
  80. }
  81. static int _rtthread_io_truncate(sqlite3_file* file_id, sqlite3_int64 size)
  82. {
  83. return SQLITE_IOERR_TRUNCATE;
  84. }
  85. static int _rtthread_io_sync(sqlite3_file* file_id, int flags)
  86. {
  87. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  88. assert((flags & 0x0F) == SQLITE_SYNC_NORMAL
  89. || (flags & 0x0F) == SQLITE_SYNC_FULL);
  90. fsync(file->fd);
  91. return SQLITE_OK;
  92. }
  93. static int _rtthread_io_file_size(sqlite3_file* file_id, sqlite3_int64 *psize)
  94. {
  95. int rc;
  96. struct stat buf;
  97. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  98. assert(file_id);
  99. rc = fstat(file->fd, &buf);
  100. if (rc != 0)
  101. {
  102. return SQLITE_IOERR_FSTAT;
  103. }
  104. *psize = buf.st_size;
  105. /* When opening a zero-size database, the findInodeInfo() procedure
  106. ** writes a single byte into that file in order to work around a bug
  107. ** in the OS-X msdos filesystem. In order to avoid problems with upper
  108. ** layers, we need to report this file size as zero even though it is
  109. ** really 1. Ticket #3260.
  110. */
  111. if (*psize == 1) *psize = 0;
  112. return SQLITE_OK;
  113. }
  114. /*
  115. ** This routine checks if there is a RESERVED lock held on the specified
  116. ** file by this or any other process. If such a lock is held, set *pResOut
  117. ** to a non-zero value otherwise *pResOut is set to zero. The return value
  118. ** is set to SQLITE_OK unless an I/O error occurs during lock checking.
  119. */
  120. static int _rtthread_io_check_reserved_lock(sqlite3_file *file_id, int *pResOut)
  121. {
  122. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  123. rt_sem_t psem = &file->sem;
  124. int reserved = 0;
  125. /* Check if a thread in this process holds such a lock */
  126. if (file->eFileLock > SHARED_LOCK)
  127. {
  128. reserved = 1;
  129. }
  130. /* Otherwise see if some other process holds it. */
  131. if (!reserved)
  132. {
  133. if (rt_sem_trytake(psem) != RT_EOK)
  134. {
  135. /* someone else has the lock when we are in NO_LOCK */
  136. reserved = (file->eFileLock < SHARED_LOCK);
  137. }
  138. else
  139. {
  140. /* we could have it if we want it */
  141. rt_sem_release(psem);
  142. }
  143. }
  144. *pResOut = reserved;
  145. return SQLITE_OK;
  146. }
  147. /*
  148. ** Lock the file with the lock specified by parameter eFileLock - one
  149. ** of the following:
  150. **
  151. ** (1) SHARED_LOCK
  152. ** (2) RESERVED_LOCK
  153. ** (3) PENDING_LOCK
  154. ** (4) EXCLUSIVE_LOCK
  155. **
  156. ** Sometimes when requesting one lock state, additional lock states
  157. ** are inserted in between. The locking might fail on one of the later
  158. ** transitions leaving the lock state different from what it started but
  159. ** still short of its goal. The following chart shows the allowed
  160. ** transitions and the inserted intermediate states:
  161. **
  162. ** UNLOCKED -> SHARED
  163. ** SHARED -> RESERVED
  164. ** SHARED -> (PENDING) -> EXCLUSIVE
  165. ** RESERVED -> (PENDING) -> EXCLUSIVE
  166. ** PENDING -> EXCLUSIVE
  167. **
  168. ** Semaphore locks only really support EXCLUSIVE locks. We track intermediate
  169. ** lock states in the sqlite3_file structure, but all locks SHARED or
  170. ** above are really EXCLUSIVE locks and exclude all other processes from
  171. ** access the file.
  172. **
  173. ** This routine will only increase a lock. Use the sqlite3OsUnlock()
  174. ** routine to lower a locking level.
  175. */
  176. static int _rtthread_io_lock(sqlite3_file *file_id, int eFileLock)
  177. {
  178. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  179. rt_sem_t psem = &file->sem;
  180. int rc = SQLITE_OK;
  181. /* if we already have a lock, it is exclusive.
  182. ** Just adjust level and punt on outta here. */
  183. if (file->eFileLock > NO_LOCK)
  184. {
  185. file->eFileLock = eFileLock;
  186. rc = SQLITE_OK;
  187. goto sem_end_lock;
  188. }
  189. /* lock semaphore now but bail out when already locked. */
  190. if (rt_sem_trytake(psem) != RT_EOK)
  191. {
  192. rc = SQLITE_BUSY;
  193. goto sem_end_lock;
  194. }
  195. /* got it, set the type and return ok */
  196. file->eFileLock = eFileLock;
  197. sem_end_lock:
  198. return rc;
  199. }
  200. /*
  201. ** Lower the locking level on file descriptor pFile to eFileLock. eFileLock
  202. ** must be either NO_LOCK or SHARED_LOCK.
  203. **
  204. ** If the locking level of the file descriptor is already at or below
  205. ** the requested locking level, this routine is a no-op.
  206. */
  207. static int _rtthread_io_unlock(sqlite3_file *file_id, int eFileLock)
  208. {
  209. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  210. rt_sem_t psem = &file->sem;
  211. assert(eFileLock <= SHARED_LOCK);
  212. /* no-op if possible */
  213. if (file->eFileLock == eFileLock)
  214. {
  215. return SQLITE_OK;
  216. }
  217. /* shared can just be set because we always have an exclusive */
  218. if (eFileLock == SHARED_LOCK)
  219. {
  220. file->eFileLock = SHARED_LOCK;
  221. return SQLITE_OK;
  222. }
  223. /* no, really unlock. */
  224. rt_sem_release(psem);
  225. file->eFileLock = NO_LOCK;
  226. return SQLITE_OK;
  227. }
  228. static int _rtthread_io_close(sqlite3_file *file_id)
  229. {
  230. int rc = 0;
  231. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  232. if (file->fd >= 0)
  233. {
  234. _rtthread_io_unlock(file_id, NO_LOCK);
  235. rt_sem_detach(&file->sem);
  236. rc = close(file->fd);
  237. file->fd = -1;
  238. }
  239. return rc;
  240. }
  241. static int _rtthread_fcntl_size_hint(sqlite3_file *file_id, i64 nByte)
  242. {
  243. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  244. if (file->szChunk > 0)
  245. {
  246. i64 nSize; /* Required file size */
  247. struct stat buf; /* Used to hold return values of fstat() */
  248. if (fstat(file->fd, &buf))
  249. {
  250. return SQLITE_IOERR_FSTAT;
  251. }
  252. nSize = ((nByte + file->szChunk - 1) / file->szChunk) * file->szChunk;
  253. if (nSize > (i64)buf.st_size)
  254. {
  255. /* If the OS does not have posix_fallocate(), fake it. Write a
  256. ** single byte to the last byte in each block that falls entirely
  257. ** within the extended region. Then, if required, a single byte
  258. ** at offset (nSize-1), to set the size of the file correctly.
  259. ** This is a similar technique to that used by glibc on systems
  260. ** that do not have a real fallocate() call.
  261. */
  262. int nBlk = 512; /* File-system block size */
  263. int nWrite = 0; /* Number of bytes written by seekAndWrite */
  264. i64 iWrite; /* Next offset to write to */
  265. iWrite = (buf.st_size / nBlk) * nBlk + nBlk - 1;
  266. assert(iWrite >= buf.st_size);
  267. assert(((iWrite + 1) % nBlk) == 0);
  268. for (/*no-op*/; iWrite < nSize + nBlk - 1; iWrite += nBlk)
  269. {
  270. if (iWrite >= nSize)
  271. {
  272. iWrite = nSize - 1;
  273. }
  274. nWrite = _rtthread_io_write(file_id, "", 1, iWrite);
  275. if (nWrite != 1)
  276. {
  277. return SQLITE_IOERR_WRITE;
  278. }
  279. }
  280. }
  281. }
  282. return SQLITE_OK;
  283. }
  284. /*
  285. ** Information and control of an open file handle.
  286. */
  287. static int _rtthread_io_file_ctrl(sqlite3_file *file_id, int op, void *pArg)
  288. {
  289. RTTHREAD_SQLITE_FILE_T *file = (RTTHREAD_SQLITE_FILE_T*)file_id;
  290. switch( op )
  291. {
  292. case SQLITE_FCNTL_LOCKSTATE: {
  293. *(int*)pArg = file->eFileLock;
  294. return SQLITE_OK;
  295. }
  296. case SQLITE_LAST_ERRNO: {
  297. *(int*)pArg = 0;
  298. return SQLITE_OK;
  299. }
  300. case SQLITE_FCNTL_CHUNK_SIZE: {
  301. file->szChunk = *(int *)pArg;
  302. return SQLITE_OK;
  303. }
  304. case SQLITE_FCNTL_SIZE_HINT: {
  305. int rc;
  306. rc = _rtthread_fcntl_size_hint(file_id, *(i64 *)pArg);
  307. return rc;
  308. }
  309. case SQLITE_FCNTL_PERSIST_WAL: {
  310. return SQLITE_OK;
  311. }
  312. case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
  313. return SQLITE_OK;
  314. }
  315. case SQLITE_FCNTL_VFSNAME: {
  316. *(char**)pArg = sqlite3_mprintf("%s", file->pvfs->zName);
  317. return SQLITE_OK;
  318. }
  319. case SQLITE_FCNTL_TEMPFILENAME: {
  320. char *zTFile = sqlite3_malloc(file->pvfs->mxPathname );
  321. if( zTFile )
  322. {
  323. _rtthread_get_temp_name(file->pvfs->mxPathname, zTFile);
  324. *(char**)pArg = zTFile;
  325. }
  326. return SQLITE_OK;
  327. }
  328. }
  329. return SQLITE_NOTFOUND;
  330. }
  331. static int _rtthread_io_sector_size(sqlite3_file *file_id)
  332. {
  333. return SQLITE_DEFAULT_SECTOR_SIZE;
  334. }
  335. static int _rtthread_io_device_characteristics(sqlite3_file *file_id)
  336. {
  337. return 0;
  338. }
  339. /*
  340. ** If possible, return a pointer to a mapping of file fd starting at offset
  341. ** iOff. The mapping must be valid for at least nAmt bytes.
  342. **
  343. ** If such a pointer can be obtained, store it in *pp and return SQLITE_OK.
  344. ** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK.
  345. ** Finally, if an error does occur, return an SQLite error code. The final
  346. ** value of *pp is undefined in this case.
  347. **
  348. ** If this function does return a pointer, the caller must eventually
  349. ** release the reference by calling unixUnfetch().
  350. */
  351. static int _rtthread_io_fetch(sqlite3_file *file_id, i64 iOff, int nAmt, void **pp)
  352. {
  353. *pp = 0;
  354. return SQLITE_OK;
  355. }
  356. /*
  357. ** If the third argument is non-NULL, then this function releases a
  358. ** reference obtained by an earlier call to unixFetch(). The second
  359. ** argument passed to this function must be the same as the corresponding
  360. ** argument that was passed to the unixFetch() invocation.
  361. **
  362. ** Or, if the third argument is NULL, then this function is being called
  363. ** to inform the VFS layer that, according to POSIX, any existing mapping
  364. ** may now be invalid and should be unmapped.
  365. */
  366. static int _rtthread_io_unfetch(sqlite3_file *fd, i64 iOff, void *p)
  367. {
  368. return SQLITE_OK;
  369. }
  370. static const sqlite3_io_methods _rtthread_io_method = {
  371. 3,
  372. _rtthread_io_close,
  373. _rtthread_io_read,
  374. _rtthread_io_write,
  375. _rtthread_io_truncate,
  376. _rtthread_io_sync,
  377. _rtthread_io_file_size,
  378. _rtthread_io_lock,
  379. _rtthread_io_unlock,
  380. _rtthread_io_check_reserved_lock,
  381. _rtthread_io_file_ctrl,
  382. _rtthread_io_sector_size,
  383. _rtthread_io_device_characteristics,
  384. 0,
  385. 0,
  386. 0,
  387. 0,
  388. _rtthread_io_fetch,
  389. _rtthread_io_unfetch
  390. };