… | |
… | |
265 | |
265 | |
266 | You could override this function in high-availability programs to, say, |
266 | You could override this function in high-availability programs to, say, |
267 | free some memory if it cannot allocate memory, to use a special allocator, |
267 | free some memory if it cannot allocate memory, to use a special allocator, |
268 | or even to sleep a while and retry until some memory is available. |
268 | or even to sleep a while and retry until some memory is available. |
269 | |
269 | |
|
|
270 | Example: The following is the C<realloc> function that libev itself uses |
|
|
271 | which should work with C<realloc> and C<free> functions of all kinds and |
|
|
272 | is probably a good basis for your own implementation. |
|
|
273 | |
|
|
274 | static void * |
|
|
275 | ev_realloc_emul (void *ptr, long size) EV_NOEXCEPT |
|
|
276 | { |
|
|
277 | if (size) |
|
|
278 | return realloc (ptr, size); |
|
|
279 | |
|
|
280 | free (ptr); |
|
|
281 | return 0; |
|
|
282 | } |
|
|
283 | |
270 | Example: Replace the libev allocator with one that waits a bit and then |
284 | Example: Replace the libev allocator with one that waits a bit and then |
271 | retries (example requires a standards-compliant C<realloc>). |
285 | retries. |
272 | |
286 | |
273 | static void * |
287 | static void * |
274 | persistent_realloc (void *ptr, size_t size) |
288 | persistent_realloc (void *ptr, size_t size) |
275 | { |
289 | { |
|
|
290 | if (!size) |
|
|
291 | { |
|
|
292 | free (ptr); |
|
|
293 | return 0; |
|
|
294 | } |
|
|
295 | |
276 | for (;;) |
296 | for (;;) |
277 | { |
297 | { |
278 | void *newptr = realloc (ptr, size); |
298 | void *newptr = realloc (ptr, size); |
279 | |
299 | |
280 | if (newptr) |
300 | if (newptr) |
… | |
… | |
3978 | The normal C API should work fine when used from C++: both ev.h and the |
3998 | The normal C API should work fine when used from C++: both ev.h and the |
3979 | libev sources can be compiled as C++. Therefore, code that uses the C API |
3999 | libev sources can be compiled as C++. Therefore, code that uses the C API |
3980 | will work fine. |
4000 | will work fine. |
3981 | |
4001 | |
3982 | Proper exception specifications might have to be added to callbacks passed |
4002 | Proper exception specifications might have to be added to callbacks passed |
3983 | to libev: exceptions may be thrown only from watcher callbacks, all |
4003 | to libev: exceptions may be thrown only from watcher callbacks, all other |
3984 | other callbacks (allocator, syserr, loop acquire/release and periodic |
4004 | callbacks (allocator, syserr, loop acquire/release and periodic reschedule |
3985 | reschedule callbacks) must not throw exceptions, and might need a C<throw |
4005 | callbacks) must not throw exceptions, and might need a C<noexcept> |
3986 | ()> specification. If you have code that needs to be compiled as both C |
4006 | specification. If you have code that needs to be compiled as both C and |
3987 | and C++ you can use the C<EV_THROW> macro for this: |
4007 | C++ you can use the C<EV_NOEXCEPT> macro for this: |
3988 | |
4008 | |
3989 | static void |
4009 | static void |
3990 | fatal_error (const char *msg) EV_THROW |
4010 | fatal_error (const char *msg) EV_NOEXCEPT |
3991 | { |
4011 | { |
3992 | perror (msg); |
4012 | perror (msg); |
3993 | abort (); |
4013 | abort (); |
3994 | } |
4014 | } |
3995 | |
4015 | |