Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Icecast-Server
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
spr0cketeer
Icecast-Server
Commits
02c9eb7f
Commit
02c9eb7f
authored
Jun 06, 2018
by
Philipp Schafft
🦁
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Feature: Added fast event API
parent
8cf3da1a
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
232 additions
and
0 deletions
+232
-0
src/fastevent.c
src/fastevent.c
+193
-0
src/fastevent.h
src/fastevent.h
+39
-0
No files found.
src/fastevent.c
View file @
02c9eb7f
...
...
@@ -14,8 +14,201 @@
#include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include "common/thread/thread.h"
#include "fastevent.h"
#include "logging.h"
#define CATMODULE "fastevent"
#ifdef FASTEVENT_ENABLED
struct
registration
{
refobject_base_t
__base
;
fastevent_type_t
type
;
fastevent_cb_t
cb
;
fastevent_freecb_t
freecb
;
void
*
userdata
;
};
struct
eventrow
{
size_t
length
;
size_t
used
;
struct
registration
**
registrations
;
};
static
struct
eventrow
fastevent_registrations
[
FASTEVENT_TYPE__END
];
static
rwlock_t
fastevent_lock
;
static
inline
struct
eventrow
*
__get_row
(
fastevent_type_t
type
)
{
size_t
idx
=
type
;
if
(
idx
>=
FASTEVENT_TYPE__END
)
return
NULL
;
return
&
(
fastevent_registrations
[
idx
]);
}
static
int
__add_to_row
(
struct
eventrow
*
row
,
struct
registration
*
registration
)
{
struct
registration
**
n
;
if
(
row
==
NULL
)
return
-
1
;
/* Check if we need to reallocate row space */
if
(
row
->
length
==
row
->
used
)
{
n
=
realloc
(
row
->
registrations
,
sizeof
(
*
n
)
*
(
row
->
length
+
4
));
if
(
n
==
NULL
)
{
ICECAST_LOG_ERROR
(
"Can not allocate row space."
);
return
-
1
;
}
row
->
registrations
=
n
;
row
->
length
+=
4
;
}
row
->
registrations
[
row
->
used
++
]
=
registration
;
return
0
;
}
static
int
__remove_from_row
(
struct
eventrow
*
row
,
struct
registration
*
registration
)
{
size_t
i
;
if
(
row
==
NULL
)
return
-
1
;
for
(
i
=
0
;
i
<
row
->
used
;
i
++
)
{
if
(
row
->
registrations
[
i
]
==
registration
)
{
memmove
(
&
(
row
->
registrations
[
i
]),
&
(
row
->
registrations
[
i
+
1
]),
sizeof
(
*
(
row
->
registrations
))
*
(
row
->
used
-
i
-
1
));
row
->
used
--
;
return
0
;
}
}
return
-
1
;
}
static
void
__unregister
(
refobject_t
self
,
void
**
userdata
)
{
struct
registration
*
registration
=
REFOBJECT_TO_TYPE
(
self
,
struct
registration
*
);
struct
eventrow
*
row
;
(
void
)
userdata
;
thread_rwlock_wlock
(
&
fastevent_lock
);
row
=
__get_row
(
registration
->
type
);
if
(
__remove_from_row
(
row
,
registration
)
!=
0
)
{
ICECAST_LOG_ERROR
(
"Can not remove fast event from row. BUG."
);
}
thread_rwlock_unlock
(
&
fastevent_lock
);
if
(
registration
->
freecb
)
registration
->
freecb
(
&
(
registration
->
userdata
));
if
(
registration
->
userdata
!=
NULL
)
free
(
registration
->
userdata
);
}
int
fastevent_initialize
(
void
)
{
thread_rwlock_create
(
&
fastevent_lock
);
return
0
;
}
int
fastevent_shutdown
(
void
)
{
size_t
i
;
thread_rwlock_wlock
(
&
fastevent_lock
);
for
(
i
=
0
;
i
<
FASTEVENT_TYPE__END
;
i
++
)
{
if
(
fastevent_registrations
[
i
].
used
)
{
ICECAST_LOG_ERROR
(
"Subsystem shutdown but elements still in use. BUG."
);
continue
;
}
free
(
fastevent_registrations
[
i
].
registrations
);
fastevent_registrations
[
i
].
registrations
=
NULL
;
}
thread_rwlock_unlock
(
&
fastevent_lock
);
thread_rwlock_destroy
(
&
fastevent_lock
);
return
0
;
}
refobject_t
fastevent_register
(
fastevent_type_t
type
,
fastevent_cb_t
cb
,
fastevent_freecb_t
freecb
,
void
*
userdata
)
{
struct
eventrow
*
row
;
struct
registration
*
registration
;
refobject_t
ret
;
if
(
cb
==
NULL
)
return
REFOBJECT_NULL
;
thread_rwlock_wlock
(
&
fastevent_lock
);
row
=
__get_row
(
type
);
if
(
row
==
NULL
)
{
thread_rwlock_unlock
(
&
fastevent_lock
);
return
REFOBJECT_NULL
;
}
ret
=
refobject_new
(
sizeof
(
struct
registration
),
__unregister
,
NULL
,
NULL
,
NULL
);
if
(
REFOBJECT_IS_NULL
(
ret
))
{
thread_rwlock_unlock
(
&
fastevent_lock
);
return
REFOBJECT_NULL
;
}
registration
=
REFOBJECT_TO_TYPE
(
ret
,
struct
registration
*
);
registration
->
type
=
type
;
registration
->
cb
=
cb
;
registration
->
freecb
=
freecb
;
registration
->
userdata
=
userdata
;
if
(
__add_to_row
(
row
,
registration
)
!=
0
)
{
thread_rwlock_unlock
(
&
fastevent_lock
);
refobject_unref
(
ret
);
return
REFOBJECT_NULL
;
}
thread_rwlock_unlock
(
&
fastevent_lock
);
return
ret
;
}
void
fastevent_emit
(
fastevent_type_t
type
,
fastevent_flag_t
flags
,
fastevent_datatype_t
datatype
,
...)
{
struct
eventrow
*
row
;
va_list
ap
,
apx
;
size_t
i
;
ICECAST_LOG_DEBUG
(
"event: type=%i, flags=%i, datatype=%i, ..."
,
(
int
)
type
,
(
int
)
flags
,
(
int
)
datatype
);
thread_rwlock_rlock
(
&
fastevent_lock
);
row
=
__get_row
(
type
);
if
(
row
==
NULL
||
row
->
used
==
0
)
{
thread_rwlock_unlock
(
&
fastevent_lock
);
return
;
}
va_start
(
ap
,
datatype
);
for
(
i
=
0
;
i
<
row
->
used
;
i
++
)
{
va_copy
(
apx
,
ap
);
row
->
registrations
[
i
]
->
cb
(
row
->
registrations
[
i
]
->
userdata
,
type
,
flags
,
datatype
,
apx
);
va_end
(
apx
);
}
thread_rwlock_unlock
(
&
fastevent_lock
);
va_end
(
ap
);
}
#endif
src/fastevent.h
View file @
02c9eb7f
...
...
@@ -9,4 +9,43 @@
#ifndef __FASTEVENT_H__
#define __FASTEVENT_H__
/* Add all conditions when to enable fast events here. */
#if 1
#define FASTEVENT_ENABLED
#endif
#include <stdarg.h>
#include <refobject.h>
typedef
enum
{
FASTEVENT_TYPE_SLOWEVENT
=
0
,
FASTEVENT_TYPE__END
/* must be last element */
}
fastevent_type_t
;
typedef
enum
{
FASTEVENT_DATATYPE_NONE
=
0
,
FASTEVENT_DATATYPE_EVENT
,
FASTEVENT_DATATYPE_CLIENT
,
FASTEVENT_DATATYPE_CONNECTION
}
fastevent_datatype_t
;
typedef
int
fastevent_flag_t
;
#define FASTEVENT_FLAG_NONE ((fastevent_flag_t)0x0000)
#define FASTEVENT_FLAG_MODIFICATION_ALLOWED ((fastevent_flag_t)0x0001)
typedef
void
(
*
fastevent_cb_t
)(
const
void
*
userdata
,
fastevent_type_t
type
,
fastevent_flag_t
flags
,
fastevent_datatype_t
datatype
,
va_list
ap
);
typedef
void
(
*
fastevent_freecb_t
)(
void
**
userdata
);
#ifdef FASTEVENT_ENABLED
int
fastevent_initialize
(
void
);
int
fastevent_shutdown
(
void
);
refobject_t
fastevent_register
(
fastevent_type_t
type
,
fastevent_cb_t
cb
,
fastevent_freecb_t
freecb
,
void
*
userdata
);
void
fastevent_emit
(
fastevent_type_t
type
,
fastevent_flag_t
flags
,
fastevent_datatype_t
datatype
,
...);
#else
#define fastevent_initialize() 0
#define fastevent_shutdown() 0
#define fastevent_register(type,cb,freecb,userdata) REFOBJECT_NULL
#define fastevent_emit(type,flags,datatype,...)
#endif
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment