Skip to content

Commit

Permalink
* made NSFileHandle threadsafe, which needed -closeFile to explicitly…
Browse files Browse the repository at this point in the history
… call -finalize now
  • Loading branch information
mulle-nat committed Dec 11, 2024
1 parent b082d45 commit 4b46011
Show file tree
Hide file tree
Showing 46 changed files with 181 additions and 102 deletions.
2 changes: 1 addition & 1 deletion .mulle/share/env/environment-plugin.sh

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .mulle/share/env/version

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .mulle/share/sde/version/mulle-sde/cmake

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required( VERSION 3.15)

project( MulleObjCOSFoundation VERSION 0.23.0 LANGUAGES C)
project( MulleObjCOSFoundation VERSION 0.24.0 LANGUAGES C)


# we don't produce any Loader, the subprojects do that
Expand Down
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ It builds differently on each platform.

| Release Version | Release Notes
|-------------------------------------------------------|--------------
| ![Mulle kybernetiK tag](https://img.shields.io/github/tag/MulleFoundation/MulleObjCOSFoundation.svg?branch=release) [![Build Status](https://github.com/MulleFoundation/MulleObjCOSFoundation/workflows/CI/badge.svg?branch=release)](//github.com/MulleFoundation/MulleObjCOSFoundation/actions) | [RELEASENOTES](RELEASENOTES.md) |
| ![Mulle kybernetiK tag](https://img.shields.io/github/tag/MulleFoundation/MulleObjCOSFoundation.svg) [![Build Status](https://github.com/MulleFoundation/MulleObjCOSFoundation/workflows/CI/badge.svg)](//github.com/MulleFoundation/MulleObjCOSFoundation/actions) | [RELEASENOTES](RELEASENOTES.md) |


## API
Expand Down Expand Up @@ -56,16 +56,14 @@ mulle-sde add github:MulleFoundation/MulleObjCOSFoundation

## Install

### Install with mulle-sde

Use [mulle-sde](//github.com/mulle-sde) to build and install MulleObjCOSFoundation:

``` sh
mulle-sde install --prefix /usr/local \
https://github.com/MulleFoundation/MulleObjCOSFoundation/archive/latest.tar.gz
```

### Manual Installation
### Legacy Installation


Download the latest [tar](https://github.com/MulleFoundation/MulleObjCOSFoundation/archive/refs/tags/latest.tar.gz) or [zip](https://github.com/MulleFoundation/MulleObjCOSFoundation/archive/refs/tags/latest.zip) archive and unpack it.
Expand Down
5 changes: 5 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.24.0

* made NSFileHandle threadsafe, which needed -closeFile to explicitly call -finalize now


## 0.23.0

feat: enhance thread safety and system integration
Expand Down
13 changes: 9 additions & 4 deletions cmake/share/InstallRpath.cmake

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/BSD/.mulle/share/env/environment-plugin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ export MULLE_SOURCETREE_SYMLINK='YES'
#
#
#
export MULLE_SDE_INSTALLED_VERSION="3.2.0"
export MULLE_SDE_INSTALLED_VERSION="3.2.2"


2 changes: 1 addition & 1 deletion src/BSD/.mulle/share/env/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.3.0
5.3.1
2 changes: 1 addition & 1 deletion src/BSD/.mulle/share/sde/version/mulle-sde/cmake
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.28.0
0.28.1
13 changes: 9 additions & 4 deletions src/BSD/cmake/share/InstallRpath.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@ if( MULLE_NO_CMAKE_INSTALL_RPATH)
set( CMAKE_SKIP_BUILD_RPATH ON)
else()
if( APPLE)
set( CMAKE_INSTALL_RPATH
"@loader_path/../lib/"
"@loader_path/../Frameworks/"
)
if( CMAKE_VERSION VERSION_GREATER_EQUAL 3.20)
# Modern CMake handles lib path automatically
set(CMAKE_INSTALL_RPATH "@loader_path/../Frameworks/")
else()
set(CMAKE_INSTALL_RPATH
"@loader_path/../lib/"
"@loader_path/../Frameworks/"
)
endif()
else()
set( CMAKE_INSTALL_RPATH "\$ORIGIN/../lib")
endif()
Expand Down
2 changes: 1 addition & 1 deletion src/Darwin/.mulle/share/env/environment-plugin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ export MULLE_SOURCETREE_SYMLINK='YES'
#
#
#
export MULLE_SDE_INSTALLED_VERSION="3.2.0"
export MULLE_SDE_INSTALLED_VERSION="3.2.2"


2 changes: 1 addition & 1 deletion src/Darwin/.mulle/share/env/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.3.0
5.3.1
2 changes: 1 addition & 1 deletion src/Darwin/.mulle/share/sde/version/mulle-sde/cmake
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.28.0
0.28.1
13 changes: 9 additions & 4 deletions src/Darwin/cmake/share/InstallRpath.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@ if( MULLE_NO_CMAKE_INSTALL_RPATH)
set( CMAKE_SKIP_BUILD_RPATH ON)
else()
if( APPLE)
set( CMAKE_INSTALL_RPATH
"@loader_path/../lib/"
"@loader_path/../Frameworks/"
)
if( CMAKE_VERSION VERSION_GREATER_EQUAL 3.20)
# Modern CMake handles lib path automatically
set(CMAKE_INSTALL_RPATH "@loader_path/../Frameworks/")
else()
set(CMAKE_INSTALL_RPATH
"@loader_path/../lib/"
"@loader_path/../Frameworks/"
)
endif()
else()
set( CMAKE_INSTALL_RPATH "\$ORIGIN/../lib")
endif()
Expand Down
2 changes: 1 addition & 1 deletion src/FreeBSD/.mulle/share/env/environment-plugin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ export MULLE_SOURCETREE_SYMLINK='YES'
#
#
#
export MULLE_SDE_INSTALLED_VERSION="3.2.0"
export MULLE_SDE_INSTALLED_VERSION="3.2.2"


2 changes: 1 addition & 1 deletion src/FreeBSD/.mulle/share/env/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.3.0
5.3.1
2 changes: 1 addition & 1 deletion src/FreeBSD/.mulle/share/sde/version/mulle-sde/cmake
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.28.0
0.28.1
13 changes: 9 additions & 4 deletions src/FreeBSD/cmake/share/InstallRpath.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@ if( MULLE_NO_CMAKE_INSTALL_RPATH)
set( CMAKE_SKIP_BUILD_RPATH ON)
else()
if( APPLE)
set( CMAKE_INSTALL_RPATH
"@loader_path/../lib/"
"@loader_path/../Frameworks/"
)
if( CMAKE_VERSION VERSION_GREATER_EQUAL 3.20)
# Modern CMake handles lib path automatically
set(CMAKE_INSTALL_RPATH "@loader_path/../Frameworks/")
else()
set(CMAKE_INSTALL_RPATH
"@loader_path/../lib/"
"@loader_path/../Frameworks/"
)
endif()
else()
set( CMAKE_INSTALL_RPATH "\$ORIGIN/../lib")
endif()
Expand Down
2 changes: 1 addition & 1 deletion src/Linux/.mulle/share/env/environment-plugin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ export MULLE_SOURCETREE_SYMLINK='YES'
#
#
#
export MULLE_SDE_INSTALLED_VERSION="3.2.0"
export MULLE_SDE_INSTALLED_VERSION="3.2.2"


2 changes: 1 addition & 1 deletion src/Linux/.mulle/share/env/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.3.0
5.3.1
2 changes: 1 addition & 1 deletion src/Linux/.mulle/share/sde/version/mulle-sde/cmake
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.28.0
0.28.1
13 changes: 9 additions & 4 deletions src/Linux/cmake/share/InstallRpath.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@ if( MULLE_NO_CMAKE_INSTALL_RPATH)
set( CMAKE_SKIP_BUILD_RPATH ON)
else()
if( APPLE)
set( CMAKE_INSTALL_RPATH
"@loader_path/../lib/"
"@loader_path/../Frameworks/"
)
if( CMAKE_VERSION VERSION_GREATER_EQUAL 3.20)
# Modern CMake handles lib path automatically
set(CMAKE_INSTALL_RPATH "@loader_path/../Frameworks/")
else()
set(CMAKE_INSTALL_RPATH
"@loader_path/../lib/"
"@loader_path/../Frameworks/"
)
endif()
else()
set( CMAKE_INSTALL_RPATH "\$ORIGIN/../lib")
endif()
Expand Down
2 changes: 1 addition & 1 deletion src/MulleObjCOSFoundation.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by Nat! on 05.04.16.
// Copyright © 2016 Mulle kybernetiK. All rights reserved.
//
#define MULLE_OBJC_OS_FOUNDATION_VERSION ((0UL << 20) | (23 << 8) | 0)
#define MULLE_OBJC_OS_FOUNDATION_VERSION ((0UL << 20) | (24 << 8) | 0)


#import "import.h"
Expand Down
2 changes: 1 addition & 1 deletion src/OSBase/.mulle/share/env/environment-plugin.sh

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/OSBase/.mulle/share/env/version

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/OSBase/.mulle/share/sde/version/mulle-sde/cmake

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 19 additions & 12 deletions src/OSBase/NSFileHandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,27 @@
MULLE_OBJC_OSBASE_FOUNDATION_GLOBAL
NSString *NSFileHandleOperationException;

enum NSFileHandleStateBit
{
NSFileHandleStateEOF = 1,
NSFileHandleStatePipe = 2,
NSFileHandleStateAgain = 4
};

//
// This class contains the abstract code for a NSFileHandle
// it could be made thread safe with little effort, but a filehandle object
// should only be accessed by a single thread anyway (the underlying file
// descriptor (like 1 for stdout) is a different thing)
//
@interface NSFileHandle : NSObject <MulleObjCInputStream, MulleObjCOutputStream>
@interface NSFileHandle : NSObject <MulleObjCInputStream, MulleObjCOutputStream, MulleObjCThreadSafe>
{
void *_fd;
int (*_closer)( void *); // TODO: use mulle_buffer_stdio_functions ??
int _mode;
struct
{
unsigned int eof : 1;
unsigned int pipe : 1;
unsigned int again : 1;
} _state;
void *_fd;
int (*_closer)( void *); // TODO: use mulle_buffer_stdio_functions ??
int _mode;
int _closerRval;
NSUIntegerAtomic _state;
}

+ (instancetype) fileHandleForReadingAtPath:(NSString *) path;
+ (instancetype) fileHandleForWritingAtPath:(NSString *) path;
+ (instancetype) fileHandleForUpdatingAtPath:(NSString *) path;
Expand All @@ -65,11 +67,16 @@ NSString *NSFileHandleOperationException;
- (int) _fileDescriptorForReading;
- (int) _fileDescriptorForWriting;


// does -finalize
- (void) closeFile;

// mulle addition, if len == -1, it will strlen bytes!!
- (void) mulleWriteBytes:(void *) bytes
length:(NSUInteger) len;

- (void) closeFile;
- (void) mulleAddToStateBits:(NSUInteger) bits;
- (NSUInteger) mulleGetStateBits;

@end

Expand Down
43 changes: 31 additions & 12 deletions src/OSBase/NSFileHandle.m
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ static id NSInitFileHandle( NSFileHandle *self, void *fd)
return( self);
}


- (instancetype) initWithFileDescriptor:(int) fd
{
return( NSInitFileHandle( self, (void *) (intptr_t) fd));
Expand Down Expand Up @@ -128,9 +129,20 @@ + (instancetype) fileHandleWithNullDevice
}


///
// we basically use -finalize as a thread sync mechanism here, as only
// one thread can be executing close
//
- (void) finalize
{
[self closeFile];
if( _closer)
{
_closerRval = (*_closer)( _fd);
if( _closerRval == 0)
_closer = 0;
// else, raise or what ?
}

[super finalize];
}

Expand All @@ -140,15 +152,7 @@ - (void) finalize

- (void) closeFile
{
int rval;

if( ! _closer)
return;

rval = (*_closer)( _fd);
if( rval == 0)
_closer = 0;
// raise or what ?
[self mullePerformFinalize];
}


Expand Down Expand Up @@ -188,7 +192,7 @@ - (int) _fileDescriptorForWriting
char *buf;
char *start;

if( ! length || self->_state.eof)
if( ! length || (NSUIntegerAtomicGet( &self->_state) & NSFileHandleStateEOF))
return( nil);

data = [NSMutableData dataWithLength:length];
Expand Down Expand Up @@ -271,7 +275,7 @@ - (void) mulleWriteBytes:(void *) bytes
{
written = [self _writeBytes:buf
length:len];
if( ! written && _state.eof)
if( ! written && (NSUIntegerAtomicGet( &self->_state) & NSFileHandleStateEOF))
break;

len -= written;
Expand Down Expand Up @@ -309,5 +313,20 @@ - (void) truncateFileAtOffset:(unsigned long long) offset
mode:_MulleObjCSeekCur]; // TODO: check!
}


- (void) mulleAddToStateBits:(NSUInteger) bits
{
NSUIntegerAtomicMaskedOr( &self->_state, ~0L, bits);
}


- (NSUInteger) mulleGetStateBits
{
NSUInteger state;

state = NSUIntegerAtomicGet( &self->_state);
return( state);
}

@end

6 changes: 6 additions & 0 deletions src/OSBase/NSRunLoop.m
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,12 @@ + (void) willFinalize
{
NSRunLoop *runLoop;

//
// if thread is already finalized, don't create another runloop
//
if( thread && _mulle_objc_object_is_finalized( thread))
return( nil);

runLoop = [thread mulleRunLoop];
if( ! runLoop && ! Self._isFinalizing)
{
Expand Down
Loading

0 comments on commit 4b46011

Please sign in to comment.