#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dispatch/dispatch.h>
#include <objc/objc-internal.h>
#include "AutoreleaseTest.h"
static void
read_releases_pending(int fd, void (^handler)(ssize_t))
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
ssize_t result = -1;
FILE *fp = fdopen(fd, "r");
char *line = NULL;
size_t linecap = 0;
ssize_t linelen;
while ((linelen = getline(&line, &linecap, fp)) > 0) {
ssize_t pending;
if (sscanf(line, "objc[%*d]: %ld releases pending", &pending) == 1) {
result = pending;
break;
}
}
free(line);
fclose(fp);
handler(result);
});
}
ssize_t
pending_autorelease_count(void)
{
__block ssize_t result = -1;
dispatch_semaphore_t sema;
int fds[2];
int saved_stderr;
pipe(fds);
fcntl(fds[1], F_SETNOSIGPIPE, 1);
sema = dispatch_semaphore_create(0);
read_releases_pending(fds[0], ^(ssize_t pending) {
result = pending;
dispatch_semaphore_signal(sema);
});
saved_stderr = dup(STDERR_FILENO);
dup2(fds[1], STDERR_FILENO);
close(fds[1]);
_objc_autoreleasePoolPrint();
dup2(saved_stderr, STDERR_FILENO);
close(saved_stderr);
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
#if !__has_feature(objc_arc)
dispatch_release(sema);
#endif
return result;
}