Skip to content

Commit a4112b8

Browse files
author
Sebastiano Merlino
committed
Changed http_resource_mirror to class
Changed event_tuple to class Moved mirrors to the hpp avoiding heap usage
1 parent e9dd2cf commit a4112b8

File tree

2 files changed

+137
-95
lines changed

2 files changed

+137
-95
lines changed

src/httpserver/webserver.hpp

Lines changed: 131 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ class long_polling_receive_response;
7272
class long_polling_send_response;
7373
struct cache_entry;
7474
class webserver;
75+
template<typename CHILD>
76+
class event_supplier;
7577

7678
typedef void(*render_ptr)(const http_request&, http_response**);
7779

@@ -312,6 +314,49 @@ namespace details
312314
return (_binder.exec()->*(_binder.get_mem_ptr()))(p1, p2, p3);
313315
}
314316
};
317+
318+
template<typename PAR1, typename PAR2, typename PAR3, typename PAR4, typename RET_TYPE=void>
319+
class functor_four
320+
{
321+
private:
322+
typedef RET_TYPE (*static_function)(PAR1 p1, PAR2 p2, PAR3 p3, PAR4 p4);
323+
typedef RET_TYPE (*void_static_function)(PAR1 p1, PAR2 p2, PAR3 p3, PAR4 p4);
324+
typedef RET_TYPE (generic_class::*generic_mem)(PAR1 p1, PAR2 p2, PAR3 p3, PAR4 p4);
325+
typedef binder<generic_mem, static_function, void_static_function> binder_type;
326+
binder_type _binder;
327+
328+
RET_TYPE exec_static(PAR1 p1, PAR2 p2, PAR3 p3, PAR4 p4) const
329+
{
330+
return (*(_binder.get_static_func()))(p1, p2, p3, p4);
331+
}
332+
public:
333+
typedef functor_four type;
334+
functor_four() { }
335+
336+
template <typename X, typename Y>
337+
functor_four(Y* pmem, RET_TYPE(X::*func)(PAR1 p1, PAR2 p2, PAR3 p3, PAR4 p4) )
338+
{
339+
_binder.bind(reinterpret_cast<X*>(pmem), func);
340+
}
341+
functor_four(RET_TYPE(*func)(PAR1 p1, PAR2 p2, PAR3 p3, PAR4 p4) )
342+
{
343+
bind(func);
344+
}
345+
template < class X, class Y >
346+
inline void bind(Y* pmem, RET_TYPE(X::*func)(PAR1 p1, PAR2 p2, PAR3 p3, PAR4 p4))
347+
{
348+
_binder.bind(reinterpret_cast<X*>(pmem), func);
349+
}
350+
inline void bind(RET_TYPE(*func)(PAR1 P1, PAR2 p2, PAR3 p3, PAR4 p4))
351+
{
352+
_binder.bind_static(this, &functor_four::exec_static, func);
353+
}
354+
RET_TYPE operator() (PAR1 p1, PAR2 p2, PAR3 p3, PAR4 p4) const
355+
{
356+
return (_binder.exec()->*(_binder.get_mem_ptr()))(p1, p2, p3, p4);
357+
}
358+
};
359+
315360
}
316361

317362
class http_endpoint;
@@ -334,63 +379,93 @@ namespace details
334379
void empty_not_acceptable_render(const http_request& r, http_response** res);
335380
bool empty_is_allowed(const std::string& method);
336381

337-
struct http_resource_mirror
382+
class http_resource_mirror
338383
{
339-
typedef binders::functor_two<const http_request&, http_response**, void> functor;
340-
typedef binders::functor_one<const std::string&, bool> functor_allowed;
341-
functor render;
342-
functor render_GET;
343-
functor render_POST;
344-
functor render_PUT;
345-
functor render_HEAD;
346-
functor render_DELETE;
347-
functor render_TRACE;
348-
functor render_OPTIONS;
349-
functor render_CONNECT;
350-
functor_allowed is_allowed;
351-
functor method_not_acceptable_resource;
384+
public:
385+
http_resource_mirror()
386+
{
387+
}
352388

353-
template<typename T>
354-
http_resource_mirror(http_resource<T>* res):
355-
render(&empty_render),
356-
render_GET(render),
357-
render_POST(render),
358-
render_PUT(render),
359-
render_HEAD(render),
360-
render_DELETE(render),
361-
render_TRACE(render),
362-
render_OPTIONS(render),
363-
render_CONNECT(render),
364-
is_allowed(&empty_is_allowed)
365-
{
366-
if(HAS_METHOD(render, T, void, const http_request&, http_response**))
367-
render.bind(res, &T::render);
368-
if(HAS_METHOD(render_GET, T, void, const http_request&, http_response**))
369-
render_GET.bind(res, &T::render_GET);
370-
if(HAS_METHOD(render_POST, T, void, const http_request&, http_response**))
371-
render_POST.bind(res, &T::render_POST);
372-
if(HAS_METHOD(render_PUT, T, void, const http_request&, http_response**))
373-
render_PUT.bind(res, &T::render_PUT);
374-
if(HAS_METHOD(render_HEAD, T, void, const http_request&, http_response**))
375-
render_HEAD.bind(res, &T::render_HEAD);
376-
if(HAS_METHOD(render_DELETE, T, void, const http_request&, http_response**))
377-
render_DELETE.bind(res, &T::render_DELETE);
378-
if(HAS_METHOD(render_TRACE, T, void, const http_request&, http_response**))
379-
render_TRACE.bind(res, &T::render_TRACE);
380-
if(HAS_METHOD(render_OPTIONS, T, void, const http_request&, http_response**))
381-
render_OPTIONS.bind(res, &T::render_OPTIONS);
382-
if(HAS_METHOD(render_CONNECT, T, void, const http_request&, http_response**))
383-
render_CONNECT.bind(res, &T::render_CONNECT);
384-
is_allowed.bind(res, &T::is_allowed);
385-
}
389+
~http_resource_mirror()
390+
{
391+
}
392+
private:
393+
typedef binders::functor_two<const http_request&, http_response**, void> functor;
394+
typedef binders::functor_one<const std::string&, bool> functor_allowed;
395+
functor render;
396+
functor render_GET;
397+
functor render_POST;
398+
functor render_PUT;
399+
functor render_HEAD;
400+
functor render_DELETE;
401+
functor render_TRACE;
402+
functor render_OPTIONS;
403+
functor render_CONNECT;
404+
functor_allowed is_allowed;
405+
functor method_not_acceptable_resource;
406+
407+
template<typename T>
408+
http_resource_mirror(http_resource<T>* res):
409+
render(&empty_render),
410+
render_GET(render),
411+
render_POST(render),
412+
render_PUT(render),
413+
render_HEAD(render),
414+
render_DELETE(render),
415+
render_TRACE(render),
416+
render_OPTIONS(render),
417+
render_CONNECT(render),
418+
is_allowed(&empty_is_allowed)
419+
{
420+
if(HAS_METHOD(render, T, void, const http_request&, http_response**))
421+
render.bind(res, &T::render);
422+
if(HAS_METHOD(render_GET, T, void, const http_request&, http_response**))
423+
render_GET.bind(res, &T::render_GET);
424+
if(HAS_METHOD(render_POST, T, void, const http_request&, http_response**))
425+
render_POST.bind(res, &T::render_POST);
426+
if(HAS_METHOD(render_PUT, T, void, const http_request&, http_response**))
427+
render_PUT.bind(res, &T::render_PUT);
428+
if(HAS_METHOD(render_HEAD, T, void, const http_request&, http_response**))
429+
render_HEAD.bind(res, &T::render_HEAD);
430+
if(HAS_METHOD(render_DELETE, T, void, const http_request&, http_response**))
431+
render_DELETE.bind(res, &T::render_DELETE);
432+
if(HAS_METHOD(render_TRACE, T, void, const http_request&, http_response**))
433+
render_TRACE.bind(res, &T::render_TRACE);
434+
if(HAS_METHOD(render_OPTIONS, T, void, const http_request&, http_response**))
435+
render_OPTIONS.bind(res, &T::render_OPTIONS);
436+
if(HAS_METHOD(render_CONNECT, T, void, const http_request&, http_response**))
437+
render_CONNECT.bind(res, &T::render_CONNECT);
438+
is_allowed.bind(res, &T::is_allowed);
439+
}
386440

387-
http_resource_mirror()
388-
{
389-
}
441+
friend class ::httpserver::webserver;
442+
};
390443

391-
~http_resource_mirror()
392-
{
393-
}
444+
class event_tuple
445+
{
446+
private:
447+
typedef void(*supply_events_ptr)(
448+
fd_set*,
449+
fd_set*,
450+
fd_set*,
451+
int*
452+
);
453+
454+
typedef long(*get_timeout_ptr)();
455+
typedef void(*dispatch_events_ptr)();
456+
supply_events_ptr supply_events;
457+
get_timeout_ptr get_timeout;
458+
dispatch_events_ptr dispatch_events;
459+
460+
friend class ::httpserver::webserver;
461+
public:
462+
template<typename T>
463+
event_tuple(event_supplier<T>* es):
464+
supply_events(std::bind1st(std::mem_fun(&T::supply_events), es)),
465+
get_timeout(std::bind1st(std::mem_fun(&T::get_timeout), es)),
466+
dispatch_events(std::bind1st(std::mem_fun(&T::dispatch_events), es))
467+
{
468+
}
394469
};
395470
}
396471

@@ -436,23 +511,11 @@ class event_supplier
436511
};
437512

438513
class create_webserver;
439-
440514
typedef bool(*validator_ptr)(const std::string&);
441515
typedef void(*unescaper_ptr)(char*);
442-
typedef void(*supply_events_ptr)(
443-
fd_set*,
444-
fd_set*,
445-
fd_set*,
446-
int*
447-
);
448-
449-
typedef long(*get_timeout_ptr)();
450-
typedef void(*dispatch_events_ptr)();
451516
typedef void(*log_access_ptr)(const std::string&);
452517
typedef void(*log_error_ptr)(const std::string&);
453518

454-
struct event_tuple;
455-
456519
/**
457520
* Class representing the webserver. Main class of the apis.
458521
**/
@@ -621,10 +684,10 @@ class webserver
621684
void register_event_supplier(const std::string& id, event_supplier<T>* ev_supplier)
622685
{
623686
pthread_rwlock_wrlock(&runguard);
624-
std::map<std::string, event_tuple*>::iterator it = event_suppliers.find(id);
687+
std::map<std::string, details::event_tuple>::iterator it = event_suppliers.find(id);
625688
if(it != event_suppliers.end())
626689
delete it->second;
627-
event_suppliers[id] = new event_tuple(&ev_supplier);
690+
event_suppliers[id] = details::event_tuple(&ev_supplier);
628691
pthread_rwlock_unlock(&runguard);
629692
}
630693

@@ -704,7 +767,7 @@ class webserver
704767
std::vector<details::daemon_item*> daemons;
705768
std::vector<pthread_t> threads;
706769

707-
std::map<std::string, event_tuple*> event_suppliers;
770+
std::map<std::string, details::event_tuple> event_suppliers;
708771

709772
void init(render_ptr single_resource);
710773
static void* select(void* self);

src/webserver.cpp

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -296,21 +296,6 @@ struct cache_entry
296296
}
297297
};
298298

299-
struct event_tuple
300-
{
301-
supply_events_ptr supply_events;
302-
get_timeout_ptr get_timeout;
303-
dispatch_events_ptr dispatch_events;
304-
305-
template<typename T>
306-
event_tuple(event_supplier<T>* es):
307-
supply_events(std::bind1st(std::mem_fun(&T::supply_events), es)),
308-
get_timeout(std::bind1st(std::mem_fun(&T::get_timeout), es)),
309-
dispatch_events(std::bind1st(std::mem_fun(&T::dispatch_events), es))
310-
{
311-
}
312-
};
313-
314299
using namespace http;
315300

316301
int policy_callback (void *, const struct sockaddr*, socklen_t);
@@ -669,17 +654,17 @@ void* webserver::select(void* self)
669654
}
670655

671656
{
672-
std::map<std::string, event_tuple*>::const_iterator it;
657+
std::map<std::string, details::event_tuple>::const_iterator it;
673658
pthread_rwlock_rdlock(&di->ws->runguard);
674659
for(it = di->ws->event_suppliers.begin(); it != di->ws->event_suppliers.end(); ++it)
675660
{
676661
int local_max;
677-
(*it).second->supply_events(&rs, &ws, &es, &local_max);
662+
(*it).second.supply_events(&rs, &ws, &es, &local_max);
678663

679664
if(local_max > max)
680665
max = local_max;
681666

682-
unsigned long t = (*it).second->get_timeout();
667+
unsigned long t = (*it).second.get_timeout();
683668
if(t < timeout)
684669
timeout = t;
685670
}
@@ -719,11 +704,11 @@ void* webserver::select(void* self)
719704
::select (max + 1, &rs, &ws, &es, &timeout_value);
720705
MHD_run (di->daemon);
721706
{
722-
std::map<std::string, event_tuple*>::const_iterator it;
707+
std::map<std::string, details::event_tuple>::const_iterator it;
723708
pthread_rwlock_rdlock(&di->ws->runguard);
724709
for(it = di->ws->event_suppliers.begin(); it != di->ws->event_suppliers.end(); ++it)
725710
{
726-
(*it).second->dispatch_events();
711+
(*it).second.dispatch_events();
727712
}
728713
}
729714
}
@@ -1862,13 +1847,7 @@ void webserver::get_response(cache_entry* ce, http_response** res)
18621847
void webserver::remove_event_supplier(const std::string& id)
18631848
{
18641849
pthread_rwlock_wrlock(&runguard);
1865-
map<string, event_tuple*>::iterator it = event_suppliers.find(id);
1866-
if(it != event_suppliers.end())
1867-
{
1868-
event_tuple* evp(it->second);
1869-
event_suppliers.erase(it);
1870-
delete evp;
1871-
}
1850+
event_suppliers.erase(id);
18721851
pthread_rwlock_unlock(&runguard);
18731852
}
18741853

0 commit comments

Comments
 (0)