Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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 d6826a6
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 51 deletions.
1 change: 0 additions & 1 deletion capi/Cargo.toml
Expand Up @@ -8,7 +8,6 @@ name = "telemetry_capi"
crate-type = ["staticlib"]

[dependencies]
atomic_cell = "0"
libc = "0"

[dependencies.telemetry]
Expand Down
8 changes: 3 additions & 5 deletions capi/include/telemetry.h
Expand Up @@ -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
61 changes: 22 additions & 39 deletions capi/src/lib.rs
@@ -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),
}
}
}
Expand Down Expand Up @@ -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);

Expand All @@ -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 };
Expand All @@ -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())
Expand All @@ -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}");

Expand Down
9 changes: 3 additions & 6 deletions examples/capi/telemetry.c
Expand Up @@ -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);
Expand Down

0 comments on commit d6826a6

Please sign in to comment.