Page MenuHomeFreeBSD

fts: Add blocks support.
Needs ReviewPublic

Authored by des on Thu, Apr 17, 5:55 PM.
Tags
None
Referenced Files
F115235743: D49877.diff
Mon, Apr 21, 5:17 PM
F115225694: D49877.diff
Mon, Apr 21, 2:51 PM
Unknown Object (File)
Mon, Apr 21, 7:14 AM
Unknown Object (File)
Mon, Apr 21, 4:41 AM
Unknown Object (File)
Mon, Apr 21, 4:26 AM
Unknown Object (File)
Mon, Apr 21, 3:25 AM
Unknown Object (File)
Sun, Apr 20, 4:19 AM
Unknown Object (File)
Sun, Apr 20, 2:04 AM
Subscribers

Details

Reviewers
theraven
Group Reviewers
Klara
Summary

This adds an fts_open_b() variant of fts_open() which takes a block
instead of a function pointer.

This was inspired by, and is intended to be compatible with, Apple's
implementation; however, although our FTS and theirs share a common
ancestor, they have diverged significantly. That and the fact that
we still target compilers which don't support blocks means Apple's
implementation was not directly reusable.

MFC after: never
Relnotes: yes
Sponsored by: Klara, Inc.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 63578
Build 60462: arc lint + arc unit

Event Timeline

des requested review of this revision.Thu, Apr 17, 5:55 PM
theraven added inline comments.
lib/libc/gen/fts.c
265

This will crash if the blocks runtime is not linked, which is not very friendly to callers. It would be nice if it either:

  • Gracefully exited with ENOSYS or similar if a blocks runtime is not present (and, ideally, documented this in the man page), or
  • Skipped this call if the block's isa pointer is &_NSConcreteGlobalBlock (i.e. the block has no captures).

The cast should not be required here. The Block_copy macro should cast the result to typeof the argument.

348

As above, this will crash if the blocks runtime isn't implemented, though (with the current code) we'll crash on the copy here first.

review feedback + memory issues

lib/libc/gen/fts.c
265

I don't see how compar->isa == &_NSConcreteGlobalBlock saves me from having to copy the block. The block descriptor itself could still go out of scope if the caller returns before calling fts_close().

des marked 2 inline comments as done.Fri, Apr 18, 5:16 PM
lib/libc/gen/fts.c
265

If the block is a global block then the block structure is a global and is never deallocated. The block *descriptor* is always a global (and is never copied by _Block_copy.

lib/libc/gen/fts.c
265

something like this?

@@ -59,6 +59,7 @@
 /* only present if linked with blocks runtime */
 void *_Block_copy(const void *) __weak_symbol;
 void _Block_release(const void *) __weak_symbol;
+extern void *_NSConcreteGlobalBlock[] __weak_symbol;
 
 static FTSENT  *fts_alloc(FTS *, char *, size_t);
 static FTSENT  *fts_build(FTS *, int);
@@ -274,6 +275,7 @@
 #ifdef __BLOCKS__
        compar = Block_copy(compar);
 #else
+       if (compar->isa != &_NSConcreteGlobalBlock)
                compar = _Block_copy(compar);
 #endif /* __BLOCKS__ */
        if (compar == NULL) {
@@ -287,6 +289,7 @@
 #ifdef __BLOCKS__
                Block_release(compar);
 #else
+               if (compar->isa != &_NSConcreteGlobalBlock)
                        _Block_release(compar);
 #endif /* __BLOCKS__ */
        }
This revision is now accepted and ready to land.Sat, Apr 19, 5:48 PM

don't copy global blocks

This revision now requires review to proceed.Sat, Apr 19, 9:14 PM
des marked an inline comment as done.Sat, Apr 19, 9:14 PM