/*
 * Copyright (c) 2017 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * file.h: unix file handling
 *
 * Copyright (c) 2008 Eliot Dresselhaus
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef included_clib_file_h
#define included_clib_file_h

#include <vppinfra/socket.h>
#include <vppinfra/pool.h>
#include <termios.h>


struct clib_file;
typedef clib_error_t *(clib_file_function_t) (struct clib_file * f);

typedef struct clib_file
{
  /* Unix file descriptor from open/socket. */
  u32 file_descriptor;

  u32 flags;
#define UNIX_FILE_DATA_AVAILABLE_TO_WRITE (1 << 0)
#define UNIX_FILE_EVENT_EDGE_TRIGGERED   (1 << 1)

  /* polling thread index */
  u32 polling_thread_index;

  /* Data available for function's use. */
  u64 private_data;

  /* Functions to be called when read/write data becomes ready. */
  clib_file_function_t *read_function, *write_function, *error_function;

  /* Description */
  u8 *description;

  /* Stats */
  u64 read_events;
  u64 write_events;
  u64 error_events;
} clib_file_t;

typedef enum
{
  UNIX_FILE_UPDATE_ADD,
  UNIX_FILE_UPDATE_MODIFY,
  UNIX_FILE_UPDATE_DELETE,
} clib_file_update_type_t;

typedef struct
{
  /* Pool of files to poll for input/output. */
  clib_file_t *file_pool;

  void (*file_update) (clib_file_t * file,
		       clib_file_update_type_t update_type);

} clib_file_main_t;

always_inline uword
clib_file_add (clib_file_main_t * um, clib_file_t * template)
{
  clib_file_t *f;
  pool_get (um->file_pool, f);
  f[0] = template[0];
  f->read_events = 0;
  f->write_events = 0;
  f->error_events = 0;
  um->file_update (f, UNIX_FILE_UPDATE_ADD);
  return f - um->file_pool;
}

always_inline void
clib_file_del (clib_file_main_t * um, clib_file_t * f)
{
  um->file_update (f, UNIX_FILE_UPDATE_DELETE);
  close (f->file_descriptor);
  f->file_descriptor = ~0;
  vec_free (f->description);
  pool_put (um->file_pool, f);
}

always_inline void
clib_file_del_by_index (clib_file_main_t * um, uword index)
{
  clib_file_t *uf;
  uf = pool_elt_at_index (um->file_pool, index);
  clib_file_del (um, uf);
}

always_inline void
clib_file_set_polling_thread (clib_file_main_t * um, uword index,
			      u32 thread_index)
{
  clib_file_t *f = pool_elt_at_index (um->file_pool, index);
  um->file_update (f, UNIX_FILE_UPDATE_DELETE);
  f->polling_thread_index = thread_index;
  um->file_update (f, UNIX_FILE_UPDATE_ADD);
}

always_inline uword
clib_file_set_data_available_to_write (clib_file_main_t * um,
				       u32 clib_file_index,
				       uword is_available)
{
  clib_file_t *uf = pool_elt_at_index (um->file_pool, clib_file_index);
  uword was_available = (uf->flags & UNIX_FILE_DATA_AVAILABLE_TO_WRITE);
  if ((was_available != 0) != (is_available != 0))
    {
      uf->flags ^= UNIX_FILE_DATA_AVAILABLE_TO_WRITE;
      um->file_update (uf, UNIX_FILE_UPDATE_MODIFY);
    }
  return was_available != 0;
}

always_inline clib_file_t *
clib_file_get (clib_file_main_t * fm, u32 file_index)
{
  if (pool_is_free_index (fm->file_pool, file_index))
    return 0;
  return pool_elt_at_index (fm->file_pool, file_index);
}

always_inline clib_error_t *
clib_file_write (clib_file_t * f)
{
  f->write_events++;
  return f->write_function (f);
}

u8 *clib_file_get_resolved_basename (char *fmt, ...);

#endif /* included_clib_file_h */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
