Fossil SCM

Various memleak fixes. Drops the reachable-at-exit memory of (fossil rebuild) on this repo from 45MB to 680kb. Added fossil_atexit_free_this() to allow us to clean up function-local static allocations.

stephan 2019-12-20 00:12 memleak-fixes
Commit 00e6d7997c3e69a6a379fdd11b89a983b5fccf118ea182b491c94fbe08f25d63
+5
--- src/bag.c
+++ src/bag.c
@@ -48,10 +48,15 @@
4848
int cnt; /* Number of integers in the bag */
4949
int sz; /* Number of slots in a[] */
5050
int used; /* Number of used slots in a[] */
5151
int *a; /* Hash table of integers that are in the bag */
5252
};
53
+/*
54
+** An expression for statically initializing a Bag instance, to be
55
+** assigned to Bag instances at their declaration point.
56
+*/
57
+#define Bag_INIT {0,0,0,0}
5358
#endif
5459
5560
/*
5661
** Initialize a Bag structure
5762
*/
5863
--- src/bag.c
+++ src/bag.c
@@ -48,10 +48,15 @@
48 int cnt; /* Number of integers in the bag */
49 int sz; /* Number of slots in a[] */
50 int used; /* Number of used slots in a[] */
51 int *a; /* Hash table of integers that are in the bag */
52 };
 
 
 
 
 
53 #endif
54
55 /*
56 ** Initialize a Bag structure
57 */
58
--- src/bag.c
+++ src/bag.c
@@ -48,10 +48,15 @@
48 int cnt; /* Number of integers in the bag */
49 int sz; /* Number of slots in a[] */
50 int used; /* Number of used slots in a[] */
51 int *a; /* Hash table of integers that are in the bag */
52 };
53 /*
54 ** An expression for statically initializing a Bag instance, to be
55 ** assigned to Bag instances at their declaration point.
56 */
57 #define Bag_INIT {0,0,0,0}
58 #endif
59
60 /*
61 ** Initialize a Bag structure
62 */
63
+9 -2
--- src/content.c
+++ src/content.c
@@ -99,22 +99,29 @@
9999
blob_zero(pBlob);
100100
bag_insert(&contentCache.inCache, rid);
101101
}
102102
103103
/*
104
-** Clear the content cache.
104
+** Clear the content cache. If it is passed true, it
105
+** also frees all associated memory, otherwise it may
106
+** retain parts for future uses of the cache.
105107
*/
106
-void content_clear_cache(void){
108
+void content_clear_cache(int bFreeIt){
107109
int i;
108110
for(i=0; i<contentCache.n; i++){
109111
blob_reset(&contentCache.a[i].content);
110112
}
111113
bag_clear(&contentCache.missing);
112114
bag_clear(&contentCache.available);
113115
bag_clear(&contentCache.inCache);
114116
contentCache.n = 0;
115117
contentCache.szTotal = 0;
118
+ if(bFreeIt){
119
+ fossil_free(contentCache.a);
120
+ contentCache.a = 0;
121
+ contentCache.nAlloc = 0;
122
+ }
116123
}
117124
118125
/*
119126
** Return the srcid associated with rid. Or return 0 if rid is
120127
** original content and not a delta.
121128
--- src/content.c
+++ src/content.c
@@ -99,22 +99,29 @@
99 blob_zero(pBlob);
100 bag_insert(&contentCache.inCache, rid);
101 }
102
103 /*
104 ** Clear the content cache.
 
 
105 */
106 void content_clear_cache(void){
107 int i;
108 for(i=0; i<contentCache.n; i++){
109 blob_reset(&contentCache.a[i].content);
110 }
111 bag_clear(&contentCache.missing);
112 bag_clear(&contentCache.available);
113 bag_clear(&contentCache.inCache);
114 contentCache.n = 0;
115 contentCache.szTotal = 0;
 
 
 
 
 
116 }
117
118 /*
119 ** Return the srcid associated with rid. Or return 0 if rid is
120 ** original content and not a delta.
121
--- src/content.c
+++ src/content.c
@@ -99,22 +99,29 @@
99 blob_zero(pBlob);
100 bag_insert(&contentCache.inCache, rid);
101 }
102
103 /*
104 ** Clear the content cache. If it is passed true, it
105 ** also frees all associated memory, otherwise it may
106 ** retain parts for future uses of the cache.
107 */
108 void content_clear_cache(int bFreeIt){
109 int i;
110 for(i=0; i<contentCache.n; i++){
111 blob_reset(&contentCache.a[i].content);
112 }
113 bag_clear(&contentCache.missing);
114 bag_clear(&contentCache.available);
115 bag_clear(&contentCache.inCache);
116 contentCache.n = 0;
117 contentCache.szTotal = 0;
118 if(bFreeIt){
119 fossil_free(contentCache.a);
120 contentCache.a = 0;
121 contentCache.nAlloc = 0;
122 }
123 }
124
125 /*
126 ** Return the srcid associated with rid. Or return 0 if rid is
127 ** original content and not a delta.
128
+7
--- src/db.c
+++ src/db.c
@@ -1628,12 +1628,15 @@
16281628
assert( g.localOpen );
16291629
assert( g.zLocalRoot );
16301630
if( zRepo==0 ){
16311631
zRepo = db_lget("repository", 0);
16321632
if( zRepo && !file_is_absolute_path(zRepo) ){
1633
+ char * zFree = zRepo;
16331634
zRepo = mprintf("%s%s", g.zLocalRoot, zRepo);
1635
+ fossil_free(zFree);
16341636
}
1637
+ fossil_atexit_free_this(zRepo);
16351638
}
16361639
return zRepo;
16371640
}
16381641
16391642
/*
@@ -2633,11 +2636,15 @@
26332636
db_swap_connections();
26342637
}
26352638
if( pSetting!=0 && pSetting->versionable ){
26362639
/* This is a versionable setting, try and get the info from a
26372640
** checked out file */
2641
+ char * zZ = z;
26382642
z = db_get_versioned(zName, z);
2643
+ if(zZ != z){
2644
+ fossil_free(zZ);
2645
+ }
26392646
}
26402647
if( z==0 ){
26412648
if( zDefault==0 && pSetting && pSetting->def[0] ){
26422649
z = fossil_strdup(pSetting->def);
26432650
}else{
26442651
--- src/db.c
+++ src/db.c
@@ -1628,12 +1628,15 @@
1628 assert( g.localOpen );
1629 assert( g.zLocalRoot );
1630 if( zRepo==0 ){
1631 zRepo = db_lget("repository", 0);
1632 if( zRepo && !file_is_absolute_path(zRepo) ){
 
1633 zRepo = mprintf("%s%s", g.zLocalRoot, zRepo);
 
1634 }
 
1635 }
1636 return zRepo;
1637 }
1638
1639 /*
@@ -2633,11 +2636,15 @@
2633 db_swap_connections();
2634 }
2635 if( pSetting!=0 && pSetting->versionable ){
2636 /* This is a versionable setting, try and get the info from a
2637 ** checked out file */
 
2638 z = db_get_versioned(zName, z);
 
 
 
2639 }
2640 if( z==0 ){
2641 if( zDefault==0 && pSetting && pSetting->def[0] ){
2642 z = fossil_strdup(pSetting->def);
2643 }else{
2644
--- src/db.c
+++ src/db.c
@@ -1628,12 +1628,15 @@
1628 assert( g.localOpen );
1629 assert( g.zLocalRoot );
1630 if( zRepo==0 ){
1631 zRepo = db_lget("repository", 0);
1632 if( zRepo && !file_is_absolute_path(zRepo) ){
1633 char * zFree = zRepo;
1634 zRepo = mprintf("%s%s", g.zLocalRoot, zRepo);
1635 fossil_free(zFree);
1636 }
1637 fossil_atexit_free_this(zRepo);
1638 }
1639 return zRepo;
1640 }
1641
1642 /*
@@ -2633,11 +2636,15 @@
2636 db_swap_connections();
2637 }
2638 if( pSetting!=0 && pSetting->versionable ){
2639 /* This is a versionable setting, try and get the info from a
2640 ** checked out file */
2641 char * zZ = z;
2642 z = db_get_versioned(zName, z);
2643 if(zZ != z){
2644 fossil_free(zZ);
2645 }
2646 }
2647 if( z==0 ){
2648 if( zDefault==0 && pSetting && pSetting->def[0] ){
2649 z = fossil_strdup(pSetting->def);
2650 }else{
2651
+38 -2
--- src/main.c
+++ src/main.c
@@ -322,10 +322,37 @@
322322
#define CGIDEBUG(X) if( g.fDebug ) cgi_debug X
323323
324324
#endif
325325
326326
Global g;
327
+
328
+/*
329
+** Infrastructure for fossil_atexit_free_this().
330
+*/
331
+static struct {
332
+ void* list[20]; /* Pointers to pass to fossil_free() during
333
+ ** atexit(). */
334
+ int n; /* Number of items currently in this->list. */
335
+} fossilFreeAtExit = { {0}, 0 };
336
+
337
+/*
338
+** If zMem is not NULL and there is space in fossil's atexit cleanup
339
+** queue, zMem is added to that queue so that it will be passed to
340
+** fossil_free() during the atexit() phase of app shutdown. If the
341
+** queue is full or zMem is NULL, this function has no side effects.
342
+**
343
+** This is intended to be called by routines which allocate heap
344
+** memory for static-scope values which otherwise won't be freed, and
345
+** the static queue size is relatively small.
346
+*/
347
+void fossil_atexit_free_this(void * zMem){
348
+ if(zMem!=0
349
+ && fossilFreeAtExit.n < (sizeof(fossilFreeAtExit.list)
350
+ / sizeof(fossilFreeAtExit.list[0]))){
351
+ fossilFreeAtExit.list[fossilFreeAtExit.n++] = zMem;
352
+ }
353
+}
327354
328355
/*
329356
** atexit() handler which frees up "some" of the resources
330357
** used by fossil.
331358
*/
@@ -381,12 +408,21 @@
381408
fossil_free(g.zPath);
382409
fossil_free(g.zRepositoryName);
383410
fossil_free(g.zRepositoryOption);
384411
fossil_free(g.zSshCmd);
385412
fossil_free(g.zTop);
386
- /* TODO: clean up the file-local content.c::contentCache
387
- ** via new function in that file */
413
+ manifest_clear_cache();
414
+ content_clear_cache(1);
415
+ rebuild_clear_cache();
416
+ if(fossilFreeAtExit.n>0){
417
+ int i;
418
+ for(i = 0; i < fossilFreeAtExit.n; ++i){
419
+ fossil_free(fossilFreeAtExit.list[i]);
420
+ fossilFreeAtExit.list[i] = 0;
421
+ }
422
+ fossilFreeAtExit.n = 0;
423
+ }
388424
/*
389425
** FIXME: The next two lines cannot always be enabled; however, they
390426
** are very useful for tracking down TH1 memory leaks.
391427
*/
392428
if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
393429
--- src/main.c
+++ src/main.c
@@ -322,10 +322,37 @@
322 #define CGIDEBUG(X) if( g.fDebug ) cgi_debug X
323
324 #endif
325
326 Global g;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
328 /*
329 ** atexit() handler which frees up "some" of the resources
330 ** used by fossil.
331 */
@@ -381,12 +408,21 @@
381 fossil_free(g.zPath);
382 fossil_free(g.zRepositoryName);
383 fossil_free(g.zRepositoryOption);
384 fossil_free(g.zSshCmd);
385 fossil_free(g.zTop);
386 /* TODO: clean up the file-local content.c::contentCache
387 ** via new function in that file */
 
 
 
 
 
 
 
 
 
388 /*
389 ** FIXME: The next two lines cannot always be enabled; however, they
390 ** are very useful for tracking down TH1 memory leaks.
391 */
392 if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
393
--- src/main.c
+++ src/main.c
@@ -322,10 +322,37 @@
322 #define CGIDEBUG(X) if( g.fDebug ) cgi_debug X
323
324 #endif
325
326 Global g;
327
328 /*
329 ** Infrastructure for fossil_atexit_free_this().
330 */
331 static struct {
332 void* list[20]; /* Pointers to pass to fossil_free() during
333 ** atexit(). */
334 int n; /* Number of items currently in this->list. */
335 } fossilFreeAtExit = { {0}, 0 };
336
337 /*
338 ** If zMem is not NULL and there is space in fossil's atexit cleanup
339 ** queue, zMem is added to that queue so that it will be passed to
340 ** fossil_free() during the atexit() phase of app shutdown. If the
341 ** queue is full or zMem is NULL, this function has no side effects.
342 **
343 ** This is intended to be called by routines which allocate heap
344 ** memory for static-scope values which otherwise won't be freed, and
345 ** the static queue size is relatively small.
346 */
347 void fossil_atexit_free_this(void * zMem){
348 if(zMem!=0
349 && fossilFreeAtExit.n < (sizeof(fossilFreeAtExit.list)
350 / sizeof(fossilFreeAtExit.list[0]))){
351 fossilFreeAtExit.list[fossilFreeAtExit.n++] = zMem;
352 }
353 }
354
355 /*
356 ** atexit() handler which frees up "some" of the resources
357 ** used by fossil.
358 */
@@ -381,12 +408,21 @@
408 fossil_free(g.zPath);
409 fossil_free(g.zRepositoryName);
410 fossil_free(g.zRepositoryOption);
411 fossil_free(g.zSshCmd);
412 fossil_free(g.zTop);
413 manifest_clear_cache();
414 content_clear_cache(1);
415 rebuild_clear_cache();
416 if(fossilFreeAtExit.n>0){
417 int i;
418 for(i = 0; i < fossilFreeAtExit.n; ++i){
419 fossil_free(fossilFreeAtExit.list[i]);
420 fossilFreeAtExit.list[i] = 0;
421 }
422 fossilFreeAtExit.n = 0;
423 }
424 /*
425 ** FIXME: The next two lines cannot always be enabled; however, they
426 ** are very useful for tracking down TH1 memory leaks.
427 */
428 if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
429
+20 -5
--- src/manifest.c
+++ src/manifest.c
@@ -68,11 +68,11 @@
6868
*/
6969
struct Manifest {
7070
Blob content; /* The original content blob */
7171
int type; /* Type of artifact. One of CFTYPE_xxxxx */
7272
int rid; /* The blob-id for this manifest */
73
- char *zBaseline; /* Baseline manifest. The B card. */
73
+ const char *zBaseline;/* Baseline manifest. The B card. */
7474
Manifest *pBaseline; /* The actual baseline manifest */
7575
char *zComment; /* Decoded comment. The C card. */
7676
double rDate; /* Date and time from D card. 0.0 if no D card. */
7777
char *zUser; /* Name of the user from the U card. */
7878
char *zRepoCksum; /* MD5 checksum of the baseline content. R card. */
@@ -384,10 +384,23 @@
384384
385385
/*
386386
** Shorthand for a control-artifact parsing error
387387
*/
388388
#define SYNTAX(T) {zErr=(T); goto manifest_syntax_error;}
389
+
390
+/*
391
+** A cache of manifest IDs which manifest_parse() has seen in this
392
+** session.
393
+*/
394
+static Bag seenManifests = Bag_INIT;
395
+/*
396
+** Frees all memory owned by the manifest "has-seen" cache. Intended
397
+** to be called only from the app's atexit() handler.
398
+*/
399
+void manifest_clear_cache(){
400
+ bag_clear(&seenManifests);
401
+}
389402
390403
/*
391404
** Parse a blob into a Manifest object. The Manifest object
392405
** takes over the input blob and will free it when the
393406
** Manifest object is freed. Zeros are inserted into the blob
@@ -428,23 +441,22 @@
428441
char *zUuid;
429442
int sz = 0;
430443
int isRepeat;
431444
int nSelfTag = 0; /* Number of T cards referring to this manifest */
432445
int nSimpleTag = 0; /* Number of T cards with "+" prefix */
433
- static Bag seen;
434446
const char *zErr = 0;
435447
unsigned int m;
436448
unsigned int seenCard = 0; /* Which card types have been seen */
437449
char zErrBuf[100]; /* Write error messages here */
438450
439451
if( rid==0 ){
440452
isRepeat = 1;
441
- }else if( bag_find(&seen, rid) ){
453
+ }else if( bag_find(&seenManifests, rid) ){
442454
isRepeat = 1;
443455
}else{
444456
isRepeat = 0;
445
- bag_insert(&seen, rid);
457
+ bag_insert(&seenManifests, rid);
446458
}
447459
448460
/* Every structural artifact ends with a '\n' character. Exit early
449461
** if that is not the case for this artifact.
450462
*/
@@ -1704,11 +1716,11 @@
17041716
*/
17051717
static int manifest_add_checkin_linkages(
17061718
int rid, /* The RID of the check-in */
17071719
Manifest *p, /* Manifest for this check-in */
17081720
int nParent, /* Number of parents for this check-in */
1709
- char **azParent /* hashes for each parent */
1721
+ char * const * azParent /* hashes for each parent */
17101722
){
17111723
int i;
17121724
int parentid = 0;
17131725
char zBaseId[30]; /* Baseline manifest RID for deltas. "NULL" otherwise */
17141726
Stmt q;
@@ -1938,10 +1950,12 @@
19381950
blob_zero(&brief);
19391951
if( once ){
19401952
once = 0;
19411953
zTitleExpr = db_get("ticket-title-expr", "title");
19421954
zStatusColumn = db_get("ticket-status-column", "status");
1955
+ fossil_atexit_free_this(zTitleExpr);
1956
+ fossil_atexit_free_this(zStatusColumn);
19431957
}
19441958
zTitle = db_text("unknown",
19451959
"SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q",
19461960
zTitleExpr, pManifest->zTicketUuid
19471961
);
@@ -2198,10 +2212,11 @@
21982212
case '-': type = 0; break; /* Cancel prior occurrences */
21992213
case '+': type = 1; break; /* Apply to target only */
22002214
case '*': type = 2; break; /* Propagate to descendants */
22012215
default:
22022216
fossil_error(1, "unknown tag type in manifest: %s", p->aTag);
2217
+ manifest_destroy(p);
22032218
return 0;
22042219
}
22052220
tag_insert(&p->aTag[i].zName[1], type, p->aTag[i].zValue,
22062221
rid, p->rDate, tid);
22072222
}
22082223
--- src/manifest.c
+++ src/manifest.c
@@ -68,11 +68,11 @@
68 */
69 struct Manifest {
70 Blob content; /* The original content blob */
71 int type; /* Type of artifact. One of CFTYPE_xxxxx */
72 int rid; /* The blob-id for this manifest */
73 char *zBaseline; /* Baseline manifest. The B card. */
74 Manifest *pBaseline; /* The actual baseline manifest */
75 char *zComment; /* Decoded comment. The C card. */
76 double rDate; /* Date and time from D card. 0.0 if no D card. */
77 char *zUser; /* Name of the user from the U card. */
78 char *zRepoCksum; /* MD5 checksum of the baseline content. R card. */
@@ -384,10 +384,23 @@
384
385 /*
386 ** Shorthand for a control-artifact parsing error
387 */
388 #define SYNTAX(T) {zErr=(T); goto manifest_syntax_error;}
 
 
 
 
 
 
 
 
 
 
 
 
 
389
390 /*
391 ** Parse a blob into a Manifest object. The Manifest object
392 ** takes over the input blob and will free it when the
393 ** Manifest object is freed. Zeros are inserted into the blob
@@ -428,23 +441,22 @@
428 char *zUuid;
429 int sz = 0;
430 int isRepeat;
431 int nSelfTag = 0; /* Number of T cards referring to this manifest */
432 int nSimpleTag = 0; /* Number of T cards with "+" prefix */
433 static Bag seen;
434 const char *zErr = 0;
435 unsigned int m;
436 unsigned int seenCard = 0; /* Which card types have been seen */
437 char zErrBuf[100]; /* Write error messages here */
438
439 if( rid==0 ){
440 isRepeat = 1;
441 }else if( bag_find(&seen, rid) ){
442 isRepeat = 1;
443 }else{
444 isRepeat = 0;
445 bag_insert(&seen, rid);
446 }
447
448 /* Every structural artifact ends with a '\n' character. Exit early
449 ** if that is not the case for this artifact.
450 */
@@ -1704,11 +1716,11 @@
1704 */
1705 static int manifest_add_checkin_linkages(
1706 int rid, /* The RID of the check-in */
1707 Manifest *p, /* Manifest for this check-in */
1708 int nParent, /* Number of parents for this check-in */
1709 char **azParent /* hashes for each parent */
1710 ){
1711 int i;
1712 int parentid = 0;
1713 char zBaseId[30]; /* Baseline manifest RID for deltas. "NULL" otherwise */
1714 Stmt q;
@@ -1938,10 +1950,12 @@
1938 blob_zero(&brief);
1939 if( once ){
1940 once = 0;
1941 zTitleExpr = db_get("ticket-title-expr", "title");
1942 zStatusColumn = db_get("ticket-status-column", "status");
 
 
1943 }
1944 zTitle = db_text("unknown",
1945 "SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q",
1946 zTitleExpr, pManifest->zTicketUuid
1947 );
@@ -2198,10 +2212,11 @@
2198 case '-': type = 0; break; /* Cancel prior occurrences */
2199 case '+': type = 1; break; /* Apply to target only */
2200 case '*': type = 2; break; /* Propagate to descendants */
2201 default:
2202 fossil_error(1, "unknown tag type in manifest: %s", p->aTag);
 
2203 return 0;
2204 }
2205 tag_insert(&p->aTag[i].zName[1], type, p->aTag[i].zValue,
2206 rid, p->rDate, tid);
2207 }
2208
--- src/manifest.c
+++ src/manifest.c
@@ -68,11 +68,11 @@
68 */
69 struct Manifest {
70 Blob content; /* The original content blob */
71 int type; /* Type of artifact. One of CFTYPE_xxxxx */
72 int rid; /* The blob-id for this manifest */
73 const char *zBaseline;/* Baseline manifest. The B card. */
74 Manifest *pBaseline; /* The actual baseline manifest */
75 char *zComment; /* Decoded comment. The C card. */
76 double rDate; /* Date and time from D card. 0.0 if no D card. */
77 char *zUser; /* Name of the user from the U card. */
78 char *zRepoCksum; /* MD5 checksum of the baseline content. R card. */
@@ -384,10 +384,23 @@
384
385 /*
386 ** Shorthand for a control-artifact parsing error
387 */
388 #define SYNTAX(T) {zErr=(T); goto manifest_syntax_error;}
389
390 /*
391 ** A cache of manifest IDs which manifest_parse() has seen in this
392 ** session.
393 */
394 static Bag seenManifests = Bag_INIT;
395 /*
396 ** Frees all memory owned by the manifest "has-seen" cache. Intended
397 ** to be called only from the app's atexit() handler.
398 */
399 void manifest_clear_cache(){
400 bag_clear(&seenManifests);
401 }
402
403 /*
404 ** Parse a blob into a Manifest object. The Manifest object
405 ** takes over the input blob and will free it when the
406 ** Manifest object is freed. Zeros are inserted into the blob
@@ -428,23 +441,22 @@
441 char *zUuid;
442 int sz = 0;
443 int isRepeat;
444 int nSelfTag = 0; /* Number of T cards referring to this manifest */
445 int nSimpleTag = 0; /* Number of T cards with "+" prefix */
 
446 const char *zErr = 0;
447 unsigned int m;
448 unsigned int seenCard = 0; /* Which card types have been seen */
449 char zErrBuf[100]; /* Write error messages here */
450
451 if( rid==0 ){
452 isRepeat = 1;
453 }else if( bag_find(&seenManifests, rid) ){
454 isRepeat = 1;
455 }else{
456 isRepeat = 0;
457 bag_insert(&seenManifests, rid);
458 }
459
460 /* Every structural artifact ends with a '\n' character. Exit early
461 ** if that is not the case for this artifact.
462 */
@@ -1704,11 +1716,11 @@
1716 */
1717 static int manifest_add_checkin_linkages(
1718 int rid, /* The RID of the check-in */
1719 Manifest *p, /* Manifest for this check-in */
1720 int nParent, /* Number of parents for this check-in */
1721 char * const * azParent /* hashes for each parent */
1722 ){
1723 int i;
1724 int parentid = 0;
1725 char zBaseId[30]; /* Baseline manifest RID for deltas. "NULL" otherwise */
1726 Stmt q;
@@ -1938,10 +1950,12 @@
1950 blob_zero(&brief);
1951 if( once ){
1952 once = 0;
1953 zTitleExpr = db_get("ticket-title-expr", "title");
1954 zStatusColumn = db_get("ticket-status-column", "status");
1955 fossil_atexit_free_this(zTitleExpr);
1956 fossil_atexit_free_this(zStatusColumn);
1957 }
1958 zTitle = db_text("unknown",
1959 "SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q",
1960 zTitleExpr, pManifest->zTicketUuid
1961 );
@@ -2198,10 +2212,11 @@
2212 case '-': type = 0; break; /* Cancel prior occurrences */
2213 case '+': type = 1; break; /* Apply to target only */
2214 case '*': type = 2; break; /* Propagate to descendants */
2215 default:
2216 fossil_error(1, "unknown tag type in manifest: %s", p->aTag);
2217 manifest_destroy(p);
2218 return 0;
2219 }
2220 tag_insert(&p->aTag[i].zName[1], type, p->aTag[i].zValue,
2221 rid, p->rDate, tid);
2222 }
2223
+13 -6
--- src/rebuild.c
+++ src/rebuild.c
@@ -176,18 +176,18 @@
176176
177177
/*
178178
** Variables used to store state information about an on-going "rebuild"
179179
** or "deconstruct".
180180
*/
181
-static int totalSize; /* Total number of artifacts to process */
182
-static int processCnt; /* Number processed so far */
183
-static int ttyOutput; /* Do progress output */
184
-static Bag bagDone; /* Bag of records rebuilt */
181
+static int totalSize; /* Total number of artifacts to process */
182
+static int processCnt; /* Number processed so far */
183
+static int ttyOutput; /* Do progress output */
184
+static Bag bagDone = Bag_INIT; /* Bag of records rebuilt */
185185
186186
static char *zFNameFormat; /* Format string for filenames on deconstruct */
187187
static int cchFNamePrefix; /* Length of directory prefix in zFNameFormat */
188
-static char *zDestDir; /* Destination directory on deconstruct */
188
+static const char *zDestDir;/* Destination directory on deconstruct */
189189
static int prefixLength; /* Length of directory prefix for deconstruct */
190190
static int fKeepRid1; /* Flag to preserve RID=1 on de- and reconstruct */
191191
192192
193193
/*
@@ -201,10 +201,17 @@
201201
fflush(stdout);
202202
lastOutput = permill;
203203
}
204204
}
205205
206
+/*
207
+** Frees rebuild-level cached state. Intended only to be called by the
208
+** app-level atexit() handler.
209
+*/
210
+void rebuild_clear_cache(){
211
+ bag_clear(&bagDone);
212
+}
206213
207214
/*
208215
** Called after each artifact is processed
209216
*/
210217
static void rebuild_step_done(int rid){
@@ -366,11 +373,11 @@
366373
Stmt s, q;
367374
int errCnt = 0;
368375
int incrSize;
369376
Blob sql;
370377
371
- bag_init(&bagDone);
378
+ bag_clear(&bagDone);
372379
ttyOutput = doOut;
373380
processCnt = 0;
374381
if (ttyOutput && !g.fQuiet) {
375382
percent_complete(0);
376383
}
377384
--- src/rebuild.c
+++ src/rebuild.c
@@ -176,18 +176,18 @@
176
177 /*
178 ** Variables used to store state information about an on-going "rebuild"
179 ** or "deconstruct".
180 */
181 static int totalSize; /* Total number of artifacts to process */
182 static int processCnt; /* Number processed so far */
183 static int ttyOutput; /* Do progress output */
184 static Bag bagDone; /* Bag of records rebuilt */
185
186 static char *zFNameFormat; /* Format string for filenames on deconstruct */
187 static int cchFNamePrefix; /* Length of directory prefix in zFNameFormat */
188 static char *zDestDir; /* Destination directory on deconstruct */
189 static int prefixLength; /* Length of directory prefix for deconstruct */
190 static int fKeepRid1; /* Flag to preserve RID=1 on de- and reconstruct */
191
192
193 /*
@@ -201,10 +201,17 @@
201 fflush(stdout);
202 lastOutput = permill;
203 }
204 }
205
 
 
 
 
 
 
 
206
207 /*
208 ** Called after each artifact is processed
209 */
210 static void rebuild_step_done(int rid){
@@ -366,11 +373,11 @@
366 Stmt s, q;
367 int errCnt = 0;
368 int incrSize;
369 Blob sql;
370
371 bag_init(&bagDone);
372 ttyOutput = doOut;
373 processCnt = 0;
374 if (ttyOutput && !g.fQuiet) {
375 percent_complete(0);
376 }
377
--- src/rebuild.c
+++ src/rebuild.c
@@ -176,18 +176,18 @@
176
177 /*
178 ** Variables used to store state information about an on-going "rebuild"
179 ** or "deconstruct".
180 */
181 static int totalSize; /* Total number of artifacts to process */
182 static int processCnt; /* Number processed so far */
183 static int ttyOutput; /* Do progress output */
184 static Bag bagDone = Bag_INIT; /* Bag of records rebuilt */
185
186 static char *zFNameFormat; /* Format string for filenames on deconstruct */
187 static int cchFNamePrefix; /* Length of directory prefix in zFNameFormat */
188 static const char *zDestDir;/* Destination directory on deconstruct */
189 static int prefixLength; /* Length of directory prefix for deconstruct */
190 static int fKeepRid1; /* Flag to preserve RID=1 on de- and reconstruct */
191
192
193 /*
@@ -201,10 +201,17 @@
201 fflush(stdout);
202 lastOutput = permill;
203 }
204 }
205
206 /*
207 ** Frees rebuild-level cached state. Intended only to be called by the
208 ** app-level atexit() handler.
209 */
210 void rebuild_clear_cache(){
211 bag_clear(&bagDone);
212 }
213
214 /*
215 ** Called after each artifact is processed
216 */
217 static void rebuild_step_done(int rid){
@@ -366,11 +373,11 @@
373 Stmt s, q;
374 int errCnt = 0;
375 int incrSize;
376 Blob sql;
377
378 bag_clear(&bagDone);
379 ttyOutput = doOut;
380 processCnt = 0;
381 if (ttyOutput && !g.fQuiet) {
382 percent_complete(0);
383 }
384
+1 -1
--- src/verify.c
+++ src/verify.c
@@ -68,11 +68,11 @@
6868
** Invoke verify_rid() on every record that has been added or modified
6969
** in the repository, in order to make sure that the repository is sane.
7070
*/
7171
static int verify_at_commit(void){
7272
int rid;
73
- content_clear_cache();
73
+ content_clear_cache(0);
7474
inFinalVerify = 1;
7575
rid = bag_first(&toVerify);
7676
while( rid>0 ){
7777
verify_rid(rid);
7878
rid = bag_next(&toVerify, rid);
7979
--- src/verify.c
+++ src/verify.c
@@ -68,11 +68,11 @@
68 ** Invoke verify_rid() on every record that has been added or modified
69 ** in the repository, in order to make sure that the repository is sane.
70 */
71 static int verify_at_commit(void){
72 int rid;
73 content_clear_cache();
74 inFinalVerify = 1;
75 rid = bag_first(&toVerify);
76 while( rid>0 ){
77 verify_rid(rid);
78 rid = bag_next(&toVerify, rid);
79
--- src/verify.c
+++ src/verify.c
@@ -68,11 +68,11 @@
68 ** Invoke verify_rid() on every record that has been added or modified
69 ** in the repository, in order to make sure that the repository is sane.
70 */
71 static int verify_at_commit(void){
72 int rid;
73 content_clear_cache(0);
74 inFinalVerify = 1;
75 rid = bag_first(&toVerify);
76 while( rid>0 ){
77 verify_rid(rid);
78 rid = bag_next(&toVerify, rid);
79

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button