Mercurial > godwindows
changeset 60:9709643f623d
Cache function pointers so they don't get garbage collected.
Added callback so they can be uncached when being removed.
author | Brian Smith <brian@dbsoft.org> |
---|---|
date | Fri, 08 Mar 2013 18:46:49 -0600 |
parents | 9ef94c1639c3 |
children | 1c4bbae2ab88 |
files | src/dw/dw.go src/dw/dwglue.c |
diffstat | 2 files changed, 43 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/src/dw/dw.go Fri Mar 08 16:44:58 2013 -0600 +++ b/src/dw/dw.go Fri Mar 08 18:46:49 2013 -0600 @@ -307,6 +307,9 @@ var VK_LCONTROL = int(C.VK_LCONTROL) var VK_RCONTROL = int(C.VK_RCONTROL) +// Cache the function pointers so they don't get garbage collected +var backs []unsafe.Pointer; + func RESOURCE(id uintptr) unsafe.Pointer { return unsafe.Pointer(id); } @@ -799,6 +802,7 @@ } func Timer_connect(interval int, sigfunc SIGNAL_FUNC, data POINTER) HTIMER { + backs = append(backs, unsafe.Pointer(sigfunc)); return HTIMER{C.go_timer_connect(C.int(interval), unsafe.Pointer(sigfunc), unsafe.Pointer(data), 0)}; } @@ -812,6 +816,7 @@ csigname := C.CString(signame); defer C.free(unsafe.Pointer(csigname)); + backs = append(backs, unsafe.Pointer(sigfunc)); C.go_signal_connect(unsafe.Pointer(window.hwnd), csigname, unsafe.Pointer(sigfunc), unsafe.Pointer(data), 0); } @@ -1769,6 +1774,7 @@ /* Classic version... */ func Print_new2(jobname string, flags uint, pages uint, drawfunc SIGNAL_FUNC, drawdata POINTER) HPRINT { + backs = append(backs, unsafe.Pointer(drawfunc)); cjobname := C.CString(jobname); defer C.free(unsafe.Pointer(cjobname)); @@ -1792,17 +1798,13 @@ runtime.LockOSThread(); } -/* Do we need to cache the function pointers so they don't get garbage collected? -var backs []unsafe.Pointer; -*/ - var go_flags_no_data C.int = 1; func (window HWND) ConnectDelete(sigfunc func(window HWND) int) { csigname := C.CString(C.DW_SIGNAL_DELETE); defer C.free(unsafe.Pointer(csigname)); - //backs = append(backs, unsafe.Pointer(&sigfunc)); + backs = append(backs, unsafe.Pointer(&sigfunc)); C.go_signal_connect(unsafe.Pointer(window.hwnd), csigname, unsafe.Pointer(&sigfunc), nil, go_flags_no_data); } @@ -1810,7 +1812,7 @@ csigname := C.CString(C.DW_SIGNAL_CLICKED); defer C.free(unsafe.Pointer(csigname)); - //backs = append(backs, unsafe.Pointer(&sigfunc)); + backs = append(backs, unsafe.Pointer(&sigfunc)); C.go_signal_connect(unsafe.Pointer(window.hwnd), csigname, unsafe.Pointer(&sigfunc), nil, go_flags_no_data); } @@ -1818,7 +1820,7 @@ csigname := C.CString(C.DW_SIGNAL_SET_FOCUS); defer C.free(unsafe.Pointer(csigname)); - //backs = append(backs, unsafe.Pointer(&sigfunc)); + backs = append(backs, unsafe.Pointer(&sigfunc)); C.go_signal_connect(unsafe.Pointer(window.hwnd), csigname, unsafe.Pointer(&sigfunc), nil, go_flags_no_data); } @@ -1826,7 +1828,7 @@ csigname := C.CString(C.DW_SIGNAL_KEY_PRESS); defer C.free(unsafe.Pointer(csigname)); - //backs = append(backs, unsafe.Pointer(&sigfunc)); + backs = append(backs, unsafe.Pointer(&sigfunc)); C.go_signal_connect(unsafe.Pointer(window.hwnd), csigname, unsafe.Pointer(&sigfunc), nil, go_flags_no_data); } @@ -1834,7 +1836,7 @@ csigname := C.CString(C.DW_SIGNAL_MOTION_NOTIFY); defer C.free(unsafe.Pointer(csigname)); - //backs = append(backs, unsafe.Pointer(&sigfunc)); + backs = append(backs, unsafe.Pointer(&sigfunc)); C.go_signal_connect(unsafe.Pointer(window.hwnd), csigname, unsafe.Pointer(&sigfunc), nil, go_flags_no_data); } @@ -1842,7 +1844,7 @@ csigname := C.CString(C.DW_SIGNAL_BUTTON_PRESS); defer C.free(unsafe.Pointer(csigname)); - //backs = append(backs, unsafe.Pointer(&sigfunc)); + backs = append(backs, unsafe.Pointer(&sigfunc)); C.go_signal_connect(unsafe.Pointer(window.hwnd), csigname, unsafe.Pointer(&sigfunc), nil, go_flags_no_data); } @@ -1850,7 +1852,7 @@ csigname := C.CString(C.DW_SIGNAL_BUTTON_RELEASE); defer C.free(unsafe.Pointer(csigname)); - //backs = append(backs, unsafe.Pointer(&sigfunc)); + backs = append(backs, unsafe.Pointer(&sigfunc)); C.go_signal_connect(unsafe.Pointer(window.hwnd), csigname, unsafe.Pointer(&sigfunc), nil, go_flags_no_data); } @@ -1858,7 +1860,7 @@ csigname := C.CString(C.DW_SIGNAL_EXPOSE); defer C.free(unsafe.Pointer(csigname)); - //backs = append(backs, unsafe.Pointer(&sigfunc)); + backs = append(backs, unsafe.Pointer(&sigfunc)); C.go_signal_connect(unsafe.Pointer(window.hwnd), csigname, unsafe.Pointer(&sigfunc), nil, go_flags_no_data); } @@ -1866,7 +1868,7 @@ csigname := C.CString(C.DW_SIGNAL_ITEM_ENTER); defer C.free(unsafe.Pointer(csigname)); - //backs = append(backs, unsafe.Pointer(&sigfunc)); + backs = append(backs, unsafe.Pointer(&sigfunc)); C.go_signal_connect(unsafe.Pointer(window.hwnd), csigname, unsafe.Pointer(&sigfunc), nil, go_flags_no_data); } @@ -1874,7 +1876,7 @@ csigname := C.CString(C.DW_SIGNAL_ITEM_CONTEXT); defer C.free(unsafe.Pointer(csigname)); - //backs = append(backs, unsafe.Pointer(&sigfunc)); + backs = append(backs, unsafe.Pointer(&sigfunc)); C.go_signal_connect(unsafe.Pointer(window.hwnd), csigname, unsafe.Pointer(&sigfunc), nil, go_flags_no_data); } @@ -1882,7 +1884,7 @@ csigname := C.CString(C.DW_SIGNAL_ITEM_SELECT); defer C.free(unsafe.Pointer(csigname)); - //backs = append(backs, unsafe.Pointer(&sigfunc)); + backs = append(backs, unsafe.Pointer(&sigfunc)); C.go_signal_connect(unsafe.Pointer(window.hwnd), csigname, unsafe.Pointer(&sigfunc), nil, go_flags_no_data); } @@ -1890,7 +1892,7 @@ csigname := C.CString(C.DW_SIGNAL_LIST_SELECT); defer C.free(unsafe.Pointer(csigname)); - //backs = append(backs, unsafe.Pointer(&sigfunc)); + backs = append(backs, unsafe.Pointer(&sigfunc)); C.go_signal_connect(unsafe.Pointer(window.hwnd), csigname, unsafe.Pointer(&sigfunc), nil, go_flags_no_data); } @@ -1898,7 +1900,7 @@ csigname := C.CString(C.DW_SIGNAL_VALUE_CHANGED); defer C.free(unsafe.Pointer(csigname)); - //backs = append(backs, unsafe.Pointer(&sigfunc)); + backs = append(backs, unsafe.Pointer(&sigfunc)); C.go_signal_connect(unsafe.Pointer(window.hwnd), csigname, unsafe.Pointer(&sigfunc), nil, go_flags_no_data); } @@ -1906,7 +1908,7 @@ csigname := C.CString(C.DW_SIGNAL_COLUMN_CLICK); defer C.free(unsafe.Pointer(csigname)); - //backs = append(backs, unsafe.Pointer(&sigfunc)); + backs = append(backs, unsafe.Pointer(&sigfunc)); C.go_signal_connect(unsafe.Pointer(window.hwnd), csigname, unsafe.Pointer(&sigfunc), nil, go_flags_no_data); } @@ -1914,7 +1916,7 @@ csigname := C.CString(C.DW_SIGNAL_SWITCH_PAGE); defer C.free(unsafe.Pointer(csigname)); - //backs = append(backs, unsafe.Pointer(&sigfunc)); + backs = append(backs, unsafe.Pointer(&sigfunc)); C.go_signal_connect(unsafe.Pointer(window.hwnd), csigname, unsafe.Pointer(&sigfunc), nil, go_flags_no_data); } @@ -1922,13 +1924,13 @@ csigname := C.CString(C.DW_SIGNAL_TREE_EXPAND); defer C.free(unsafe.Pointer(csigname)); - //backs = append(backs, unsafe.Pointer(&sigfunc)); + backs = append(backs, unsafe.Pointer(&sigfunc)); C.go_signal_connect(unsafe.Pointer(window.hwnd), csigname, unsafe.Pointer(&sigfunc), nil, go_flags_no_data); } func (id HTIMER) Connect(sigfunc func() int, interval int) { if id.tid == 0 { - //backs = append(backs, unsafe.Pointer(&sigfunc)); + backs = append(backs, unsafe.Pointer(&sigfunc)); id.tid = C.go_timer_connect(C.int(interval), unsafe.Pointer(&sigfunc), nil, go_flags_no_data); } } @@ -1941,7 +1943,7 @@ func (print HPRINT) Connect(drawfunc func(HPRINT, HPIXMAP, int) int, flags uint, pages int) { if print.hprint == nil { - //backs = append(backs, unsafe.Pointer(&sigfunc)); + backs = append(backs, unsafe.Pointer(&drawfunc)); cjobname := C.CString(print.jobname); defer C.free(unsafe.Pointer(cjobname)); @@ -1957,6 +1959,22 @@ Print_cancel(print); } +//export go_callback_remove +func go_callback_remove(pfunc unsafe.Pointer) { + // Scan through the callback function pointer list... + for i, p := range backs { + // When we find the pointer of the function + // we are removing... + if p == pfunc { + // Remove it from the callback list... + // So it can be garbage collected if not used + backs = append(backs[:i], backs[i+1:]...); + //delete(backs, i); + return; + } + } +} + //export go_int_callback_basic func go_int_callback_basic(pfunc unsafe.Pointer, window unsafe.Pointer, data unsafe.Pointer, flags C.int) C.int { if (flags & go_flags_no_data) == go_flags_no_data {
--- a/src/dw/dwglue.c Fri Mar 08 16:44:58 2013 -0600 +++ b/src/dw/dwglue.c Fri Mar 08 18:46:49 2013 -0600 @@ -1099,6 +1099,7 @@ extern int go_int_callback_tree(void *pfunc, void* window, void *item, void *data, int flags); extern int go_int_callback_timer(void *pfunc, void *data, int flags); extern int go_int_callback_print(void *pfunc, void *print, void *pixmap, int page_num, void *data, int flags); +extern void go_callback_remove(void *pfunc); static int DWSIGNAL go_callback_basic(HWND window, void *data) { @@ -1262,6 +1263,8 @@ { if(data) { + void **param = (void **)data; + go_callback_remove(param[0]); free(data); } }