Skip to content

Modifications and cleanup for compilation on OS/X#42

Closed
waTeim wants to merge 4 commits into
etr:masterfrom
waTeim:master
Closed

Modifications and cleanup for compilation on OS/X#42
waTeim wants to merge 4 commits into
etr:masterfrom
waTeim:master

Conversation

@waTeim
Copy link
Copy Markdown

@waTeim waTeim commented Feb 18, 2014

I've made modifications mostly for compilation on OS/X to succeed. Found 1 generic bug and one bug that is OS/X specific. The resulting library have been tested by inclusion in a program compiled for both OS/X and Linux. The changes are limited in scope and can be verified readily by inspection. I also made some changes that are not strictly necessary, but suited to my development environment.

More specifically;

  1. clang requires that the copy constructor of http_endpoint be public.

  2. Changed to match declarations and forward declarations; class for class, struct for struct

  3. clang may have further requirements needing fully defined types or there is a scenario not seen before that can give rise to use of a class not fully defined for which include file inclusion fixes the problem

  4. OS/X AF_INET STREAM_SOCKETS do not support SOCK_CLOSEXEC; the system call returns EPROTONOSUPPORT not EINVAL.

  5. Changed a getter to const as it doesn't change the class state and expands the scenarios in which a temporary object need not be created.

  6. Fixed a typo in set_requestor_port.

  7. Changed to allow building in the same directory, modified .gitignore to ignore the resulting targets

Added various include directives in http_response.cpp and
http_resource.cpp and modified http_endpoint copy constructor to
make it public to satifify clang.

Fixed typo/bug in http_request::set_requestor_port.

Modified various forwards to match actual declarations.

Modified configure to allow build in same directory.
@etr
Copy link
Copy Markdown
Owner

etr commented Feb 18, 2014

Thank you for your help. I discuss here the changes. I am a lot interested in having details especially regarding the points 1 and 3.

  1. Point one is unclear - it is a specific design choice for that constructor to not be public. I would like to understand why clang need it to be public to see if it is possible to mediate the solution.

  2. Perfect.

  3. As per point 1. It is weird that clang do not tolerate standard use of implementation hiding. I am actually moving forward in the future to press much more in hiding some parts of the implementation inside "details" package.

  4. Ok

  5. Perfect.

  6. Ok

  7. Not ok on building in the same directory - do not understand the reason behind this change.

@waTeim
Copy link
Copy Markdown
Author

waTeim commented Feb 18, 2014

  1. and 3) I think this may be the difference between what gcc and clang deem to be appropriate circumstances necessary for copy elision. In that circumstance gcc elided the constructor -- is is trivially copyable? -- and clang did not, and thus needed the copy constructor to be accessible. It's just a guess though. What I can do is undo the changes privately and report back the error message and locations where clang complains.

  2. Yea I figured, especially since you put in a change to specifically prevent this. All I can say is as much as you don't like it being that way I don't like it not being that way. It's your project, do I'll go with the flow and keep it only on my fork. I hope there's an easy way for each of us to keep this separate. If you need me to do something special make it easy for you to maintain what you want let me know.

@etr
Copy link
Copy Markdown
Owner

etr commented Feb 18, 2014

Don't worry, I will probably anyway move the pull request manually.

I installed a clang instance to test it and see if I can obtain something that actually works fine with both compilers.

Regarding 7) yes, I really don't like compilations in the same folder - they usually end up in mixups between code and binaries that more than once have made me cry blood to be solved.

Once I move the pull request (or part of it) inside the code, I will add you in the AUTHORS file as a collaborator in the format:

FirstName FamilyName emailAddress

let me know if for any reason you don't want to have your name or your e-mail address inserted there.

@waTeim
Copy link
Copy Markdown
Author

waTeim commented Feb 18, 2014

Cool!

Name: Jeff Waller

Also, just to make it fun, XCode 5 clang is not the latest clang...

clang --version
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.2
Thread model: posix

  1. is easy anyway. If http_endpoint copy constructor is private, the following results, so maybe it's Apple's or clang's implementation of std:?

In file included from webserver.cpp:23:

...

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:1505:36: error: calling a private constructor of class 'httpserver::details::http_endpoint'
::new ((void*)__p) _Tp(__a0);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:1258:20: note: in instantiation of function template specialization
'std::__1::allocator_traits<std::__1::allocator<std::__1::__tree_node<std::__1::pair<httpserver::details::http_endpoint, httpserver::details::http_resource_mirror>, void *> >
>::construct<httpserver::details::http_endpoint, httpserver::details::http_endpoint>' requested here
__node_traits::construct(__na, _VSTD::addressof(__h->_value.first), __k);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:1276:29: note: in instantiation of member function 'std::__1::map<httpserver::details::http_endpoint,
httpserver::details::http_resource_mirror, std::__1::lesshttpserver::details::http_endpoint, std::__1::allocator<std::__1::pair<const httpserver::details::http_endpoint,
httpserver::details::http_resource_mirror> > >::__construct_node' requested here
__node_holder __h = __construct_node(__k);
^
webserver.cpp:255:71: note: in instantiation of member function 'std::__1::map<httpserver::details::http_endpoint, httpserver::details::http_resource_mirror, std::__1::lesshttpserver::details::http_endpoint,
std::__1::allocator<std::__1::pair<const httpserver::details::http_endpoint, httpserver::details::http_resource_mirror> > >::operator[]' requested here
registered_resources_str[idx.url_complete] = &registered_resources[idx];
^
./httpserver/details/http_endpoint.hpp:67:9: note: implicitly declared private here
http_endpoint(const http_endpoint& h);

@etr
Copy link
Copy Markdown
Owner

etr commented Feb 22, 2014

I made some changes. It seems to compile on both my clang 3.2 installation and clang 3.3 on travis-ci. Let me know if the current trunk works on your clang 5.0.
I also created an option in configure "--enable-same-directory-build" that disable the control (this way you can avoid to fork and have to align my changes back).

@waTeim
Copy link
Copy Markdown
Author

waTeim commented Feb 23, 2014

Hey I like the configure option!

Unfortunately, I think OS/X std impl is going to insist that http_endpoint is publicly available it's essentially the same error as before.

Which appears to arise from this one statement:

registered_resources_str[idx.url_complete] = &registered_resources[idx];

Makes sense too because of this:

webserver.hpp:232

std::map<details::http_endpoint, details::http_resource_mirror> registered_resources;

if instead it was something like

std::map<details::http_endpoint, details::http_resource_mirror*> registered_resources;

or

std::map< details::http_endpoint, std::shared_ptr<details::http_resource_mirror> > registered_resources;

this second option is probably going to force std=c++11 though, which is limiting, but maybe no big deal in 2014.

that would probably satisfy the OS/X impl.

mv -f .deps/string_utilities.Tpo .deps/string_utilities.Plo
/bin/sh ../libtool --tag=CXX --mode=compile clang++ -DHAVE_CONFIG_H -I. -I.. -I../ -I./httpserver/ -O3 -fPIC -Wall -DHTTPSERVER_COMPILATION -D_REENTRANT -I/usr/local/include -MT webserver.lo -MD -MP -MF .deps/webserver.Tpo -c -o webserver.lo webserver.cpp
libtool: compile: clang++ -DHAVE_CONFIG_H -I. -I.. -I../ -I./httpserver/ -O3 -fPIC -Wall -DHTTPSERVER_COMPILATION -D_REENTRANT -I/usr/local/include -MT webserver.lo -MD -MP -MF .deps/webserver.Tpo -c webserver.cpp -fno-common -DPIC -o .libs/webserver.o
In file included from webserver.cpp:23:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/iostream:38:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/ios:216:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/_locale:15:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/string:434:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/algorithm:594:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:1505:36: error: calling a private constructor of class
'httpserver::details::http_endpoint'
::new ((void
)__p) _Tp(__a0);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:1258:20: note: in instantiation of function template specialization
'std::__1::allocator_traits<std::__1::allocator<std::__1::__tree_node<std::__1::pair<httpserver::details::http_endpoint, httpserver::details::http_resource_mirror>, void *> >
>::construct<httpserver::details::http_endpoint, httpserver::details::http_endpoint>' requested here
__node_traits::construct(__na, _VSTD::addressof(__h->_value.first), __k);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:1276:29: note: in instantiation of member function
'std::__1::map<httpserver::details::http_endpoint, httpserver::details::http_resource_mirror, std::__1::lesshttpserver::details::http_endpoint, std::__1::allocator<std::__1::pair<const
httpserver::details::http_endpoint, httpserver::details::http_resource_mirror> > >::__construct_node' requested here
__node_holder __h = __construct_node(__k);
^
webserver.cpp:255:71: note: in instantiation of member function 'std::__1::map<httpserver::details::http_endpoint, httpserver::details::http_resource_mirror,
std::__1::lesshttpserver::details::http_endpoint, std::__1::allocator<std::__1::pair<const httpserver::details::http_endpoint, httpserver::details::http_resource_mirror> > >::operator[]'
requested here
registered_resources_str[idx.url_complete] = &registered_resources[idx];
^
./httpserver/details/http_endpoint.hpp:68:9: note: declared private here
http_endpoint(const http_endpoint& h);
^
In file included from webserver.cpp:23:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/iostream:38:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/ios:216:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__locale:15:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/string:434:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/algorithm:594:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:1628:23: error: 'http_endpoint' is a private member of
'httpserver::details::http_endpoint'
__p->
_Tp();
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:1526:14: note: in instantiation of function template specialization
'std::__1::allocator_traits<std::__1::allocator<std::__1::__tree_node<std::__1::pair<httpserver::details::http_endpoint, httpserver::details::http_resource_mirror>, void *> >
>::__destroyhttpserver::details::http_endpoint' requested here
{__destroy(__has_destroy<allocator_type, Tp>(), __a, __p);}
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:526:29: note: in instantiation of function template specialization
'std::__1::allocator_traits<std::__1::allocator<std::__1::__tree_node<std::__1::pair<httpserver::details::http_endpoint, httpserver::details::http_resource_mirror>, void *> >
>::destroyhttpserver::details::http_endpoint' requested here
__alloc_traits::destroy(_na, _VSTD::addressof(__p->_value.first));
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:2687:13: note: in instantiation of member function
'std::__1::__map_node_destructor<std::__1::allocator<std::__1::__tree_node<std::__1::pair<httpserver::details::http_endpoint, httpserver::details::http_resource_mirror>, void *> >
>::operator()' requested here
_ptr.second()(__tmp);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:2655:46: note: in instantiation of member function
'std::__1::unique_ptr<std::__1::__tree_node<std::__1::pair<httpserver::details::http_endpoint, httpserver::details::http_resource_mirror>, void *>,
std::__1::__map_node_destructor<std::__1::allocator<std::__1::__tree_node<std::__1::pair<httpserver::details::http_endpoint, httpserver::details::http_resource_mirror>, void *> > > >::reset'
requested here
_LIBCPP_INLINE_VISIBILITY ~unique_ptr() {reset();}
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/map:1276:29: note: in instantiation of member function
'std::__1::unique_ptr<std::__1::__tree_node<std::__1::pair<httpserver::details::http_endpoint, httpserver::details::http_resource_mirror>, void *>,
std::__1::__map_node_destructor<std::__1::allocator<std::__1::__tree_node<std::__1::pair<httpserver::details::http_endpoint, httpserver::details::http_resource_mirror>, void *> > >
>::~unique_ptr' requested here
__node_holder __h = __construct_node(__k);
^
webserver.cpp:255:71: note: in instantiation of member function 'std::__1::map<httpserver::details::http_endpoint, httpserver::details::http_resource_mirror,
std::__1::lesshttpserver::details::http_endpoint, std::__1::allocator<std::__1::pair<const httpserver::details::http_endpoint, httpserver::details::http_resource_mirror> > >::operator[]'
requested here
registered_resources_str[idx.url_complete] = &registered_resources[idx];
^
./httpserver/details/http_endpoint.hpp:72:9: note: declared private here
~http_endpoint(); //if inlined it causes problems during ruby wrapper compiling

@etr
Copy link
Copy Markdown
Owner

etr commented Feb 23, 2014

I think they are avoiding somehow the type erasure in new versions - since it compiles with 3.2 and 3.3.
A pointer or shared_ptr in the value type would not solve the problem since what clang claims to want be public is the key not the value.
I will try to install a clang 5.

@waTeim
Copy link
Copy Markdown
Author

waTeim commented Feb 23, 2014

Oops, haha, you're right of course, but then same comments, but for the key not the value.

@etr
Copy link
Copy Markdown
Owner

etr commented Feb 24, 2014

I tried to block the possibilities for clang to build the partial object. I do not see why clang need to build a temporary copy of the key while inserting - this actually does not happen in linux implementation of LLVM 3.3 that matches your version on Mac OS/X. This make me strongly suspect that Mac implementation is just wrong.

It would be long to explain the details of why I need an object and not a pointer as key and it is much more easy to explain why it is not possible to use C++11 costructs since there are guys compiling this library with gcc 4.1.

I still think that having a public constructor for http_endpoint is not a good choice and I will not change this because they are not able to build a decent compiler.

Said this, let me know if this new version works, otherwise I will add an #ifdef that moves to public the constructor in OS/X environments - at least this shame will be confined.

@etr etr closed this Apr 5, 2014
etr added a commit that referenced this pull request May 28, 2026
Address all 48 minor findings from the 2026-05-26 review pass. Summary of
changes by file:

src/detail/webserver_aliases.cpp
- Remove redundant `static` from `append_sanitized` (anon namespace already
  provides internal linkage; findings #6/#15/#16)
- Trim verbose format-compatibility comment to single-line reference (#7)

src/detail/webserver_finalize.cpp
- Trim file-level comment block to two-sentence summary (#20)
- Add clarifying comment to the `!mr->response` defensive guard (#21)
- Rename `bytes` → `bytes_queued` to match the ctx field it populates (#22)
- Add inline NOTE to elapsed ternary: alias must not read ctx.elapsed (#36)
- Sentinel check for degenerate start_time: emit nanoseconds{-1} when
  answer_to_connection never ran, so hook authors can distinguish port-scan
  paths from real (but very slow) requests (#37)

src/detail/webserver_request.cpp
- Remove redundant `mr->ws = parent` from complete_request; add comment
  noting the field is pre-populated in answer_to_connection (#3)
- Add NOTE comments at both before_handler and skip_handler short-circuit
  paths documenting that after_handler does not fire there (#38)
- Collapse stale TASK-050 migration comment to one line (#25)

src/httpserver/hook_context.hpp
- Add @note to response_sent_ctx documenting elapsed==zero when only the
  log_access alias fires (no add_hook(response_sent, ...) registered) (#9)
- Add @note to request_completed_ctx documenting the nanoseconds{-1}
  sentinel for degenerate start_time paths (#37)

src/httpserver/create_webserver.hpp
- Add @param note to log_access() setter documenting that the callable
  must be CopyConstructible (#35)

examples/clf_access_log.cpp
- Refactor emit_clf_line to use early null guard + unconditional extraction
  of method/path (idiomatic pattern matching webserver_aliases.cpp) (#12-14)
- Add comment explaining intentional 'HTTP/1.1' hardcoding (#33)

specs/architecture/04-components/hooks.md
- Update after_handler, response_sent, request_completed rows with
  file:symbol fire-site references (#26, #27)
- Fix stale webserver.cpp references for route_resolved, before_handler,
  and handler_exception rows (pre-existing staleness from TASK-048) (#27)
- Update API surface comment: after_handler_ctx uses http_response* not
  http_response& (#4)
- Add after_handler firing rules paragraph documenting which paths fire /
  skip after_handler (#1, #2)

specs/tasks/M5-routing-lifecycle/TASK-050.md
- Update three action items to reference correct TUs (webserver_finalize.cpp,
  webserver_callbacks.cpp) and correct field types (#28, #40)

test/integ/hooks_no_firing.cpp
- Add positive firing-count assertions for all wired phases on the happy-path
  GET (after_handler, response_sent, request_completed, route_resolved,
  before_handler, connection_opened, connection_closed, request_received) to
  give the test lasting regression value (#10, #42)

test/integ/hooks_request_completed_fires_on_early_failure.cpp
- Remove timing-dependent 50ms sleep; rely on ws.stop() as synchronisation
  barrier, consistent with other integ tests in this task (#11, #43)

test/unit/hooks_log_access_alias_slot_test.cpp
- Add assertion that '-' replacement appears at injection site in path
  sanitization test (not just absence of control chars) (#44)
- Add assertion that 'GET' remains intact in method sanitization test (#46)
- Add fourth test case pinning construction-time isolation between two
  webservers each with their own log_access callable; documents that
  runtime re-registration is deferred to a future task (#48)

specs/unworked_review_issues/2026-05-26_123948_task-050.md
- Mark all 48 items with [x] and disposition notes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
etr added a commit that referenced this pull request May 28, 2026
…eview-cleanup)

Major findings (5 total):
- #1 (adr-violation): implementation is correct per DR-012/DR-009 §5.2; deferred.
- #2/#3/#28 (code-structure, triplicate): extracted append_impl<P,Sig> template
  helper in resource_hook_table.cpp anonymous namespace; each of the five
  append_* methods now delegates in one line (mirrors fire_short_circuit_impl
  / fire_void_impl pattern).
- #4/#5 (test-structure, advisory): deferred — project prefers per-case
  explicit test bodies for independent failure reporting.

Key minor fixes applied (cosmetic, no behavior change):
- TOCTOU anti-pattern (#6/#35/#36/#45/#47/#48): removed expired()+lock()
  double-check from per_route_table() helper; fire_request_completed_gated
  now uses the helper consistently (was inline-expanded).
- Shadow variable (#15/#38): renamed local var per_route_table → rtable in
  fire_before_handler_gated, consistent with other gated-fire helpers.
- Lifetime comment (#12): added "res keeps the resource alive while rtable
  is in use" note in handle_dispatch_exception.
- Memory-order comment (#50): documented acquire-chain at rtable fetch site
  in fire_before_handler_gated.
- Sentinel assertions (#41/#61/#62): removed LT_CHECK_EQ(true, true) from
  hooks_per_route_resource_destroyed_first.cpp and hook_api_shape_test.cpp;
  replaced with descriptive comments.
- resource_hook_table.hpp comments (#8): clarified named-vector vs std::array
  tradeoff and any_hooks_ unused slots.
- http_resource.hpp (#24/#27): added copy-shares-hook-table note; added
  comment before HTTPSERVER_COMPILATION guard.
- http-resource.md / DR-012.md (#9/#42/#43): documented per-route hook bus
  and PIMPL storage choice.

All 62 items marked [x] in specs/unworked_review_issues/2026-05-26_230100_task-051.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants