Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing API: what a handle should be

Let's suppose we're writing a library implementing some API. The lib creates some resources (connections/internal data structures/whatever) and returns a handle which then is used to make further calls.

What are recommended ways to represent a handle?

  • Should it be a raw pointer to some internal data structure allocated while creating a session?

  • If it is the case, how do I secure the lib in case API functions are called after close method which deallocates the data handle has pointed to?

If handle is an abstract number (like key in "handle"->"obj" map), won't it affect performance?

What other approaches are possible? Which one should I choose?

If anybody has worked on API's, could you share your experience on the subject?

The question is too wide and abstract, but currently I'm working on very similar task and just don't know how to tackle the problem.

I've been looking through sqlite3 sources, their handle is just a pointer to dynamically allocated structure, they set some magic numbers while opening connection and closing it and checking validity of a handle consists in checking those magic numbers. Is it safe enough?

like image 492
olegst Avatar asked Dec 19 '22 04:12

olegst


2 Answers

I'd design the "close"-function to set the opaque pointer to NULL.

interface.h:

typedef struct handle_internals * Handle;

int handle_open(/* out */ Handle * phandle, ..);
int handle_close(/* in out */ Handle * phandle)

int handle_func1(Handle handle, ..);
...

implementation.c:

...

#include "interface.h"

...

struct handle_internals
{
  ...
}

int handle_open(Handle * phandle, ..)
{
  if (NULL == phandle)
  {
    errno = EINVAL;
    return -1;
  }

  *phandle = malloc(sizeof ** phandle);

  ...

  return 0;
}

int handle_close(Handle * phandle)
{
  if (NULL == phandle)
  {
    errno = EINVAL;
    return -1;
  }

  free(*phandle);
  *phandle = NULL;

  return 0;
}

int handle_func1(Handle handle, ..)
{
  if (NULL == handle)
  {
    errno = EINVAL;
    return -1;
  }

  ...

  return 0;
}
like image 192
alk Avatar answered Dec 28 '22 06:12

alk


The question "is it safe enough?" depends on your application.

If it's a Sudoku solver running on your laptop then it's probably OK to have minimal or no handle verification.

If it's a controller for a self driving car then I would hope that you want to be very confident you're not working on garbage.

For most uses it's fine to use opaque pointers.

like image 34
Motti Avatar answered Dec 28 '22 05:12

Motti