A simple way to simulate an application crash is forcing a division by zero exception: this may not be the cause of the crash of your application once it has been moved to production environment, but it's an example can light on libjf power.
Example 3-2. two_files_crash.c
1 #include <jf_file.h> 2 int main() 3 { 4 int rc; 5 size_t write; 6 jf_journal_t j; 7 jf_file_t jf1, jf2; 8 struct jf_journal_opts_s jopts; 9 struct jf_file_open_opts_s fopts; 10 const char *file1_data1 = "First string for first file\n"; 11 const char *file1_data2 = "Second string for first file\n"; 12 const char *file2_data1 = "First string for second file\n"; 13 const char *file2_data2 = "Second string for second file\n"; 14 int x, y; 15 jf_set_default_journal_opts(&jopts); 16 jopts.flags |= JF_JOURNAL_PROP_OPEN_O_CREAT | 17 JF_JOURNAL_PROP_OPEN_O_EXCL; 18 rc = jf_journal_open(&j, "jf_tut_foo-journal", 2, &jopts); 19 if (JF_RC_OK != rc) { 20 printf("%d/%s\n", rc, jf_strerror(rc)); 21 return 1; 22 } 23 jf_set_default_file_open_opts(&fopts); 24 fopts.join_the_journal = TRUE; 25 rc = jf_file_open(&jf1, &j, "jf_tut_foo-data1", "w", &fopts); 26 if (JF_RC_OK != rc) { 27 printf("%d/%s\n", rc, jf_strerror(rc)); 28 return 1; 29 } 30 rc = jf_file_open(&jf2, &j, "jf_tut_foo-data2", "w", &fopts); 31 if (JF_RC_OK != rc) { 32 printf("%d/%s\n", rc, jf_strerror(rc)); 33 return 1; 34 } 35 rc = jf_file_write(&jf1, file1_data1, strlen(file1_data1), 36 &write); 37 if (JF_RC_OK != rc) { 38 printf("%d/%s\n", rc, jf_strerror(rc)); 39 return 1; 40 } 41 rc = jf_file_write(&jf2, file2_data1, strlen(file2_data1), 42 &write); 43 if (JF_RC_OK != rc) { 44 printf("%d/%s\n", rc, jf_strerror(rc)); 45 return 1; 46 } 47 rc = jf_journal_commit(&j); 48 if (JF_RC_OK != rc) { 49 printf("%d/%s\n", rc, jf_strerror(rc)); 50 return 1; 51 } 52 rc = jf_file_write(&jf1, file1_data2, strlen(file1_data2), 53 &write); 54 if (JF_RC_OK != rc) { 55 printf("%d/%s\n", rc, jf_strerror(rc)); 56 return 1; 57 } 58 rc = jf_file_write(&jf2, file2_data2, strlen(file2_data2), 59 &write); 60 if (JF_RC_OK != rc) { 61 printf("%d/%s\n", rc, jf_strerror(rc)); 62 return 1; 63 } 64 /* a fool crash simulation */ 65 x = 0; y = 5; 66 while (TRUE) 67 x += 5 / y--; 68 printf("This should not print x = %d\n", x); 69 rc = jf_file_close(&jf1); 70 if (JF_RC_OK != rc) { 71 printf("%d/%s\n", rc, jf_strerror(rc)); 72 return 1; 73 } 74 rc = jf_file_close(&jf2); 75 if (JF_RC_OK != rc) { 76 printf("%d/%s\n", rc, jf_strerror(rc)); 77 return 1; 78 } 79 rc = jf_journal_close(&j); 80 if (JF_RC_OK != rc) { 81 printf("%d/%s\n", rc, jf_strerror(rc)); 82 return 1; 83 } 84 printf("two_files_crash program ended OK!\n"); 85 return 0; 86 }
two_files_crash.c is slightly different than two_files.c:
a first commit is performed by our application to successfully close the first transaction
a trick has been introduced to force a "division by zero" exception (row 67) avoiding the situation is detected by most compilers.
To compile two_files_crash.c source code use our old friend libtool command:
libtool --mode=link gcc -Wall -I/opt/libjf/include -L/opt/libjf/lib -ljf \ -o two_files_crash two_files_crash.cif you executed two_files program too, the execution of two_files_crash should exploit an error condition:
tiian@linux:~/tutorial> ./two_files_crash -15/ERROR: file can not be created because it already existsthe problem is due to two_files_crash request of "new journal creation" (take a look at row 16); remove old files and run it again:
tiian@linux:~/tutorial> rm jf_tut_foo-* tiian@linux:~/tutorial> ./two_files_crash Floating point exceptionour application crashed as expected, look at journaled files:
tiian@linux:~/tutorial> ls -la jf_tut_foo-* -rw-r--r-- 1 tiian users 28 2005-08-11 17:34 jf_tut_foo-data1 -rw-r--r-- 1 tiian users 29 2005-08-11 17:34 jf_tut_foo-data2 -rw-r--r-- 1 tiian users 16605 2005-08-11 17:34 jf_tut_foo-journal tiian@linux:~/tutorial> cat jf_tut_foo-data1 First string for first file tiian@linux:~/tutorial> cat jf_tut_foo-data2 First string for second filestrings of first transaction are at their place as desired, strings of second transaction were backed out as expected and data kept by journaled files are consistent.
You may enjoy transactionality of this example moving rows 64-68 in different places like between rows 40 and 41.