Ohm-Management - Projektarbeit B-ME
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

dtrace_provider.cc 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. #include "dtrace_provider.h"
  2. #include <nan.h>
  3. #include <stdio.h>
  4. namespace node {
  5. using namespace v8;
  6. DTraceProvider::DTraceProvider() : Nan::ObjectWrap() {
  7. provider = NULL;
  8. }
  9. DTraceProvider::~DTraceProvider() {
  10. usdt_provider_disable(provider);
  11. usdt_provider_free(provider);
  12. }
  13. Nan::Persistent<FunctionTemplate> DTraceProvider::constructor_template;
  14. void DTraceProvider::Initialize(v8::Local<Object> target) {
  15. Nan::HandleScope scope;
  16. Local<FunctionTemplate> t = Nan::New<FunctionTemplate>(DTraceProvider::New);
  17. t->InstanceTemplate()->SetInternalFieldCount(1);
  18. t->SetClassName(Nan::New<String>("DTraceProvider").ToLocalChecked());
  19. constructor_template.Reset(t);
  20. Nan::SetPrototypeMethod(t, "addProbe", DTraceProvider::AddProbe);
  21. Nan::SetPrototypeMethod(t, "removeProbe", DTraceProvider::RemoveProbe);
  22. Nan::SetPrototypeMethod(t, "enable", DTraceProvider::Enable);
  23. Nan::SetPrototypeMethod(t, "disable", DTraceProvider::Disable);
  24. Nan::SetPrototypeMethod(t, "fire", DTraceProvider::Fire);
  25. target->Set(Nan::New<String>("DTraceProvider").ToLocalChecked(), t->GetFunction());
  26. DTraceProbe::Initialize(target);
  27. }
  28. NAN_METHOD(DTraceProvider::New) {
  29. Nan::HandleScope scope;
  30. DTraceProvider *p = new DTraceProvider();
  31. char module[128];
  32. p->Wrap(info.This());
  33. if (info.Length() < 1 || !info[0]->IsString()) {
  34. Nan::ThrowTypeError("Must give provider name as argument");
  35. return;
  36. }
  37. String::Utf8Value name(info[0]->ToString());
  38. if (info.Length() == 2) {
  39. if (!info[1]->IsString()) {
  40. Nan::ThrowTypeError("Must give module name as argument");
  41. return;
  42. }
  43. String::Utf8Value mod(info[1]->ToString());
  44. (void) snprintf(module, sizeof (module), "%s", *mod);
  45. } else if (info.Length() == 1) {
  46. // If no module name is provided, develop a synthetic module name based
  47. // on our address
  48. (void) snprintf(module, sizeof (module), "mod-%p", p);
  49. } else {
  50. Nan::ThrowError("Expected only provider name and module as arguments");
  51. return;
  52. }
  53. if ((p->provider = usdt_create_provider(*name, module)) == NULL) {
  54. Nan::ThrowError("usdt_create_provider failed");
  55. return;
  56. }
  57. info.GetReturnValue().Set(info.This());
  58. }
  59. NAN_METHOD(DTraceProvider::AddProbe) {
  60. Nan::HandleScope scope;
  61. const char *types[USDT_ARG_MAX];
  62. v8::Local<Object> obj = info.Holder();
  63. DTraceProvider *provider = Nan::ObjectWrap::Unwrap<DTraceProvider>(obj);
  64. // create a DTraceProbe object
  65. v8::Local<Function> klass =
  66. Nan::New<FunctionTemplate>(DTraceProbe::constructor_template)->GetFunction();
  67. v8::Local<Object> pd = Nan::NewInstance(klass).ToLocalChecked();
  68. // store in provider object
  69. DTraceProbe *probe = Nan::ObjectWrap::Unwrap<DTraceProbe>(pd->ToObject());
  70. obj->Set(info[0]->ToString(), pd);
  71. // reference the provider to avoid GC'ing it when only probes remain in scope.
  72. Nan::ForceSet(pd, Nan::New<String>("__prov__").ToLocalChecked(), obj,
  73. static_cast<PropertyAttribute>(DontEnum | ReadOnly | DontDelete));
  74. // add probe to provider
  75. for (int i = 0; i < USDT_ARG_MAX; i++) {
  76. if (i < info.Length() - 1) {
  77. String::Utf8Value type(info[i + 1]->ToString());
  78. if (strncmp("json", *type, 4) == 0)
  79. probe->arguments[i] = new DTraceJsonArgument();
  80. else if (strncmp("char *", *type, 6) == 0)
  81. probe->arguments[i] = new DTraceStringArgument();
  82. else if (strncmp("int", *type, 3) == 0)
  83. probe->arguments[i] = new DTraceIntegerArgument();
  84. else
  85. probe->arguments[i] = new DTraceStringArgument();
  86. types[i] = strdup(probe->arguments[i]->Type());
  87. probe->argc++;
  88. }
  89. }
  90. String::Utf8Value name(info[0]->ToString());
  91. probe->probedef = usdt_create_probe(*name, *name, probe->argc, types);
  92. Nan::SetInternalFieldPointer(pd, 1, provider);
  93. usdt_provider_add_probe(provider->provider, probe->probedef);
  94. for (size_t i = 0; i < probe->argc; i++) {
  95. free((char *)types[i]);
  96. }
  97. info.GetReturnValue().Set(pd);
  98. }
  99. NAN_METHOD(DTraceProvider::RemoveProbe) {
  100. Nan::HandleScope scope;
  101. v8::Local<Object> provider_obj = info.Holder();
  102. DTraceProvider *provider = Nan::ObjectWrap::Unwrap<DTraceProvider>(provider_obj);
  103. v8::Local<Object> probe_obj = Local<Object>::Cast(info[0]);
  104. DTraceProbe *probe = Nan::ObjectWrap::Unwrap<DTraceProbe>(probe_obj);
  105. v8::Local<String> name = Nan::New<String>(probe->probedef->name).ToLocalChecked();
  106. provider_obj->Delete(name);
  107. if (usdt_provider_remove_probe(provider->provider, probe->probedef) != 0) {
  108. Nan::ThrowError(usdt_errstr(provider->provider));
  109. return;
  110. }
  111. info.GetReturnValue().Set(Nan::True());
  112. }
  113. NAN_METHOD(DTraceProvider::Enable) {
  114. Nan::HandleScope scope;
  115. DTraceProvider *provider = Nan::ObjectWrap::Unwrap<DTraceProvider>(info.Holder());
  116. if (usdt_provider_enable(provider->provider) != 0) {
  117. Nan::ThrowError(usdt_errstr(provider->provider));
  118. return;
  119. }
  120. return;
  121. }
  122. NAN_METHOD(DTraceProvider::Disable) {
  123. Nan::HandleScope scope;
  124. DTraceProvider *provider = Nan::ObjectWrap::Unwrap<DTraceProvider>(info.Holder());
  125. if (usdt_provider_disable(provider->provider) != 0) {
  126. Nan::ThrowError(usdt_errstr(provider->provider));
  127. return;
  128. }
  129. return;
  130. }
  131. NAN_METHOD(DTraceProvider::Fire) {
  132. Nan::HandleScope scope;
  133. if (!info[0]->IsString()) {
  134. Nan::ThrowTypeError("Must give probe name as first argument");
  135. return;
  136. }
  137. if (!info[1]->IsFunction()) {
  138. Nan::ThrowTypeError("Must give probe value callback as second argument");
  139. return;
  140. }
  141. v8::Local<Object> holder = info.Holder();
  142. DTraceProvider *provider = Nan::ObjectWrap::Unwrap<DTraceProvider>(holder);
  143. Nan::MaybeLocal<v8::Value> maybe = Nan::Get(holder, info[0]);
  144. if (maybe.IsEmpty()) {
  145. return;
  146. }
  147. v8::Local<v8::Value> value = maybe.ToLocalChecked();
  148. if (!value->IsObject()) {
  149. return;
  150. }
  151. v8::Local<Object> probe = Local<Object>::Cast(value);
  152. if (probe->InternalFieldCount() != 2) {
  153. return;
  154. }
  155. if (Nan::GetInternalFieldPointer(probe, 1) != provider) {
  156. return;
  157. }
  158. DTraceProbe *p = Nan::ObjectWrap::Unwrap<DTraceProbe>(probe);
  159. if (p == NULL) {
  160. return;
  161. }
  162. p->_fire(info, 1);
  163. info.GetReturnValue().Set(Nan::True());
  164. }
  165. extern "C" void
  166. init(v8::Local<Object> target) {
  167. DTraceProvider::Initialize(target);
  168. }
  169. NODE_MODULE(DTraceProviderBindings, init)
  170. } // namespace node