close the device only if it's opened

This commit is contained in:
Alexandre Ratchov 2012-10-15 18:19:07 +02:00
parent cf80edff3e
commit 61c00bcef2
3 changed files with 66 additions and 118 deletions

View File

@ -478,7 +478,8 @@ dev_midi_exit(void *arg)
dev_log(d); dev_log(d);
log_puts(": midi end point died\n"); log_puts(": midi end point died\n");
} }
dev_close(d); if (d->pstate != DEV_CFG)
dev_close(d);
} }
void void
@ -915,8 +916,7 @@ dev_cycle(struct dev *d)
dev_log(d); dev_log(d);
log_puts(": device stopped\n"); log_puts(": device stopped\n");
} }
if (d->sio) siofile_stop(d->sio);
siofile_stop(d->sio);
d->pstate = DEV_INIT; d->pstate = DEV_INIT;
if (d->refcnt == 0) if (d->refcnt == 0)
dev_close(d); dev_close(d);
@ -998,7 +998,7 @@ dev_new(char *path, struct aparams *par,
d->mtc.origin = 0; d->mtc.origin = 0;
d->tstate = MMC_STOP; d->tstate = MMC_STOP;
d->next = dev_list; d->next = dev_list;
dev_list = d; dev_list = d;
return d; return d;
} }
@ -1126,10 +1126,8 @@ dev_close(struct dev *d)
s->ops = NULL; s->ops = NULL;
d->slot_list = snext; d->slot_list = snext;
} }
if (d->sio) { siofile_del(d->sio);
siofile_del(d->sio); d->sio = NULL;
d->sio = NULL;
}
dev_clear(d); dev_clear(d);
d->pstate = DEV_CFG; d->pstate = DEV_CFG;
} }
@ -1223,7 +1221,8 @@ dev_del(struct dev *d)
log_puts(": deleting\n"); log_puts(": deleting\n");
} }
#endif #endif
dev_close(d); if (d->pstate != DEV_CFG)
dev_close(d);
for (p = &dev_list; *p != d; p = &(*p)->next) { for (p = &dev_list; *p != d; p = &(*p)->next) {
#ifdef DEBUG #ifdef DEBUG
if (*p == NULL) { if (*p == NULL) {
@ -1266,8 +1265,7 @@ dev_wakeup(struct dev *d)
d->prime = 0; d->prime = 0;
} }
d->pstate = DEV_RUN; d->pstate = DEV_RUN;
if (d->sio) siofile_start(d->sio);
siofile_start(d->sio);
} }
} }

View File

@ -20,6 +20,7 @@
* slow syscalls are no longer disruptive, e.g. at the end of the poll() loop. * slow syscalls are no longer disruptive, e.g. at the end of the poll() loop.
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include "utils.h" #include "utils.h"
@ -136,24 +137,6 @@ panic(void)
abort(); abort();
} }
#if 0
/*
* allocate memory, and abort on error
*/
void *
xmalloc(size_t size)
{
void *p;
p = malloc(size);
if (p == NULL) {
log_puts("failed to allocate memory\n");
panic();
}
return p;
}
#endif
/* /*
* return a random number, will be used to randomize memory bocks * return a random number, will be used to randomize memory bocks
*/ */
@ -179,129 +162,94 @@ memrnd(void *addr, size_t size)
* header of a memory block * header of a memory block
*/ */
struct mem_hdr { struct mem_hdr {
char *owner; /* who allocaed the block ? */ struct mem_hdr *next; /* next allocated block */
unsigned words; /* data chunk size expressed in sizeof(int) */ char *tag; /* hint on what allocated the block */
#define MAGIC_FREE 0xa55f9811 /* a (hopefully) ``rare'' number */ size_t size; /* data chunk size in bytes */
unsigned magic; /* random number, but not MAGIC_FREE */ char end[sizeof(void *)]; /* copy of trailed (random bytes) */
}; };
unsigned mem_nalloc = 0, mem_nfree = 0, mem_debug = 0; #define MEM_HDR_SIZE ((sizeof(struct mem_hdr) + 15) & ~15)
struct mem_hdr *mem_list= NULL;
/* /*
* return a random number, will be used to randomize memory bocks * allocate 'size' bytes of memory (with size > 0). This functions never
*/
unsigned
mem_rnd(void)
{
static unsigned seed = 1989123;
seed = (seed * 1664525) + 1013904223;
return seed;
}
/*
* allocate 'n' bytes of memory (with n > 0). This functions never
* fails (and never returns NULL), if there isn't enough memory then * fails (and never returns NULL), if there isn't enough memory then
* we abord the program. The memory block is randomized to break code * we abort the program. The memory block is randomized to break code
* that doesn't initialize the block. We also add a footer and a * that doesn't initialize the block. We also add a footer and a
* trailer to detect writes outside the block boundaries. * trailer to detect writes outside the block boundaries.
*/ */
void * void *
mem_alloc(unsigned bytes, char *owner) mem_alloc(size_t size, char *tag)
{ {
unsigned words, i, *p;
struct mem_hdr *hdr; struct mem_hdr *hdr;
char *p;
if (bytes == 0) {
log_puts(owner); if (size == 0) {
log_puts(tag);
log_puts(": mem_alloc: nbytes = 0\n"); log_puts(": mem_alloc: nbytes = 0\n");
panic(); panic();
} }
hdr = malloc(size + MEM_HDR_SIZE + sizeof(hdr->end));
/*
* calculates the number of ints corresponding to ``bytes''
*/
words = (bytes + sizeof(int) - 1) / sizeof(int);
/*
* allocate the header, the data chunk and the trailer
*/
hdr = malloc(sizeof(struct mem_hdr) + (words + 1) * sizeof(int));
if (hdr == NULL) { if (hdr == NULL) {
log_puts(owner); log_puts(tag);
log_puts(": mem_alloc: failed to allocate "); log_puts(": mem_alloc: failed to allocate ");
log_putx(words); log_putx(size);
log_puts(" words\n"); log_puts(" bytes\n");
panic(); panic();
} }
p = (char *)hdr + MEM_HDR_SIZE;
/* hdr->tag = tag;
* find a random magic, but not MAGIC_FREE hdr->size = size;
*/ memrnd(hdr->end, sizeof(hdr->end));
do { memset(p, 0xd0, size);
hdr->magic = mem_rnd(); memcpy(p + size, hdr->end, sizeof(hdr->end));
} while (hdr->magic == MAGIC_FREE); hdr->next = mem_list;
mem_list = hdr;
/* return p;
* randomize data chunk
*/
p = (unsigned *)(hdr + 1);
for (i = words; i > 0; i--)
*p++ = mem_rnd();
/*
* trailer is equal to the magic
*/
*p = hdr->magic;
hdr->owner = owner;
hdr->words = words;
mem_nalloc++;
return hdr + 1;
} }
/* /*
* free a memory block. Also check that the header and the trailer * free a memory block. Also check that the header and the trailer
* werent changed and randomise the block, so that the block is not * weren't changed and randomise the block, so that the block is not
* usable once freed * usable once freed
*/ */
void void
mem_free(void *mem) mem_free(void *p)
{ {
struct mem_hdr *hdr; struct mem_hdr *hdr, **ph;
unsigned i, *p;
hdr = (struct mem_hdr *)mem - 1; hdr = (struct mem_hdr *)((char *)p - MEM_HDR_SIZE);
p = (unsigned *)mem; if (memcmp(hdr->end, (char *)p + hdr->size, sizeof(hdr->end)) != 0) {
log_puts(hdr->tag);
if (hdr->magic == MAGIC_FREE) { log_puts(": block trailer corrupted\n");
log_puts("mem_free: block seems already freed\n");
panic(); panic();
} }
if (hdr->magic != p[hdr->words]) { memset(p, 0xdf, hdr->size);
log_puts("mem_free: block corrupted\n"); for (ph = &mem_list; *ph != NULL; ph = &(*ph)->next) {
panic(); if (*ph == hdr) {
*ph = hdr->next;
free(hdr);
return;
}
} }
log_puts(hdr->tag);
/* log_puts(": not allocated (double free?)\n");
* randomize block, so it's not usable panic();
*/
for (i = hdr->words; i > 0; i--)
*p++ = mem_rnd();
hdr->magic = MAGIC_FREE;
mem_nfree++;
free(hdr);
} }
void void
mem_stats(void) mem_stats(void)
{ {
if (mem_debug) { struct mem_hdr *hdr;
log_puts("mem_stats: used=");
log_putu(mem_nalloc - mem_nfree); if (mem_list) {
log_puts(", alloc="); log_puts("allocated memory blocs: ");
log_putu(mem_nalloc); for (hdr = mem_list; hdr != NULL; hdr = hdr->next) {
log_puts(hdr->tag);
if (hdr->next)
log_puts(", ");
}
log_puts("\n"); log_puts("\n");
} }
} }

View File

@ -17,6 +17,8 @@
#ifndef UTILS_H #ifndef UTILS_H
#define UTILS_H #define UTILS_H
#include <sys/types.h>
void log_puts(char *); void log_puts(char *);
void log_putx(unsigned long); void log_putx(unsigned long);
void log_putu(unsigned long); void log_putu(unsigned long);
@ -25,7 +27,7 @@ void panic(void);
void log_flush(void); void log_flush(void);
//void *xmalloc(size_t); //void *xmalloc(size_t);
void *mem_alloc(unsigned, char *); void *mem_alloc(size_t, char *);
void mem_free(void *); void mem_free(void *);
void mem_stats(void); void mem_stats(void);