Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: third_party/sqlite/src/src/test_multiplex.c

Issue 2751253002: [sql] Import SQLite 3.17.0. (Closed)
Patch Set: also clang on Linux i386 Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/sqlite/src/src/test_multiplex.h ('k') | third_party/sqlite/src/src/test_mutex.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ** 2010 October 28 2 ** 2010 October 28
3 ** 3 **
4 ** The author disclaims copyright to this source code. In place of 4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing: 5 ** a legal notice, here is a blessing:
6 ** 6 **
7 ** May you do good and not evil. 7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others. 8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give. 9 ** May you share freely, never taking more than you give.
10 ** 10 **
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 /* 61 /*
62 ** These should be defined to be the same as the values in 62 ** These should be defined to be the same as the values in
63 ** sqliteInt.h. They are defined separately here so that 63 ** sqliteInt.h. They are defined separately here so that
64 ** the multiplex VFS shim can be built as a loadable 64 ** the multiplex VFS shim can be built as a loadable
65 ** module. 65 ** module.
66 */ 66 */
67 #define UNUSED_PARAMETER(x) (void)(x) 67 #define UNUSED_PARAMETER(x) (void)(x)
68 #define MAX_PAGE_SIZE 0x10000 68 #define MAX_PAGE_SIZE 0x10000
69 #define DEFAULT_SECTOR_SIZE 0x1000 69 #define DEFAULT_SECTOR_SIZE 0x1000
70 70
71 /*
72 ** For a build without mutexes, no-op the mutex calls.
73 */
74 #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0
75 #define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8)
76 #define sqlite3_mutex_free(X)
77 #define sqlite3_mutex_enter(X)
78 #define sqlite3_mutex_try(X) SQLITE_OK
79 #define sqlite3_mutex_leave(X)
80 #define sqlite3_mutex_held(X) ((void)(X),1)
81 #define sqlite3_mutex_notheld(X) ((void)(X),1)
82 #endif /* SQLITE_THREADSAFE==0 */
83
84 /* Maximum chunk number */ 71 /* Maximum chunk number */
85 #define MX_CHUNK_NUMBER 299 72 #define MX_CHUNK_NUMBER 299
86 73
87 /* First chunk for rollback journal files */ 74 /* First chunk for rollback journal files */
88 #define SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET 400 75 #define SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET 400
89 #define SQLITE_MULTIPLEX_WAL_8_3_OFFSET 700 76 #define SQLITE_MULTIPLEX_WAL_8_3_OFFSET 700
90 77
91 78
92 /************************ Shim Definitions ******************************/ 79 /************************ Shim Definitions ******************************/
93 80
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 sqlite3_file *p; /* Handle for the chunk */ 119 sqlite3_file *p; /* Handle for the chunk */
133 char *z; /* Name of this chunk */ 120 char *z; /* Name of this chunk */
134 } *aReal; /* list of all chunks */ 121 } *aReal; /* list of all chunks */
135 int nReal; /* Number of chunks */ 122 int nReal; /* Number of chunks */
136 char *zName; /* Base filename of this group */ 123 char *zName; /* Base filename of this group */
137 int nName; /* Length of base filename */ 124 int nName; /* Length of base filename */
138 int flags; /* Flags used for original opening */ 125 int flags; /* Flags used for original opening */
139 unsigned int szChunk; /* Chunk size used for this group */ 126 unsigned int szChunk; /* Chunk size used for this group */
140 unsigned char bEnabled; /* TRUE to use Multiplex VFS for this file */ 127 unsigned char bEnabled; /* TRUE to use Multiplex VFS for this file */
141 unsigned char bTruncate; /* TRUE to enable truncation of databases */ 128 unsigned char bTruncate; /* TRUE to enable truncation of databases */
142 multiplexGroup *pNext, *pPrev; /* Doubly linked list of all group objects */
143 }; 129 };
144 130
145 /* 131 /*
146 ** An instance of the following object represents each open connection 132 ** An instance of the following object represents each open connection
147 ** to a file that is multiplex'ed. This object is a 133 ** to a file that is multiplex'ed. This object is a
148 ** subclass of sqlite3_file. The sqlite3_file object for the underlying 134 ** subclass of sqlite3_file. The sqlite3_file object for the underlying
149 ** VFS is appended to this structure. 135 ** VFS is appended to this structure.
150 */ 136 */
151 struct multiplexConn { 137 struct multiplexConn {
152 sqlite3_file base; /* Base class - must be first */ 138 sqlite3_file base; /* Base class - must be first */
(...skipping 27 matching lines...) Expand all
180 ** has to create a wrapper sqlite3_file of the same version. Hence 166 ** has to create a wrapper sqlite3_file of the same version. Hence
181 ** there are two I/O method structures, one for version 1 and the other 167 ** there are two I/O method structures, one for version 1 and the other
182 ** for version 2. 168 ** for version 2.
183 */ 169 */
184 sqlite3_io_methods sIoMethodsV1; 170 sqlite3_io_methods sIoMethodsV1;
185 sqlite3_io_methods sIoMethodsV2; 171 sqlite3_io_methods sIoMethodsV2;
186 172
187 /* True when this shim has been initialized. 173 /* True when this shim has been initialized.
188 */ 174 */
189 int isInitialized; 175 int isInitialized;
190
191 /* For run-time access any of the other global data structures in this
192 ** shim, the following mutex must be held. In practice, all this mutex
193 ** protects is add/remove operations to/from the linked list of group objects
194 ** starting at pGroups below. More specifically, it protects the value of
195 ** pGroups itself, and the pNext/pPrev fields of each multiplexGroup
196 ** structure. */
197 sqlite3_mutex *pMutex;
198
199 /* List of multiplexGroup objects.
200 */
201 multiplexGroup *pGroups;
202 } gMultiplex; 176 } gMultiplex;
203 177
204 /************************* Utility Routines *********************************/ 178 /************************* Utility Routines *********************************/
205 /* 179 /*
206 ** Acquire and release the mutex used to serialize access to the
207 ** list of multiplexGroups.
208 */
209 static void multiplexEnter(void){ sqlite3_mutex_enter(gMultiplex.pMutex); }
210 static void multiplexLeave(void){ sqlite3_mutex_leave(gMultiplex.pMutex); }
211
212 /*
213 ** Compute a string length that is limited to what can be stored in 180 ** Compute a string length that is limited to what can be stored in
214 ** lower 30 bits of a 32-bit signed integer. 181 ** lower 30 bits of a 32-bit signed integer.
215 ** 182 **
216 ** The value returned will never be negative. Nor will it ever be greater 183 ** The value returned will never be negative. Nor will it ever be greater
217 ** than the actual length of the string. For very long strings (greater 184 ** than the actual length of the string. For very long strings (greater
218 ** than 1GiB) the value returned might be less than the true string length. 185 ** than 1GiB) the value returned might be less than the true string length.
219 */ 186 */
220 static int multiplexStrlen30(const char *z){ 187 static int multiplexStrlen30(const char *z){
221 const char *z2 = z; 188 const char *z2 = z;
222 if( z==0 ) return 0; 189 if( z==0 ) return 0;
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 int sz = 0; 479 int sz = 0;
513 char *zToFree = 0; 480 char *zToFree = 0;
514 481
515 UNUSED_PARAMETER(pVfs); 482 UNUSED_PARAMETER(pVfs);
516 memset(pConn, 0, pVfs->szOsFile); 483 memset(pConn, 0, pVfs->szOsFile);
517 assert( zName || (flags & SQLITE_OPEN_DELETEONCLOSE) ); 484 assert( zName || (flags & SQLITE_OPEN_DELETEONCLOSE) );
518 485
519 /* We need to create a group structure and manage 486 /* We need to create a group structure and manage
520 ** access to this group of files. 487 ** access to this group of files.
521 */ 488 */
522 multiplexEnter();
523 pMultiplexOpen = (multiplexConn*)pConn; 489 pMultiplexOpen = (multiplexConn*)pConn;
524 490
525 if( rc==SQLITE_OK ){ 491 if( rc==SQLITE_OK ){
526 /* allocate space for group */ 492 /* allocate space for group */
527 nName = zName ? multiplexStrlen30(zName) : 0; 493 nName = zName ? multiplexStrlen30(zName) : 0;
528 sz = sizeof(multiplexGroup) /* multiplexGroup */ 494 sz = sizeof(multiplexGroup) /* multiplexGroup */
529 + nName + 1; /* zName */ 495 + nName + 1; /* zName */
530 pGroup = sqlite3_malloc64( sz ); 496 pGroup = sqlite3_malloc64( sz );
531 if( pGroup==0 ){ 497 if( pGroup==0 ){
532 rc = SQLITE_NOMEM; 498 rc = SQLITE_NOMEM;
533 } 499 }
534 } 500 }
535 501
536 if( rc==SQLITE_OK ){ 502 if( rc==SQLITE_OK ){
537 const char *zUri = (flags & SQLITE_OPEN_URI) ? zName : 0; 503 const char *zUri = (flags & SQLITE_OPEN_URI) ? zName : 0;
538 /* assign pointers to extra space allocated */ 504 /* assign pointers to extra space allocated */
539 memset(pGroup, 0, sz); 505 memset(pGroup, 0, sz);
540 pMultiplexOpen->pGroup = pGroup; 506 pMultiplexOpen->pGroup = pGroup;
541 pGroup->bEnabled = (unsigned char)-1; 507 pGroup->bEnabled = (unsigned char)-1;
542 pGroup->bTruncate = sqlite3_uri_boolean(zUri, "truncate", 508 pGroup->bTruncate = (unsigned char)sqlite3_uri_boolean(zUri, "truncate",
543 (flags & SQLITE_OPEN_MAIN_DB)==0); 509 (flags & SQLITE_OPEN_MAIN_DB)==0);
544 pGroup->szChunk = (int)sqlite3_uri_int64(zUri, "chunksize", 510 pGroup->szChunk = (int)sqlite3_uri_int64(zUri, "chunksize",
545 SQLITE_MULTIPLEX_CHUNK_SIZE); 511 SQLITE_MULTIPLEX_CHUNK_SIZE);
546 pGroup->szChunk = (pGroup->szChunk+0xffff)&~0xffff; 512 pGroup->szChunk = (pGroup->szChunk+0xffff)&~0xffff;
547 if( zName ){ 513 if( zName ){
548 char *p = (char *)&pGroup[1]; 514 char *p = (char *)&pGroup[1];
549 pGroup->zName = p; 515 pGroup->zName = p;
550 memcpy(pGroup->zName, zName, nName+1); 516 memcpy(pGroup->zName, zName, nName+1);
551 pGroup->nName = nName; 517 pGroup->nName = nName;
552 } 518 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 } 585 }
620 } 586 }
621 } 587 }
622 588
623 if( rc==SQLITE_OK ){ 589 if( rc==SQLITE_OK ){
624 if( pSubOpen->pMethods->iVersion==1 ){ 590 if( pSubOpen->pMethods->iVersion==1 ){
625 pMultiplexOpen->base.pMethods = &gMultiplex.sIoMethodsV1; 591 pMultiplexOpen->base.pMethods = &gMultiplex.sIoMethodsV1;
626 }else{ 592 }else{
627 pMultiplexOpen->base.pMethods = &gMultiplex.sIoMethodsV2; 593 pMultiplexOpen->base.pMethods = &gMultiplex.sIoMethodsV2;
628 } 594 }
629 /* place this group at the head of our list */
630 pGroup->pNext = gMultiplex.pGroups;
631 if( gMultiplex.pGroups ) gMultiplex.pGroups->pPrev = pGroup;
632 gMultiplex.pGroups = pGroup;
633 }else{ 595 }else{
634 multiplexFreeComponents(pGroup); 596 multiplexFreeComponents(pGroup);
635 sqlite3_free(pGroup); 597 sqlite3_free(pGroup);
636 } 598 }
637 } 599 }
638 multiplexLeave();
639 sqlite3_free(zToFree); 600 sqlite3_free(zToFree);
640 return rc; 601 return rc;
641 } 602 }
642 603
643 /* 604 /*
644 ** This is the xDelete method used for the "multiplex" VFS. 605 ** This is the xDelete method used for the "multiplex" VFS.
645 ** It attempts to delete the filename specified. 606 ** It attempts to delete the filename specified.
646 */ 607 */
647 static int multiplexDelete( 608 static int multiplexDelete(
648 sqlite3_vfs *pVfs, /* The multiplex VFS */ 609 sqlite3_vfs *pVfs, /* The multiplex VFS */
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 static int multiplexRandomness(sqlite3_vfs *a, int b, char *c){ 671 static int multiplexRandomness(sqlite3_vfs *a, int b, char *c){
711 return gMultiplex.pOrigVfs->xRandomness(gMultiplex.pOrigVfs, b, c); 672 return gMultiplex.pOrigVfs->xRandomness(gMultiplex.pOrigVfs, b, c);
712 } 673 }
713 static int multiplexSleep(sqlite3_vfs *a, int b){ 674 static int multiplexSleep(sqlite3_vfs *a, int b){
714 return gMultiplex.pOrigVfs->xSleep(gMultiplex.pOrigVfs, b); 675 return gMultiplex.pOrigVfs->xSleep(gMultiplex.pOrigVfs, b);
715 } 676 }
716 static int multiplexCurrentTime(sqlite3_vfs *a, double *b){ 677 static int multiplexCurrentTime(sqlite3_vfs *a, double *b){
717 return gMultiplex.pOrigVfs->xCurrentTime(gMultiplex.pOrigVfs, b); 678 return gMultiplex.pOrigVfs->xCurrentTime(gMultiplex.pOrigVfs, b);
718 } 679 }
719 static int multiplexGetLastError(sqlite3_vfs *a, int b, char *c){ 680 static int multiplexGetLastError(sqlite3_vfs *a, int b, char *c){
720 return gMultiplex.pOrigVfs->xGetLastError(gMultiplex.pOrigVfs, b, c); 681 if( gMultiplex.pOrigVfs->xGetLastError ){
682 return gMultiplex.pOrigVfs->xGetLastError(gMultiplex.pOrigVfs, b, c);
683 }else{
684 return 0;
685 }
721 } 686 }
722 static int multiplexCurrentTimeInt64(sqlite3_vfs *a, sqlite3_int64 *b){ 687 static int multiplexCurrentTimeInt64(sqlite3_vfs *a, sqlite3_int64 *b){
723 return gMultiplex.pOrigVfs->xCurrentTimeInt64(gMultiplex.pOrigVfs, b); 688 return gMultiplex.pOrigVfs->xCurrentTimeInt64(gMultiplex.pOrigVfs, b);
724 } 689 }
725 690
726 /************************ I/O Method Wrappers *******************************/ 691 /************************ I/O Method Wrappers *******************************/
727 692
728 /* xClose requests get passed through to the original VFS. 693 /* xClose requests get passed through to the original VFS.
729 ** We loop over all open chunk handles and close them. 694 ** We loop over all open chunk handles and close them.
730 ** The group structure for this file is unlinked from 695 ** The group structure for this file is unlinked from
731 ** our list of groups and freed. 696 ** our list of groups and freed.
732 */ 697 */
733 static int multiplexClose(sqlite3_file *pConn){ 698 static int multiplexClose(sqlite3_file *pConn){
734 multiplexConn *p = (multiplexConn*)pConn; 699 multiplexConn *p = (multiplexConn*)pConn;
735 multiplexGroup *pGroup = p->pGroup; 700 multiplexGroup *pGroup = p->pGroup;
736 int rc = SQLITE_OK; 701 int rc = SQLITE_OK;
737 multiplexEnter();
738 multiplexFreeComponents(pGroup); 702 multiplexFreeComponents(pGroup);
739 /* remove from linked list */
740 if( pGroup->pNext ) pGroup->pNext->pPrev = pGroup->pPrev;
741 if( pGroup->pPrev ){
742 pGroup->pPrev->pNext = pGroup->pNext;
743 }else{
744 gMultiplex.pGroups = pGroup->pNext;
745 }
746 sqlite3_free(pGroup); 703 sqlite3_free(pGroup);
747 multiplexLeave();
748 return rc; 704 return rc;
749 } 705 }
750 706
751 /* Pass xRead requests thru to the original VFS after 707 /* Pass xRead requests thru to the original VFS after
752 ** determining the correct chunk to operate on. 708 ** determining the correct chunk to operate on.
753 ** Break up reads across chunk boundaries. 709 ** Break up reads across chunk boundaries.
754 */ 710 */
755 static int multiplexRead( 711 static int multiplexRead(
756 sqlite3_file *pConn, 712 sqlite3_file *pConn,
757 void *pBuf, 713 void *pBuf,
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 } 790 }
835 791
836 /* Pass xTruncate requests thru to the original VFS after 792 /* Pass xTruncate requests thru to the original VFS after
837 ** determining the correct chunk to operate on. Delete any 793 ** determining the correct chunk to operate on. Delete any
838 ** chunks above the truncate mark. 794 ** chunks above the truncate mark.
839 */ 795 */
840 static int multiplexTruncate(sqlite3_file *pConn, sqlite3_int64 size){ 796 static int multiplexTruncate(sqlite3_file *pConn, sqlite3_int64 size){
841 multiplexConn *p = (multiplexConn*)pConn; 797 multiplexConn *p = (multiplexConn*)pConn;
842 multiplexGroup *pGroup = p->pGroup; 798 multiplexGroup *pGroup = p->pGroup;
843 int rc = SQLITE_OK; 799 int rc = SQLITE_OK;
844 multiplexEnter();
845 if( !pGroup->bEnabled ){ 800 if( !pGroup->bEnabled ){
846 sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0); 801 sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
847 if( pSubOpen==0 ){ 802 if( pSubOpen==0 ){
848 rc = SQLITE_IOERR_TRUNCATE; 803 rc = SQLITE_IOERR_TRUNCATE;
849 }else{ 804 }else{
850 rc = pSubOpen->pMethods->xTruncate(pSubOpen, size); 805 rc = pSubOpen->pMethods->xTruncate(pSubOpen, size);
851 } 806 }
852 }else{ 807 }else{
853 int i; 808 int i;
854 int iBaseGroup = (int)(size / pGroup->szChunk); 809 int iBaseGroup = (int)(size / pGroup->szChunk);
(...skipping 11 matching lines...) Expand all
866 } 821 }
867 } 822 }
868 if( rc==SQLITE_OK ){ 823 if( rc==SQLITE_OK ){
869 pSubOpen = multiplexSubOpen(pGroup, iBaseGroup, &rc, 0, 0); 824 pSubOpen = multiplexSubOpen(pGroup, iBaseGroup, &rc, 0, 0);
870 if( pSubOpen ){ 825 if( pSubOpen ){
871 rc = pSubOpen->pMethods->xTruncate(pSubOpen, size % pGroup->szChunk); 826 rc = pSubOpen->pMethods->xTruncate(pSubOpen, size % pGroup->szChunk);
872 } 827 }
873 } 828 }
874 if( rc ) rc = SQLITE_IOERR_TRUNCATE; 829 if( rc ) rc = SQLITE_IOERR_TRUNCATE;
875 } 830 }
876 multiplexLeave();
877 return rc; 831 return rc;
878 } 832 }
879 833
880 /* Pass xSync requests through to the original VFS without change 834 /* Pass xSync requests through to the original VFS without change
881 */ 835 */
882 static int multiplexSync(sqlite3_file *pConn, int flags){ 836 static int multiplexSync(sqlite3_file *pConn, int flags){
883 multiplexConn *p = (multiplexConn*)pConn; 837 multiplexConn *p = (multiplexConn*)pConn;
884 multiplexGroup *pGroup = p->pGroup; 838 multiplexGroup *pGroup = p->pGroup;
885 int rc = SQLITE_OK; 839 int rc = SQLITE_OK;
886 int i; 840 int i;
887 multiplexEnter();
888 for(i=0; i<pGroup->nReal; i++){ 841 for(i=0; i<pGroup->nReal; i++){
889 sqlite3_file *pSubOpen = pGroup->aReal[i].p; 842 sqlite3_file *pSubOpen = pGroup->aReal[i].p;
890 if( pSubOpen ){ 843 if( pSubOpen ){
891 int rc2 = pSubOpen->pMethods->xSync(pSubOpen, flags); 844 int rc2 = pSubOpen->pMethods->xSync(pSubOpen, flags);
892 if( rc2!=SQLITE_OK ) rc = rc2; 845 if( rc2!=SQLITE_OK ) rc = rc2;
893 } 846 }
894 } 847 }
895 multiplexLeave();
896 return rc; 848 return rc;
897 } 849 }
898 850
899 /* Pass xFileSize requests through to the original VFS. 851 /* Pass xFileSize requests through to the original VFS.
900 ** Aggregate the size of all the chunks before returning. 852 ** Aggregate the size of all the chunks before returning.
901 */ 853 */
902 static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){ 854 static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){
903 multiplexConn *p = (multiplexConn*)pConn; 855 multiplexConn *p = (multiplexConn*)pConn;
904 multiplexGroup *pGroup = p->pGroup; 856 multiplexGroup *pGroup = p->pGroup;
905 int rc = SQLITE_OK; 857 int rc = SQLITE_OK;
906 int i; 858 int i;
907 multiplexEnter();
908 if( !pGroup->bEnabled ){ 859 if( !pGroup->bEnabled ){
909 sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0); 860 sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
910 if( pSubOpen==0 ){ 861 if( pSubOpen==0 ){
911 rc = SQLITE_IOERR_FSTAT; 862 rc = SQLITE_IOERR_FSTAT;
912 }else{ 863 }else{
913 rc = pSubOpen->pMethods->xFileSize(pSubOpen, pSize); 864 rc = pSubOpen->pMethods->xFileSize(pSubOpen, pSize);
914 } 865 }
915 }else{ 866 }else{
916 *pSize = 0; 867 *pSize = 0;
917 for(i=0; rc==SQLITE_OK; i++){ 868 for(i=0; rc==SQLITE_OK; i++){
918 sqlite3_int64 sz = multiplexSubSize(pGroup, i, &rc); 869 sqlite3_int64 sz = multiplexSubSize(pGroup, i, &rc);
919 if( sz==0 ) break; 870 if( sz==0 ) break;
920 *pSize = i*(sqlite3_int64)pGroup->szChunk + sz; 871 *pSize = i*(sqlite3_int64)pGroup->szChunk + sz;
921 } 872 }
922 } 873 }
923 multiplexLeave();
924 return rc; 874 return rc;
925 } 875 }
926 876
927 /* Pass xLock requests through to the original VFS unchanged. 877 /* Pass xLock requests through to the original VFS unchanged.
928 */ 878 */
929 static int multiplexLock(sqlite3_file *pConn, int lock){ 879 static int multiplexLock(sqlite3_file *pConn, int lock){
930 multiplexConn *p = (multiplexConn*)pConn; 880 multiplexConn *p = (multiplexConn*)pConn;
931 int rc; 881 int rc;
932 sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0); 882 sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
933 if( pSubOpen ){ 883 if( pSubOpen ){
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
967 multiplexConn *p = (multiplexConn*)pConn; 917 multiplexConn *p = (multiplexConn*)pConn;
968 multiplexGroup *pGroup = p->pGroup; 918 multiplexGroup *pGroup = p->pGroup;
969 int rc = SQLITE_ERROR; 919 int rc = SQLITE_ERROR;
970 sqlite3_file *pSubOpen; 920 sqlite3_file *pSubOpen;
971 921
972 if( !gMultiplex.isInitialized ) return SQLITE_MISUSE; 922 if( !gMultiplex.isInitialized ) return SQLITE_MISUSE;
973 switch( op ){ 923 switch( op ){
974 case MULTIPLEX_CTRL_ENABLE: 924 case MULTIPLEX_CTRL_ENABLE:
975 if( pArg ) { 925 if( pArg ) {
976 int bEnabled = *(int *)pArg; 926 int bEnabled = *(int *)pArg;
977 pGroup->bEnabled = bEnabled; 927 pGroup->bEnabled = (unsigned char)bEnabled;
978 rc = SQLITE_OK; 928 rc = SQLITE_OK;
979 } 929 }
980 break; 930 break;
981 case MULTIPLEX_CTRL_SET_CHUNK_SIZE: 931 case MULTIPLEX_CTRL_SET_CHUNK_SIZE:
982 if( pArg ) { 932 if( pArg ) {
983 unsigned int szChunk = *(unsigned*)pArg; 933 unsigned int szChunk = *(unsigned*)pArg;
984 if( szChunk<1 ){ 934 if( szChunk<1 ){
985 rc = SQLITE_MISUSE; 935 rc = SQLITE_MISUSE;
986 }else{ 936 }else{
987 /* Round up to nearest multiple of MAX_PAGE_SIZE. */ 937 /* Round up to nearest multiple of MAX_PAGE_SIZE. */
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
1140 ** 1090 **
1141 ** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once 1091 ** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once
1142 ** during start-up. 1092 ** during start-up.
1143 */ 1093 */
1144 int sqlite3_multiplex_initialize(const char *zOrigVfsName, int makeDefault){ 1094 int sqlite3_multiplex_initialize(const char *zOrigVfsName, int makeDefault){
1145 sqlite3_vfs *pOrigVfs; 1095 sqlite3_vfs *pOrigVfs;
1146 if( gMultiplex.isInitialized ) return SQLITE_MISUSE; 1096 if( gMultiplex.isInitialized ) return SQLITE_MISUSE;
1147 pOrigVfs = sqlite3_vfs_find(zOrigVfsName); 1097 pOrigVfs = sqlite3_vfs_find(zOrigVfsName);
1148 if( pOrigVfs==0 ) return SQLITE_ERROR; 1098 if( pOrigVfs==0 ) return SQLITE_ERROR;
1149 assert( pOrigVfs!=&gMultiplex.sThisVfs ); 1099 assert( pOrigVfs!=&gMultiplex.sThisVfs );
1150 gMultiplex.pMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
1151 if( !gMultiplex.pMutex ){
1152 return SQLITE_NOMEM;
1153 }
1154 gMultiplex.pGroups = NULL;
1155 gMultiplex.isInitialized = 1; 1100 gMultiplex.isInitialized = 1;
1156 gMultiplex.pOrigVfs = pOrigVfs; 1101 gMultiplex.pOrigVfs = pOrigVfs;
1157 gMultiplex.sThisVfs = *pOrigVfs; 1102 gMultiplex.sThisVfs = *pOrigVfs;
1158 gMultiplex.sThisVfs.szOsFile += sizeof(multiplexConn); 1103 gMultiplex.sThisVfs.szOsFile += sizeof(multiplexConn);
1159 gMultiplex.sThisVfs.zName = SQLITE_MULTIPLEX_VFS_NAME; 1104 gMultiplex.sThisVfs.zName = SQLITE_MULTIPLEX_VFS_NAME;
1160 gMultiplex.sThisVfs.xOpen = multiplexOpen; 1105 gMultiplex.sThisVfs.xOpen = multiplexOpen;
1161 gMultiplex.sThisVfs.xDelete = multiplexDelete; 1106 gMultiplex.sThisVfs.xDelete = multiplexDelete;
1162 gMultiplex.sThisVfs.xAccess = multiplexAccess; 1107 gMultiplex.sThisVfs.xAccess = multiplexAccess;
1163 gMultiplex.sThisVfs.xFullPathname = multiplexFullPathname; 1108 gMultiplex.sThisVfs.xFullPathname = multiplexFullPathname;
1164 gMultiplex.sThisVfs.xDlOpen = multiplexDlOpen; 1109 gMultiplex.sThisVfs.xDlOpen = multiplexDlOpen;
(...skipping 21 matching lines...) Expand all
1186 gMultiplex.sIoMethodsV1.xDeviceCharacteristics = 1131 gMultiplex.sIoMethodsV1.xDeviceCharacteristics =
1187 multiplexDeviceCharacteristics; 1132 multiplexDeviceCharacteristics;
1188 gMultiplex.sIoMethodsV2 = gMultiplex.sIoMethodsV1; 1133 gMultiplex.sIoMethodsV2 = gMultiplex.sIoMethodsV1;
1189 gMultiplex.sIoMethodsV2.iVersion = 2; 1134 gMultiplex.sIoMethodsV2.iVersion = 2;
1190 gMultiplex.sIoMethodsV2.xShmMap = multiplexShmMap; 1135 gMultiplex.sIoMethodsV2.xShmMap = multiplexShmMap;
1191 gMultiplex.sIoMethodsV2.xShmLock = multiplexShmLock; 1136 gMultiplex.sIoMethodsV2.xShmLock = multiplexShmLock;
1192 gMultiplex.sIoMethodsV2.xShmBarrier = multiplexShmBarrier; 1137 gMultiplex.sIoMethodsV2.xShmBarrier = multiplexShmBarrier;
1193 gMultiplex.sIoMethodsV2.xShmUnmap = multiplexShmUnmap; 1138 gMultiplex.sIoMethodsV2.xShmUnmap = multiplexShmUnmap;
1194 sqlite3_vfs_register(&gMultiplex.sThisVfs, makeDefault); 1139 sqlite3_vfs_register(&gMultiplex.sThisVfs, makeDefault);
1195 1140
1196 sqlite3_auto_extension((void*)multiplexFuncInit); 1141 sqlite3_auto_extension((void(*)(void))multiplexFuncInit);
1197 1142
1198 return SQLITE_OK; 1143 return SQLITE_OK;
1199 } 1144 }
1200 1145
1201 /* 1146 /*
1202 ** CAPI: Shutdown the multiplex system - sqlite3_multiplex_shutdown() 1147 ** CAPI: Shutdown the multiplex system - sqlite3_multiplex_shutdown()
1203 ** 1148 **
1204 ** All SQLite database connections must be closed before calling this 1149 ** All SQLite database connections must be closed before calling this
1205 ** routine. 1150 ** routine.
1206 ** 1151 **
1207 ** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once while 1152 ** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once while
1208 ** shutting down in order to free all remaining multiplex groups. 1153 ** shutting down in order to free all remaining multiplex groups.
1209 */ 1154 */
1210 int sqlite3_multiplex_shutdown(int eForce){ 1155 int sqlite3_multiplex_shutdown(int eForce){
1211 int rc = SQLITE_OK; 1156 int rc = SQLITE_OK;
1212 if( gMultiplex.isInitialized==0 ) return SQLITE_MISUSE; 1157 if( gMultiplex.isInitialized==0 ) return SQLITE_MISUSE;
1213 if( gMultiplex.pGroups ){
1214 sqlite3_log(SQLITE_MISUSE, "sqlite3_multiplex_shutdown() called "
1215 "while database connections are still open");
1216 if( !eForce ) return SQLITE_MISUSE;
1217 rc = SQLITE_MISUSE;
1218 }
1219 gMultiplex.isInitialized = 0; 1158 gMultiplex.isInitialized = 0;
1220 sqlite3_mutex_free(gMultiplex.pMutex);
1221 sqlite3_vfs_unregister(&gMultiplex.sThisVfs); 1159 sqlite3_vfs_unregister(&gMultiplex.sThisVfs);
1222 memset(&gMultiplex, 0, sizeof(gMultiplex)); 1160 memset(&gMultiplex, 0, sizeof(gMultiplex));
1223 return rc; 1161 return rc;
1224 } 1162 }
1225 1163
1226 /***************************** Test Code ***********************************/ 1164 /***************************** Test Code ***********************************/
1227 #ifdef SQLITE_TEST 1165 #ifdef SQLITE_TEST
1228 #include <tcl.h> 1166 #if defined(INCLUDE_SQLITE_TCL_H)
1167 # include "sqlite_tcl.h"
1168 #else
1169 # include "tcl.h"
1170 # ifndef SQLITE_TCLAPI
1171 # define SQLITE_TCLAPI
1172 # endif
1173 #endif
1229 extern const char *sqlite3ErrName(int); 1174 extern const char *sqlite3ErrName(int);
1230 1175
1231 1176
1232 /* 1177 /*
1233 ** tclcmd: sqlite3_multiplex_initialize NAME MAKEDEFAULT 1178 ** tclcmd: sqlite3_multiplex_initialize NAME MAKEDEFAULT
1234 */ 1179 */
1235 static int test_multiplex_initialize( 1180 static int SQLITE_TCLAPI test_multiplex_initialize(
1236 void * clientData, 1181 void * clientData,
1237 Tcl_Interp *interp, 1182 Tcl_Interp *interp,
1238 int objc, 1183 int objc,
1239 Tcl_Obj *CONST objv[] 1184 Tcl_Obj *CONST objv[]
1240 ){ 1185 ){
1241 const char *zName; /* Name of new multiplex VFS */ 1186 const char *zName; /* Name of new multiplex VFS */
1242 int makeDefault; /* True to make the new VFS the default */ 1187 int makeDefault; /* True to make the new VFS the default */
1243 int rc; /* Value returned by multiplex_initialize() */ 1188 int rc; /* Value returned by multiplex_initialize() */
1244 1189
1245 UNUSED_PARAMETER(clientData); 1190 UNUSED_PARAMETER(clientData);
(...skipping 10 matching lines...) Expand all
1256 /* Call sqlite3_multiplex_initialize() */ 1201 /* Call sqlite3_multiplex_initialize() */
1257 rc = sqlite3_multiplex_initialize(zName, makeDefault); 1202 rc = sqlite3_multiplex_initialize(zName, makeDefault);
1258 Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC); 1203 Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
1259 1204
1260 return TCL_OK; 1205 return TCL_OK;
1261 } 1206 }
1262 1207
1263 /* 1208 /*
1264 ** tclcmd: sqlite3_multiplex_shutdown 1209 ** tclcmd: sqlite3_multiplex_shutdown
1265 */ 1210 */
1266 static int test_multiplex_shutdown( 1211 static int SQLITE_TCLAPI test_multiplex_shutdown(
1267 void * clientData, 1212 void * clientData,
1268 Tcl_Interp *interp, 1213 Tcl_Interp *interp,
1269 int objc, 1214 int objc,
1270 Tcl_Obj *CONST objv[] 1215 Tcl_Obj *CONST objv[]
1271 ){ 1216 ){
1272 int rc; /* Value returned by multiplex_shutdown() */ 1217 int rc; /* Value returned by multiplex_shutdown() */
1273 1218
1274 UNUSED_PARAMETER(clientData); 1219 UNUSED_PARAMETER(clientData);
1275 1220
1276 if( objc==2 && strcmp(Tcl_GetString(objv[1]),"-force")!=0 ){ 1221 if( objc==2 && strcmp(Tcl_GetString(objv[1]),"-force")!=0 ){
1277 objc = 3; 1222 objc = 3;
1278 } 1223 }
1279 if( (objc!=1 && objc!=2) ){ 1224 if( (objc!=1 && objc!=2) ){
1280 Tcl_WrongNumArgs(interp, 1, objv, "?-force?"); 1225 Tcl_WrongNumArgs(interp, 1, objv, "?-force?");
1281 return TCL_ERROR; 1226 return TCL_ERROR;
1282 } 1227 }
1283 1228
1284 /* Call sqlite3_multiplex_shutdown() */ 1229 /* Call sqlite3_multiplex_shutdown() */
1285 rc = sqlite3_multiplex_shutdown(objc==2); 1230 rc = sqlite3_multiplex_shutdown(objc==2);
1286 Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC); 1231 Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
1287 1232
1288 return TCL_OK; 1233 return TCL_OK;
1289 } 1234 }
1290 1235
1291 /* 1236 /*
1292 ** tclcmd: sqlite3_multiplex_dump
1293 */
1294 static int test_multiplex_dump(
1295 void * clientData,
1296 Tcl_Interp *interp,
1297 int objc,
1298 Tcl_Obj *CONST objv[]
1299 ){
1300 Tcl_Obj *pResult;
1301 Tcl_Obj *pGroupTerm;
1302 multiplexGroup *pGroup;
1303 int i;
1304 int nChunks = 0;
1305
1306 UNUSED_PARAMETER(clientData);
1307 UNUSED_PARAMETER(objc);
1308 UNUSED_PARAMETER(objv);
1309
1310 pResult = Tcl_NewObj();
1311 multiplexEnter();
1312 for(pGroup=gMultiplex.pGroups; pGroup; pGroup=pGroup->pNext){
1313 pGroupTerm = Tcl_NewObj();
1314
1315 if( pGroup->zName ){
1316 pGroup->zName[pGroup->nName] = '\0';
1317 Tcl_ListObjAppendElement(interp, pGroupTerm,
1318 Tcl_NewStringObj(pGroup->zName, -1));
1319 }else{
1320 Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewObj());
1321 }
1322 Tcl_ListObjAppendElement(interp, pGroupTerm,
1323 Tcl_NewIntObj(pGroup->nName));
1324 Tcl_ListObjAppendElement(interp, pGroupTerm,
1325 Tcl_NewIntObj(pGroup->flags));
1326
1327 /* count number of chunks with open handles */
1328 for(i=0; i<pGroup->nReal; i++){
1329 if( pGroup->aReal[i].p!=0 ) nChunks++;
1330 }
1331 Tcl_ListObjAppendElement(interp, pGroupTerm,
1332 Tcl_NewIntObj(nChunks));
1333
1334 Tcl_ListObjAppendElement(interp, pGroupTerm,
1335 Tcl_NewIntObj(pGroup->szChunk));
1336 Tcl_ListObjAppendElement(interp, pGroupTerm,
1337 Tcl_NewIntObj(pGroup->nReal));
1338
1339 Tcl_ListObjAppendElement(interp, pResult, pGroupTerm);
1340 }
1341 multiplexLeave();
1342 Tcl_SetObjResult(interp, pResult);
1343 return TCL_OK;
1344 }
1345
1346 /*
1347 ** Tclcmd: test_multiplex_control HANDLE DBNAME SUB-COMMAND ?INT-VALUE? 1237 ** Tclcmd: test_multiplex_control HANDLE DBNAME SUB-COMMAND ?INT-VALUE?
1348 */ 1238 */
1349 static int test_multiplex_control( 1239 static int SQLITE_TCLAPI test_multiplex_control(
1350 ClientData cd, 1240 ClientData cd,
1351 Tcl_Interp *interp, 1241 Tcl_Interp *interp,
1352 int objc, 1242 int objc,
1353 Tcl_Obj *CONST objv[] 1243 Tcl_Obj *CONST objv[]
1354 ){ 1244 ){
1355 int rc; /* Return code from file_control() */ 1245 int rc; /* Return code from file_control() */
1356 int idx; /* Index in aSub[] */ 1246 int idx; /* Index in aSub[] */
1357 Tcl_CmdInfo cmdInfo; /* Command info structure for HANDLE */ 1247 Tcl_CmdInfo cmdInfo; /* Command info structure for HANDLE */
1358 sqlite3 *db; /* Underlying db handle for HANDLE */ 1248 sqlite3 *db; /* Underlying db handle for HANDLE */
1359 int iValue = 0; 1249 int iValue = 0;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1410 ** module. This should be the only procedure visible from outside 1300 ** module. This should be the only procedure visible from outside
1411 ** of this module. 1301 ** of this module.
1412 */ 1302 */
1413 int Sqlitemultiplex_Init(Tcl_Interp *interp){ 1303 int Sqlitemultiplex_Init(Tcl_Interp *interp){
1414 static struct { 1304 static struct {
1415 char *zName; 1305 char *zName;
1416 Tcl_ObjCmdProc *xProc; 1306 Tcl_ObjCmdProc *xProc;
1417 } aCmd[] = { 1307 } aCmd[] = {
1418 { "sqlite3_multiplex_initialize", test_multiplex_initialize }, 1308 { "sqlite3_multiplex_initialize", test_multiplex_initialize },
1419 { "sqlite3_multiplex_shutdown", test_multiplex_shutdown }, 1309 { "sqlite3_multiplex_shutdown", test_multiplex_shutdown },
1420 { "sqlite3_multiplex_dump", test_multiplex_dump },
1421 { "sqlite3_multiplex_control", test_multiplex_control }, 1310 { "sqlite3_multiplex_control", test_multiplex_control },
1422 }; 1311 };
1423 int i; 1312 int i;
1424 1313
1425 for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ 1314 for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
1426 Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); 1315 Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
1427 } 1316 }
1428 1317
1429 return TCL_OK; 1318 return TCL_OK;
1430 } 1319 }
1431 #endif 1320 #endif
OLDNEW
« no previous file with comments | « third_party/sqlite/src/src/test_multiplex.h ('k') | third_party/sqlite/src/src/test_mutex.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698