ruby-dtrace 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +7 -0
- data/Manifest.txt +10 -1
- data/Rakefile +3 -1
- data/ext/dtrace_aggdata.c +139 -0
- data/ext/dtrace_api.c +17 -9
- data/ext/dtrace_api.h +15 -7
- data/ext/dtrace_bufdata.c +91 -0
- data/ext/dtrace_hdl.c +101 -0
- data/ext/dtrace_probedata.c +129 -0
- data/ext/dtrace_recdesc.c +0 -23
- data/ext/dtrace_util.c +91 -0
- data/ext/extconf.rb +1 -1
- data/lib/dtrace.rb +6 -1
- data/lib/dtraceaggregate.rb +13 -0
- data/lib/dtraceconsumer.rb +99 -0
- data/lib/dtraceprobe.rb +13 -0
- data/lib/dtraceprobedata.rb +16 -0
- data/lib/dtracerecord.rb +8 -0
- data/plugin/dtrace/lib/dtracer.rb +6 -5
- data/test/test_dtrace.rb +0 -306
- data/test/test_dtrace_workapi.rb +142 -0
- metadata +13 -3
- data/ext/dtrace_aggregate.c +0 -150
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -2,16 +2,24 @@ History.txt
|
|
2
2
|
Manifest.txt
|
3
3
|
README.txt
|
4
4
|
Rakefile
|
5
|
-
ext/
|
5
|
+
ext/dtrace_aggdata.c
|
6
6
|
ext/dtrace_api.c
|
7
7
|
ext/dtrace_api.h
|
8
|
+
ext/dtrace_bufdata.c
|
8
9
|
ext/dtrace_hdl.c
|
9
10
|
ext/dtrace_probe.c
|
11
|
+
ext/dtrace_probedata.c
|
10
12
|
ext/dtrace_program.c
|
11
13
|
ext/dtrace_programinfo.c
|
12
14
|
ext/dtrace_recdesc.c
|
15
|
+
ext/dtrace_util.c
|
13
16
|
ext/extconf.rb
|
14
17
|
lib/dtrace.rb
|
18
|
+
lib/dtraceaggregate.rb
|
19
|
+
lib/dtraceconsumer.rb
|
20
|
+
lib/dtraceprobe.rb
|
21
|
+
lib/dtraceprobedata.rb
|
22
|
+
lib/dtracerecord.rb
|
15
23
|
plugin/dtrace/README
|
16
24
|
plugin/dtrace/Rakefile
|
17
25
|
plugin/dtrace/bin/dtracer.rb
|
@@ -26,3 +34,4 @@ plugin/dtrace/tasks/dtrace.rake
|
|
26
34
|
plugin/dtrace/test/dtrace_test.rb
|
27
35
|
plugin/dtrace/views/dtrace/_report.rhtml
|
28
36
|
test/test_dtrace.rb
|
37
|
+
test/test_dtrace_workapi.rb
|
data/Rakefile
CHANGED
@@ -0,0 +1,139 @@
|
|
1
|
+
/* Ruby-Dtrace
|
2
|
+
* (c) 2007 Chris Andrews <chris@nodnol.org>
|
3
|
+
*/
|
4
|
+
|
5
|
+
#include "dtrace_api.h"
|
6
|
+
|
7
|
+
RUBY_EXTERN VALUE eDtraceException;
|
8
|
+
|
9
|
+
/* :nodoc: */
|
10
|
+
VALUE dtraceaggdata_init(VALUE self)
|
11
|
+
{
|
12
|
+
dtrace_bufdata_t *data;
|
13
|
+
|
14
|
+
Data_Get_Struct(self, dtrace_bufdata_t, data);
|
15
|
+
return self;
|
16
|
+
}
|
17
|
+
|
18
|
+
|
19
|
+
VALUE dtraceaggdata_value(VALUE self)
|
20
|
+
{
|
21
|
+
dtrace_bufdata_t *bufdata;
|
22
|
+
const dtrace_aggdata_t *aggdata;
|
23
|
+
const dtrace_aggdesc_t *aggdesc;
|
24
|
+
const dtrace_recdesc_t *rec;
|
25
|
+
const char *s;
|
26
|
+
dtrace_actkind_t act = DTRACEACT_NONE;
|
27
|
+
int64_t aggid;
|
28
|
+
uint64_t normal;
|
29
|
+
caddr_t addr;
|
30
|
+
int64_t value;
|
31
|
+
VALUE v = Qnil;
|
32
|
+
|
33
|
+
Data_Get_Struct(self, dtrace_bufdata_t, bufdata);
|
34
|
+
aggdata = bufdata->dtbda_aggdata;
|
35
|
+
s = bufdata->dtbda_buffered;
|
36
|
+
rec = bufdata->dtbda_recdesc;
|
37
|
+
|
38
|
+
if (aggdata == NULL) {
|
39
|
+
rb_raise(eDtraceException, "null aggdata");
|
40
|
+
return Qnil;
|
41
|
+
}
|
42
|
+
|
43
|
+
aggdesc = aggdata->dtada_desc;
|
44
|
+
|
45
|
+
if (aggdesc == NULL) {
|
46
|
+
rb_raise(eDtraceException, "null aggdesc");
|
47
|
+
return Qnil;
|
48
|
+
}
|
49
|
+
|
50
|
+
aggid = *((int64_t *)(aggdata->dtada_data +
|
51
|
+
aggdesc->dtagd_rec[0].dtrd_offset));
|
52
|
+
if (aggid < 0) {
|
53
|
+
rb_raise(eDtraceException, "negative aggregation ID");
|
54
|
+
return Qnil;
|
55
|
+
}
|
56
|
+
|
57
|
+
act = rec->dtrd_action;
|
58
|
+
|
59
|
+
if (bufdata->dtbda_flags & DTRACE_BUFDATA_AGGKEY) {
|
60
|
+
|
61
|
+
switch (act) {
|
62
|
+
case DTRACEACT_STACK:
|
63
|
+
case DTRACEACT_USTACK:
|
64
|
+
case DTRACEACT_JSTACK:
|
65
|
+
/* todo */
|
66
|
+
break;
|
67
|
+
case DTRACEACT_USYM:
|
68
|
+
case DTRACEACT_UADDR:
|
69
|
+
case DTRACEACT_UMOD:
|
70
|
+
case DTRACEACT_SYM:
|
71
|
+
case DTRACEACT_MOD:
|
72
|
+
/* todo */
|
73
|
+
break;
|
74
|
+
default:
|
75
|
+
v = handle_bytedata((aggdata->dtada_data + rec->dtrd_offset), rec->dtrd_size);
|
76
|
+
}
|
77
|
+
|
78
|
+
|
79
|
+
} else if (bufdata->dtbda_flags & DTRACE_BUFDATA_AGGVAL) {
|
80
|
+
|
81
|
+
normal = aggdata->dtada_normal;
|
82
|
+
addr = aggdata->dtada_data + rec->dtrd_offset;
|
83
|
+
|
84
|
+
if (act == DTRACEAGG_AVG) {
|
85
|
+
uint64_t *data = (uint64_t *)addr;
|
86
|
+
value = (data[0] ? (long long)(data[1] / normal / data[0]) : 0);
|
87
|
+
} else {
|
88
|
+
value = (*((int64_t *)addr)) / normal;
|
89
|
+
}
|
90
|
+
|
91
|
+
if (act == DTRACEAGG_QUANTIZE || act == DTRACEAGG_LQUANTIZE) {
|
92
|
+
v = Qnil; // dtj_new_distribution(data, rec, jc);
|
93
|
+
} else {
|
94
|
+
switch (act) {
|
95
|
+
case DTRACEAGG_COUNT:
|
96
|
+
if (value < 0)
|
97
|
+
rb_raise(eDtraceException, "count value is negative");
|
98
|
+
v = INT2FIX(value);
|
99
|
+
break;
|
100
|
+
case DTRACEAGG_AVG:
|
101
|
+
case DTRACEAGG_MIN:
|
102
|
+
case DTRACEAGG_MAX:
|
103
|
+
case DTRACEAGG_SUM:
|
104
|
+
v = INT2FIX(value);
|
105
|
+
break;
|
106
|
+
default:
|
107
|
+
v = Qnil;
|
108
|
+
rb_raise(eDtraceException, "unexpected aggregation action: %d", act);
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
} else if (bufdata->dtbda_flags & DTRACE_BUFDATA_AGGVAL) {
|
113
|
+
|
114
|
+
v = Qnil;
|
115
|
+
|
116
|
+
}
|
117
|
+
|
118
|
+
return v;
|
119
|
+
}
|
120
|
+
|
121
|
+
VALUE dtraceaggdata_aggtype(VALUE self)
|
122
|
+
{
|
123
|
+
dtrace_bufdata_t *bufdata;
|
124
|
+
VALUE v;
|
125
|
+
|
126
|
+
Data_Get_Struct(self, dtrace_bufdata_t, bufdata);
|
127
|
+
|
128
|
+
if (bufdata->dtbda_flags & DTRACE_BUFDATA_AGGKEY)
|
129
|
+
v = rb_str_new2("tuple");
|
130
|
+
else if (bufdata->dtbda_flags & DTRACE_BUFDATA_AGGVAL)
|
131
|
+
v = rb_str_new2("value");
|
132
|
+
else if (bufdata->dtbda_flags & DTRACE_BUFDATA_AGGLAST)
|
133
|
+
v = rb_str_new2("last");
|
134
|
+
else
|
135
|
+
v = rb_str_new2("unknown");
|
136
|
+
|
137
|
+
return v;
|
138
|
+
}
|
139
|
+
|
data/ext/dtrace_api.c
CHANGED
@@ -10,6 +10,8 @@ VALUE cDtraceProgram;
|
|
10
10
|
VALUE cDtraceProgramInfo;
|
11
11
|
VALUE cDtraceAggData;
|
12
12
|
VALUE cDtraceRecDesc;
|
13
|
+
VALUE cDtraceProbeData;
|
14
|
+
VALUE cDtraceBufData;
|
13
15
|
|
14
16
|
VALUE eDtraceException;
|
15
17
|
|
@@ -28,6 +30,9 @@ void Init_dtrace_api() {
|
|
28
30
|
rb_define_method(cDtrace, "aggregate_clear", dtrace_hdl_aggregate_clear, 0); // in dtrace_hdl.c
|
29
31
|
rb_define_method(cDtrace, "error", dtrace_hdl_error, 0); // in dtrace_hdl.c
|
30
32
|
rb_define_method(cDtrace, "setopt", dtrace_hdl_setopt, 2); // in dtrace_hdl.c
|
33
|
+
rb_define_method(cDtrace, "sleep", dtrace_hdl_sleep, 0); // in dtrace_hdl.c
|
34
|
+
rb_define_method(cDtrace, "work", dtrace_hdl_work, 2); // in dtrace_hdl.c
|
35
|
+
rb_define_method(cDtrace, "buf_consumer", dtrace_hdl_buf_consumer, 1); // in dtrace_hdl.c
|
31
36
|
rb_define_alloc_func(cDtrace, dtrace_hdl_alloc);
|
32
37
|
|
33
38
|
cDtraceProbe = rb_define_class("DtraceProbe", rb_cObject);
|
@@ -38,6 +43,15 @@ void Init_dtrace_api() {
|
|
38
43
|
rb_define_method(cDtraceProbe, "func", dtraceprobe_func, 0); // in dtrace_probe.c
|
39
44
|
rb_define_method(cDtraceProbe, "name", dtraceprobe_name, 0); // in dtrace_probe.c
|
40
45
|
|
46
|
+
cDtraceProbeData = rb_define_class("DtraceProbeData", rb_cObject);
|
47
|
+
rb_define_method(cDtraceProbeData, "initialize", dtraceprobedata_init, 0); // in dtrace_probedata.c
|
48
|
+
rb_define_method(cDtraceProbeData, "probedesc", dtraceprobedata_probedesc, 0); // in dtrace_probedata.c
|
49
|
+
rb_define_method(cDtraceProbeData, "each_record", dtraceprobedata_each_record, 0); // in dtrace_probedata.c
|
50
|
+
|
51
|
+
cDtraceBufData = rb_define_class("DtraceBufData", rb_cObject);
|
52
|
+
rb_define_method(cDtraceBufData, "initialize", dtracebufdata_init, 0); // in dtrace_bufdata.c
|
53
|
+
rb_define_method(cDtraceBufData, "record", dtracebufdata_record, 0); // in dtrace_bufdata.c
|
54
|
+
|
41
55
|
cDtraceProgram = rb_define_class("DtraceProgram", rb_cObject);
|
42
56
|
rb_define_method(cDtraceProgram, "initialize", dtraceprogram_init, 0); // in dtrace_program.c
|
43
57
|
rb_define_method(cDtraceProgram, "execute", dtraceprogram_exec, 0); // in dtrace_program.c
|
@@ -51,18 +65,12 @@ void Init_dtrace_api() {
|
|
51
65
|
rb_define_method(cDtraceProgramInfo, "speculations_count", dtraceprograminfo_speculations_count, 0); // in dtrace_programinfo.c
|
52
66
|
|
53
67
|
cDtraceAggData = rb_define_class("DtraceAggData", rb_cObject);
|
54
|
-
rb_define_method(cDtraceAggData, "initialize", dtraceaggdata_init,
|
55
|
-
rb_define_method(cDtraceAggData, "
|
56
|
-
rb_define_method(cDtraceAggData, "
|
57
|
-
rb_define_method(cDtraceAggData, "size", dtraceaggdata_size, 0); // in dtrace_aggregate.c
|
58
|
-
rb_define_method(cDtraceAggData, "each_record", dtraceaggdata_each_record, 0); // in dtrace_aggregate.c
|
59
|
-
rb_define_method(cDtraceAggData, "num_records", dtraceaggdata_num_records, 0); // in dtrace_aggregate.c
|
60
|
-
rb_define_method(cDtraceAggData, "[]", dtraceaggdata_record, 1); // in dtrace_aggregate.c
|
61
|
-
rb_define_method(cDtraceAggData, "probe", dtraceaggdata_probe, 0); // in dtrace_aggregate.c
|
68
|
+
rb_define_method(cDtraceAggData, "initialize", dtraceaggdata_init, 0); // in dtrace_aggdata.c
|
69
|
+
rb_define_method(cDtraceAggData, "value", dtraceaggdata_value, 0); // in dtrace_aggdata.c
|
70
|
+
rb_define_method(cDtraceAggData, "aggtype", dtraceaggdata_aggtype, 0); // in dtrace_aggdata.c
|
62
71
|
|
63
72
|
cDtraceRecDesc = rb_define_class("DtraceRecDesc", rb_cObject);
|
64
73
|
rb_define_method(cDtraceRecDesc, "initialize", dtracerecdesc_init, 0); // in dtrace_recdesc.c
|
65
|
-
rb_define_method(cDtraceRecDesc, "data", dtracerecdesc_data, 0); // in dtrace_recdesc.c
|
66
74
|
|
67
75
|
eDtraceException = rb_define_class("DtraceException", rb_eStandardError);
|
68
76
|
}
|
data/ext/dtrace_api.h
CHANGED
@@ -8,14 +8,11 @@
|
|
8
8
|
#include "/usr/include/dtrace.h"
|
9
9
|
#include "ruby.h"
|
10
10
|
|
11
|
+
VALUE handle_bytedata(caddr_t addr, uint32_t nbytes);
|
12
|
+
|
11
13
|
VALUE dtraceaggdata_init(VALUE self);
|
12
|
-
VALUE dtraceaggdata_desc(VALUE self);
|
13
14
|
VALUE dtraceaggdata_value(VALUE self);
|
14
|
-
VALUE
|
15
|
-
VALUE dtraceaggdata_each_record(VALUE self);
|
16
|
-
VALUE dtraceaggdata_num_records(VALUE self);
|
17
|
-
VALUE dtraceaggdata_record(VALUE self, VALUE index);
|
18
|
-
VALUE dtraceaggdata_probe(VALUE self);
|
15
|
+
VALUE dtraceaggdata_aggtype(VALUE self);
|
19
16
|
|
20
17
|
void dtrace_hdl_free (void *handle);
|
21
18
|
VALUE dtrace_hdl_alloc(VALUE klass);
|
@@ -31,6 +28,11 @@ VALUE dtrace_hdl_aggregate_print(VALUE self);
|
|
31
28
|
VALUE dtrace_hdl_aggregate_snap(VALUE self);
|
32
29
|
VALUE dtrace_hdl_aggregate_clear(VALUE self);
|
33
30
|
VALUE dtrace_hdl_error(VALUE self);
|
31
|
+
VALUE dtrace_hdl_sleep(VALUE self);
|
32
|
+
VALUE dtrace_hdl_work(VALUE self,
|
33
|
+
VALUE probe_consumer_proc,
|
34
|
+
VALUE rec_consumer_proc);
|
35
|
+
VALUE dtrace_hdl_buf_consumer(VALUE self, VALUE buf_consumer_proc);
|
34
36
|
|
35
37
|
VALUE dtraceprobe_init(VALUE self);
|
36
38
|
VALUE dtraceprobe_probe_id(VALUE self);
|
@@ -39,6 +41,13 @@ VALUE dtraceprobe_mod(VALUE self);
|
|
39
41
|
VALUE dtraceprobe_func(VALUE self);
|
40
42
|
VALUE dtraceprobe_name(VALUE self);
|
41
43
|
|
44
|
+
VALUE dtraceprobedata_init(VALUE self);
|
45
|
+
VALUE dtraceprobedata_probedesc(VALUE self);
|
46
|
+
VALUE dtraceprobedata_each_record(VALUE self);
|
47
|
+
|
48
|
+
VALUE dtracebufdata_init(VALUE self);
|
49
|
+
VALUE dtracebufdata_record(VALUE self);
|
50
|
+
|
42
51
|
VALUE dtraceprogram_init(VALUE self);
|
43
52
|
VALUE dtraceprogram_exec(VALUE self);
|
44
53
|
VALUE dtraceprogram_info(VALUE self);
|
@@ -50,4 +59,3 @@ VALUE dtraceprograminfo_matches_count(VALUE self);
|
|
50
59
|
VALUE dtraceprograminfo_speculations_count(VALUE self);
|
51
60
|
|
52
61
|
VALUE dtracerecdesc_init(VALUE self);
|
53
|
-
VALUE dtracerecdesc_data(VALUE self);
|
@@ -0,0 +1,91 @@
|
|
1
|
+
/* Ruby-Dtrace
|
2
|
+
* (c) 2007 Chris Andrews <chris@nodnol.org>
|
3
|
+
*/
|
4
|
+
|
5
|
+
#include "dtrace_api.h"
|
6
|
+
|
7
|
+
RUBY_EXTERN VALUE eDtraceException;
|
8
|
+
RUBY_EXTERN VALUE cDtraceAggData;
|
9
|
+
RUBY_EXTERN VALUE cDtraceRecDesc;
|
10
|
+
|
11
|
+
/* :nodoc: */
|
12
|
+
VALUE dtracebufdata_init(VALUE self)
|
13
|
+
{
|
14
|
+
dtrace_bufdata_t *data;
|
15
|
+
|
16
|
+
Data_Get_Struct(self, dtrace_bufdata_t, data);
|
17
|
+
return self;
|
18
|
+
}
|
19
|
+
|
20
|
+
VALUE dtracebufdata_record(VALUE self)
|
21
|
+
{
|
22
|
+
dtrace_bufdata_t *bufdata;
|
23
|
+
const dtrace_recdesc_t *rec;
|
24
|
+
dtrace_actkind_t act = DTRACEACT_NONE;
|
25
|
+
const char *s;
|
26
|
+
VALUE v = Qnil;
|
27
|
+
VALUE dtracerecord;
|
28
|
+
VALUE dtraceaggdata;
|
29
|
+
VALUE dtracerecdesc;
|
30
|
+
|
31
|
+
Data_Get_Struct(self, dtrace_bufdata_t, bufdata);
|
32
|
+
|
33
|
+
if (bufdata->dtbda_aggdata) {
|
34
|
+
dtraceaggdata = Data_Wrap_Struct(cDtraceAggData, 0, NULL, (dtrace_bufdata_t *)bufdata);
|
35
|
+
return dtraceaggdata;
|
36
|
+
}
|
37
|
+
|
38
|
+
s = bufdata->dtbda_buffered;
|
39
|
+
if (s == NULL) {
|
40
|
+
return Qnil;
|
41
|
+
}
|
42
|
+
|
43
|
+
rec = bufdata->dtbda_recdesc;
|
44
|
+
if (rec) {
|
45
|
+
act = rec->dtrd_action;
|
46
|
+
}
|
47
|
+
|
48
|
+
switch (act) {
|
49
|
+
case DTRACEACT_DIFEXPR:
|
50
|
+
/* trace() action */
|
51
|
+
break;
|
52
|
+
case DTRACEACT_PRINTF:
|
53
|
+
/*
|
54
|
+
* Only the formatted string was not available to dtj_chewrec(),
|
55
|
+
* so we attach that now.
|
56
|
+
*/
|
57
|
+
v = rb_str_new2(s);
|
58
|
+
break;
|
59
|
+
case DTRACEACT_STACK:
|
60
|
+
case DTRACEACT_USTACK:
|
61
|
+
case DTRACEACT_JSTACK:
|
62
|
+
/* stand-alone stack(), ustack(), or jstack() action */
|
63
|
+
v = rb_str_new2(s);
|
64
|
+
break;
|
65
|
+
case DTRACEACT_USYM:
|
66
|
+
case DTRACEACT_UADDR:
|
67
|
+
case DTRACEACT_UMOD:
|
68
|
+
case DTRACEACT_SYM:
|
69
|
+
case DTRACEACT_MOD:
|
70
|
+
v = rb_str_new2(s);
|
71
|
+
break;
|
72
|
+
case DTRACEACT_PRINTA:
|
73
|
+
v = rb_str_new2(s);
|
74
|
+
break;
|
75
|
+
default:
|
76
|
+
/*
|
77
|
+
* The record handle defers nothing else to this
|
78
|
+
* bufhandler.
|
79
|
+
*/
|
80
|
+
break;
|
81
|
+
}
|
82
|
+
|
83
|
+
if (!NIL_P(v)) {
|
84
|
+
dtracerecord = rb_class_new_instance(0, NULL, rb_path2class("DtraceRecord"));
|
85
|
+
rb_iv_set(dtracerecord, "@value", v);
|
86
|
+
return (dtracerecord);
|
87
|
+
}
|
88
|
+
else {
|
89
|
+
return Qnil;
|
90
|
+
}
|
91
|
+
}
|
data/ext/dtrace_hdl.c
CHANGED
@@ -8,6 +8,9 @@ RUBY_EXTERN VALUE eDtraceException;
|
|
8
8
|
RUBY_EXTERN VALUE cDtraceProbe;
|
9
9
|
RUBY_EXTERN VALUE cDtraceProgram;
|
10
10
|
RUBY_EXTERN VALUE cDtraceAggData;
|
11
|
+
RUBY_EXTERN VALUE cDtraceRecDesc;
|
12
|
+
RUBY_EXTERN VALUE cDtraceProbeData;
|
13
|
+
RUBY_EXTERN VALUE cDtraceBufData;
|
11
14
|
|
12
15
|
void dtrace_hdl_free (void *handle)
|
13
16
|
{
|
@@ -278,3 +281,101 @@ VALUE dtrace_hdl_error(VALUE self)
|
|
278
281
|
return rb_str_new2(error_string);
|
279
282
|
}
|
280
283
|
|
284
|
+
/*
|
285
|
+
* Sleep until we need to wake up to honour D options controlling
|
286
|
+
* consumption rates.
|
287
|
+
*/
|
288
|
+
VALUE dtrace_hdl_sleep(VALUE self)
|
289
|
+
{
|
290
|
+
dtrace_hdl_t *handle;
|
291
|
+
|
292
|
+
Data_Get_Struct(self, dtrace_hdl_t, handle);
|
293
|
+
dtrace_sleep(handle);
|
294
|
+
return Qnil;
|
295
|
+
}
|
296
|
+
|
297
|
+
typedef struct dtrace_work_handlers {
|
298
|
+
VALUE probe;
|
299
|
+
VALUE rec;
|
300
|
+
} dtrace_work_handlers_t;
|
301
|
+
|
302
|
+
static int _probe_consumer(const dtrace_probedata_t *data, void *arg)
|
303
|
+
{
|
304
|
+
VALUE proc;
|
305
|
+
dtrace_work_handlers_t handlers;
|
306
|
+
VALUE probedata;
|
307
|
+
|
308
|
+
handlers = *(dtrace_work_handlers_t *) arg;
|
309
|
+
proc = handlers.probe;
|
310
|
+
|
311
|
+
probedata = Data_Wrap_Struct(cDtraceProbeData, 0, NULL, (dtrace_probedata_t *)data);
|
312
|
+
rb_funcall(proc, rb_intern("call"), 1, probedata);
|
313
|
+
|
314
|
+
return (DTRACE_CONSUME_THIS);
|
315
|
+
}
|
316
|
+
|
317
|
+
static int _rec_consumer(const dtrace_probedata_t *data, const dtrace_recdesc_t *rec, void *arg)
|
318
|
+
{
|
319
|
+
VALUE proc;
|
320
|
+
dtrace_work_handlers_t handlers;
|
321
|
+
VALUE recdesc;
|
322
|
+
|
323
|
+
handlers = *(dtrace_work_handlers_t *) arg;
|
324
|
+
proc = handlers.rec;
|
325
|
+
|
326
|
+
recdesc = Data_Wrap_Struct(cDtraceRecDesc, 0, NULL, (dtrace_recdesc_t *)rec);
|
327
|
+
rb_funcall(proc, rb_intern("call"), 1, recdesc);
|
328
|
+
|
329
|
+
return (DTRACE_CONSUME_THIS);
|
330
|
+
}
|
331
|
+
|
332
|
+
static int _buf_consumer(const dtrace_bufdata_t *bufdata, void *arg)
|
333
|
+
{
|
334
|
+
VALUE proc;
|
335
|
+
VALUE dtracebufdata;
|
336
|
+
|
337
|
+
proc = (VALUE)arg;
|
338
|
+
|
339
|
+
dtracebufdata = Data_Wrap_Struct(cDtraceBufData, 0, NULL, (dtrace_bufdata_t *)bufdata);
|
340
|
+
rb_funcall(proc, rb_intern("call"), 1, dtracebufdata);
|
341
|
+
|
342
|
+
return (DTRACE_HANDLE_OK);
|
343
|
+
}
|
344
|
+
|
345
|
+
/*
|
346
|
+
* Process any data waiting from the D program.
|
347
|
+
*/
|
348
|
+
VALUE dtrace_hdl_work(VALUE self,
|
349
|
+
VALUE probe_consumer_proc,
|
350
|
+
VALUE rec_consumer_proc)
|
351
|
+
{
|
352
|
+
dtrace_hdl_t *handle;
|
353
|
+
dtrace_workstatus_t status;
|
354
|
+
dtrace_work_handlers_t handlers;
|
355
|
+
|
356
|
+
Data_Get_Struct(self, dtrace_hdl_t, handle);
|
357
|
+
|
358
|
+
/* fill out the handlers struct */
|
359
|
+
handlers.probe = probe_consumer_proc;
|
360
|
+
handlers.rec = rec_consumer_proc;
|
361
|
+
|
362
|
+
status = dtrace_work(handle, NULL, _probe_consumer, _rec_consumer, &handlers);
|
363
|
+
|
364
|
+
return INT2FIX(status);
|
365
|
+
}
|
366
|
+
|
367
|
+
/*
|
368
|
+
* Set up the buffered output handler for this handle.
|
369
|
+
*/
|
370
|
+
VALUE dtrace_hdl_buf_consumer(VALUE self, VALUE buf_consumer)
|
371
|
+
{
|
372
|
+
dtrace_hdl_t *handle;
|
373
|
+
Data_Get_Struct(self, dtrace_hdl_t, handle);
|
374
|
+
|
375
|
+
/* attach the buffered output handler */
|
376
|
+
if (dtrace_handle_buffered(handle, &_buf_consumer, (void *)buf_consumer) == -1) {
|
377
|
+
rb_raise(eDtraceException, "failed to establish buffered handler");
|
378
|
+
}
|
379
|
+
|
380
|
+
return Qnil;
|
381
|
+
}
|