Logo Search packages:      
Sourcecode: darcs version File versions

zlib_helper.c

/*
 * Copyright (C) 2003 David Roundy
 * Most of the UTF code is Copyright (C) 1999-2001 Free Software Foundation, Inc.
 * This file is part of darcs.
 *
 * Darcs is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Library General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with the GNU LIBICONV Library; see the file COPYING.LIB.
 * If not, write to the Free Software Foundation, Inc., 59 Temple Place -
 * Suite 330, Boston, MA 02111-1307, USA.
 *
 */
#include <sys/types.h>
#include <unistd.h>
#include <zlib.h>
#include <stdlib.h>

#ifdef WIN32THREADS
#include <windows.h>
#else
#include <pthread.h>
#endif

#include "zlib_helper.h"

const int bufsize = 1024;

typedef struct {
  int fd;
  void *gzf;
} thread_data;

#ifdef WIN32THREADS
DWORD WINAPI the_reader(void *void_th) {
#else
static void *the_reader(void *void_th) {
#endif
  char buf[bufsize];
  thread_data *th = (thread_data *)void_th;
  while (!gzeof(th->gzf)) {
    int bytesread = gzread(th->gzf, buf, bufsize);
    int byteswritten = 0;
    while (byteswritten < bytesread)
      byteswritten += write(th->fd, buf+byteswritten, bytesread-byteswritten);
  }
  gzclose(th->gzf);
  close(th->fd);
  free(th);
  return NULL;
}

int gzreader(char *f, int *thid) {
  int fd[2];
#ifdef WIN32THREADS
  HANDLE hdl;
  DWORD temp;
#else
  pthread_t the_thid;
#endif
  thread_data *th = (thread_data *) malloc(sizeof(thread_data));
  if (!th) return -1;
  if (pipe(fd)) {
    free(th);
    return -1;
  }
  th->gzf = gzopen(f,"rb");
  th->fd = fd[1];
#ifdef WIN32THREADS
  hdl = CreateThread(NULL, 0, the_reader, th, 0, &temp);
  if (!hdl) {
    gzclose(th->gzf);
    close(th->fd);
    free(th);
    return -2;
  }
  *thid = (int) hdl;
#else
  if (pthread_create(&the_thid, NULL, the_reader, th)) {
    gzclose(th->gzf);
    close(th->fd);
    free(th);
    return -2;
  }
  *thid = the_thid;
#endif
  return fd[0];
}

#ifdef WIN32THREADS
DWORD WINAPI the_writer(void *void_th) {
#else
static void *the_writer(void *void_th) {
#endif
  char buf[bufsize];
  thread_data *th = (thread_data *)void_th;
  int bytesread;
  while (bytesread = read(th->fd,buf,bufsize)) {
    int byteswritten = 0;
    while (byteswritten < bytesread) {
      int morebytes = gzwrite(th->gzf, buf+byteswritten,
                              bytesread-byteswritten);
      if (morebytes == 0) {
        gzclose(th->gzf);
      close(th->fd);
      free(th);
        return (void *)1; /* Error!!! */
      }
      byteswritten += morebytes;
    }
  }
  gzclose(th->gzf);
  close(th->fd);
  free(th);
  return NULL;
}

int gzwriter(char *f, int *thid) {
  int fd[2];
#ifdef WIN32THREADS
  HANDLE hdl;
  DWORD temp;
#else
  pthread_t the_thid;
#endif
  thread_data *th = (thread_data *) malloc(sizeof(thread_data));
  if (!th) return -1;
  if (pipe(fd)) {
    free(th);
    return -1;
  }
  th->gzf = gzopen(f,"wb");
  th->fd = fd[0];
#ifdef WIN32THREADS
  hdl = CreateThread(NULL, 0, the_writer, th, 0, &temp);
  if (!hdl) {
    gzclose(th->gzf);
    close(th->fd);
    free(th);
    return -2;
  }
  *thid = (int) hdl;
#else
  if (pthread_create(&the_thid, NULL, the_writer, th)) {
    gzclose(th->gzf);
    close(th->fd);
    return -2;
  }
  *thid = the_thid;
#endif
  return fd[1];
}

int wait_on_gz(int thid) {
#ifdef WIN32THREADS
  int retval = 0;
  int joinval = WaitForSingleObject((HANDLE) thid, INFINITE);
  if (joinval == 0)
    GetExitCodeThread((HANDLE) thid, (LPDWORD)&retval);
#else
  void* retval;
  int joinval = pthread_join(thid, &retval);
#endif
  if (joinval) return joinval;
  else return (int) retval;
}

void detach_gz(int thid) {
#ifdef WIN32THREADS
  CloseHandle((HANDLE)thid);
#else
  pthread_detach(thid);
#endif
}


Generated by  Doxygen 1.6.0   Back to index