⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 io.c

📁 著名的手机浏览器开源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * File: IO.c * * Copyright (C) 2000, 2001, 2002 Jorge Arellano Cid <jcid@dillo.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *//* * Dillo's signal driven IO engine */#include <pthread.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <fcntl.h>#include <unistd.h>#include <sys/stat.h>#include <sys/uio.h>#include <sys/socket.h>#include <gdk/gdk.h>#include "../msg.h"#include "../chain.h"#include "../list.h"#include "../klist.h"#include "IO.h"#define DEBUG_LEVEL 5#include "../debug.h"/* * Symbolic defines for shutdown() function * (Not defined in the same header file, for all distros --Jcid) */#define IO_StopRd   0#define IO_StopWr   1#define IO_StopRdWr 2/* * Local data */static Klist_t *ValidIOs = NULL; /* Active IOs list. It holds pointers to                                  * IOData_t structures. *//* * Debug procedure...static void IO_print_cond_status(gchar  *str,  GIOCondition  cond,                                 GIOChannel *gio, gint key){   MSG("%s FD=%d key=%d [", str, g_io_channel_unix_get_fd(gio), key);   MSG(cond & G_IO_IN ? "G_IO_IN " : "");   MSG(cond & G_IO_OUT ? "G_IO_OUT " : "");   MSG(cond & G_IO_PRI ? "G_IO_PRI " : "");   MSG(cond & G_IO_ERR ? "G_IO_ERR " : "");   MSG(cond & G_IO_HUP ? "G_IO_HUP " : "");   MSG(cond & G_IO_NVAL ? "G_IO_NVAL " : "");   MSG("]\n");} *//* IO API  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *//* * Return a newly created, and initialized, 'io' struct */IOData_t *a_IO_new(gint op, gint fd){   IOData_t *io = g_new0(IOData_t, 1);   io->Op = op;   io->FD = fd;   io->GioCh = g_io_channel_unix_new(fd);   io->Flags = 0;   io->Key = 0;   return io;}/* * Set the transfer buffer. * (if we allocate it, we free it) */void a_IO_set_buf(IOData_t *io, void *Buf, size_t BufSize){   if (io->Flags & IOFlag_FreeIOBuf) {      g_free(io->BufStart);      io->Flags &= ~IOFlag_FreeIOBuf;   }   if (!Buf && BufSize) {      io->BufStart = io->Buf = g_malloc(BufSize);      io->BufSize = BufSize;      io->Flags |= IOFlag_FreeIOBuf;   } else {      io->BufStart = io->Buf = Buf;      io->BufSize = BufSize;   }}/* * Add a new chunk to the transfer buffer. * (we allocate it, so we free it) */void a_IO_add_buf(IOData_t *io, void *Buf, size_t BufSize){   size_t offset;   if (BufSize == 0) {      /* This is the last chunk */      io->Flags |= IOFlag_ForceClose;      return;   }   offset = (io->Buf) ? io->Buf - io->BufStart : 0;   io->BufStart = g_realloc(io->BufStart, offset + io->BufSize + BufSize);   memcpy(io->BufStart + offset + io->BufSize, Buf, BufSize);   io->Buf = io->BufStart + offset;   io->BufSize += BufSize;   io->Flags |= IOFlag_FreeIOBuf;}/* * Return transfer buffer. */void a_IO_get_buf(IOData_t *io, void **Buf, size_t *BufSize){   *Buf = io->Buf;   *BufSize = io->BufSize;}typedef struct {   pthread_t thrID;        /* Thread id */   pthread_mutex_t mut;   pthread_cond_t cond;   gint FD;   void *Buf1Start;   void *Buf1;   size_t Buf1Size;   void *Buf2;   size_t Buf2Size;   gint LastChunk;   gint Done;} thr_data_t;/* Active data for threaded chunk transfers */static thr_data_t **ThrData = NULL;static gint ThrDataSize = 0;static gint ThrDataMax = 8;/* * Create a new ThrData node */static thr_data_t *IO_thrdata_new(gint FD){   thr_data_t *data;   data = g_new(thr_data_t, 1);   pthread_mutex_init(&data->mut, NULL);   pthread_cond_init(&data->cond, NULL);   data->FD = FD;   data->Buf1Start = data->Buf1 = data->Buf2 = NULL;   data->Buf1Size = data->Buf2Size = 0;   data->LastChunk = 0;   data->Done = 0;   return data;}/* * Free a ThrData node */static void IO_thrdata_free(thr_data_t *td){   pthread_mutex_destroy(&td->mut);   pthread_cond_destroy(&td->cond);   g_free(td);}/* * Search data node for a FD * (This also frees already closed data) */static thr_data_t *IO_thrdata_find(gint FD){   gint i, idx = -1;   for (i = 0; i < ThrDataSize; ++i) {      if (ThrData[i]->Done) {         IO_thrdata_free(ThrData[i]);         a_List_remove(ThrData, i, ThrDataSize);         --i;      } else if (ThrData[i]->FD == FD) {         idx = i;      }   }   if (idx != -1)      return ThrData[idx];   return NULL;}/* * Write the data buffer through a FD. * [This function runs on its own thread] */static void *IO_write_chunk(void *ptr){   gint lock = 0;   thr_data_t *data = ptr;   ssize_t St;   gint st, done;   /* switch to detached state */   pthread_detach(data->thrID);   _MSG("thr::\n");   _MSG("      [thrID:%lu]\n", (gulong)data->thrID);   while (1) {      _MSG("thr:: trying to lock mutex\n");      if (!lock) {         pthread_mutex_lock(&data->mut);         lock = 1;      }      _MSG("thr:: mutex locked!\n");      _MSG("thr:: Buf1:%p Buf2:%p LastChunk:%d Done:%d\n",           data->Buf1, data->Buf2, data->LastChunk, data->Done);      if (data->Buf2) {         /* Buf1 := Buf2;  Buf2 := NULL */         g_free(data->Buf1Start);         data->Buf1Start = data->Buf1 = data->Buf2;         data->Buf1Size = data->Buf2Size;         data->Buf2 = NULL;         data->Buf2Size = 0;         _MSG("thr:: Buf1:%p Buf2:%p LastChunk:%d Done:%d\n",              data->Buf1, data->Buf2, data->LastChunk, data->Done);         pthread_mutex_unlock(&data->mut);         lock = 0;         _MSG("thr:: mutex unlocked!\n");         /*** write all ***/         done = 0;         while (!done) {            St = write(data->FD, data->Buf1, data->Buf1Size);            _MSG("thr:: St=%d\n", St);            if (St < 0) {               if (errno == EINTR) {                  continue;               } else {                  perror("IO_write_chunk");                  return NULL;               }            } else if ((size_t)St < data->Buf1Size) {               /* Not all data written */               data->Buf1 = (gchar *)data->Buf1 + St;               data->Buf1Size -= St;            } else {               /* All data in buffer written */               //sleep(1);               done = 1;            }         }      }      /* Buf1 was written, prepare the next step... */      if (!lock) {         pthread_mutex_lock(&data->mut);         lock = 1;      }      if (data->Buf2)         continue;      else if (data->LastChunk) {         do            st = close(data->FD);         while (st < 0 && errno == EINTR);         data->Done = 1;         pthread_mutex_unlock(&data->mut);         _MSG("thr:: LastChunk:%d Done:%d  --Bailing out!\n",              data->LastChunk, data->Done);         return NULL;      } else {         _MSG("thr:: going to cond_wait...\n");         pthread_cond_wait(&data->cond, &data->mut);         lock = 1;      }   }/* while (1) */}/* * Write a data chunk from a pthread * (LastChunk -> close tansfer) */void a_IO_write_chunk(gint FD, void *Buf, size_t BufSize){   thr_data_t *data;   /* Search data node for this FD */   data = IO_thrdata_find(FD);   if (!data) {      data = IO_thrdata_new(FD);      a_List_add(ThrData, ThrDataSize, ThrDataMax);      ThrData[ThrDataSize] = data;      ThrDataSize++;      pthread_create(&data->thrID, NULL, IO_write_chunk, data);   }   pthread_mutex_lock(&data->mut);    if (Buf && BufSize) {       data->Buf2 = g_realloc(data->Buf2, data->Buf2Size + BufSize);       memcpy(data->Buf2 + data->Buf2Size, Buf, BufSize);       data->Buf2Size = data->Buf2Size + BufSize;    } else {       data->LastChunk = 1;    }    pthread_cond_signal(&data->cond);   pthread_mutex_unlock(&data->mut);}/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *//* * Register an IO in ValidIOs */static void IO_ins(IOData_t *io){   io->Key = a_Klist_insert(&ValidIOs, (gpointer)io);}/* * Remove an IO from ValidIOs */static void IO_del(IOData_t *io){   a_Klist_remove(ValidIOs, io->Key);}/* * Return a io by its Key (NULL if not found) */static IOData_t *IO_get(gint Key){   return a_Klist_get_data(ValidIOs, Key);}/* * Free an 'io' struct */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -