xamarin-macios/runtime/shared.h

61 строка
1.3 KiB
C
Исходник Обычный вид История

2016-04-21 15:19:32 +03:00
//
// shared.h: Shared native code between Xamarin.iOS and Xamarin.Mac.
//
//
// Authors:
// Rolf Bjarne Kvinge <rolf@xamarin.com>
//
// Copyright 2013 Xamarin Inc.
//
#ifndef __SHARED_H__
#define __SHARED_H__
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void (init_cocoa_func) (void);
void initialize_cocoa_threads (init_cocoa_func *func);
void install_nsautoreleasepool_hooks ();
id xamarin_init_nsthread (id obj, bool is_direct, id target, SEL sel, id arg);
void xamarin_insert_dllmap ();
2016-04-21 15:19:32 +03:00
/*
* Block support
*/
struct Xamarin_block_descriptor {
unsigned long int reserved; // NULL
unsigned long int size; // sizeof(struct Block_literal_1)
// optional helper functions
void (*copy_helper) (void *dst, void *src); // IFF (1<<25)
void (*dispose_helper)(void *src); // IFF (1<<25)
// required ABI.2010.3.16
const char *signature; // IFF (1<<30)
Share the same block descriptors between copies of a block. Fixes #43592. (#683) In bug #43592 the following occurs: * App calls an API that takes a block. * We create a stack-based ObjC block based on the delegate the app provided. This block has a pointer to a block description, describing the block in question (including the signature of the block, as an ObjC-type encoded string). We allocate a new block description for every block. * Apple's API stores the pointer to the signature string somewhere. * Apple calls _Block_copy to get a heap-based block. * We create a heap-based block, and copy the entire description into the new heap-based block (including a copy of the signature). * Apple returns from the API, and then we free the stack-based block (and the descriptor, and thus the signature string in the descriptor). * Apple uses the pointer to the signature stored previously to investigate the signature of the block, and crashes because this signature has been freed. The assumption in Apple's code is that the description will never be freed, which is true for any Xcode project (clang will always be able to create the block description at compile-time and emit it in the binary, which means the memory will never be freed). We could potentially do the same thing in the static registrar, but we'd still need a solution when using the dynamic registrar. To fix this instead of copying the entire description structure when creating a heap-based block from the stack-based block, we make the description ref- counted, and just use the same description in the heap-based block. The signature will now stay in memory until both the heap-based and stack- based blocks have been freed, and we hope Apple doesn't have any API that needs the signature after all the blocks for that signature have been freed. https://bugzilla.xamarin.com/show_bug.cgi?id=43592
2016-08-26 20:22:38 +03:00
volatile int ref_count;
2016-04-21 15:19:32 +03:00
// variable-length string
};
struct Block_literal {
void *isa;
int flags;
int reserved;
void (*invoke)(void *, ...);
struct Xamarin_block_descriptor *descriptor;
void *local_handle;
void *global_handle;
};
struct Xamarin_block_descriptor * xamarin_get_block_descriptor ();
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __SHARED_H__ */