|
33 | 33 | Ok(())
|
34 | 34 | }
|
35 | 35 |
|
| 36 | +/// Set the memory allocator to a different memory allocator. |
| 37 | +/// |
| 38 | +/// This allocator will then be used to make all memory allocations for |
| 39 | +/// libgit2 operations. If the given `allocator` is None, then the |
| 40 | +/// system default will be restored. |
| 41 | +pub unsafe fn set_allocator( |
| 42 | + gmalloc: *const extern "C" fn(libc::size_t, *const core::ffi::c_char, core::ffi::c_int) -> *mut core::ffi::c_void, |
| 43 | + grealloc: *const extern "C" fn(*mut core::ffi::c_void, libc::size_t, *const core::ffi::c_char, core::ffi::c_int) -> *mut core::ffi::c_void, |
| 44 | + gfree: *const extern "C" fn(*mut core::ffi::c_void), |
| 45 | +) -> Result<(), Error> { |
| 46 | + crate::init(); |
| 47 | + let allocator = raw::git_allocator{ |
| 48 | + gmalloc: gmalloc, |
| 49 | + gfree: gfree, |
| 50 | + grealloc: grealloc, |
| 51 | + }; |
| 52 | + try_call!(raw::git_libgit2_opts( |
| 53 | + raw::GIT_OPT_SET_ALLOCATOR as libc::c_int, |
| 54 | + &allocator as *const raw::git_allocator |
| 55 | + )); |
| 56 | + Ok(()) |
| 57 | +} |
| 58 | + |
36 | 59 | /// Reset the search path for a given level of config data to the default
|
37 | 60 | /// (generally based on environment variables).
|
38 | 61 | ///
|
@@ -416,6 +439,8 @@ pub unsafe fn set_server_timeout_in_milliseconds(timeout: libc::c_int) -> Result
|
416 | 439 |
|
417 | 440 | #[cfg(test)]
|
418 | 441 | mod test {
|
| 442 | + use crate::test::repo_init; |
| 443 | + |
419 | 444 | use super::*;
|
420 | 445 |
|
421 | 446 | #[test]
|
@@ -447,6 +472,40 @@ mod test {
|
447 | 472 | }
|
448 | 473 | }
|
449 | 474 |
|
| 475 | + static mut ALLOC_CALLED: bool = false; |
| 476 | + static mut FREE_CALLED: bool = false; |
| 477 | + |
| 478 | + #[test] |
| 479 | + fn custom_allocator() { |
| 480 | + unsafe { |
| 481 | + extern "C" fn gmalloc(size: libc::size_t, _: *const core::ffi::c_char, _: core::ffi::c_int) -> *mut core::ffi::c_void { |
| 482 | + unsafe { |
| 483 | + ALLOC_CALLED = true; |
| 484 | + libc::malloc(size) |
| 485 | + } |
| 486 | + } |
| 487 | + extern "C" fn grealloc(ptr: *mut core::ffi::c_void, size: libc::size_t, _: *const core::ffi::c_char, _: core::ffi::c_int) -> *mut core::ffi::c_void { |
| 488 | + unsafe { |
| 489 | + ALLOC_CALLED = true; |
| 490 | + libc::realloc(ptr, size) |
| 491 | + } |
| 492 | + } |
| 493 | + extern "C" fn gfree(ptr: *mut core::ffi::c_void) { |
| 494 | + unsafe { |
| 495 | + FREE_CALLED = true; |
| 496 | + libc::free(ptr) |
| 497 | + } |
| 498 | + } |
| 499 | + assert!(set_allocator( |
| 500 | + gmalloc as *const extern "C" fn(libc::size_t, *const core::ffi::c_char, core::ffi::c_int) -> *mut core::ffi::c_void, |
| 501 | + grealloc as *const extern "C" fn(*mut core::ffi::c_void, libc::size_t, *const core::ffi::c_char, core::ffi::c_int) -> *mut core::ffi::c_void, |
| 502 | + gfree as *const extern "C" fn(*mut core::ffi::c_void), |
| 503 | + ).is_ok()); |
| 504 | + repo_init(); |
| 505 | + assert!(ALLOC_CALLED); |
| 506 | + assert!(FREE_CALLED);} |
| 507 | + } |
| 508 | + |
450 | 509 | #[test]
|
451 | 510 | fn server_connect_timeout() {
|
452 | 511 | unsafe {
|
|
0 commit comments