12
12
13
13
static ErlNifResourceType * connection_type = NULL ;
14
14
static ErlNifResourceType * statement_type = NULL ;
15
+ static sqlite3_mem_methods default_alloc_methods = {0 };
15
16
16
17
typedef struct connection
17
18
{
@@ -23,6 +24,83 @@ typedef struct statement
23
24
sqlite3_stmt * statement ;
24
25
} statement_t ;
25
26
27
+ static void *
28
+ exqlite_malloc (int bytes )
29
+ {
30
+ assert (bytes > 0 );
31
+
32
+ int * p = enif_alloc (bytes + sizeof (int ));
33
+ if (p ) {
34
+ p [0 ] = bytes ;
35
+ p ++ ;
36
+ }
37
+
38
+ return p ;
39
+ }
40
+
41
+ static void
42
+ exqlite_free (void * prior )
43
+ {
44
+ if (!prior ) {
45
+ return ;
46
+ }
47
+
48
+ int * p = prior ;
49
+
50
+ // Shift the pointer back to free the proper block of data
51
+ p -- ;
52
+
53
+ return enif_free (p );
54
+ }
55
+
56
+ static void *
57
+ exqlite_realloc (void * prior , int bytes )
58
+ {
59
+ assert (prior );
60
+ assert (bytes > 0 );
61
+
62
+ int * p = prior ;
63
+ p -- ;
64
+
65
+ p = enif_realloc (p , bytes + sizeof (int ));
66
+ if (p ) {
67
+ p [0 ] = bytes ;
68
+ p ++ ;
69
+ }
70
+
71
+ return p ;
72
+ }
73
+
74
+ static int
75
+ exqlite_mem_size (void * prior )
76
+ {
77
+ if (!prior ) {
78
+ return 0 ;
79
+ }
80
+
81
+ int * p = prior ;
82
+ p -- ;
83
+
84
+ return p [0 ];
85
+ }
86
+
87
+ static int
88
+ exqlite_mem_round_up (int bytes )
89
+ {
90
+ return (bytes + 7 ) & ~7 ;
91
+ }
92
+
93
+ static int
94
+ exqlite_mem_init (void * ptr )
95
+ {
96
+ return SQLITE_OK ;
97
+ }
98
+
99
+ static void
100
+ exqlite_mem_shutdown (void * ptr )
101
+ {
102
+ }
103
+
26
104
static const char *
27
105
get_sqlite3_error_msg (int rc , sqlite3 * db )
28
106
{
@@ -496,7 +574,7 @@ exqlite_multi_step(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
496
574
return enif_make_tuple2 (env , make_atom (env , "done" ), rows );
497
575
498
576
case SQLITE_ROW :
499
- row = make_row (env , statement -> statement );
577
+ row = make_row (env , statement -> statement );
500
578
rows = enif_make_list_cell (env , row , rows );
501
579
break ;
502
580
@@ -533,10 +611,9 @@ exqlite_step(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
533
611
switch (rc ) {
534
612
case SQLITE_ROW :
535
613
return enif_make_tuple2 (
536
- env ,
537
- make_atom (env , "row" ),
538
- make_row (env , statement -> statement )
539
- );
614
+ env ,
615
+ make_atom (env , "row" ),
616
+ make_row (env , statement -> statement ));
540
617
case SQLITE_BUSY :
541
618
return make_atom (env , "busy" );
542
619
case SQLITE_DONE :
@@ -651,8 +728,8 @@ exqlite_serialize(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
651
728
652
729
connection_t * conn = NULL ;
653
730
ErlNifBinary database_name ;
654
- ERL_NIF_TERM eos = enif_make_int (env , 0 );
655
- unsigned char * buffer = NULL ;
731
+ ERL_NIF_TERM eos = enif_make_int (env , 0 );
732
+ unsigned char * buffer = NULL ;
656
733
sqlite3_int64 buffer_size = 0 ;
657
734
ERL_NIF_TERM serialized ;
658
735
@@ -668,7 +745,7 @@ exqlite_serialize(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
668
745
return make_error_tuple (env , "database_name_not_iolist" );
669
746
}
670
747
671
- buffer = sqlite3_serialize (conn -> db , (char * ) database_name .data , & buffer_size , 0 );
748
+ buffer = sqlite3_serialize (conn -> db , (char * )database_name .data , & buffer_size , 0 );
672
749
if (!buffer ) {
673
750
return make_error_tuple (env , "serialization_failed" );
674
751
}
@@ -684,13 +761,13 @@ exqlite_deserialize(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
684
761
{
685
762
assert (env );
686
763
687
- connection_t * conn = NULL ;
764
+ connection_t * conn = NULL ;
688
765
unsigned char * buffer = NULL ;
689
766
ErlNifBinary database_name ;
690
767
ERL_NIF_TERM eos = enif_make_int (env , 0 );
691
768
ErlNifBinary serialized ;
692
- int size = 0 ;
693
- int rc = 0 ;
769
+ int size = 0 ;
770
+ int rc = 0 ;
694
771
int flags = SQLITE_DESERIALIZE_FREEONCLOSE | SQLITE_DESERIALIZE_RESIZEABLE ;
695
772
696
773
if (argc != 3 ) {
@@ -709,7 +786,7 @@ exqlite_deserialize(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
709
786
return enif_make_badarg (env );
710
787
}
711
788
712
- size = serialized .size ;
789
+ size = serialized .size ;
713
790
buffer = sqlite3_malloc (size );
714
791
if (!buffer ) {
715
792
return make_error_tuple (env , "deserialization_failed" );
@@ -785,6 +862,19 @@ on_load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info)
785
862
{
786
863
assert (env );
787
864
865
+ static const sqlite3_mem_methods methods = {
866
+ exqlite_malloc ,
867
+ exqlite_free ,
868
+ exqlite_realloc ,
869
+ exqlite_mem_size ,
870
+ exqlite_mem_round_up ,
871
+ exqlite_mem_init ,
872
+ exqlite_mem_shutdown ,
873
+ 0 };
874
+
875
+ sqlite3_config (SQLITE_CONFIG_GETMALLOC , & default_alloc_methods );
876
+ sqlite3_config (SQLITE_CONFIG_MALLOC , & methods );
877
+
788
878
connection_type = enif_open_resource_type (
789
879
env ,
790
880
"exqlite" ,
@@ -810,6 +900,13 @@ on_load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info)
810
900
return 0 ;
811
901
}
812
902
903
+ static void
904
+ on_unload (ErlNifEnv * caller_env , void * priv_data )
905
+ {
906
+ assert (caller_env );
907
+
908
+ sqlite3_config (SQLITE_CONFIG_MALLOC , & default_alloc_methods );
909
+ }
813
910
814
911
//
815
912
// Enable extension loading
@@ -870,4 +967,4 @@ static ErlNifFunc nif_funcs[] = {
870
967
#define ERL_NIF_INIT_DECL (MODNAME ) ErlNifEntry* sqlite3_nif_nif_init(ERL_NIF_INIT_ARGS)
871
968
#endif
872
969
873
- ERL_NIF_INIT (Elixir .Exqlite .Sqlite3NIF , nif_funcs , on_load , NULL , NULL , NULL )
970
+ ERL_NIF_INIT (Elixir .Exqlite .Sqlite3NIF , nif_funcs , on_load , NULL , NULL , on_unload )
0 commit comments