Permalink
Browse files

Remove use of unstable features in API by threading telemetry service…

… through function arguments as required.
  • Loading branch information...
jdm committed Oct 17, 2015
1 parent 74188a5 commit d6826a6f1e8c91ab71d3321ca2c99b7866c025ff
Showing with 28 additions and 51 deletions.
  1. +0 −1 capi/Cargo.toml
  2. +3 −5 capi/include/telemetry.h
  3. +22 −39 capi/src/lib.rs
  4. +3 −6 examples/capi/telemetry.c
@@ -8,7 +8,6 @@ name = "telemetry_capi"
crate-type = ["staticlib"]
[dependencies]
atomic_cell = "0"
libc = "0"
[dependencies.telemetry]
@@ -9,15 +9,13 @@ struct count_t;
struct telemetry_t* telemetry_init(int is_active);
void telemetry_free(struct telemetry_t*);
struct flag_t* telemetry_new_flag(const char* name);
void telemetry_add_flag(struct telemetry_t* telemetry, struct flag_t* flag);
struct flag_t* telemetry_new_flag(struct telemetry_t* telemetry, const char* name);
void telemetry_record_flag(struct flag_t* flag);
struct count_t* telemetry_new_count(const char* name);
void telemetry_add_count(struct telemetry_t* telemetry, struct count_t* count);
struct count_t* telemetry_new_count(struct telemetry_t* telemetry, const char* name);
void telemetry_record_count(struct count_t* count, unsigned int value);
char* telemetry_serialize_plain_json();
char* telemetry_serialize_plain_json(struct telemetry_t* telemetry);
void telemetry_free_serialized_json(char* serialized);
#endif
@@ -1,32 +1,27 @@
#![feature(const_fn)]
#![allow(non_camel_case_types)]
extern crate atomic_cell;
extern crate libc;
extern crate telemetry;
use atomic_cell::{CleanGuard, StaticCell};
use std::ptr;
use std::ffi::{CStr, CString};
use std::str;
use std::sync::Arc;
use std::sync::mpsc::channel;
use telemetry::{Subset, Service};
use telemetry::{Subset, Service, SerializationFormat};
use telemetry::plain::{Histogram, Flag, Count};
pub struct telemetry_t {
_guard: CleanGuard<'static>,
service: Service,
flags: Vec<*mut flag_t>,
counts: Vec<*mut count_t>,
}
impl telemetry_t {
fn new(is_active: bool) -> telemetry_t {
let guard = TELEMETRY.init(Arc::new(Service::new(is_active)));
telemetry_t {
flags: vec![],
counts: vec![],
_guard: guard,
service: Service::new(is_active),
}
}
}
@@ -73,7 +68,7 @@ impl CHistogram for count_t {
}
}
unsafe fn new_histogram<T: CHistogram>(name: *const libc::c_char) -> *mut T {
unsafe fn new_histogram<T: CHistogram>(telemetry: &Service, name: *const libc::c_char) -> *mut T {
assert!(!name.is_null());
let c_str = CStr::from_ptr(name);
@@ -82,13 +77,9 @@ unsafe fn new_histogram<T: CHistogram>(name: *const libc::c_char) -> *mut T {
Err(_) => return ptr::null_mut(),
};
let telemetry = TELEMETRY.get().unwrap();
Box::into_raw(Box::new(T::new(r_str, &telemetry)))
}
static TELEMETRY: StaticCell<Arc<Service>> = StaticCell::new();
#[no_mangle]
pub unsafe extern "C" fn telemetry_init(is_active: libc::c_int) -> *mut telemetry_t {
let is_active = if is_active != 0 { true } else { false };
@@ -102,57 +93,51 @@ pub unsafe extern "C" fn telemetry_free(telemetry: *mut telemetry_t) {
}
#[no_mangle]
pub unsafe extern "C" fn telemetry_new_flag(name: *const libc::c_char) -> *mut flag_t {
new_histogram(name)
pub unsafe extern "C" fn telemetry_new_flag(telemetry: *mut telemetry_t,
name: *const libc::c_char) -> *mut flag_t {
let flag = new_histogram(&(*telemetry).service, name);
(*telemetry).flags.push(flag);
flag
}
unsafe fn free_flag(flag: *mut flag_t) {
let flag = Box::from_raw(flag);
drop(flag);
}
#[no_mangle]
pub unsafe extern "C" fn telemetry_add_flag(telemetry: *mut telemetry_t, flag: *mut flag_t) {
let telemetry = &mut *telemetry;
telemetry.flags.push(flag);
}
#[no_mangle]
pub unsafe extern "C" fn telemetry_record_flag(flag: *mut flag_t) {
(*flag).inner.record(());
}
#[no_mangle]
pub unsafe extern "C" fn telemetry_new_count(name: *const libc::c_char) -> *mut count_t {
new_histogram(name)
pub unsafe extern "C" fn telemetry_new_count(telemetry: *mut telemetry_t,
name: *const libc::c_char) -> *mut count_t {
let count = new_histogram(&(*telemetry).service, name);
(*telemetry).counts.push(count);
count
}
unsafe fn free_count(count: *mut count_t) {
let flag = Box::from_raw(count);
drop(flag);
}
#[no_mangle]
pub unsafe extern "C" fn telemetry_add_count(telemetry: *mut telemetry_t, count: *mut count_t) {
let telemetry = &mut *telemetry;
telemetry.counts.push(count);
}
#[no_mangle]
pub unsafe extern "C" fn telemetry_record_count(count: *mut count_t, value: libc::c_uint) {
(*count).inner.record(value);
}
fn serialize(subset: Subset) -> Option<String> {
let service = TELEMETRY.get().unwrap();
fn serialize(telemetry: &telemetry_t, subset: Subset) -> Option<String> {
let (sender, receiver) = channel();
service.to_json(subset, telemetry::SerializationFormat::SimpleJson, sender);
telemetry.service.to_json(subset, SerializationFormat::SimpleJson, sender);
receiver.recv().ok().map(|s| format!("{}", s.pretty()))
}
#[no_mangle]
pub unsafe extern "C" fn telemetry_serialize_plain_json() -> *mut libc::c_char {
serialize(Subset::AllPlain)
pub unsafe extern "C" fn telemetry_serialize_plain_json(telemetry: *mut telemetry_t)
-> *mut libc::c_char {
serialize(&*telemetry, Subset::AllPlain)
.and_then(|s| CString::new(s).ok())
.map(|s| s.into_raw())
.unwrap_or(ptr::null_mut())
@@ -170,19 +155,17 @@ fn it_works() {
let telemetry = telemetry_init(1);
let name = CString::new("FLAG").unwrap();
let flag = telemetry_new_flag(name.as_ptr());
telemetry_add_flag(telemetry, flag);
let flag = telemetry_new_flag(telemetry, name.as_ptr());
let name = CString::new("COUNT").unwrap();
let count = telemetry_new_count(name.as_ptr());
telemetry_add_count(telemetry, count);
let count = telemetry_new_count(telemetry, name.as_ptr());
telemetry_record_flag(flag);
telemetry_record_count(count, 2);
telemetry_record_count(count, 3);
let s = telemetry_serialize_plain_json();
let s = telemetry_serialize_plain_json(telemetry);
let repr = CStr::from_ptr(s as *const libc::c_char).to_string_lossy();
assert_eq!(repr, "{\n \"COUNT\": 5,\n \"FLAG\": 1\n}");
@@ -6,16 +6,13 @@
int main(int argc, char* argv[]) {
struct telemetry_t* telemetry = telemetry_init(1);
struct flag_t* flag = telemetry_new_flag("FLAG");
telemetry_add_flag(telemetry, flag);
struct count_t* count = telemetry_new_count("COUNT");
telemetry_add_count(telemetry, count);
struct flag_t* flag = telemetry_new_flag(telemetry, "FLAG");
struct count_t* count = telemetry_new_count(telemetry, "COUNT");
telemetry_record_flag(flag);
telemetry_record_count(count, 2);
char* serialized = telemetry_serialize_plain_json();
char* serialized = telemetry_serialize_plain_json(telemetry);
assert(!strcmp(serialized, "{\n \"COUNT\": 2,\n \"FLAG\": 1\n}"));
printf("%s\n", serialized);
telemetry_free_serialized_json(serialized);

0 comments on commit d6826a6

Please sign in to comment.