summaryrefslogtreecommitdiffabout
path: root/include/sitecing/component_so.h
blob: 3239d4ac08d0f2a2a37b37e0de6b2de747549932 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#ifndef __SITECING_COMPONENT_SO_H
#define __SITECING_COMPONENT_SO_H

#include <sys/types.h>
#include <sys/stat.h>
#include <string>
#include <map>
#include <list>
#include "sitecing/acomponent.h"

/**
 * @file
 * @brief Classes related to the .so components handling.
 */

namespace sitecing {
    using namespace std;

    /**
     * The 'class' component object.
     */
    class component_so {
	public:
	    /**
	     * The type of the component instantiating function.
	     */
	    typedef acomponent *(*egg_t)();
	    /**
	     * Type for storing the list of instances and the reference counts.
	     */
	    typedef map<acomponent*,int> used_chickens_t;
	    /**
	     * The type for storing the list of unused instances.
	     */
	    typedef list<acomponent*> free_chickens_t;

	    /**
	     * The .so file name.
	     */
	    string sofile;
	    /**
	     * The stat structure for the .so loaded.
	     */
	    struct stat stso;
	    /**
	     * The dloaded .so handle.
	     */
	    void *dl;
	    /**
	     * Pointer to the instatiator function.
	     */
	    egg_t egg;
	    /**
	     * The list of instances in use.
	     */
	    used_chickens_t chickens_used;
	    /**
	     * The list of unused instances.
	     */
	    free_chickens_t chickens_free;

	    /**
	     * @param soname the .so file name
	     */
	    component_so(const string& soname);
	    ~component_so();
	    /**
	     * Check whether the loaded .so is in sync with the disk file.
	     */
	    bool is_uptodate() const;

	    /**
	     * @todo TODO: wish I could remember -- document me.
	     */
	    acomponent* allocate_chicken();
	    /**
	     * @todo TODO: wish I could remember -- document me.
	     */
	    void allocate_chicken(acomponent *ac);
	    /**
	     * @todo TODO: wish I could remember -- document me.
	     */
	    void deallocate_chicken(acomponent *ac);
    };

    /**
     * The component instance container.
     */
    class so_component {
	public:
	    /**
	     * Pointer to the component 'class'.
	     */
	    component_so *hen;
	    /**
	     * The instance in question.
	     */
	    acomponent* ac;

	    so_component()
		: hen(0), ac(0) { }
	    /**
	     * @param h the 'class' object.
	     * @param scif pointer to the interface to the site-C-ing core.
	     */
	    so_component(component_so *h,sitecing_interface *scif);
	    /**
	     * Copy constructor
	     * @param s source instance.
	     */
	    so_component(const so_component& s)
		: hen(0), ac(0) { attach(s); }
	    ~so_component() { detach(); }

	    /**
	     * Assignment operator.
	     * @param s source instance.
	     */
	    so_component& operator=(const so_component& s) {
		attach(s); return *this;
	    }

	    /**
	     * @todo TODO: wish I could remember the details -- document me.
	     * @param h the 'class' object.
	     * @param a the instance to be attached.
	     */
	    void attach(component_so *h,acomponent *a);
	    /**
	     * @todo TODO: wish I could remember the details -- document me.
	     * @param s the source instance.
	     */
	    void attach(const so_component& s) { attach(s.hen,s.ac); }
	    /**
	     * @todo TODO: wish I could remember the details -- document me.
	     */
	    void detach();
    };

    /**
     * The typed component instance container template.
     * @param CT the component class.
     */
    template<typename CT>
	class so_component_t : public sitecing::so_component {
	    public:
		/**
		 * @param s The untyped instance container.
		 */
		so_component_t(const so_component& s)
		    : so_component(s) { }
		CT* operator->() {
		    return static_cast<CT*>(ac->__the_most_derived_this());
		}
	};
    
}

#endif /* __SITECING_COMPONENT_SO_H */