<commit_before>/* ------------------------------------------------------------------------- *
 * Copyright (C) 2013 Jolla Ltd.
 * Contact: <NAME> <<EMAIL>>
 * License: LGPLv2
 * ------------------------------------------------------------------------- */

/* ========================================================================= *
 * Most of the functions in this module are just thunks that load and call
 * the real functionality from hybris-plugin on demand. If the hybris plugin
 * is not installed or underlying android code does not support some hw
 * elements these functions turn in to "NOP and return failure".
 *
 * In addition to the above this module also:
 * - moves sensor input data via pipe from worker thread context to the
 *   thread that is running the glib mainloop.
 * - proxies diagnostic output from hybris-plugin to mce_log()
 * ========================================================================= */

#define MCE_HYBRIS_INTERNAL 1
#include "mce-hybris.h"
#include "mce-log.h"
#include "mce-conf.h"
#include "mce-modules.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <dlfcn.h>

#include <glib.h>

static void mce_hybris_ps_set_hook(mce_hybris_ps_fn cb);
static void mce_hybris_als_set_hook(mce_hybris_als_fn cb);

/* ------------------------------------------------------------------------- *
 * Feeding sensor data via pipe to glib mainloop goes roughly as follows
 *
 * --- mce-libhybris-plugin worker thread --
 * 1) uses blocking poll_dev->poll() function to read sensor data
 * 2) uses a set of callbacks to write the data to a pipe
 * --- mce-libhybris-module --
 * 3) iowatch reads the data from pipe
 * 4) and passes the data to mce via another set of callbacks
 * --- mce sensor handling code --
 * 5) can act on the data in the context that runs gmainloop
 * ------------------------------------------------------------------------- */

/** Sensor enumeration for mux @ worker thread -> pipe -> demux @ mainloop */
enum
{
  EVEPIPE_ALS,
  EVEPIPE_PS,
};

/** Sensor data passed over pipe */
typedef struct
{
  int64_t time;  // time stamp from android side
  int32_t type;  // EVEPIPE_ALS or EVEPIPE_PS
  float   value; // sensor data from android side
} evepipe_t;

/** Initialize once flag for sensor data pipe */
static bool evepipe_done = false;

/** Callback for handling proximity data */
static mce_hybris_ps_fn  evepipe_ps_cb  = 0;

/** Callback for handling ambient light data */
static mce_hybris_als_fn evepipe_als_cb = 0;

/** The sensor data pipe */
static int               evepipe_fd[2]  = { -1, -1 };

/** I/O watch id for the sensor data pipe */
static guint             evepipe_id     = 0;

/** I/O watch callback for handling pipe input
 *
 * @param channel    (not used)
 * @param condition  (not used)
 * @param data       (not used)
 *
 * @return TRUE to keep the iowatch alive, or FALSE to remove it
 */
static gboolean evepipe_recv_cb(GIOChannel *channel,
                                GIOCondition condition,
                                gpointer data)
{
  /* we just want the cb ... */
  (void)channel; (void)condition; (void)data;

  gboolean keep_going = TRUE;

  evepipe_t eve[64];

  int rc = read(evepipe_fd[0], eve, sizeof eve);

  if( rc < 0 ) {
    switch( errno ) {
    case EINTR:
    case EAGAIN:
      break;

    default:
      mce_log(LL_ERR, "failed to read sensor events: %m");
      keep_going = FALSE;
      break;
    }
    goto cleanup;
  }

  rc /= sizeof *eve;

  for( int i = 0; i < rc; ++i ) {
    switch( eve[i].type ) {
    case EVEPIPE_PS:
      if( evepipe_ps_cb ) {
        evepipe_ps_cb(eve[i].time, eve[i].value);
      }
      break;

    case EVEPIPE_ALS:
      if( evepipe_als_cb ) {
        evepipe_als_cb(eve[i].time, eve[i].value);
      }
      break;

    default:
      break;
    }
  }

cleanup:

  if( !keep_going )  {
    mce_log(LL_CRIT, "disabling sensor event pipe iowatch");
    evepipe_id = 0;
  }

  return keep_going;
}

/** Write sensor data to the pipe
 *
 * @param timestamp nanoseconds
 * @param type      EVEPIPE_ALS or EVEPIPE_PS
 * @param data      sensor data
 */
static void evepipe_send(int64_t timestamp, int32_t type, float data)
{
  evepipe_t eve =
  {
    .time  = timestamp,
    .type  = type,
    .value = data,
  };

  int rc = TEMP_FAILURE_RETRY(write(evepipe_fd[1], &eve, sizeof eve));

  if( rc != sizeof eve ) {
    // TODO: since this happens from separate thread, we might want
    //       to do something bit more clever in case the sensor data
    //       overflows the pipe ...
    abort();
  }
}

/** Write PS data to the sensor data pipe
 *
 * @param timestamp nanoseconds
 * @param distance  centimeters
 */
static void evepipe_send_ps(int64_t timestamp, float distance)
{
  evepipe_send(timestamp, EVEPIPE_PS, distance);
}<commit_msg>Use mce_abort() instead of plain abort()<commit_after>/* ------------------------------------------------------------------------- *
 * Copyright (C) 2013 Jolla Ltd.
 * Contact: <NAME> <<EMAIL>>
 * License: LGPLv2
 * ------------------------------------------------------------------------- */

/* ========================================================================= *
 * Most of the functions in this module are just thunks that load and call
 * the real functionality from hybris-plugin on demand. If the hybris plugin
 * is not installed or underlying android code does not support some hw
 * elements these functions turn in to "NOP and return failure".
 *
 * In addition to the above this module also:
 * - moves sensor input data via pipe from worker thread context to the
 *   thread that is running the glib mainloop.
 * - proxies diagnostic output from hybris-plugin to mce_log()
 * ========================================================================= */

#define MCE_HYBRIS_INTERNAL 1
#include "mce-hybris.h"
#include "mce.h"
#include "mce-log.h"
#include "mce-conf.h"
#include "mce-modules.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <dlfcn.h>

#include <glib.h>

static void mce_hybris_ps_set_hook(mce_hybris_ps_fn cb);
static void mce_hybris_als_set_hook(mce_hybris_als_fn cb);

/* ------------------------------------------------------------------------- *
 * Feeding sensor data via pipe to glib mainloop goes roughly as follows
 *
 * --- mce-libhybris-plugin worker thread --
 * 1) uses blocking poll_dev->poll() function to read sensor data
 * 2) uses a set of callbacks to write the data to a pipe
 * --- mce-libhybris-module --
 * 3) iowatch reads the data from pipe
 * 4) and passes the data to mce via another set of callbacks
 * --- mce sensor handling code --
 * 5) can act on the data in the context that runs gmainloop
 * ------------------------------------------------------------------------- */

/** Sensor enumeration for mux @ worker thread -> pipe -> demux @ mainloop */
enum
{
  EVEPIPE_ALS,
  EVEPIPE_PS,
};

/** Sensor data passed over pipe */
typedef struct
{
  int64_t time;  // time stamp from android side
  int32_t type;  // EVEPIPE_ALS or EVEPIPE_PS
  float   value; // sensor data from android side
} evepipe_t;

/** Initialize once flag for sensor data pipe */
static bool evepipe_done = false;

/** Callback for handling proximity data */
static mce_hybris_ps_fn  evepipe_ps_cb  = 0;

/** Callback for handling ambient light data */
static mce_hybris_als_fn evepipe_als_cb = 0;

/** The sensor data pipe */
static int               evepipe_fd[2]  = { -1, -1 };

/** I/O watch id for the sensor data pipe */
static guint             evepipe_id     = 0;

/** I/O watch callback for handling pipe input
 *
 * @param channel    (not used)
 * @param condition  (not used)
 * @param data       (not used)
 *
 * @return TRUE to keep the iowatch alive, or FALSE to remove it
 */
static gboolean evepipe_recv_cb(GIOChannel *channel,
                                GIOCondition condition,
                                gpointer data)
{
  /* we just want the cb ... */
  (void)channel; (void)condition; (void)data;

  gboolean keep_going = TRUE;

  evepipe_t eve[64];

  int rc = read(evepipe_fd[0], eve, sizeof eve);

  if( rc < 0 ) {
    switch( errno ) {
    case EINTR:
    case EAGAIN:
      break;

    default:
      mce_log(LL_ERR, "failed to read sensor events: %m");
      keep_going = FALSE;
      break;
    }
    goto cleanup;
  }

  rc /= sizeof *eve;

  for( int i = 0; i < rc; ++i ) {
    switch( eve[i].type ) {
    case EVEPIPE_PS:
      if( evepipe_ps_cb ) {
        evepipe_ps_cb(eve[i].time, eve[i].value);
      }
      break;

    case EVEPIPE_ALS:
      if( evepipe_als_cb ) {
        evepipe_als_cb(eve[i].time, eve[i].value);
      }
      break;

    default:
      break;
    }
  }

cleanup:

  if( !keep_going )  {
    mce_log(LL_CRIT, "disabling sensor event pipe iowatch");
    evepipe_id = 0;
  }

  return keep_going;
}

/** Write sensor data to the pipe
 *
 * @param timestamp nanoseconds
 * @param type      EVEPIPE_ALS or EVEPIPE_PS
 * @param data      sensor data
 */
static void evepipe_send(int64_t timestamp, int32_t type, float data)
{
  evepipe_t eve =
  {
    .time  = timestamp,
    .type  = type,
    .value = data,
  };

  int rc = TEMP_FAILURE_RETRY(write(evepipe_fd[1], &eve, sizeof eve));

  if( rc != sizeof eve ) {
    // TODO: since this happens from separate thread, we might want
    //       to do something bit more clever in case the sensor data
    //       overflows the pipe ...
    mce_abort();
  }
}

/** Write PS data to the sensor data pipe
 *
 * @param timestamp nanoseconds
 * @param distance  centimeters
 */
static void evepipe_send_ps(int64_t timestamp, float distance)
{
  evepipe_send(timestamp, EVEPIPE_PS, distance);
}
{'fraction_non_alphanumeric': 0.18497942386831276, 'fraction_numerical': 0.0069958847736625515, 'mean_word_length': 2.303092082908597, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2038214', 'n_tokens_mistral': 3141, 'n_tokens_neox': 2948, 'n_words': 1007}