espace / eventmachine forked from riham/eventmachine

A fast network I/O and event-management framework for Ruby, Java, and C++ programmers.

This URL has Read+Write access

eventmachine / ext / binder.cpp
100644 127 lines (87 sloc) 2.624 kb
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
/*****************************************************************************
 
$Id$
 
File: binder.cpp
Date: 07Apr06
 
Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
Gmail: blackhedd
 
This program is free software; you can redistribute it and/or modify
it under the terms of either: 1) the GNU General Public License
as published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version; or 2) Ruby's License.
 
See the file COPYING for complete licensing information.
 
*****************************************************************************/
 
#include "project.h"
 
#define DEV_URANDOM "/dev/urandom"
 
 
map<string, Bindable_t*> Bindable_t::BindingBag;
 
 
/********************************
STATIC Bindable_t::CreateBinding
********************************/
 
string Bindable_t::CreateBinding()
{
static int index = 0;
static string seed;
 
if ((index >= 1000000) || (seed.length() == 0)) {
#ifdef OS_UNIX
int fd = open (DEV_URANDOM, O_RDONLY);
if (fd < 0)
throw std::runtime_error ("No entropy device");
 
unsigned char u[16];
size_t r = read (fd, u, sizeof(u));
if (r < sizeof(u))
throw std::runtime_error ("Unable to read entropy device");
 
unsigned char *u1 = (unsigned char*)u;
char u2 [sizeof(u) * 2 + 1];
 
for (size_t i=0; i < sizeof(u); i++)
sprintf (u2 + (i * 2), "%02x", u1[i]);
 
seed = string (u2);
#endif
 
 
#ifdef OS_WIN32
UUID uuid;
UuidCreate (&uuid);
unsigned char *uuidstring = NULL;
UuidToString (&uuid, &uuidstring);
if (!uuidstring)
throw std::runtime_error ("Unable to read uuid");
seed = string ((const char*)uuidstring);
 
RpcStringFree (&uuidstring);
#endif
 
index = 0;
 
 
}
 
stringstream ss;
ss << seed << (++index);
return ss.str();
}
 
 
/*****************************
STATIC: Bindable_t::GetObject
*****************************/
 
Bindable_t *Bindable_t::GetObject (const char *binding)
{
  string s (binding ? binding : "");
  return GetObject (s);
}
 
/*****************************
STATIC: Bindable_t::GetObject
*****************************/
 
Bindable_t *Bindable_t::GetObject (const string &binding)
{
  map<string, Bindable_t*>::const_iterator i = BindingBag.find (binding);
  if (i != BindingBag.end())
    return i->second;
  else
    return NULL;
}
 
 
/**********************
Bindable_t::Bindable_t
**********************/
 
Bindable_t::Bindable_t()
{
Binding = Bindable_t::CreateBinding();
BindingBag [Binding] = this;
}
 
 
 
/***********************
Bindable_t::~Bindable_t
***********************/
 
Bindable_t::~Bindable_t()
{
BindingBag.erase (Binding);
}